rspec 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +122 -2
- data/README +10 -9
- data/Rakefile +22 -49
- data/TODO +2 -0
- data/bin/spec +1 -1
- data/bin/spec_translator +8 -8
- data/examples/{auto_spec_description_example.rb → pure/autogenerated_docstrings_example.rb} +0 -0
- data/examples/{before_and_after_example.rb → pure/before_and_after_example.rb} +1 -0
- data/examples/{behave_as_example.rb → pure/behave_as_example.rb} +0 -0
- data/examples/{custom_expectation_matchers.rb → pure/custom_expectation_matchers.rb} +0 -0
- data/examples/{custom_formatter.rb → pure/custom_formatter.rb} +1 -0
- data/examples/{dynamic_spec.rb → pure/dynamic_spec.rb} +0 -0
- data/examples/{file_accessor.rb → pure/file_accessor.rb} +1 -0
- data/examples/{file_accessor_spec.rb → pure/file_accessor_spec.rb} +0 -0
- data/examples/{greeter_spec.rb → pure/greeter_spec.rb} +1 -0
- data/examples/{helper_method_example.rb → pure/helper_method_example.rb} +0 -0
- data/examples/{io_processor.rb → pure/io_processor.rb} +0 -0
- data/examples/{io_processor_spec.rb → pure/io_processor_spec.rb} +0 -0
- data/examples/{legacy_spec.rb → pure/legacy_spec.rb} +1 -0
- data/examples/{mocking_example.rb → pure/mocking_example.rb} +0 -0
- data/examples/pure/multi_threaded_behaviour_runner.rb +28 -0
- data/examples/pure/nested_classes_example.rb +36 -0
- data/examples/{partial_mock_example.rb → pure/partial_mock_example.rb} +0 -0
- data/examples/{pending_example.rb → pure/pending_example.rb} +0 -0
- data/examples/{predicate_example.rb → pure/predicate_example.rb} +0 -0
- data/examples/{priority.txt → pure/priority.txt} +0 -0
- data/examples/pure/shared_example_group_example.rb +66 -0
- data/examples/pure/shared_stack_examples.rb +38 -0
- data/examples/pure/spec_helper.rb +3 -0
- data/examples/{stack.rb → pure/stack.rb} +0 -0
- data/examples/{stack_spec.rb → pure/stack_spec.rb} +1 -35
- data/examples/pure/stack_spec_with_nested_example_groups.rb +67 -0
- data/examples/{stubbing_example.rb → pure/stubbing_example.rb} +0 -0
- data/examples/stories/adder.rb +13 -0
- data/examples/stories/addition +34 -0
- data/examples/stories/addition.rb +9 -0
- data/examples/stories/calculator.rb +65 -0
- data/examples/stories/game-of-life/README.txt +21 -0
- data/examples/stories/game-of-life/behaviour/everything.rb +6 -0
- data/examples/stories/game-of-life/behaviour/examples/examples.rb +3 -0
- data/examples/stories/game-of-life/behaviour/examples/game_behaviour.rb +35 -0
- data/examples/stories/game-of-life/behaviour/examples/grid_behaviour.rb +66 -0
- data/examples/stories/game-of-life/behaviour/stories/CellsWithLessThanTwoNeighboursDie.story +21 -0
- data/examples/stories/game-of-life/behaviour/stories/CellsWithMoreThanThreeNeighboursDie.story +21 -0
- data/examples/stories/game-of-life/behaviour/stories/EmptySpacesWithThreeNeighboursCreateACell.story +42 -0
- data/examples/stories/game-of-life/behaviour/stories/ICanCreateACell.story +42 -0
- data/examples/stories/game-of-life/behaviour/stories/ICanKillACell.story +17 -0
- data/examples/stories/game-of-life/behaviour/stories/TheGridWraps.story +53 -0
- data/examples/stories/game-of-life/behaviour/stories/create_a_cell.rb +52 -0
- data/examples/stories/game-of-life/behaviour/stories/helper.rb +6 -0
- data/examples/stories/game-of-life/behaviour/stories/kill_a_cell.rb +26 -0
- data/examples/stories/game-of-life/behaviour/stories/steps.rb +5 -0
- data/examples/stories/game-of-life/behaviour/stories/stories.rb +3 -0
- data/examples/stories/game-of-life/behaviour/stories/stories.txt +22 -0
- data/examples/stories/game-of-life/life.rb +3 -0
- data/examples/stories/game-of-life/life/game.rb +23 -0
- data/examples/stories/game-of-life/life/grid.rb +43 -0
- data/examples/stories/helper.rb +9 -0
- data/examples/stories/steps/addition_steps.rb +18 -0
- data/lib/autotest/rspec.rb +1 -2
- data/lib/spec.rb +30 -6
- data/lib/spec/example.rb +12 -0
- data/lib/spec/{dsl → example}/configuration.rb +48 -39
- data/lib/spec/{dsl → example}/errors.rb +2 -2
- data/lib/spec/example/example_group.rb +16 -0
- data/lib/spec/example/example_group_factory.rb +62 -0
- data/lib/spec/example/example_group_methods.rb +412 -0
- data/lib/spec/example/example_matcher.rb +42 -0
- data/lib/spec/example/example_methods.rb +101 -0
- data/lib/spec/example/module_reopening_fix.rb +21 -0
- data/lib/spec/example/pending.rb +18 -0
- data/lib/spec/example/shared_example_group.rb +58 -0
- data/lib/spec/expectations/differs/default.rb +15 -10
- data/lib/spec/expectations/errors.rb +7 -1
- data/lib/spec/expectations/extensions/object.rb +12 -7
- data/lib/spec/expectations/handler.rb +13 -4
- data/lib/spec/extensions.rb +2 -0
- data/lib/spec/extensions/class.rb +24 -0
- data/lib/spec/extensions/main.rb +54 -0
- data/lib/spec/extensions/object.rb +5 -1
- data/lib/spec/interop/test.rb +10 -0
- data/lib/spec/interop/test/unit/autorunner.rb +6 -0
- data/lib/spec/interop/test/unit/testcase.rb +61 -0
- data/lib/spec/interop/test/unit/testresult.rb +6 -0
- data/lib/spec/interop/test/unit/testsuite_adapter.rb +34 -0
- data/lib/spec/interop/test/unit/ui/console/testrunner.rb +60 -0
- data/lib/spec/matchers.rb +11 -15
- data/lib/spec/matchers/be.rb +23 -6
- data/lib/spec/matchers/change.rb +25 -1
- data/lib/spec/matchers/exist.rb +17 -0
- data/lib/spec/matchers/operator_matcher.rb +1 -0
- data/lib/spec/matchers/simple_matcher.rb +29 -0
- data/lib/spec/matchers/throw_symbol.rb +2 -0
- data/lib/spec/mocks.rb +5 -2
- data/lib/spec/mocks/argument_expectation.rb +1 -1
- data/lib/spec/mocks/message_expectation.rb +62 -44
- data/lib/spec/mocks/methods.rb +2 -2
- data/lib/spec/mocks/mock.rb +24 -3
- data/lib/spec/mocks/proxy.rb +26 -23
- data/lib/spec/mocks/space.rb +1 -1
- data/lib/spec/mocks/spec_methods.rb +20 -12
- data/lib/spec/rake/spectask.rb +19 -1
- data/lib/spec/rake/verify_rcov.rb +1 -1
- data/lib/spec/runner.rb +33 -10
- data/lib/spec/runner/backtrace_tweaker.rb +3 -3
- data/lib/spec/runner/class_and_arguments_parser.rb +16 -0
- data/lib/spec/runner/command_line.rb +18 -12
- data/lib/spec/runner/drb_command_line.rb +4 -5
- data/lib/spec/runner/example_group_runner.rb +59 -0
- data/lib/spec/runner/formatter/base_formatter.rb +10 -8
- data/lib/spec/runner/formatter/base_text_formatter.rb +18 -18
- data/lib/spec/runner/formatter/failing_example_groups_formatter.rb +31 -0
- data/lib/spec/runner/formatter/failing_examples_formatter.rb +3 -5
- data/lib/spec/runner/formatter/html_formatter.rb +37 -27
- data/lib/spec/runner/formatter/profile_formatter.rb +47 -0
- data/lib/spec/runner/formatter/progress_bar_formatter.rb +3 -4
- data/lib/spec/runner/formatter/specdoc_formatter.rb +27 -13
- data/lib/spec/runner/formatter/story/html_formatter.rb +124 -0
- data/lib/spec/runner/formatter/story/plain_text_formatter.rb +123 -0
- data/lib/spec/runner/formatter/text_mate_formatter.rb +16 -0
- data/lib/spec/runner/heckle_runner.rb +9 -9
- data/lib/spec/runner/option_parser.rb +140 -138
- data/lib/spec/runner/options.rb +168 -90
- data/lib/spec/runner/reporter.rb +58 -40
- data/lib/spec/runner/spec_parser.rb +11 -8
- data/lib/spec/story.rb +10 -0
- data/lib/spec/story/extensions.rb +1 -0
- data/lib/spec/story/extensions/main.rb +86 -0
- data/lib/spec/story/given_scenario.rb +14 -0
- data/lib/spec/story/runner.rb +58 -0
- data/lib/spec/story/runner/plain_text_story_runner.rb +48 -0
- data/lib/spec/story/runner/scenario_collector.rb +18 -0
- data/lib/spec/story/runner/scenario_runner.rb +46 -0
- data/lib/spec/story/runner/story_mediator.rb +123 -0
- data/lib/spec/story/runner/story_parser.rb +227 -0
- data/lib/spec/story/runner/story_runner.rb +67 -0
- data/lib/spec/story/scenario.rb +14 -0
- data/lib/spec/story/step.rb +48 -0
- data/lib/spec/story/step_group.rb +89 -0
- data/lib/spec/story/step_mother.rb +37 -0
- data/lib/spec/story/story.rb +42 -0
- data/lib/spec/story/world.rb +124 -0
- data/lib/spec/version.rb +4 -5
- data/plugins/mock_frameworks/rspec.rb +1 -1
- data/spec/autotest/rspec_spec.rb +13 -7
- data/spec/autotest_helper.rb +4 -3
- data/spec/rspec_suite.rb +7 -0
- data/spec/ruby_forker.rb +13 -0
- data/spec/spec/example/configuration_spec.rb +290 -0
- data/spec/spec/example/example_group_class_definition_spec.rb +48 -0
- data/spec/spec/example/example_group_factory_spec.rb +129 -0
- data/spec/spec/example/example_group_methods_spec.rb +465 -0
- data/spec/spec/example/example_group_spec.rb +711 -0
- data/spec/spec/{dsl → example}/example_matcher_spec.rb +23 -18
- data/spec/spec/example/example_methods_spec.rb +75 -0
- data/spec/spec/example/example_runner_spec.rb +194 -0
- data/spec/spec/example/example_spec.rb +53 -0
- data/spec/spec/example/nested_example_group_spec.rb +59 -0
- data/spec/spec/example/pending_module_spec.rb +31 -0
- data/spec/spec/{dsl → example}/predicate_matcher_spec.rb +1 -1
- data/spec/spec/example/shared_example_group_spec.rb +265 -0
- data/spec/spec/example/subclassing_example_group_spec.rb +25 -0
- data/spec/spec/expectations/differs/default_spec.rb +5 -3
- data/spec/spec/expectations/extensions/object_spec.rb +63 -2
- data/spec/spec/extensions/main_spec.rb +50 -0
- data/spec/spec/interop/test/unit/test_unit_spec_helper.rb +14 -0
- data/spec/spec/interop/test/unit/testcase_spec.rb +10 -0
- data/spec/spec/interop/test/unit/testcase_spec_with_test_unit.rb +20 -0
- data/spec/spec/interop/test/unit/testsuite_adapter_spec.rb +9 -0
- data/spec/spec/interop/test/unit/testsuite_adapter_spec_with_test_unit.rb +34 -0
- data/spec/spec/matchers/be_spec.rb +15 -0
- data/spec/spec/matchers/change_spec.rb +87 -0
- data/spec/spec/matchers/description_generation_spec.rb +31 -37
- data/spec/spec/matchers/exist_spec.rb +31 -22
- data/spec/spec/matchers/handler_spec.rb +42 -1
- data/spec/spec/matchers/have_spec.rb +1 -1
- data/spec/spec/matchers/mock_constraint_matchers_spec.rb +1 -1
- data/spec/spec/matchers/operator_matcher_spec.rb +1 -1
- data/spec/spec/matchers/simple_matcher_spec.rb +31 -0
- data/spec/spec/matchers/throw_symbol_spec.rb +4 -1
- data/spec/spec/mocks/bug_report_10263.rb +24 -0
- data/spec/spec/mocks/bug_report_15719_spec.rb +30 -0
- data/spec/spec/mocks/bug_report_8165_spec.rb +2 -2
- data/spec/spec/mocks/failing_mock_argument_constraints_spec.rb +1 -0
- data/spec/spec/mocks/mock_spec.rb +200 -102
- data/spec/spec/mocks/multiple_return_value_spec.rb +1 -1
- data/spec/spec/mocks/options_hash_spec.rb +19 -7
- data/spec/spec/mocks/partial_mock_spec.rb +31 -9
- data/spec/spec/mocks/passing_mock_argument_constraints_spec.rb +6 -0
- data/spec/spec/mocks/stub_spec.rb +120 -98
- data/spec/spec/package/bin_spec_spec.rb +7 -5
- data/spec/spec/runner/class_and_argument_parser_spec.rb +23 -0
- data/spec/spec/runner/command_line_spec.rb +140 -27
- data/spec/spec/runner/drb_command_line_spec.rb +39 -31
- data/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb +44 -0
- data/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +16 -11
- data/spec/spec/runner/formatter/html_formatter_spec.rb +60 -50
- data/spec/spec/runner/formatter/profile_formatter_spec.rb +65 -0
- data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +29 -13
- data/spec/spec/runner/formatter/snippet_extractor_spec.rb +14 -7
- data/spec/spec/runner/formatter/spec_mate_formatter_spec.rb +103 -0
- data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +103 -39
- data/spec/spec/runner/formatter/story/html_formatter_spec.rb +56 -0
- data/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb +289 -0
- data/spec/spec/runner/heckle_runner_spec.rb +29 -14
- data/spec/spec/runner/heckler_spec.rb +4 -5
- data/spec/spec/runner/noisy_backtrace_tweaker_spec.rb +5 -5
- data/spec/spec/runner/option_parser_spec.rb +86 -58
- data/spec/spec/runner/options_spec.rb +239 -120
- data/spec/spec/runner/output_one_time_fixture.rb +7 -0
- data/spec/spec/runner/output_one_time_fixture_runner.rb +8 -0
- data/spec/spec/runner/output_one_time_spec.rb +16 -0
- data/spec/spec/runner/quiet_backtrace_tweaker_spec.rb +6 -6
- data/spec/spec/runner/reporter_spec.rb +147 -163
- data/spec/spec/runner/spec_parser_spec.rb +31 -0
- data/spec/spec/runner_spec.rb +11 -0
- data/spec/spec/spec_classes.rb +12 -5
- data/spec/spec/story/builders.rb +46 -0
- data/spec/spec/story/extensions/main_spec.rb +161 -0
- data/spec/spec/story/extensions_spec.rb +14 -0
- data/spec/spec/story/given_scenario_spec.rb +27 -0
- data/spec/spec/story/runner/plain_text_story_runner_spec.rb +92 -0
- data/spec/spec/story/runner/scenario_collector_spec.rb +27 -0
- data/spec/spec/story/runner/scenario_runner_spec.rb +142 -0
- data/spec/spec/story/runner/story_mediator_spec.rb +133 -0
- data/spec/spec/story/runner/story_parser_spec.rb +384 -0
- data/spec/spec/story/runner/story_runner_spec.rb +219 -0
- data/spec/spec/story/runner_spec.rb +106 -0
- data/spec/spec/story/scenario_spec.rb +20 -0
- data/spec/spec/story/step_group_spec.rb +157 -0
- data/spec/spec/story/step_mother_spec.rb +72 -0
- data/spec/spec/story/step_spec.rb +147 -0
- data/spec/spec/story/story_helper.rb +2 -0
- data/spec/spec/story/story_spec.rb +86 -0
- data/spec/spec/story/world_spec.rb +416 -0
- data/spec/spec/translator_spec.rb +2 -1
- data/spec/spec_helper.rb +59 -2
- data/stories/all.rb +5 -0
- data/stories/example_groups/autogenerated_docstrings +26 -0
- data/stories/example_groups/example_group_with_should_methods +17 -0
- data/stories/example_groups/nested_groups +17 -0
- data/stories/example_groups/output +20 -0
- data/stories/example_groups/stories.rb +7 -0
- data/stories/helper.rb +6 -0
- data/stories/interop/examples_and_tests_together +30 -0
- data/stories/interop/stories.rb +7 -0
- data/stories/interop/test_case_with_should_methods +17 -0
- data/stories/pending_stories/README +3 -0
- data/stories/resources/helpers/cmdline.rb +9 -0
- data/stories/resources/helpers/story_helper.rb +16 -0
- data/stories/resources/matchers/smart_match.rb +37 -0
- data/stories/resources/spec/example_group_with_should_methods.rb +12 -0
- data/stories/resources/spec/simple_spec.rb +8 -0
- data/stories/resources/steps/running_rspec.rb +50 -0
- data/stories/resources/test/spec_and_test_together.rb +57 -0
- data/stories/resources/test/test_case_with_should_methods.rb +30 -0
- metadata +232 -106
- data/EXAMPLES.rd +0 -111
- data/examples/multi_threaded_behaviour_runner.rb +0 -25
- data/examples/shared_behaviours_example.rb +0 -39
- data/examples/spec_helper.rb +0 -1
- data/examples/test_case_adapter_example.rb +0 -26
- data/examples/test_case_spec.rb +0 -65
- data/lib/spec/dsl.rb +0 -11
- data/lib/spec/dsl/behaviour.rb +0 -220
- data/lib/spec/dsl/behaviour_callbacks.rb +0 -82
- data/lib/spec/dsl/behaviour_eval.rb +0 -231
- data/lib/spec/dsl/behaviour_factory.rb +0 -42
- data/lib/spec/dsl/composite_proc_builder.rb +0 -33
- data/lib/spec/dsl/description.rb +0 -76
- data/lib/spec/dsl/example.rb +0 -135
- data/lib/spec/dsl/example_matcher.rb +0 -40
- data/lib/spec/dsl/example_should_raise_handler.rb +0 -74
- data/lib/spec/runner/behaviour_runner.rb +0 -123
- data/lib/spec/runner/extensions/kernel.rb +0 -50
- data/lib/spec/runner/extensions/object.rb +0 -32
- data/lib/spec/runner/formatter.rb +0 -9
- data/lib/spec/runner/formatter/failing_behaviours_formatter.rb +0 -29
- data/lib/spec/runner/formatter/rdoc_formatter.rb +0 -24
- data/lib/spec/test_case_adapter.rb +0 -10
- data/spec/spec/dsl/behaviour_eval_spec.rb +0 -79
- data/spec/spec/dsl/behaviour_factory_spec.rb +0 -48
- data/spec/spec/dsl/behaviour_spec.rb +0 -661
- data/spec/spec/dsl/composite_proc_builder_spec.rb +0 -44
- data/spec/spec/dsl/configuration_spec.rb +0 -55
- data/spec/spec/dsl/description_spec.rb +0 -89
- data/spec/spec/dsl/example_class_spec.rb +0 -24
- data/spec/spec/dsl/example_instance_spec.rb +0 -160
- data/spec/spec/dsl/example_should_raise_spec.rb +0 -137
- data/spec/spec/dsl/shared_behaviour_spec.rb +0 -252
- data/spec/spec/runner/behaviour_runner_spec.rb +0 -229
- data/spec/spec/runner/context_matching_spec.rb +0 -27
- data/spec/spec/runner/extensions/bug_report_10577_spec.rb +0 -35
- data/spec/spec/runner/extensions/kernel_spec.rb +0 -36
- data/spec/spec/runner/formatter/failing_behaviours_formatter_spec.rb +0 -40
- data/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb +0 -20
- data/spec/spec/runner/formatter/progress_bar_formatter_failure_dump_spec.rb +0 -36
- data/spec/spec/runner/formatter/rdoc_formatter_dry_run_spec.rb +0 -19
- data/spec/spec/runner/formatter/rdoc_formatter_spec.rb +0 -46
- data/spec/spec/runner/formatter/specdoc_formatter_dry_run_spec.rb +0 -21
- data/spec/spec/runner/object_ext_spec.rb +0 -11
data/lib/spec/runner/reporter.rb
CHANGED
@@ -1,40 +1,52 @@
|
|
1
1
|
module Spec
|
2
2
|
module Runner
|
3
3
|
class Reporter
|
4
|
+
attr_reader :options, :example_groups
|
4
5
|
|
5
|
-
def initialize(
|
6
|
-
@
|
7
|
-
@
|
8
|
-
clear
|
6
|
+
def initialize(options)
|
7
|
+
@options = options
|
8
|
+
@options.reporter = self
|
9
|
+
clear
|
9
10
|
end
|
10
11
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
12
|
+
def add_example_group(example_group)
|
13
|
+
formatters.each do |f|
|
14
|
+
f.add_example_group(example_group)
|
15
|
+
end
|
16
|
+
example_groups << example_group
|
14
17
|
end
|
15
18
|
|
16
|
-
def example_started(
|
17
|
-
|
19
|
+
def example_started(example)
|
20
|
+
formatters.each{|f| f.example_started(example)}
|
18
21
|
end
|
19
22
|
|
20
|
-
def example_finished(
|
21
|
-
@
|
23
|
+
def example_finished(example, error=nil)
|
24
|
+
@examples << example
|
22
25
|
|
23
|
-
if
|
24
|
-
|
25
|
-
elsif error
|
26
|
-
|
27
|
-
elsif Spec::DSL::ExamplePendingError === error
|
28
|
-
example_pending(@behaviour_names.last, name, error.message)
|
26
|
+
if error.nil?
|
27
|
+
example_passed(example)
|
28
|
+
elsif Spec::Example::ExamplePendingError === error
|
29
|
+
example_pending(example_groups.last, example, error.message)
|
29
30
|
else
|
30
|
-
example_failed(
|
31
|
+
example_failed(example, error)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def failure(example, error)
|
36
|
+
backtrace_tweaker.tweak_backtrace(error)
|
37
|
+
example_name = "#{example_groups.last.description} #{example.description}"
|
38
|
+
failure = Failure.new(example_name, error)
|
39
|
+
@failures << failure
|
40
|
+
formatters.each do |f|
|
41
|
+
f.example_failed(example, @failures.length, failure)
|
31
42
|
end
|
32
43
|
end
|
44
|
+
alias_method :example_failed, :failure
|
33
45
|
|
34
46
|
def start(number_of_examples)
|
35
|
-
clear
|
47
|
+
clear
|
36
48
|
@start_time = Time.new
|
37
|
-
|
49
|
+
formatters.each{|f| f.start(number_of_examples)}
|
38
50
|
end
|
39
51
|
|
40
52
|
def end
|
@@ -43,22 +55,31 @@ module Spec
|
|
43
55
|
|
44
56
|
# Dumps the summary and returns the total number of failures
|
45
57
|
def dump
|
46
|
-
|
58
|
+
formatters.each{|f| f.start_dump}
|
59
|
+
dump_pending
|
47
60
|
dump_failures
|
48
|
-
|
49
|
-
f.dump_summary(duration, @
|
61
|
+
formatters.each do |f|
|
62
|
+
f.dump_summary(duration, @examples.length, @failures.length, @pending_count)
|
50
63
|
f.close
|
51
64
|
end
|
52
65
|
@failures.length
|
53
66
|
end
|
54
67
|
|
55
68
|
private
|
69
|
+
|
70
|
+
def formatters
|
71
|
+
@options.formatters
|
72
|
+
end
|
73
|
+
|
74
|
+
def backtrace_tweaker
|
75
|
+
@options.backtrace_tweaker
|
76
|
+
end
|
56
77
|
|
57
|
-
def clear
|
58
|
-
@
|
78
|
+
def clear
|
79
|
+
@example_groups = []
|
59
80
|
@failures = []
|
60
81
|
@pending_count = 0
|
61
|
-
@
|
82
|
+
@examples = []
|
62
83
|
@start_time = nil
|
63
84
|
@end_time = nil
|
64
85
|
end
|
@@ -66,31 +87,28 @@ module Spec
|
|
66
87
|
def dump_failures
|
67
88
|
return if @failures.empty?
|
68
89
|
@failures.inject(1) do |index, failure|
|
69
|
-
|
90
|
+
formatters.each{|f| f.dump_failure(index, failure)}
|
70
91
|
index + 1
|
71
92
|
end
|
72
93
|
end
|
94
|
+
def dump_pending
|
95
|
+
formatters.each{|f| f.dump_pending}
|
96
|
+
end
|
73
97
|
|
74
98
|
def duration
|
75
99
|
return @end_time - @start_time unless (@end_time.nil? or @start_time.nil?)
|
76
100
|
return "0.0"
|
77
101
|
end
|
78
102
|
|
79
|
-
def example_passed(
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
def example_failed(name, error, failure_location)
|
84
|
-
@backtrace_tweaker.tweak_backtrace(error, failure_location)
|
85
|
-
example_name = "#{@behaviour_names.last} #{name}"
|
86
|
-
failure = Failure.new(example_name, error)
|
87
|
-
@failures << failure
|
88
|
-
@formatters.each{|f| f.example_failed(name, @failures.length, failure)}
|
103
|
+
def example_passed(example)
|
104
|
+
formatters.each{|f| f.example_passed(example)}
|
89
105
|
end
|
90
106
|
|
91
|
-
def example_pending(
|
107
|
+
def example_pending(example_group, example, message="Not Yet Implemented")
|
92
108
|
@pending_count += 1
|
93
|
-
|
109
|
+
formatters.each do |f|
|
110
|
+
f.example_pending(example_group.description, example, message)
|
111
|
+
end
|
94
112
|
end
|
95
113
|
|
96
114
|
class Failure
|
@@ -112,7 +130,7 @@ module Spec
|
|
112
130
|
end
|
113
131
|
|
114
132
|
def pending_fixed?
|
115
|
-
@exception.is_a?(Spec::
|
133
|
+
@exception.is_a?(Spec::Example::PendingExampleFixedError)
|
116
134
|
end
|
117
135
|
|
118
136
|
def expectation_not_met?
|
@@ -4,12 +4,12 @@ module Spec
|
|
4
4
|
class SpecParser
|
5
5
|
def spec_name_for(io, line_number)
|
6
6
|
source = io.read
|
7
|
-
|
7
|
+
example_group, example_group_line = example_group_at_line(source, line_number)
|
8
8
|
example, example_line = example_at_line(source, line_number)
|
9
|
-
if
|
10
|
-
"#{
|
11
|
-
elsif
|
12
|
-
|
9
|
+
if example_group && example && (example_group_line < example_line)
|
10
|
+
"#{example_group} #{example}"
|
11
|
+
elsif example_group
|
12
|
+
example_group
|
13
13
|
else
|
14
14
|
nil
|
15
15
|
end
|
@@ -17,7 +17,7 @@ module Spec
|
|
17
17
|
|
18
18
|
protected
|
19
19
|
|
20
|
-
def
|
20
|
+
def example_group_at_line(source, line_number)
|
21
21
|
find_above(source, line_number, /^\s*(context|describe)\s+(.*)\s+do/)
|
22
22
|
end
|
23
23
|
|
@@ -40,8 +40,11 @@ module Spec
|
|
40
40
|
|
41
41
|
def parse_description(str)
|
42
42
|
return str[1..-2] if str =~ /^['"].*['"]$/
|
43
|
-
if matches = /^
|
44
|
-
return ::Spec::
|
43
|
+
if matches = /^['"](.*)['"](,.*)?$/.match(str)
|
44
|
+
return ::Spec::Example::ExampleGroupMethods.description_text(matches[1])
|
45
|
+
end
|
46
|
+
if matches = /^(.*)\s*,\s*['"](.*)['"](,.*)?$/.match(str)
|
47
|
+
return ::Spec::Example::ExampleGroupMethods.description_text(matches[1], matches[2])
|
45
48
|
end
|
46
49
|
return str
|
47
50
|
end
|
data/lib/spec/story.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'spec/story/extensions'
|
3
|
+
require 'spec/story/given_scenario'
|
4
|
+
require 'spec/story/runner'
|
5
|
+
require 'spec/story/scenario'
|
6
|
+
require 'spec/story/step'
|
7
|
+
require 'spec/story/step_group'
|
8
|
+
require 'spec/story/step_mother'
|
9
|
+
require 'spec/story/story'
|
10
|
+
require 'spec/story/world'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'spec/story/extensions/main'
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Spec
|
2
|
+
module Story
|
3
|
+
module Extensions
|
4
|
+
module Main
|
5
|
+
def Story(title, narrative, params = {}, &body)
|
6
|
+
::Spec::Story::Runner.story_runner.Story(title, narrative, params, &body)
|
7
|
+
end
|
8
|
+
|
9
|
+
# Calling this deprecated is silly, since it hasn't been released yet. But, for
|
10
|
+
# those who are reading this - this will be deleted before the 1.1 release.
|
11
|
+
def run_story(*args, &block)
|
12
|
+
runner = Spec::Story::Runner::PlainTextStoryRunner.new(*args)
|
13
|
+
runner.instance_eval(&block) if block
|
14
|
+
runner.run
|
15
|
+
end
|
16
|
+
|
17
|
+
# Creates (or appends to an existing) a namespaced group of steps for use in Stories
|
18
|
+
#
|
19
|
+
# == Examples
|
20
|
+
#
|
21
|
+
# # Creating a new group
|
22
|
+
# steps_for :forms do
|
23
|
+
# When("user enters $value in the $field field") do ... end
|
24
|
+
# When("user submits the $form form") do ... end
|
25
|
+
# end
|
26
|
+
def steps_for(tag, &block)
|
27
|
+
steps = rspec_story_steps[tag]
|
28
|
+
steps.instance_eval(&block) if block
|
29
|
+
steps
|
30
|
+
end
|
31
|
+
|
32
|
+
# Creates a context for running a Plain Text Story with specific groups of Steps.
|
33
|
+
# Also supports adding arbitrary steps that will only be accessible to
|
34
|
+
# the Story being run.
|
35
|
+
#
|
36
|
+
# == Examples
|
37
|
+
#
|
38
|
+
# # Run a Story with one group of steps
|
39
|
+
# with_steps_for :checking_accounts do
|
40
|
+
# run File.dirname(__FILE__) + "/withdraw_cash"
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# # Run a Story, adding steps that are only available for this Story
|
44
|
+
# with_steps_for :accounts do
|
45
|
+
# Given "user is logged in as account administrator"
|
46
|
+
# run File.dirname(__FILE__) + "/reconcile_accounts"
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# # Run a Story with steps from two groups
|
50
|
+
# with_steps_for :checking_accounts, :savings_accounts do
|
51
|
+
# run File.dirname(__FILE__) + "/transfer_money"
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# # Run a Story with a specific Story extension
|
55
|
+
# with_steps_for :login, :navigation do
|
56
|
+
# run File.dirname(__FILE__) + "/user_changes_password", :type => RailsStory
|
57
|
+
# end
|
58
|
+
def with_steps_for(*tags, &block)
|
59
|
+
steps = Spec::Story::StepGroup.new do
|
60
|
+
extend StoryRunnerStepGroupAdapter
|
61
|
+
end
|
62
|
+
tags.each {|tag| steps << rspec_story_steps[tag]}
|
63
|
+
steps.instance_eval(&block) if block
|
64
|
+
steps
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
module StoryRunnerStepGroupAdapter
|
70
|
+
def run(path, options={})
|
71
|
+
runner = Spec::Story::Runner::PlainTextStoryRunner.new(path, options)
|
72
|
+
runner.steps << self
|
73
|
+
runner.run
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def rspec_story_steps # :nodoc:
|
78
|
+
$rspec_story_steps ||= Spec::Story::StepGroupHash.new
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
include Spec::Story::Extensions::Main
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Spec
|
2
|
+
module Story
|
3
|
+
class GivenScenario
|
4
|
+
def initialize(name)
|
5
|
+
@name = name
|
6
|
+
end
|
7
|
+
|
8
|
+
def perform(instance, ignore_name)
|
9
|
+
scenario = Runner::StoryRunner.scenario_from_current_story(@name)
|
10
|
+
Runner::ScenarioRunner.new.run(scenario, instance)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec/story/runner/scenario_collector.rb'
|
2
|
+
require 'spec/story/runner/scenario_runner.rb'
|
3
|
+
require 'spec/story/runner/story_runner.rb'
|
4
|
+
require 'spec/story/runner/story_parser.rb'
|
5
|
+
require 'spec/story/runner/story_mediator.rb'
|
6
|
+
require 'spec/story/runner/plain_text_story_runner.rb'
|
7
|
+
|
8
|
+
module Spec
|
9
|
+
module Story
|
10
|
+
module Runner
|
11
|
+
class << self
|
12
|
+
def run_options # :nodoc:
|
13
|
+
@run_options ||= ::Spec::Runner::OptionParser.parse(ARGV, $stderr, $stdout)
|
14
|
+
end
|
15
|
+
|
16
|
+
def story_runner # :nodoc:
|
17
|
+
unless @story_runner
|
18
|
+
@story_runner = StoryRunner.new(scenario_runner, world_creator)
|
19
|
+
run_options.story_formatters.each do |formatter|
|
20
|
+
register_listener(formatter)
|
21
|
+
end
|
22
|
+
Runner.register_exit_hook
|
23
|
+
end
|
24
|
+
@story_runner
|
25
|
+
end
|
26
|
+
|
27
|
+
def scenario_runner # :nodoc:
|
28
|
+
@scenario_runner ||= ScenarioRunner.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def world_creator # :nodoc:
|
32
|
+
@world_creator ||= World
|
33
|
+
end
|
34
|
+
|
35
|
+
# Use this to register a customer output formatter.
|
36
|
+
def register_listener(listener)
|
37
|
+
story_runner.add_listener(listener) # run_started, story_started, story_ended, #run_ended
|
38
|
+
world_creator.add_listener(listener) # found_scenario, step_succeeded, step_failed, step_failed
|
39
|
+
scenario_runner.add_listener(listener) # scenario_started, scenario_succeeded, scenario_pending, scenario_failed
|
40
|
+
end
|
41
|
+
|
42
|
+
def register_exit_hook # :nodoc:
|
43
|
+
# TODO - when story runner uses test/unit runners like example runner does we can kill
|
44
|
+
# this and also the assorted Kernel.stub!(:at_exit) in examples
|
45
|
+
at_exit do
|
46
|
+
Runner.story_runner.run_stories unless $!
|
47
|
+
end
|
48
|
+
# TODO exit with non-zero status if run fails
|
49
|
+
end
|
50
|
+
|
51
|
+
def dry_run
|
52
|
+
run_options.dry_run
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Spec
|
2
|
+
module Story
|
3
|
+
module Runner
|
4
|
+
class PlainTextStoryRunner
|
5
|
+
# You can initialize a PlainTextStoryRunner with the path to the
|
6
|
+
# story file or a block, in which you can define the path using load.
|
7
|
+
#
|
8
|
+
# == Examples
|
9
|
+
#
|
10
|
+
# PlainTextStoryRunner.new('path/to/file')
|
11
|
+
#
|
12
|
+
# PlainTextStoryRunner.new do |runner|
|
13
|
+
# runner.load 'path/to/file'
|
14
|
+
# end
|
15
|
+
def initialize(*args)
|
16
|
+
@options = Hash === args.last ? args.pop : {}
|
17
|
+
@story_file = args.empty? ? nil : args.shift
|
18
|
+
yield self if block_given?
|
19
|
+
end
|
20
|
+
|
21
|
+
def []=(key, value)
|
22
|
+
@options[key] = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def load(path)
|
26
|
+
@story_file = path
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
raise "You must set a path to the file with the story. See the RDoc." if @story_file.nil?
|
31
|
+
mediator = Spec::Story::Runner::StoryMediator.new(steps, Spec::Story::Runner.story_runner, @options)
|
32
|
+
parser = Spec::Story::Runner::StoryParser.new(mediator)
|
33
|
+
|
34
|
+
story_text = File.read(@story_file)
|
35
|
+
parser.parse(story_text.split("\n"))
|
36
|
+
|
37
|
+
mediator.run_stories
|
38
|
+
end
|
39
|
+
|
40
|
+
def steps
|
41
|
+
@step_group ||= Spec::Story::StepGroup.new
|
42
|
+
yield @step_group if block_given?
|
43
|
+
@step_group
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Spec
|
2
|
+
module Story
|
3
|
+
module Runner
|
4
|
+
class ScenarioCollector
|
5
|
+
attr_accessor :scenarios
|
6
|
+
|
7
|
+
def initialize(story)
|
8
|
+
@story = story
|
9
|
+
@scenarios = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def Scenario(name, &body)
|
13
|
+
@scenarios << Scenario.new(@story, name, &body)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Spec
|
2
|
+
module Story
|
3
|
+
module Runner
|
4
|
+
class ScenarioRunner
|
5
|
+
def initialize
|
6
|
+
@listeners = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(scenario, world)
|
10
|
+
@listeners.each { |l| l.scenario_started(scenario.story.title, scenario.name) }
|
11
|
+
run_story_ignoring_scenarios(scenario.story, world)
|
12
|
+
|
13
|
+
world.start_collecting_errors
|
14
|
+
world.instance_eval(&scenario.body)
|
15
|
+
if world.errors.empty?
|
16
|
+
@listeners.each { |l| l.scenario_succeeded(scenario.story.title, scenario.name) }
|
17
|
+
else
|
18
|
+
if Spec::Example::ExamplePendingError === (e = world.errors.first)
|
19
|
+
@listeners.each { |l| l.scenario_pending(scenario.story.title, scenario.name, e.message) }
|
20
|
+
else
|
21
|
+
@listeners.each { |l| l.scenario_failed(scenario.story.title, scenario.name, e) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_listener(listener)
|
27
|
+
@listeners << listener
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def run_story_ignoring_scenarios(story, world)
|
33
|
+
class << world
|
34
|
+
def Scenario(name, &block)
|
35
|
+
# do nothing
|
36
|
+
end
|
37
|
+
end
|
38
|
+
story.run_in(world)
|
39
|
+
class << world
|
40
|
+
remove_method(:Scenario)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|