lib/command-unit.rb in command-unit-0.0.1 vs lib/command-unit.rb in command-unit-0.0.2

- old
+ new

@@ -1,5 +1,12 @@ +require 'stringio' +require_relative 'command-unit/scenario' +require_relative 'command-unit/test' +require_relative 'command-unit/expectation' +require_relative 'command-unit/expectation_result' +require_relative 'command-unit/hooks' + module CommandUnit @@scenario_count = 0 @@scenarios = [] @@ -16,44 +23,50 @@ else description = description_or_nil namespace = namespace_or_description end - @@scenarios.push Scenario.new(namespace, description, &block) + @@scenarios.push Scenario.new(namespace, description, STDOUT, &block) + return @@scenarios.last end - def run(namespace_or_scenario_or_nowt = nil) + def run_silent(namespace_or_nil=nil) + output = StringIO.new + run(namespace_or_nil, output) + return output.string + end + + def run(namespace_or_scenario_or_nowt=nil, out_stream=STDOUT) + hooks = Hooks.new if namespace_or_scenario_or_nowt.nil? # Run the lot... + out_stream.puts "\nRunning #{@@scenarios.count} scenarios..." @@scenarios.each do |scenario| - scenario.run + scenario.run(hooks, out_stream) end else if namespace_or_scenario_or_nowt.is_a? Symbol - @@scenarios.each do |scenario| - next unless scenario.namespace == namespace_or_scenario_or_nowt - scenario.run + namespace = namespace_or_scenario_or_nowt + scenarios_in_namespace = @@scenarios.select { |s| s.namespace == namespace } + out_stream.puts "\nRunning #{scenarios_in_namespace.length} scenarios in namespace '#{namespace}'..." + scenarios_in_namespace.each do |scenario| + scenario.run(hooks, out_stream) end elsif namespace_or_scenario.is_a? Scenario - namespace_or_scenario_or_nowt.run + scenario = namespace_or_scenario + out_stream.puts "\nRunning single scenario..." + scenario.run(hooks, out_stream) else raise "You must pass either a Scenario, a Symbol (namespace), or nil into run. You passed a #{namespace_or_scenario_or_nowt.class}" end end - end - require 'stringio' + t = hooks.totaliser + message = "\nRan #{t.scenarios_run} scenarios, #{t.scenarios_passed} passed, #{t.scenarios_failed} failed (tests passed: #{t.tests_passed}, failed: #{t.tests_failed}) (expectations passed: #{t.expectations_passed}, failed: #{t.expectations_failed})\n" - def capture_stdout - out = StringIO.new - $stdout = out - yield - r = out.string - return r - ensure - $stdout = STDOUT + out_stream.puts message end def ensure_inside_scenario raise "#{caller[0]} must be called from inside a scenario block" if @@current_scenario == nil end @@ -86,109 +99,14 @@ def i_expect(desc, &i_expect_block) ensure_inside_scenario @@current_scenario.current_test.add_expectation Expectation.new(desc, &i_expect_block) end - def success(desc = '') + def pass(desc = '') ExpectationResult.new(desc, true) end - def failure(desc = '') + def fail(desc = '') ExpectationResult.new(desc, false) end - class Scenario - def initialize(namespace, desc, &block) - @namespace = namespace - @id = @@scenario_count += 1 - @desc = desc - @block = block - @set_up_block = nil - @tests = [] - @current_test = nil - @tear_down_block = nil - @scenario_set_up_block = nil - @scenario_tear_down_block = nil - @tests_run = 0 - @expectations_run = 0 - @expectations_met = 0 - @expectations_not_met = 0 - @inconclusive_expectations = 0 - end - - def run - puts "\nRunning scenario #{@id}: #{@desc}" - @@current_scenario = self - @block.call - context = {} - @scenario_set_up_block.call(context) unless @scenario_set_up_block.nil? - @tests.each do |test| - puts "\tWhen I #{test.when_i_text}" - @tests_run += 1 - @set_up_block.call(context) unless @set_up_block.nil? - test.when_i_block.call(context) unless test.when_i_block.nil? - test.expectations.each do |expectation| - print "\t\tI expect #{expectation.desc}..." - result = expectation.block.call(context) - @expectations_run += 1 - if result.respond_to? :success? - if result.success? - @expectations_met +=1 - puts "Success! #{result.message}" - else - @expectations_not_met +=1 - puts "Failure! #{result.message}" - end - else - @inconclusive_expectations += 1 - puts "Inconclusive! #{result}" - end - end - @tear_down_block.call(context) unless @tear_down_block.nil? - end - @scenario_tear_down_block.call(context) unless @scenario_tear_down_block.nil? - @@current_scenario = nil - - puts "Scenario #{@id} finished, #{@tests_run} tests, #{@expectations_run} expectations with #{@expectations_met} successful and #{@expectations_not_met} failures." - end - - def add_test(test) - @tests.push test - @current_test = test - end - - attr_accessor :desc, :block, :set_up_block, :tests, :tear_down_block, :current_test, - :scenario_set_up_block, :scenario_tear_down_block, :namespace - end - - class Test - def initialize(when_i_text, &when_i_block) - @when_i_text = when_i_text - @when_i_block = when_i_block - @expectations = [] - end - attr_reader :when_i_text, :when_i_block, :expectations - def add_expectation(expectation) - @expectations.push expectation - end - end - - class Expectation - def initialize(expectation_text, &expectaton_block) - @desc = expectation_text - @block = expectaton_block - end - attr_accessor :desc, :block - end - - class ExpectationResult - def initialize(description, expectation_met) - @message = description - @success = expectation_met - end - attr_reader :message - def success? - @success - end - - end end