classTryouts# = Tryout## A Tryout is a set of drills (each drill is a test). #classTryout# The name of this tryoutattr_reader:name# A default value for Drill.dtypeattr_reader:dtype# A block to executed one time before starting the drillsattr_reader:setup# A block to executed one time before starting the drillsattr_reader:clean# An Array of Drill objectsattr_reader:drills# The number of dreams that came true (successful drills)attr_reader:passed# The number of dreams that did not come true (failed drills)attr_reader:failed# For drill type :cli, this is the name of the command to test. It# should be a valid method available to a Rye::Box object.# For drill type :api, this attribute is ignored. attr_reader:command# A Hash of Dream objects for this Tryout. The keys are drill names. attr_reader:dream_catcher@@valid_dtypes=[:cli,:api]definitialize(name,dtype,command=nil,*args)raise"Must supply command for dtype :cli"ifdtype==:cli&&command.nil?raise"#{dtype} is not a valid drill type"if!@@valid_dtypes.member?(dtype)@name,@dtype,@command=name,dtype,command@drills,@dream_catcher=[],[]@passed,@failed=0,0end## --------------------------------------- EXTERNAL API -----# Populate this Tryout from a block. The block should contain calls to # the external DSL methods: dream, drill, xdrilldeffrom_block(b=nil,&inline)runtime=b.nil??inline:binstance_eval&runtimeend# Execute all Drill objectsdefrunDrillContext.module_eval&setupifsetup.is_a?(Proc)putsTryouts::TRYOUT_MSG.bright%@name@drills.eachdo|drill|drill.runDrillContext.newnote=drill.dreams.empty??'[nodream]':''putsdrill.success??"PASS".color(:green):"FAIL #{note}".color(:red)puts" #{drill.reality.output.inspect}"ifTryouts.verbose>0ifTryouts.verbose>1drill.reality.stash.each_pairdo|n,v|puts'%14s: %s'%[n,v.inspect]endenddrill.success??@passed+=1:@failed+=1endDrillContext.module_eval&cleanifclean.is_a?(Proc)end# Prints error output. If there are no errors, it prints nothing. defreportreturntrueifsuccess?failed=@drills.select{|d|!d.success?}failed.each_with_indexdo|drill,index|dreams,reality=drill.dreams,drill.realitytitle=' %-59s'%%Q{ERROR #{index+1}/#{failed.size} "#{drill.name}"}puts$/,' '<<title.color(:red).att(:reverse)ifdreams.empty?puts'%12s: %s'%["expected","[nodream]"]puts'%12s: %s'%["returned",reality.output.inspect]elsedreams.eachdo|dream|puts'%12s: %s'%["expected",dream.output.inspect]endputs'%12s: %s'%["returned",reality.output.inspect]unlessreality.error.nil?puts'%12s: %s'%["error",reality.error.inspect]endunlessreality.trace.nil?puts'%12s: %s'%["trace",reality.trace.join($/+' '*14)]putsendendendfalseend# Did every Tryout finish successfully?defsuccess?return@successunless@success.nil?# Returns true only when every Tryout result returns true@success=!(@drills.collect{|r|r.success?}.member?(false))end# Add a Drill object to the list for this Tryout. If there is one or# more dreams in +@dream_catcher+, it will be added to drill +d+. defadd_drill(d)unless@dream_catcher.empty?d.add_dreams*@dream_catcher.clone# We need to clone here b/c@dream_catcher.clear# Ruby passes by reference.enddrills<<ddend## --------------------------------------- EXTERNAL DSL -----# A block to executed one time _before_ starting the drillsdefsetup(&block)return@setupunlessblock@setup=blockend# A block to executed one time _after_ the drillsdefclean(&block)return@cleanunlessblock@clean=blockend# Create and add a Drill object to the list for this Tryout# +name+ is the name of the drill. # +args+ is sent directly to the Drill class. The values are specific on the Sergeant.defdrill(dname,*args,&definition)raise"Empty drill name (#{@name})"ifdname.nil?||dname.empty?drill=Tryouts::Drill.new(dname,@dtype,*args,&definition)self.add_drilldrillend# A quick way to comment out a drilldefxdrill(*args,&b);@dream_catcher.clear;end# ignore calls to xdrill## NOTE: This method is DSL-only. It's not intended to be used in OO syntax. defdream(*args,&definition)ifargs.empty?dobj=Tryouts::Drill::Dream.from_blockdefinitionelseifargs.size==1dobj=Tryouts::Drill::Dream.new(args.shift)# dream 'OUTPUT'elsedobj=Tryouts::Drill::Dream.new(*args)# dream 'OUTPUT', :formatendend@dream_catcher.pushdobjdobjend# A quick way to comment out a dreamdefxdream(*args,&b);endend;end