class Tryouts::Drill
This class represents a drill. A drill is single test.
= Drill
def self.valid_dtype?(t); @@valid_dtypes.member?(t); end
def self.valid_dtype?(t); @@valid_dtypes.member?(t); end
def self.valid_dtypes; @@valid_dtypes; end
def self.valid_dtypes; @@valid_dtypes; end
def add_dream(d); @dreams << d; end
def add_dream(d); @dreams << d; end
def add_dreams(*d); @dreams += d; end
def add_dreams(*d); @dreams += d; end
def flag
def flag if skip? "SKIP" elsif success? "PASS".color(@clr).bright else note = @dreams.empty? ? '[nodream]' : '' "FAIL #{note}".color(@clr).bright end end
def has_error?
def has_error? !@reality.error.nil? end
def info
def info out = StringIO.new if Tryouts.verbose > 0 if @dtype == :benchmark unless @reality.output.nil? mean, sdev, sum = @reality.output.mean, @reality.output.sdev, @reality.output.sum out.puts '%6s%.4f (sdev:%.4f sum:%.4f)'.color(@clr) % ['', mean, sdev, sum] end elsif @dtype == :cli out.puts '%6s%s'.color(@clr) % ['', @reality.command] output = @reality.output output = output.join($/ + ' '*6) if output.kind_of?(Array) out.puts '%6s%s'.color(@clr) % ['', output] else out.puts '%6s%s'.color(@clr) % ['', @reality.output.inspect] end unless @reality.stash.empty? @reality.stash.each_pair do |n,v| out.puts '%18s: %s'.color(@clr) % [n,v.inspect] end end end if Tryouts.verbose > 1 @dreams.each do |dream| if dream != @reality out.puts '%6s%s'.color(:red) % ['', dream.test_to_string(@reality)] else out.puts '%6s%s'.color(:green) % ["", dream.test_to_string(@reality)] end end out.puts end out.rewind out.read end
def initialize(name, dtype, *args, &drill)
* dream FORMAT, OUTPUT, REPS (benchmark only)
* dream FORMAT, OUTPUT
* dream OUTPUT
The DSL syntax:
is compared to the exepected output of the dreams.
* +&drill+ The body of the drill. The return value of this block
* +args+ These are dependent on the drill type. See the Sergeant classes
* +dtype+ A Symbol representing the drill type. One of: :api, :benchmark
* +name+ The display name of this drill
def initialize(name, dtype, *args, &drill) @name, @dtype, @drill, @skip = name, dtype, drill, false @dreams = [] # We create a default empty reality but if the drill runs correctly # this reality gets replaced with the return value from the drill. @reality = Tryouts::Drill::Reality.new case @dtype when :cli # For CLI drills, a block takes precedence over inline args. # A block will contain multiple shell commands (see Rye::Box#batch) args = [] if dtype == :cli && drill.is_a?(Proc) @sergeant = Tryouts::Drill::Sergeant::CLI.new *args when :api default_output = drill.nil? ? args.shift : nil @sergeant = Tryouts::Drill::Sergeant::API.new default_output unless args.empty? if args.size == 1 dream_output, format = args.first, nil else dream_output, format = args[1], args[0] end @dreams << Tryouts::Drill::Dream.new(dream_output, format) end when :benchmark if args.size == 1 reps = args.first else dream_output, format, reps = args[1], args[0], args[2] end @sergeant = Tryouts::Drill::Sergeant::Benchmark.new reps @dreams << Tryouts::Drill::Dream.new(Tryouts::Stats, :class) unless dream_output.nil? @dreams << Tryouts::Drill::Dream.new(dream_output, format) end when :skip @skip = true else raise NoSergeant, "Weird drill sergeant: #{@dtype}" end @clr = :red end
def report
def report return if skip? out = StringIO.new out.puts '%12s'.color(:red) % '[nodream]' if @dreams.empty? @dreams.each do |dream| next if dream == reality #? :normal : :red out.puts '%12s: %s'.color(@clr) % ["failed", dream.test_to_string(@reality)] out.puts '%12s: %s' % ["drill", @reality.comparison_value(dream).inspect] out.puts '%12s: %s' % ["dream", dream.comparison_value.inspect] out.puts end unless @reality.error.nil? out.puts '%14s: %s' % [@reality.etype, @reality.error.to_s.split($/).join($/ + ' '*16)] end unless @reality.trace.nil? trace = Tryouts.verbose > 1 ? @reality.trace : [@reality.trace.first] out.puts '%14s %s' % ['', trace.join($/ + ' '*16)] out.puts end out.rewind out.read end
def run(context=nil)
def run(context=nil) unless @dreams.empty? @dreams.each { |d| d.execute_output_block } end begin @reality = @sergeant.run @drill, context # Store the stash from the drill block @reality.stash = context.stash if context.respond_to? :stash # If the drill block returned true we assume success if there's no dream if @dreams.empty? && @reality.output == true @dreams << Tryouts::Drill::Dream.new @dreams.first.output = true end rescue => ex @reality.ecode, @reality.etype = -2, ex.class @reality.error, @reality.trace = ex.message, ex.backtrace end self.success? end
def skip?; @skip; end
def skip?; @skip; end
def success?
def success? return false if @dreams.empty? && @reality.output != true begin @dreams.each { |d| return false unless d == @reality } rescue => ex puts ex.message, ex.backtrace if Tryouts.debug? return false end @clr = :green true end