rspec 1.1.11 → 1.1.12
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/.autotest +4 -0
- data/History.txt +55 -0
- data/Manifest.txt +102 -122
- data/README.txt +30 -12
- data/Rakefile +10 -10
- data/TODO.txt +10 -2
- data/{failing_examples → examples/failing}/README.txt +0 -0
- data/{failing_examples → examples/failing}/diffing_spec.rb +0 -0
- data/{failing_examples → examples/failing}/failing_autogenerated_docstrings_example.rb +0 -0
- data/{failing_examples/failure_in_teardown.rb → examples/failing/failure_in_after.rb} +1 -1
- data/{failing_examples/failure_in_setup.rb → examples/failing/failure_in_before.rb} +1 -1
- data/{failing_examples → examples/failing}/mocking_example.rb +0 -0
- data/{failing_examples → examples/failing}/mocking_with_flexmock.rb +0 -0
- data/{failing_examples → examples/failing}/mocking_with_mocha.rb +0 -0
- data/{failing_examples → examples/failing}/mocking_with_rr.rb +0 -0
- data/{failing_examples → examples/failing}/partial_mock_example.rb +0 -0
- data/{failing_examples → examples/failing}/predicate_example.rb +5 -0
- data/{failing_examples → examples/failing}/raising_example.rb +0 -0
- data/{failing_examples → examples/failing}/spec_helper.rb +1 -1
- data/{failing_examples → examples/failing}/syntax_error_example.rb +0 -0
- data/{failing_examples → examples/failing}/team_spec.rb +0 -0
- data/{failing_examples → examples/failing}/timeout_behaviour.rb +0 -0
- data/examples/{pure → passing}/autogenerated_docstrings_example.rb +6 -0
- data/examples/{pure → passing}/before_and_after_example.rb +0 -0
- data/examples/{pure → passing}/behave_as_example.rb +0 -0
- data/examples/{pure → passing}/custom_expectation_matchers.rb +0 -0
- data/examples/{pure → passing}/custom_formatter.rb +1 -1
- data/examples/{pure → passing}/dynamic_spec.rb +2 -2
- data/examples/{pure → passing}/file_accessor.rb +0 -0
- data/examples/{pure → passing}/file_accessor_spec.rb +0 -0
- data/examples/{pure → passing}/greeter_spec.rb +0 -0
- data/examples/{pure → passing}/helper_method_example.rb +0 -0
- data/examples/{pure → passing}/io_processor.rb +0 -0
- data/examples/{pure → passing}/io_processor_spec.rb +0 -0
- data/examples/{pure → passing}/legacy_spec.rb +0 -0
- data/examples/{pure → passing}/mocking_example.rb +0 -0
- data/examples/{pure/multi_threaded_behaviour_runner.rb → passing/multi_threaded_example_group_runner.rb} +1 -3
- data/examples/{pure → passing}/nested_classes_example.rb +0 -0
- data/examples/{pure → passing}/partial_mock_example.rb +0 -0
- data/examples/{pure → passing}/pending_example.rb +0 -0
- data/examples/{pure → passing}/predicate_example.rb +0 -0
- data/examples/{pure → passing}/priority.txt +0 -0
- data/examples/{pure → passing}/shared_example_group_example.rb +0 -0
- data/examples/{pure → passing}/shared_stack_examples.rb +1 -3
- data/examples/passing/simple_matcher_example.rb +31 -0
- data/examples/{pure → passing}/spec_helper.rb +0 -0
- data/examples/{pure → passing}/stack.rb +0 -0
- data/examples/{pure → passing}/stack_spec.rb +3 -2
- data/examples/{pure → passing}/stack_spec_with_nested_example_groups.rb +0 -0
- data/examples/{pure → passing}/stubbing_example.rb +0 -0
- data/examples/{pure → passing}/yielding_example.rb +0 -0
- data/examples/ruby1.9.compatibility/access_to_constants_spec.rb +86 -0
- data/features/before_and_after_blocks/before_and_after_blocks.feature +168 -0
- data/{stories/example_groups/autogenerated_docstrings → features/example_groups/autogenerated_docstrings.feature} +5 -5
- data/{stories/example_groups/example_group_with_should_methods → features/example_groups/example_group_with_should_methods.feature} +3 -3
- data/{stories/example_groups/nested_groups → features/example_groups/nested_groups.feature} +4 -4
- data/{stories/example_groups/output → features/example_groups/output.feature} +3 -8
- data/{stories/interop/examples_and_tests_together → features/interop/examples_and_tests_together.feature} +5 -4
- data/features/interop/test_but_not_test_unit.feature +14 -0
- data/{stories/interop/test_case_with_should_methods → features/interop/test_case_with_should_methods.feature} +2 -2
- data/{stories/mock_framework_integration/use_flexmock.story → features/mock_framework_integration/use_flexmock.feature} +1 -1
- data/features/step_definitions/running_rspec.rb +54 -0
- data/features/support/env.rb +26 -0
- data/{stories/resources → features/support}/helpers/cmdline.rb +0 -0
- data/{stories/resources → features/support}/helpers/story_helper.rb +1 -1
- data/{stories/resources → features/support}/matchers/smart_match.rb +0 -0
- data/{plugins → lib/adapters}/mock_frameworks/flexmock.rb +1 -1
- data/{plugins → lib/adapters}/mock_frameworks/mocha.rb +1 -1
- data/{plugins → lib/adapters}/mock_frameworks/rr.rb +1 -1
- data/{plugins → lib/adapters}/mock_frameworks/rspec.rb +2 -2
- data/lib/autotest/rspec.rb +4 -3
- data/lib/spec.rb +2 -27
- data/lib/spec/dsl.rb +1 -0
- data/lib/spec/{extensions → dsl}/main.rb +10 -10
- data/lib/spec/example.rb +175 -1
- data/lib/spec/example/before_and_after_hooks.rb +30 -24
- data/lib/spec/example/example_group.rb +1 -0
- data/lib/spec/example/example_group_factory.rb +26 -9
- data/lib/spec/example/example_group_methods.rb +138 -113
- data/lib/spec/example/example_methods.rb +88 -25
- data/lib/spec/example/shared_example_group.rb +28 -21
- data/lib/spec/expectations.rb +22 -18
- data/lib/spec/expectations/handler.rb +16 -36
- data/lib/spec/interop/test/unit/testcase.rb +19 -17
- data/lib/spec/interop/test/unit/testresult.rb +1 -1
- data/lib/spec/interop/test/unit/testsuite_adapter.rb +1 -1
- data/lib/spec/matchers.rb +7 -28
- data/lib/spec/matchers/be.rb +103 -116
- data/lib/spec/matchers/be_close.rb +6 -22
- data/lib/spec/matchers/eql.rb +7 -25
- data/lib/spec/matchers/equal.rb +7 -25
- data/lib/spec/matchers/errors.rb +5 -0
- data/lib/spec/matchers/exist.rb +8 -14
- data/lib/spec/matchers/generated_descriptions.rb +48 -0
- data/lib/spec/matchers/has.rb +12 -28
- data/lib/spec/matchers/include.rb +12 -9
- data/lib/spec/matchers/match.rb +8 -27
- data/lib/spec/matchers/match_array.rb +79 -0
- data/lib/spec/matchers/method_missing.rb +9 -0
- data/lib/spec/matchers/operator_matcher.rb +39 -48
- data/lib/spec/matchers/raise_error.rb +4 -8
- data/lib/spec/matchers/respond_to.rb +33 -8
- data/lib/spec/matchers/throw_symbol.rb +49 -17
- data/lib/spec/matchers/wrap_expectation.rb +55 -0
- data/lib/spec/mocks/argument_constraints.rb +77 -5
- data/lib/spec/mocks/message_expectation.rb +7 -7
- data/lib/spec/mocks/proxy.rb +14 -12
- data/lib/spec/rake/spectask.rb +4 -6
- data/lib/spec/ruby.rb +9 -0
- data/lib/spec/runner.rb +37 -162
- data/lib/spec/runner/backtrace_tweaker.rb +5 -3
- data/lib/spec/runner/class_and_arguments_parser.rb +7 -9
- data/lib/spec/runner/command_line.rb +6 -8
- data/lib/spec/{example → runner}/configuration.rb +46 -47
- data/lib/spec/runner/example_group_runner.rb +15 -4
- data/lib/spec/runner/formatter/base_text_formatter.rb +4 -3
- data/lib/spec/runner/formatter/html_formatter.rb +14 -11
- data/lib/spec/runner/formatter/nested_text_formatter.rb +2 -2
- data/lib/spec/runner/heckle_runner.rb +58 -56
- data/lib/spec/runner/option_parser.rb +8 -4
- data/lib/spec/runner/options.rb +29 -14
- data/lib/spec/runner/reporter.rb +1 -1
- data/lib/spec/runner/spec_parser.rb +11 -9
- data/lib/spec/story/runner.rb +40 -42
- data/lib/spec/story/runner/story_runner.rb +10 -6
- data/lib/spec/story/world.rb +66 -70
- data/lib/spec/version.rb +4 -2
- data/{rake_tasks → resources/rake}/examples.rake +0 -0
- data/{rake_tasks → resources/rake}/examples_with_rcov.rake +0 -0
- data/{rake_tasks → resources/rake}/failing_examples_with_html.rake +0 -0
- data/{rake_tasks → resources/rake}/verify_rcov.rake +0 -0
- data/{stories/resources → resources}/spec/example_group_with_should_methods.rb +1 -1
- data/{stories/resources → resources}/spec/simple_spec.rb +1 -1
- data/resources/spec/spec_with_flexmock.rb +19 -0
- data/{stories/resources → resources}/test/spec_and_test_together.rb +1 -1
- data/resources/test/spec_including_test_but_not_unit.rb +11 -0
- data/{stories/resources → resources}/test/test_case_with_should_methods.rb +2 -2
- data/rspec.gemspec +16 -6
- data/spec/autotest/autotest_helper.rb +2 -2
- data/spec/autotest/discover_spec.rb +4 -15
- data/spec/autotest/failed_results_re_spec.rb +24 -0
- data/spec/autotest/rspec_spec.rb +2 -38
- data/spec/spec/dsl/main_spec.rb +88 -0
- data/spec/spec/example/example_group_class_definition_spec.rb +6 -2
- data/spec/spec/example/example_group_factory_spec.rb +50 -10
- data/spec/spec/example/example_group_methods_spec.rb +210 -160
- data/spec/spec/example/example_group_spec.rb +44 -52
- data/spec/spec/example/example_matcher_spec.rb +6 -23
- data/spec/spec/example/example_methods_spec.rb +176 -54
- data/spec/spec/example/helper_method_spec.rb +24 -0
- data/spec/spec/example/pending_module_spec.rb +2 -8
- data/spec/spec/example/shared_example_group_spec.rb +56 -80
- data/spec/spec/expectations/extensions/object_spec.rb +0 -50
- data/spec/spec/expectations/wrap_expectation_spec.rb +30 -0
- data/spec/spec/interop/test/unit/spec_spec.rb +1 -5
- data/spec/spec/interop/test/unit/test_unit_spec_helper.rb +4 -0
- data/spec/spec/matchers/be_close_spec.rb +12 -10
- data/spec/spec/matchers/be_spec.rb +62 -7
- data/spec/spec/matchers/description_generation_spec.rb +19 -0
- data/spec/spec/matchers/eql_spec.rb +7 -6
- data/spec/spec/matchers/equal_spec.rb +7 -6
- data/spec/spec/matchers/handler_spec.rb +4 -43
- data/spec/spec/matchers/has_spec.rb +1 -1
- data/spec/spec/matchers/have_spec.rb +23 -18
- data/spec/spec/matchers/include_spec.rb +24 -0
- data/spec/spec/matchers/match_array_spec.rb +83 -0
- data/spec/spec/matchers/matcher_methods_spec.rb +1 -13
- data/spec/spec/matchers/raise_error_spec.rb +18 -0
- data/spec/spec/matchers/respond_to_spec.rb +71 -9
- data/spec/spec/matchers/throw_symbol_spec.rb +85 -43
- data/spec/spec/mocks/bug_report_11545_spec.rb +4 -5
- data/spec/spec/mocks/bug_report_496.rb +11 -9
- data/spec/spec/mocks/bug_report_600_spec.rb +22 -0
- data/spec/spec/mocks/hash_including_matcher_spec.rb +39 -2
- data/spec/spec/mocks/hash_not_including_matcher_spec.rb +67 -0
- data/spec/spec/mocks/mock_spec.rb +5 -6
- data/spec/spec/mocks/nil_expectation_warning_spec.rb +2 -2
- data/spec/spec/mocks/passing_mock_argument_constraints_spec.rb +18 -3
- data/spec/spec/mocks/stub_spec.rb +6 -0
- data/spec/spec/mocks/stubbed_message_expectations_spec.rb +14 -0
- data/spec/spec/runner/command_line_spec.rb +4 -4
- data/spec/spec/runner/configuration_spec.rb +301 -0
- data/spec/spec/runner/drb_command_line_spec.rb +4 -4
- data/spec/spec/runner/example_group_runner_spec.rb +33 -0
- data/spec/spec/runner/formatter/base_formatter_spec.rb +13 -102
- data/spec/spec/runner/formatter/base_text_formatter_spec.rb +23 -0
- data/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb +5 -5
- data/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +3 -3
- data/spec/spec/runner/formatter/html_formatted-1.8.4.html +6 -6
- data/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html +9 -9
- data/spec/spec/runner/formatter/html_formatted-1.8.5.html +6 -6
- data/spec/spec/runner/formatter/html_formatted-1.8.6-jruby.html +10 -10
- data/spec/spec/runner/formatter/html_formatted-1.8.6.html +39 -30
- data/spec/spec/runner/formatter/html_formatted-1.8.7.html +379 -0
- data/spec/spec/runner/formatter/html_formatted-1.9.1.html +379 -0
- data/spec/spec/runner/formatter/html_formatter_spec.rb +14 -13
- data/spec/spec/runner/formatter/nested_text_formatter_spec.rb +5 -5
- data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +7 -17
- data/spec/spec/runner/formatter/spec_mate_formatter_spec.rb +18 -17
- data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +5 -5
- data/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html +6 -6
- data/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html +33 -30
- data/spec/spec/runner/formatter/text_mate_formatted-1.8.7.html +373 -0
- data/spec/spec/runner/formatter/text_mate_formatted-1.9.1.html +373 -0
- data/spec/spec/runner/heckler_spec.rb +16 -9
- data/spec/spec/runner/option_parser_spec.rb +3 -18
- data/spec/spec/runner/options_spec.rb +27 -8
- data/spec/spec/runner/reporter_spec.rb +5 -5
- data/spec/spec/runner/resources/custom_example_group_runner.rb +14 -0
- data/spec/spec/runner/resources/utf8_encoded.rb +7 -0
- data/spec/spec/runner/spec_parser_spec.rb +85 -79
- data/spec/spec/spec_spec.rb +21 -0
- data/spec/spec_helper.rb +9 -1
- data/story_server/prototype/javascripts/prototype.js +1 -1
- metadata +119 -131
- data/examples/stories/adder.rb +0 -13
- data/examples/stories/addition +0 -34
- data/examples/stories/addition.rb +0 -9
- data/examples/stories/calculator.rb +0 -65
- data/examples/stories/game-of-life/.loadpath +0 -5
- data/examples/stories/game-of-life/README.txt +0 -21
- data/examples/stories/game-of-life/behaviour/everything.rb +0 -6
- data/examples/stories/game-of-life/behaviour/examples/examples.rb +0 -3
- data/examples/stories/game-of-life/behaviour/examples/game_behaviour.rb +0 -35
- data/examples/stories/game-of-life/behaviour/examples/grid_behaviour.rb +0 -66
- data/examples/stories/game-of-life/behaviour/stories/CellsWithLessThanTwoNeighboursDie.story +0 -21
- data/examples/stories/game-of-life/behaviour/stories/CellsWithMoreThanThreeNeighboursDie.story +0 -21
- data/examples/stories/game-of-life/behaviour/stories/EmptySpacesWithThreeNeighboursCreateACell.story +0 -42
- data/examples/stories/game-of-life/behaviour/stories/ICanCreateACell.story +0 -42
- data/examples/stories/game-of-life/behaviour/stories/ICanKillACell.story +0 -17
- data/examples/stories/game-of-life/behaviour/stories/TheGridWraps.story +0 -53
- data/examples/stories/game-of-life/behaviour/stories/create_a_cell.rb +0 -52
- data/examples/stories/game-of-life/behaviour/stories/helper.rb +0 -6
- data/examples/stories/game-of-life/behaviour/stories/kill_a_cell.rb +0 -26
- data/examples/stories/game-of-life/behaviour/stories/steps.rb +0 -5
- data/examples/stories/game-of-life/behaviour/stories/stories.rb +0 -3
- data/examples/stories/game-of-life/behaviour/stories/stories.txt +0 -22
- data/examples/stories/game-of-life/life.rb +0 -3
- data/examples/stories/game-of-life/life/game.rb +0 -23
- data/examples/stories/game-of-life/life/grid.rb +0 -43
- data/examples/stories/helper.rb +0 -9
- data/examples/stories/steps/addition_steps.rb +0 -18
- data/lib/spec/adapters.rb +0 -1
- data/lib/spec/adapters/ruby_engine.rb +0 -26
- data/lib/spec/adapters/ruby_engine/mri.rb +0 -8
- data/lib/spec/adapters/ruby_engine/rubinius.rb +0 -8
- data/lib/spec/extensions.rb +0 -4
- data/lib/spec/extensions/class.rb +0 -24
- data/lib/spec/extensions/metaclass.rb +0 -7
- data/lib/spec/extensions/object.rb +0 -6
- data/spec/spec/adapters/ruby_engine_spec.rb +0 -16
- data/spec/spec/example/configuration_spec.rb +0 -296
- data/spec/spec/example/example_runner_spec.rb +0 -194
- data/spec/spec/extensions/main_spec.rb +0 -71
- data/stories/all.rb +0 -5
- data/stories/configuration/before_blocks.story +0 -21
- data/stories/configuration/stories.rb +0 -7
- data/stories/example_groups/stories.rb +0 -7
- data/stories/helper.rb +0 -6
- data/stories/interop/stories.rb +0 -7
- data/stories/mock_framework_integration/stories.rb +0 -7
- data/stories/pending_stories/README +0 -3
- data/stories/resources/spec/before_blocks_example.rb +0 -32
- data/stories/resources/spec/spec_with_flexmock.rb +0 -18
- data/stories/resources/steps/running_rspec.rb +0 -50
- data/stories/resources/stories/failing_story.rb +0 -15
- data/stories/stories/multiline_steps.story +0 -23
- data/stories/stories/steps/multiline_steps.rb +0 -13
- data/stories/stories/stories.rb +0 -6
@@ -2,39 +2,60 @@ module Spec
|
|
2
2
|
module Matchers
|
3
3
|
|
4
4
|
class ThrowSymbol #:nodoc:
|
5
|
-
def initialize(
|
6
|
-
@
|
7
|
-
@
|
5
|
+
def initialize(expected_symbol = nil, expected_arg=nil)
|
6
|
+
@expected_symbol = expected_symbol
|
7
|
+
@expected_arg = expected_arg
|
8
|
+
@caught_symbol = nil
|
8
9
|
end
|
9
10
|
|
10
11
|
def matches?(given_proc)
|
11
12
|
begin
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
if @expected_symbol.nil?
|
14
|
+
given_proc.call
|
15
|
+
else
|
16
|
+
@caught_arg = catch :proc_did_not_throw_anything do
|
17
|
+
catch @expected_symbol do
|
18
|
+
given_proc.call
|
19
|
+
throw :proc_did_not_throw_anything, :nothing_thrown
|
20
|
+
end
|
21
|
+
end
|
22
|
+
@caught_symbol = @expected_symbol unless @caught_arg == :nothing_thrown
|
23
|
+
end
|
24
|
+
|
25
|
+
# Ruby 1.8 uses NameError with `symbol'
|
26
|
+
# Ruby 1.9 uses ArgumentError with :symbol
|
27
|
+
rescue NameError, ArgumentError => e
|
28
|
+
raise e unless e.message =~ /uncaught throw (`|\:)([a-zA-Z0-9_]*)(')?/
|
29
|
+
@caught_symbol = $2.to_sym
|
30
|
+
|
16
31
|
ensure
|
17
|
-
if @
|
18
|
-
return
|
32
|
+
if @expected_symbol.nil?
|
33
|
+
return !@caught_symbol.nil?
|
19
34
|
else
|
20
|
-
|
35
|
+
if @expected_arg.nil?
|
36
|
+
return @caught_symbol == @expected_symbol
|
37
|
+
else
|
38
|
+
# puts [@caught_symbol, @expected_symbol].inspect
|
39
|
+
# puts [@caught_arg, @expected_arg].inspect
|
40
|
+
return @caught_symbol == @expected_symbol && @caught_arg == @expected_arg
|
41
|
+
end
|
21
42
|
end
|
22
43
|
end
|
23
44
|
end
|
24
45
|
|
25
46
|
def failure_message
|
26
|
-
if @
|
27
|
-
"expected #{expected}, got #{@
|
47
|
+
if @caught_symbol
|
48
|
+
"expected #{expected}, got #{@caught_symbol.inspect}"
|
28
49
|
else
|
29
50
|
"expected #{expected} but nothing was thrown"
|
30
51
|
end
|
31
52
|
end
|
32
53
|
|
33
54
|
def negative_failure_message
|
34
|
-
if @
|
55
|
+
if @expected_symbol
|
35
56
|
"expected #{expected} not to be thrown"
|
36
57
|
else
|
37
|
-
"expected no Symbol, got :#{@
|
58
|
+
"expected no Symbol, got :#{@caught_symbol}"
|
38
59
|
end
|
39
60
|
end
|
40
61
|
|
@@ -45,7 +66,11 @@ module Spec
|
|
45
66
|
private
|
46
67
|
|
47
68
|
def expected
|
48
|
-
@
|
69
|
+
@expected_symbol.nil? ? "a Symbol" : "#{@expected_symbol.inspect}#{args}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def args
|
73
|
+
@expected_arg.nil? ? "" : " with #{@expected_arg.inspect}"
|
49
74
|
end
|
50
75
|
|
51
76
|
end
|
@@ -53,20 +78,27 @@ module Spec
|
|
53
78
|
# :call-seq:
|
54
79
|
# should throw_symbol()
|
55
80
|
# should throw_symbol(:sym)
|
81
|
+
# should throw_symbol(:sym, arg)
|
56
82
|
# should_not throw_symbol()
|
57
83
|
# should_not throw_symbol(:sym)
|
58
|
-
#
|
59
|
-
# Given a Symbol argument, matches if the given proc throws the specified Symbol.
|
84
|
+
# should_not throw_symbol(:sym, arg)
|
60
85
|
#
|
61
86
|
# Given no argument, matches if a proc throws any Symbol.
|
62
87
|
#
|
88
|
+
# Given a Symbol, matches if the given proc throws the specified Symbol.
|
89
|
+
#
|
90
|
+
# Given a Symbol and an arg, matches if the given proc throws the
|
91
|
+
# specified Symbol with the specified arg.
|
92
|
+
#
|
63
93
|
# == Examples
|
64
94
|
#
|
65
95
|
# lambda { do_something_risky }.should throw_symbol
|
66
96
|
# lambda { do_something_risky }.should throw_symbol(:that_was_risky)
|
97
|
+
# lambda { do_something_risky }.should throw_symbol(:that_was_risky, culprit)
|
67
98
|
#
|
68
99
|
# lambda { do_something_risky }.should_not throw_symbol
|
69
100
|
# lambda { do_something_risky }.should_not throw_symbol(:that_was_risky)
|
101
|
+
# lambda { do_something_risky }.should_not throw_symbol(:that_was_risky, culprit)
|
70
102
|
def throw_symbol(sym=nil)
|
71
103
|
Matchers::ThrowSymbol.new(sym)
|
72
104
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Spec
|
2
|
+
module Matchers
|
3
|
+
# wraps an expectation in a block that will return true if the
|
4
|
+
# expectation passes and false if it fails (without bubbling up
|
5
|
+
# the failure).
|
6
|
+
#
|
7
|
+
# This is intended to be used in the context of a simple matcher,
|
8
|
+
# and is especially useful for wrapping multiple expectations or
|
9
|
+
# one or more assertions from test/unit extensions when running
|
10
|
+
# with test/unit.
|
11
|
+
#
|
12
|
+
# == Examples
|
13
|
+
#
|
14
|
+
# def eat_cheese(cheese)
|
15
|
+
# simple_matcher do |mouse, matcher|
|
16
|
+
# matcher.failure_message = "expected #{mouse} to eat cheese"
|
17
|
+
# wrap_expectation do |matcher|
|
18
|
+
# assert_eats_cheese(mouse)
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# describe Mouse do
|
24
|
+
# it "eats cheese" do
|
25
|
+
# Mouse.new.should eat_cheese
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# You might be wondering "why would I do this if I could just say"
|
30
|
+
# assert_eats_cheese?", a fair question, indeed. You might prefer
|
31
|
+
# to replace the word assert with something more aligned with the
|
32
|
+
# rest of your code examples. You are using rspec, after all.
|
33
|
+
#
|
34
|
+
# The other benefit you get is that you can use the negative version
|
35
|
+
# of the matcher:
|
36
|
+
#
|
37
|
+
# describe Cat do
|
38
|
+
# it "does not eat cheese" do
|
39
|
+
# Cat.new.should_not eat_cheese
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# So in the event there is no assert_does_not_eat_cheese available,
|
44
|
+
# you're all set!
|
45
|
+
def wrap_expectation(matcher, &block)
|
46
|
+
begin
|
47
|
+
block.call(matcher)
|
48
|
+
return true
|
49
|
+
rescue Exception => e
|
50
|
+
matcher.failure_message = e.message
|
51
|
+
return false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -73,6 +73,25 @@ module Spec
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
+
class HashNotIncludingConstraint
|
77
|
+
def initialize(expected)
|
78
|
+
@expected = expected
|
79
|
+
end
|
80
|
+
|
81
|
+
def ==(actual)
|
82
|
+
@expected.each do | key, value |
|
83
|
+
return false if actual.has_key?(key) && value == actual[key]
|
84
|
+
end
|
85
|
+
true
|
86
|
+
rescue NoMethodError => ex
|
87
|
+
return false
|
88
|
+
end
|
89
|
+
|
90
|
+
def description
|
91
|
+
"hash_not_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
76
95
|
class DuckTypeConstraint
|
77
96
|
def initialize(*methods_to_respond_to)
|
78
97
|
@methods_to_respond_to = methods_to_respond_to
|
@@ -102,6 +121,26 @@ module Spec
|
|
102
121
|
@given == expected
|
103
122
|
end
|
104
123
|
end
|
124
|
+
|
125
|
+
class InstanceOf
|
126
|
+
def initialize(klass)
|
127
|
+
@klass = klass
|
128
|
+
end
|
129
|
+
|
130
|
+
def ==(actual)
|
131
|
+
actual.instance_of?(@klass)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
class KindOf
|
136
|
+
def initialize(klass)
|
137
|
+
@klass = klass
|
138
|
+
end
|
139
|
+
|
140
|
+
def ==(actual)
|
141
|
+
actual.kind_of?(@klass)
|
142
|
+
end
|
143
|
+
end
|
105
144
|
|
106
145
|
# :call-seq:
|
107
146
|
# object.should_receive(:message).with(any_args())
|
@@ -153,12 +192,45 @@ module Spec
|
|
153
192
|
end
|
154
193
|
|
155
194
|
# :call-seq:
|
156
|
-
# object.should_receive(:message).with(hash_including(:
|
157
|
-
#
|
158
|
-
#
|
195
|
+
# object.should_receive(:message).with(hash_including(:key => val))
|
196
|
+
# object.should_receive(:message).with(hash_including(:key))
|
197
|
+
# object.should_receive(:message).with(hash_including(:key, :key2 => val2))
|
198
|
+
# Passes if the argument is a hash that includes the specified key(s) or key/value
|
159
199
|
# pairs. If the hash includes other keys, it will still pass.
|
160
|
-
def hash_including(
|
161
|
-
HashIncludingConstraint.new(
|
200
|
+
def hash_including(*args)
|
201
|
+
HashIncludingConstraint.new(anythingize_lonely_keys(*args))
|
202
|
+
end
|
203
|
+
|
204
|
+
# :call-seq:
|
205
|
+
# object.should_receive(:message).with(hash_not_including(:key => val))
|
206
|
+
# object.should_receive(:message).with(hash_not_including(:key))
|
207
|
+
# object.should_receive(:message).with(hash_not_including(:key, :key2 => :val2))
|
208
|
+
#
|
209
|
+
# Passes if the argument is a hash that doesn't include the specified key(s) or key/value
|
210
|
+
def hash_not_including(*args)
|
211
|
+
HashNotIncludingConstraint.new(anythingize_lonely_keys(*args))
|
212
|
+
end
|
213
|
+
|
214
|
+
# Passes if arg.instance_of?(klass)
|
215
|
+
def instance_of(klass)
|
216
|
+
InstanceOf.new(klass)
|
217
|
+
end
|
218
|
+
|
219
|
+
alias_method :an_instance_of, :instance_of
|
220
|
+
|
221
|
+
# Passes if arg.kind_of?(klass)
|
222
|
+
def kind_of(klass)
|
223
|
+
KindOf.new(klass)
|
224
|
+
end
|
225
|
+
|
226
|
+
alias_method :a_kind_of, :kind_of
|
227
|
+
|
228
|
+
private
|
229
|
+
|
230
|
+
def anythingize_lonely_keys(*args)
|
231
|
+
hash = args.last.class == Hash ? args.delete_at(-1) : {}
|
232
|
+
args.each { | arg | hash[arg] = anything }
|
233
|
+
hash
|
162
234
|
end
|
163
235
|
end
|
164
236
|
end
|
@@ -32,6 +32,7 @@ module Spec
|
|
32
32
|
child.expected_from = expected_from
|
33
33
|
child.method_block = method_block
|
34
34
|
child.expected_received_count = expected_received_count
|
35
|
+
child.clear_actual_received_count!
|
35
36
|
new_gen = error_generator.clone
|
36
37
|
new_gen.opts = opts
|
37
38
|
child.error_generator = new_gen
|
@@ -39,11 +40,6 @@ module Spec
|
|
39
40
|
child
|
40
41
|
end
|
41
42
|
|
42
|
-
def error_generator_opts=(opts={})
|
43
|
-
@error_generator.opts = opts
|
44
|
-
end
|
45
|
-
protected :error_generator_opts=
|
46
|
-
|
47
43
|
def expected_args
|
48
44
|
@args_expectation.args
|
49
45
|
end
|
@@ -92,7 +88,7 @@ module Spec
|
|
92
88
|
@args_to_yield << args
|
93
89
|
self
|
94
90
|
end
|
95
|
-
|
91
|
+
|
96
92
|
def matches(sym, args)
|
97
93
|
@sym == sym and @args_expectation.args_match?(args)
|
98
94
|
end
|
@@ -196,7 +192,7 @@ module Spec
|
|
196
192
|
@sym == sym and not @args_expectation.args_match?(args)
|
197
193
|
end
|
198
194
|
|
199
|
-
def verify_messages_received
|
195
|
+
def verify_messages_received
|
200
196
|
return if expected_messages_received? || failed_fast?
|
201
197
|
|
202
198
|
generate_error
|
@@ -314,6 +310,10 @@ module Spec
|
|
314
310
|
2
|
315
311
|
end
|
316
312
|
end
|
313
|
+
|
314
|
+
def clear_actual_received_count!
|
315
|
+
@actual_received_count = 0
|
316
|
+
end
|
317
317
|
|
318
318
|
end
|
319
319
|
|
data/lib/spec/mocks/proxy.rb
CHANGED
@@ -60,7 +60,7 @@ module Spec
|
|
60
60
|
@stubs.unshift MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, nil, :any, opts)
|
61
61
|
@stubs.first
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
def verify #:nodoc:
|
65
65
|
verify_expectations
|
66
66
|
ensure
|
@@ -91,14 +91,14 @@ module Spec
|
|
91
91
|
if expectation = find_almost_matching_expectation(sym, *args)
|
92
92
|
expectation.advise(args, block) unless expectation.expected_messages_received?
|
93
93
|
end
|
94
|
-
stub.invoke(
|
94
|
+
stub.invoke(args, block)
|
95
95
|
elsif expectation
|
96
96
|
expectation.invoke(args, block)
|
97
97
|
elsif expectation = find_almost_matching_expectation(sym, *args)
|
98
98
|
expectation.advise(args, block) if null_object? unless expectation.expected_messages_received?
|
99
99
|
raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(sym) or null_object?)
|
100
100
|
else
|
101
|
-
@target.
|
101
|
+
@target.__send__ :method_missing, sym, *args, &block
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
@@ -125,14 +125,16 @@ module Spec
|
|
125
125
|
|
126
126
|
def define_expected_method(sym)
|
127
127
|
visibility_string = "#{visibility(sym)} :#{sym}"
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
128
|
+
unless @proxied_methods.include?(sym)
|
129
|
+
if target_responds_to?(sym)
|
130
|
+
munged_sym = munge(sym)
|
131
|
+
target_metaclass.instance_eval do
|
132
|
+
alias_method munged_sym, sym if method_defined?(sym.to_s)
|
133
|
+
end
|
134
|
+
@proxied_methods << sym
|
132
135
|
end
|
133
|
-
@proxied_methods << sym
|
134
136
|
end
|
135
|
-
|
137
|
+
|
136
138
|
target_metaclass.class_eval(<<-EOF, __FILE__, __LINE__)
|
137
139
|
def #{sym}(*args, &block)
|
138
140
|
__mock_proxy.message_received :#{sym}, *args, &block
|
@@ -142,9 +144,9 @@ module Spec
|
|
142
144
|
end
|
143
145
|
|
144
146
|
def target_responds_to?(sym)
|
145
|
-
return @target.
|
147
|
+
return @target.__send__(munge(:respond_to?),sym) if @already_proxied_respond_to
|
146
148
|
return @already_proxied_respond_to = true if sym == :respond_to?
|
147
|
-
return @target.respond_to?(sym)
|
149
|
+
return @target.respond_to?(sym, true)
|
148
150
|
end
|
149
151
|
|
150
152
|
def visibility(sym)
|
@@ -193,7 +195,7 @@ module Spec
|
|
193
195
|
alias_method sym, munged_sym
|
194
196
|
undef_method munged_sym
|
195
197
|
else
|
196
|
-
|
198
|
+
remove_method sym
|
197
199
|
end
|
198
200
|
end
|
199
201
|
end
|
data/lib/spec/rake/spectask.rb
CHANGED
@@ -56,12 +56,10 @@ module Spec
|
|
56
56
|
# end
|
57
57
|
#
|
58
58
|
class SpecTask < ::Rake::TaskLib
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
module_eval "def #{name}() evaluate(@#{name}) end" # Allows use of procs
|
64
|
-
end
|
59
|
+
def self.attr_accessor(*names)
|
60
|
+
super(*names)
|
61
|
+
names.each do |name|
|
62
|
+
module_eval "def #{name}() evaluate(@#{name}) end" # Allows use of procs
|
65
63
|
end
|
66
64
|
end
|
67
65
|
|
data/lib/spec/ruby.rb
ADDED
data/lib/spec/runner.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'spec/runner/configuration'
|
1
2
|
require 'spec/runner/options'
|
2
3
|
require 'spec/runner/option_parser'
|
3
4
|
require 'spec/runner/example_group_runner'
|
@@ -9,166 +10,22 @@ require 'spec/runner/spec_parser'
|
|
9
10
|
require 'spec/runner/class_and_arguments_parser'
|
10
11
|
|
11
12
|
module Spec
|
12
|
-
# == ExampleGroups and Examples
|
13
|
-
#
|
14
|
-
# Rather than expressing examples in classes, RSpec uses a custom DSLL (DSL light) to
|
15
|
-
# describe groups of examples.
|
16
|
-
#
|
17
|
-
# A ExampleGroup is the equivalent of a fixture in xUnit-speak. It is a metaphor for the context
|
18
|
-
# in which you will run your executable example - a set of known objects in a known starting state.
|
19
|
-
# We begin be describing
|
20
|
-
#
|
21
|
-
# describe Account do
|
22
|
-
#
|
23
|
-
# before do
|
24
|
-
# @account = Account.new
|
25
|
-
# end
|
26
|
-
#
|
27
|
-
# it "should have a balance of $0" do
|
28
|
-
# @account.balance.should == Money.new(0, :dollars)
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
# We use the before block to set up the Example (given), and then the #it method to
|
34
|
-
# hold the example code that expresses the event (when) and the expected outcome (then).
|
35
|
-
#
|
36
|
-
# == Helper Methods
|
37
|
-
#
|
38
|
-
# A primary goal of RSpec is to keep the examples clear. We therefore prefer
|
39
|
-
# less indirection than you might see in xUnit examples and in well factored, DRY production code. We feel
|
40
|
-
# that duplication is OK if removing it makes it harder to understand an example without
|
41
|
-
# having to look elsewhere to understand its context.
|
42
|
-
#
|
43
|
-
# That said, RSpec does support some level of encapsulating common code in helper
|
44
|
-
# methods that can exist within a context or within an included module.
|
45
|
-
#
|
46
|
-
# == Setup and Teardown
|
47
|
-
#
|
48
|
-
# You can use before and after within a Example. Both methods take an optional
|
49
|
-
# scope argument so you can run the block before :each example or before :all examples
|
50
|
-
#
|
51
|
-
# describe "..." do
|
52
|
-
# before :all do
|
53
|
-
# ...
|
54
|
-
# end
|
55
|
-
#
|
56
|
-
# before :each do
|
57
|
-
# ...
|
58
|
-
# end
|
59
|
-
#
|
60
|
-
# it "should do something" do
|
61
|
-
# ...
|
62
|
-
# end
|
63
|
-
#
|
64
|
-
# it "should do something else" do
|
65
|
-
# ...
|
66
|
-
# end
|
67
|
-
#
|
68
|
-
# after :each do
|
69
|
-
# ...
|
70
|
-
# end
|
71
|
-
#
|
72
|
-
# after :all do
|
73
|
-
# ...
|
74
|
-
# end
|
75
|
-
#
|
76
|
-
# end
|
77
|
-
#
|
78
|
-
# The <tt>before :each</tt> block will run before each of the examples, once for each example. Likewise,
|
79
|
-
# the <tt>after :each</tt> block will run after each of the examples.
|
80
|
-
#
|
81
|
-
# It is also possible to specify a <tt>before :all</tt> and <tt>after :all</tt>
|
82
|
-
# block that will run only once for each behaviour, respectively before the first <code>before :each</code>
|
83
|
-
# and after the last <code>after :each</code>. The use of these is generally discouraged, because it
|
84
|
-
# introduces dependencies between the examples. Still, it might prove useful for very expensive operations
|
85
|
-
# if you know what you are doing.
|
86
|
-
#
|
87
|
-
# == Local helper methods
|
88
|
-
#
|
89
|
-
# You can include local helper methods by simply expressing them within a context:
|
90
|
-
#
|
91
|
-
# describe "..." do
|
92
|
-
#
|
93
|
-
# it "..." do
|
94
|
-
# helper_method
|
95
|
-
# end
|
96
|
-
#
|
97
|
-
# def helper_method
|
98
|
-
# ...
|
99
|
-
# end
|
100
|
-
#
|
101
|
-
# end
|
102
|
-
#
|
103
|
-
# == Included helper methods
|
104
|
-
#
|
105
|
-
# You can include helper methods in multiple contexts by expressing them within
|
106
|
-
# a module, and then including that module in your context:
|
107
|
-
#
|
108
|
-
# module AccountExampleHelperMethods
|
109
|
-
# def helper_method
|
110
|
-
# ...
|
111
|
-
# end
|
112
|
-
# end
|
113
|
-
#
|
114
|
-
# describe "A new account" do
|
115
|
-
# include AccountExampleHelperMethods
|
116
|
-
# before do
|
117
|
-
# @account = Account.new
|
118
|
-
# end
|
119
|
-
#
|
120
|
-
# it "should have a balance of $0" do
|
121
|
-
# helper_method
|
122
|
-
# @account.balance.should eql(Money.new(0, :dollars))
|
123
|
-
# end
|
124
|
-
# end
|
125
|
-
#
|
126
|
-
# == Shared Example Groups
|
127
|
-
#
|
128
|
-
# You can define a shared Example Group, that may be used on other groups
|
129
|
-
#
|
130
|
-
# share_examples_for "All Editions" do
|
131
|
-
# it "all editions behaviour" ...
|
132
|
-
# end
|
133
|
-
#
|
134
|
-
# describe SmallEdition do
|
135
|
-
# it_should_behave_like "All Editions"
|
136
|
-
#
|
137
|
-
# it "should do small edition stuff" do
|
138
|
-
# ...
|
139
|
-
# end
|
140
|
-
# end
|
141
|
-
#
|
142
|
-
# You can also assign the shared group to a module and include that
|
143
|
-
#
|
144
|
-
# share_as :AllEditions do
|
145
|
-
# it "should do all editions stuff" ...
|
146
|
-
# end
|
147
|
-
#
|
148
|
-
# describe SmallEdition do
|
149
|
-
# it_should_behave_like AllEditions
|
150
|
-
#
|
151
|
-
# it "should do small edition stuff" do
|
152
|
-
# ...
|
153
|
-
# end
|
154
|
-
# end
|
155
|
-
#
|
156
|
-
# And, for those of you who prefer to use something more like Ruby, you
|
157
|
-
# can just include the module directly
|
158
|
-
#
|
159
|
-
# describe SmallEdition do
|
160
|
-
# include AllEditions
|
161
|
-
#
|
162
|
-
# it "should do small edition stuff" do
|
163
|
-
# ...
|
164
|
-
# end
|
165
|
-
# end
|
166
13
|
module Runner
|
14
|
+
|
15
|
+
class ExampleGroupCreationListener
|
16
|
+
def register_example_group(klass)
|
17
|
+
Spec::Runner.options.add_example_group klass
|
18
|
+
Spec::Runner.register_at_exit_hook
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Spec::Example::ExampleGroupMethods.example_group_creation_listeners << ExampleGroupCreationListener.new
|
23
|
+
|
167
24
|
class << self
|
168
25
|
def configuration # :nodoc:
|
169
|
-
@configuration ||= Spec::
|
26
|
+
@configuration ||= Spec::Runner::Configuration.new
|
170
27
|
end
|
171
|
-
|
28
|
+
|
172
29
|
# Use this to configure various configurable aspects of
|
173
30
|
# RSpec:
|
174
31
|
#
|
@@ -177,19 +34,19 @@ module Spec
|
|
177
34
|
# end
|
178
35
|
#
|
179
36
|
# The yielded <tt>configuration</tt> object is a
|
180
|
-
# Spec::
|
37
|
+
# Spec::Runner::Configuration instance. See its RDoc
|
181
38
|
# for details about what you can do with it.
|
182
39
|
#
|
183
40
|
def configure
|
184
41
|
yield configuration
|
185
42
|
end
|
186
|
-
|
43
|
+
|
187
44
|
def register_at_exit_hook # :nodoc:
|
188
45
|
unless @already_registered_at_exit_hook
|
189
46
|
at_exit do
|
190
|
-
unless $! ||
|
191
|
-
success =
|
192
|
-
exit success if
|
47
|
+
unless $! || run? || Spec::Example::ExampleGroupFactory.registered_or_ancestor_of_registered?(options.example_groups)
|
48
|
+
success = run
|
49
|
+
exit success if exit?
|
193
50
|
end
|
194
51
|
end
|
195
52
|
@already_registered_at_exit_hook = true
|
@@ -203,11 +60,29 @@ module Spec
|
|
203
60
|
parser.options
|
204
61
|
end
|
205
62
|
end
|
206
|
-
|
63
|
+
|
207
64
|
def use options
|
208
65
|
@options = options
|
209
66
|
end
|
210
67
|
|
68
|
+
def test_unit_defined?
|
69
|
+
Object.const_defined?(:Test) && Test.const_defined?(:Unit) && Test::Unit.respond_to?(:run?)
|
70
|
+
end
|
71
|
+
|
72
|
+
def run?
|
73
|
+
Runner.options.examples_run?
|
74
|
+
end
|
75
|
+
|
76
|
+
def run
|
77
|
+
return true if run?
|
78
|
+
options.run_examples
|
79
|
+
end
|
80
|
+
|
81
|
+
def exit?
|
82
|
+
!test_unit_defined? || Test::Unit.run?
|
83
|
+
end
|
211
84
|
end
|
212
85
|
end
|
213
86
|
end
|
87
|
+
|
88
|
+
require 'spec/interop/test' if Spec::Runner::test_unit_defined?
|