rspec 0.8.2 → 0.9.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 +125 -9
- data/EXAMPLES.rd +50 -27
- data/README +14 -1
- data/Rakefile +95 -42
- data/UPGRADE +31 -0
- data/bin/spec +0 -1
- data/bin/spec_translator +6 -0
- data/examples/auto_spec_description_example.rb +19 -0
- data/examples/{setup_teardown_example.rb → before_and_after_example.rb} +6 -6
- data/examples/behave_as_example.rb +45 -0
- data/examples/custom_expectation_matchers.rb +13 -12
- data/examples/dynamic_spec.rb +2 -2
- data/examples/file_accessor_spec.rb +2 -2
- data/examples/greeter_spec.rb +3 -3
- data/examples/helper_method_example.rb +2 -2
- data/examples/io_processor_spec.rb +4 -4
- data/examples/legacy_spec.rb +10 -0
- data/examples/mocking_example.rb +5 -5
- data/examples/multi_threaded_behaviour_runner.rb +25 -0
- data/examples/partial_mock_example.rb +4 -4
- data/examples/predicate_example.rb +4 -4
- data/examples/priority.txt +1 -0
- data/examples/shared_behaviours_example.rb +31 -0
- data/examples/stack_spec.rb +52 -69
- data/examples/stubbing_example.rb +10 -10
- data/examples/test_case_adapter_example.rb +26 -0
- data/examples/test_case_spec.rb +6 -6
- data/lib/spec.rb +9 -4
- data/lib/spec/dsl.rb +10 -0
- data/lib/spec/dsl/behaviour.rb +189 -0
- data/lib/spec/dsl/behaviour_callbacks.rb +43 -0
- data/lib/spec/dsl/behaviour_eval.rb +170 -0
- data/lib/spec/dsl/behaviour_factory.rb +32 -0
- data/lib/spec/dsl/composite_proc_builder.rb +28 -0
- data/lib/spec/dsl/configuration.rb +38 -0
- data/lib/spec/dsl/description.rb +34 -0
- data/lib/spec/dsl/example.rb +114 -0
- data/lib/spec/dsl/example_matcher.rb +28 -0
- data/lib/spec/{runner/spec_should_raise_handler.rb → dsl/example_should_raise_handler.rb} +4 -4
- data/lib/spec/expectations.rb +0 -3
- data/lib/spec/expectations/differs/default.rb +0 -1
- data/lib/spec/expectations/extensions.rb +0 -1
- data/lib/spec/expectations/extensions/object.rb +10 -53
- data/lib/spec/expectations/handler.rb +14 -18
- data/lib/spec/extensions.rb +1 -0
- data/lib/spec/extensions/object.rb +6 -0
- data/lib/spec/matchers.rb +19 -21
- data/lib/spec/matchers/be.rb +40 -11
- data/lib/spec/matchers/be_close.rb +2 -2
- data/lib/spec/matchers/operator_matcher.rb +52 -0
- data/lib/spec/matchers/respond_to.rb +21 -11
- data/lib/spec/mocks.rb +5 -28
- data/lib/spec/mocks/argument_constraint_matchers.rb +12 -0
- data/lib/spec/mocks/argument_expectation.rb +7 -4
- data/lib/spec/mocks/methods.rb +11 -16
- data/lib/spec/mocks/mock.rb +6 -3
- data/lib/spec/mocks/{mock_handler.rb → proxy.rb} +4 -7
- data/lib/spec/mocks/space.rb +28 -0
- data/lib/spec/mocks/spec_methods.rb +30 -0
- data/lib/spec/rake/spectask.rb +23 -21
- data/lib/spec/rake/verify_rcov.rb +1 -0
- data/lib/spec/runner.rb +88 -35
- data/lib/spec/runner/backtrace_tweaker.rb +2 -1
- data/lib/spec/runner/behaviour_runner.rb +102 -0
- data/lib/spec/runner/command_line.rb +5 -17
- data/lib/spec/runner/drb_command_line.rb +2 -2
- data/lib/spec/runner/extensions/kernel.rb +22 -9
- data/lib/spec/runner/formatter.rb +4 -0
- data/lib/spec/runner/formatter/base_formatter.rb +63 -0
- data/lib/spec/runner/formatter/base_text_formatter.rb +22 -52
- data/lib/spec/runner/formatter/failing_behaviours_formatter.rb +25 -0
- data/lib/spec/runner/formatter/failing_examples_formatter.rb +22 -0
- data/lib/spec/runner/formatter/html_formatter.rb +74 -29
- data/lib/spec/runner/formatter/progress_bar_formatter.rb +6 -8
- data/lib/spec/runner/formatter/rdoc_formatter.rb +6 -6
- data/lib/spec/runner/formatter/snippet_extractor.rb +52 -0
- data/lib/spec/runner/formatter/specdoc_formatter.rb +6 -6
- data/lib/spec/runner/heckle_runner.rb +8 -7
- data/lib/spec/runner/option_parser.rb +136 -55
- data/lib/spec/runner/options.rb +26 -0
- data/lib/spec/runner/reporter.rb +38 -31
- data/lib/spec/runner/spec_parser.rb +22 -13
- data/lib/spec/test_case_adapter.rb +10 -0
- data/lib/spec/translator.rb +103 -86
- data/lib/spec/version.rb +7 -15
- data/plugins/mock_frameworks/flexmock.rb +27 -0
- data/plugins/mock_frameworks/mocha.rb +21 -0
- data/plugins/mock_frameworks/rspec.rb +18 -0
- data/spec/spec/dsl/behaviour_eval_spec.rb +49 -0
- data/spec/spec/dsl/behaviour_factory_spec.rb +30 -0
- data/spec/spec/dsl/behaviour_spec.rb +508 -0
- data/spec/spec/dsl/composite_proc_builder_spec.rb +57 -0
- data/spec/spec/dsl/configuration_spec.rb +43 -0
- data/spec/spec/dsl/description_spec.rb +51 -0
- data/spec/spec/dsl/example_class_spec.rb +24 -0
- data/spec/spec/dsl/example_instance_spec.rb +140 -0
- data/spec/spec/dsl/example_should_raise_spec.rb +137 -0
- data/spec/spec/dsl/predicate_matcher_spec.rb +21 -0
- data/spec/spec/dsl/shared_behaviour_spec.rb +186 -0
- data/spec/spec/expectations/differs/default_spec.rb +12 -12
- data/spec/spec/expectations/extensions/object_spec.rb +10 -10
- data/spec/spec/expectations/fail_with_spec.rb +20 -20
- data/spec/spec/matchers/be_close_spec.rb +37 -31
- data/spec/spec/matchers/be_spec.rb +50 -41
- data/spec/spec/matchers/change_spec.rb +54 -54
- data/spec/spec/matchers/description_generation_spec.rb +43 -31
- data/spec/spec/matchers/eql_spec.rb +24 -37
- data/spec/spec/matchers/equal_spec.rb +24 -37
- data/spec/spec/matchers/exist_spec.rb +48 -0
- data/spec/spec/matchers/handler_spec.rb +36 -23
- data/spec/spec/matchers/has_spec.rb +8 -8
- data/spec/spec/matchers/have_spec.rb +38 -38
- data/spec/spec/matchers/include_spec.rb +6 -6
- data/spec/spec/matchers/match_spec.rb +8 -8
- data/spec/spec/matchers/matcher_methods_spec.rb +24 -31
- data/spec/spec/matchers/raise_error_spec.rb +34 -34
- data/spec/spec/matchers/respond_to_spec.rb +32 -8
- data/spec/spec/matchers/satisfy_spec.rb +6 -6
- data/spec/spec/matchers/should_===_spec.rb +38 -0
- data/spec/spec/matchers/should_==_spec.rb +37 -0
- data/spec/spec/matchers/should_=~_spec.rb +36 -0
- data/spec/spec/matchers/throw_symbol_spec.rb +47 -55
- data/spec/spec/mocks/any_number_of_times_spec.rb +16 -21
- data/spec/spec/mocks/argument_expectation_spec.rb +3 -3
- data/spec/spec/mocks/at_least_spec.rb +30 -30
- data/spec/spec/mocks/at_most_spec.rb +53 -57
- data/spec/spec/mocks/bug_report_10260_spec.rb +8 -0
- data/spec/spec/mocks/bug_report_7611_spec.rb +3 -3
- data/spec/spec/mocks/bug_report_7805_spec.rb +3 -3
- data/spec/spec/mocks/bug_report_8165_spec.rb +5 -5
- data/spec/spec/mocks/bug_report_8302_spec.rb +5 -5
- data/spec/spec/mocks/failing_mock_argument_constraints_spec.rb +26 -27
- data/spec/spec/mocks/mock_ordering_spec.rb +19 -15
- data/spec/spec/mocks/mock_space_spec.rb +54 -0
- data/spec/spec/mocks/mock_spec.rb +111 -141
- data/spec/spec/mocks/multiple_return_value_spec.rb +48 -48
- data/spec/spec/mocks/null_object_mock_spec.rb +10 -10
- data/spec/spec/mocks/once_counts_spec.rb +32 -35
- data/spec/spec/mocks/options_hash_spec.rb +12 -10
- data/spec/spec/mocks/partial_mock_spec.rb +15 -15
- data/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb +24 -22
- data/spec/spec/mocks/passing_mock_argument_constraints_spec.rb +19 -19
- data/spec/spec/mocks/precise_counts_spec.rb +28 -32
- data/spec/spec/mocks/record_messages_spec.rb +10 -10
- data/spec/spec/mocks/stub_spec.rb +45 -45
- data/spec/spec/mocks/twice_counts_spec.rb +21 -21
- data/spec/spec/package/bin_spec_spec.rb +12 -0
- data/spec/spec/runner/behaviour_runner_spec.rb +114 -0
- data/spec/spec/runner/command_line_spec.rb +8 -8
- data/spec/spec/runner/context_matching_spec.rb +14 -15
- data/spec/spec/runner/drb_command_line_spec.rb +12 -12
- data/spec/spec/runner/execution_context_spec.rb +8 -29
- data/spec/spec/runner/extensions/kernel_spec.rb +36 -0
- data/spec/spec/runner/formatter/failing_behaviours_formatter_spec.rb +27 -0
- data/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +28 -0
- data/spec/spec/runner/formatter/html_formatter_spec.rb +9 -8
- data/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb +6 -6
- data/spec/spec/runner/formatter/progress_bar_formatter_failure_dump_spec.rb +10 -10
- data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +22 -27
- data/spec/spec/runner/formatter/rdoc_formatter_dry_run_spec.rb +6 -5
- data/spec/spec/runner/formatter/rdoc_formatter_spec.rb +17 -17
- data/spec/spec/runner/formatter/snippet_extractor_spec.rb +11 -0
- data/spec/spec/runner/formatter/specdoc_formatter_dry_run_spec.rb +6 -6
- data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +17 -17
- data/spec/spec/runner/heckle_runner_spec.rb +21 -21
- data/spec/spec/runner/heckler_spec.rb +5 -5
- data/spec/spec/runner/noisy_backtrace_tweaker_spec.rb +12 -12
- data/spec/spec/runner/object_ext_spec.rb +3 -3
- data/spec/spec/runner/option_parser_spec.rb +171 -102
- data/spec/spec/runner/quiet_backtrace_tweaker_spec.rb +21 -12
- data/spec/spec/runner/reporter_spec.rb +106 -97
- data/spec/spec/runner/spec_matcher_spec.rb +46 -51
- data/spec/spec/runner/spec_parser_spec.rb +72 -16
- data/spec/spec/spec_classes.rb +12 -3
- data/spec/spec/translator_spec.rb +165 -36
- metadata +66 -76
- data/RELEASE-PLAN +0 -117
- data/examples/auto_spec_name_generation_example.rb +0 -18
- data/lib/spec/callback.rb +0 -11
- data/lib/spec/callback/callback_container.rb +0 -60
- data/lib/spec/callback/extensions/module.rb +0 -24
- data/lib/spec/callback/extensions/object.rb +0 -37
- data/lib/spec/deprecated.rb +0 -3
- data/lib/spec/expectations/extensions/proc.rb +0 -57
- data/lib/spec/expectations/should.rb +0 -5
- data/lib/spec/expectations/should/base.rb +0 -64
- data/lib/spec/expectations/should/change.rb +0 -69
- data/lib/spec/expectations/should/have.rb +0 -128
- data/lib/spec/expectations/should/not.rb +0 -74
- data/lib/spec/expectations/should/should.rb +0 -81
- data/lib/spec/expectations/sugar.rb +0 -47
- data/lib/spec/runner/context.rb +0 -154
- data/lib/spec/runner/context_eval.rb +0 -142
- data/lib/spec/runner/context_runner.rb +0 -55
- data/lib/spec/runner/execution_context.rb +0 -17
- data/lib/spec/runner/spec_matcher.rb +0 -25
- data/lib/spec/runner/specification.rb +0 -114
- data/spec/spec/callback/callback_container_spec.rb +0 -27
- data/spec/spec/callback/module_spec.rb +0 -37
- data/spec/spec/callback/object_spec.rb +0 -90
- data/spec/spec/callback/object_with_class_callback_spec.rb +0 -19
- data/spec/spec/expectations/should/should_==_spec.rb +0 -19
- data/spec/spec/expectations/should/should_=~_spec.rb +0 -13
- data/spec/spec/expectations/should/should_be_a_kind_of_spec.rb +0 -21
- data/spec/spec/expectations/should/should_be_an_instance_of_spec.rb +0 -30
- data/spec/spec/expectations/should/should_be_arbitrary_predicate_spec.rb +0 -81
- data/spec/spec/expectations/should/should_be_close_spec.rb +0 -18
- data/spec/spec/expectations/should/should_be_comparison_operator_spec.rb +0 -44
- data/spec/spec/expectations/should/should_be_false_spec.rb +0 -39
- data/spec/spec/expectations/should/should_be_spec.rb +0 -11
- data/spec/spec/expectations/should/should_be_true_spec.rb +0 -27
- data/spec/spec/expectations/should/should_change_spec.rb +0 -184
- data/spec/spec/expectations/should/should_eql_spec.rb +0 -11
- data/spec/spec/expectations/should/should_equal_spec.rb +0 -11
- data/spec/spec/expectations/should/should_have_at_least_spec.rb +0 -53
- data/spec/spec/expectations/should/should_have_at_most_spec.rb +0 -45
- data/spec/spec/expectations/should/should_have_key_spec.rb +0 -21
- data/spec/spec/expectations/should/should_have_spec.rb +0 -64
- data/spec/spec/expectations/should/should_include_spec.rb +0 -59
- data/spec/spec/expectations/should/should_match_spec.rb +0 -25
- data/spec/spec/expectations/should/should_not_==_spec.rb +0 -15
- data/spec/spec/expectations/should/should_not_be_a_kind_of_spec.rb +0 -21
- data/spec/spec/expectations/should/should_not_be_an_instance_of_spec.rb +0 -11
- data/spec/spec/expectations/should/should_not_be_arbitrary_predicate_spec.rb +0 -68
- data/spec/spec/expectations/should/should_not_be_spec.rb +0 -11
- data/spec/spec/expectations/should/should_not_change_spec.rb +0 -24
- data/spec/spec/expectations/should/should_not_eql_spec.rb +0 -11
- data/spec/spec/expectations/should/should_not_equal_spec.rb +0 -11
- data/spec/spec/expectations/should/should_not_have_key_spec.rb +0 -15
- data/spec/spec/expectations/should/should_not_include_spec.rb +0 -58
- data/spec/spec/expectations/should/should_not_match_spec.rb +0 -11
- data/spec/spec/expectations/should/should_not_raise_spec.rb +0 -75
- data/spec/spec/expectations/should/should_not_respond_to_spec.rb +0 -15
- data/spec/spec/expectations/should/should_not_throw_spec.rb +0 -35
- data/spec/spec/expectations/should/should_raise_spec.rb +0 -66
- data/spec/spec/expectations/should/should_respond_to_spec.rb +0 -15
- data/spec/spec/expectations/should/should_satisfy_spec.rb +0 -35
- data/spec/spec/expectations/should/should_throw_spec.rb +0 -27
- data/spec/spec/runner/context_runner_spec.rb +0 -100
- data/spec/spec/runner/context_spec.rb +0 -405
- data/spec/spec/runner/kernel_ext_spec.rb +0 -16
- data/spec/spec/runner/spec_name_generation_spec.rb +0 -102
- data/spec/spec/runner/specification_class_spec.rb +0 -72
- data/spec/spec/runner/specification_instance_spec.rb +0 -160
- data/spec/spec/runner/specification_should_raise_spec.rb +0 -136
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
describe "A consumer of a stub" do
|
|
4
|
+
it "should be able to stub methods on any Object" do
|
|
5
5
|
obj = Object.new
|
|
6
6
|
obj.stub!(:foobar).and_return {:return_value}
|
|
7
7
|
obj.foobar.should equal(:return_value)
|
|
@@ -14,17 +14,17 @@ class StubbableClass
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
describe "A stubbed method on a class" do
|
|
18
|
+
it "should return the stubbed value" do
|
|
19
19
|
StubbableClass.stub!(:find).and_return(:stub_return)
|
|
20
20
|
StubbableClass.find(1).should equal(:stub_return)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
it "should revert to the original method after each spec" do
|
|
24
24
|
StubbableClass.find(1).should equal(:original_return)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
it "can stub! and mock the same message" do
|
|
28
28
|
StubbableClass.stub!(:msg).and_return(:stub_value)
|
|
29
29
|
StubbableClass.should_receive(:msg).with(:arg).and_return(:mock_value)
|
|
30
30
|
|
|
@@ -37,14 +37,14 @@ context "A stubbed method on a class" do
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
describe "A mock" do
|
|
41
|
+
it "can stub!" do
|
|
42
42
|
mock = mock("stubbing mock")
|
|
43
43
|
mock.stub!(:msg).and_return(:value)
|
|
44
44
|
(1..10).each {mock.msg.should equal(:value)}
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
it "can stub! and mock" do
|
|
48
48
|
mock = mock("stubbing mock")
|
|
49
49
|
mock.stub!(:stub_message).and_return(:stub_value)
|
|
50
50
|
mock.should_receive(:mock_message).once.and_return(:mock_value)
|
|
@@ -53,7 +53,7 @@ context "A mock" do
|
|
|
53
53
|
(1..10).each {mock.stub_message.should equal(:stub_value)}
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
it "can stub! and mock the same message" do
|
|
57
57
|
mock = mock("stubbing mock")
|
|
58
58
|
mock.stub!(:msg).and_return(:stub_value)
|
|
59
59
|
mock.should_receive(:msg).with(:arg).and_return(:mock_value)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#This is an example of using RSpec's expectations in test/unit.
|
|
2
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
|
3
|
+
|
|
4
|
+
require 'test/unit'
|
|
5
|
+
require 'spec/test_case_adapter'
|
|
6
|
+
|
|
7
|
+
class IntegratingRSpecExpectationsIntoTestCaseTest < Test::Unit::TestCase
|
|
8
|
+
|
|
9
|
+
def test_should_support_rspecs_equality_expectations
|
|
10
|
+
5.should == 5
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_should_support_rspecs_comparison_expectations
|
|
14
|
+
5.should be > 4
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class Band
|
|
18
|
+
def players
|
|
19
|
+
["John", "Paul", "George", "Ringo"]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_should_support_rspecs_collection_expectations
|
|
24
|
+
Band.new.should have(4).players
|
|
25
|
+
end
|
|
26
|
+
end
|
data/examples/test_case_spec.rb
CHANGED
|
@@ -32,32 +32,32 @@ module RandomHelperModule
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
describe "RSpec should integrate with Test::Unit::TestCase" do
|
|
36
36
|
inherit RSpecIntegrationTest
|
|
37
37
|
include RandomHelperModule
|
|
38
38
|
|
|
39
39
|
fixtures :some_table
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
before(:each) do
|
|
42
42
|
@rspec_setup_called = true
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
it "TestCase#setup should be called." do
|
|
46
46
|
@test_case_setup_called.should be_true
|
|
47
47
|
@rspec_setup_called.should be_true
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
it "RSpec should be able to access TestCase methods" do
|
|
51
51
|
helper_method
|
|
52
52
|
@helper_method_called.should be_true
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
it "RSpec should be able to accept included modules" do
|
|
56
56
|
random_task
|
|
57
57
|
@random_task_called.should be_true
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
after(:each) do
|
|
61
61
|
RSpecIntegrationTest.verify_class_method
|
|
62
62
|
end
|
|
63
63
|
end
|
data/lib/spec.rb
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
require 'spec/
|
|
1
|
+
require 'spec/extensions'
|
|
2
2
|
require 'spec/version'
|
|
3
|
-
require 'spec/callback'
|
|
4
3
|
require 'spec/matchers'
|
|
5
4
|
require 'spec/expectations'
|
|
6
|
-
require 'spec/mocks'
|
|
7
|
-
require 'spec/runner'
|
|
8
5
|
require 'spec/translator'
|
|
6
|
+
require 'spec/dsl'
|
|
7
|
+
require 'spec/runner'
|
|
8
|
+
|
|
9
|
+
class Object
|
|
10
|
+
def metaclass
|
|
11
|
+
class << self; self; end
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/spec/dsl.rb
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require 'spec/dsl/description'
|
|
2
|
+
require 'spec/dsl/configuration'
|
|
3
|
+
require 'spec/dsl/behaviour_callbacks'
|
|
4
|
+
require 'spec/dsl/behaviour'
|
|
5
|
+
require 'spec/dsl/behaviour_eval'
|
|
6
|
+
require 'spec/dsl/composite_proc_builder'
|
|
7
|
+
require 'spec/dsl/example'
|
|
8
|
+
require 'spec/dsl/example_matcher'
|
|
9
|
+
require 'spec/dsl/example_should_raise_handler'
|
|
10
|
+
require 'spec/dsl/behaviour_factory'
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
module Spec
|
|
2
|
+
module DSL
|
|
3
|
+
class EvalModule < Module; end
|
|
4
|
+
class Behaviour
|
|
5
|
+
extend BehaviourCallbacks
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
def add_shared_behaviour(behaviour)
|
|
9
|
+
raise ArgumentError.new("Shared Behaviour '#{behaviour.description}' already exists") if find_shared_behaviour(behaviour.description)
|
|
10
|
+
shared_behaviours << behaviour
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def find_shared_behaviour(behaviour_description)
|
|
14
|
+
shared_behaviours.find { |b| b.description == behaviour_description }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def shared_behaviours
|
|
18
|
+
# TODO - this needs to be global, or at least accessible from
|
|
19
|
+
# from subclasses of Behaviour in a centralized place. I'm not loving
|
|
20
|
+
# this as a solution, but it works for now.
|
|
21
|
+
$shared_behaviours ||= []
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def initialize(*args, &behaviour_block)
|
|
26
|
+
init_description(*args)
|
|
27
|
+
init_eval_module
|
|
28
|
+
before_eval
|
|
29
|
+
eval_behaviour(&behaviour_block)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def init_description(*args)
|
|
35
|
+
@description = Description.new(*args)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def init_eval_module
|
|
39
|
+
@eval_module = EvalModule.new
|
|
40
|
+
@eval_module.extend BehaviourEval::ModuleMethods
|
|
41
|
+
@eval_module.include BehaviourEval::InstanceMethods
|
|
42
|
+
@eval_module.behaviour = self
|
|
43
|
+
@eval_module.description = @description
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def eval_behaviour(&behaviour_block)
|
|
47
|
+
@eval_module.class_eval(&behaviour_block)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
protected
|
|
51
|
+
|
|
52
|
+
def before_eval
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
public
|
|
56
|
+
|
|
57
|
+
def run(reporter, dry_run=false, reverse=false, timeout=nil)
|
|
58
|
+
return if shared?
|
|
59
|
+
reporter.add_behaviour(description)
|
|
60
|
+
prepare_execution_context_class
|
|
61
|
+
errors = run_before_all(reporter, dry_run)
|
|
62
|
+
|
|
63
|
+
specs = reverse ? examples.reverse : examples
|
|
64
|
+
example_execution_context = nil
|
|
65
|
+
|
|
66
|
+
if errors.empty?
|
|
67
|
+
specs.each do |example|
|
|
68
|
+
example_execution_context = execution_context(example)
|
|
69
|
+
example_execution_context.copy_instance_variables_from(@before_and_after_all_context_instance) unless before_all_proc.nil?
|
|
70
|
+
example.run(reporter, before_each_proc, after_each_proc, dry_run, example_execution_context, timeout)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
@before_and_after_all_context_instance.copy_instance_variables_from(example_execution_context) unless after_all_proc.nil?
|
|
75
|
+
run_after_all(reporter, dry_run)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def number_of_examples
|
|
79
|
+
examples.length
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def matches?(specified_examples)
|
|
83
|
+
matcher ||= ExampleMatcher.new(description)
|
|
84
|
+
|
|
85
|
+
examples.each do |example|
|
|
86
|
+
return true if example.matches?(matcher, specified_examples)
|
|
87
|
+
end
|
|
88
|
+
return false
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def shared?
|
|
92
|
+
@description[:shared]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def retain_examples_matching!(specified_examples)
|
|
96
|
+
return if specified_examples.index(description)
|
|
97
|
+
matcher = ExampleMatcher.new(description)
|
|
98
|
+
examples.reject! do |example|
|
|
99
|
+
!example.matches?(matcher, specified_examples)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def methods
|
|
104
|
+
my_methods = super
|
|
105
|
+
my_methods |= @eval_module.methods
|
|
106
|
+
my_methods
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
protected
|
|
110
|
+
|
|
111
|
+
# Messages that this class does not understand
|
|
112
|
+
# are passed directly to the @eval_module.
|
|
113
|
+
def method_missing(sym, *args, &block)
|
|
114
|
+
@eval_module.send(sym, *args, &block)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def prepare_execution_context_class
|
|
118
|
+
plugin_mock_framework
|
|
119
|
+
weave_in_included_modules
|
|
120
|
+
define_predicate_matchers #this is in behaviour_eval
|
|
121
|
+
execution_context_class
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def weave_in_included_modules
|
|
125
|
+
mods = included_modules
|
|
126
|
+
eval_module = @eval_module
|
|
127
|
+
execution_context_class.class_eval do
|
|
128
|
+
include eval_module
|
|
129
|
+
Spec::Runner.configuration.included_modules.each do |mod|
|
|
130
|
+
include mod
|
|
131
|
+
end
|
|
132
|
+
mods.each do |mod|
|
|
133
|
+
include mod
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def execution_context(example)
|
|
139
|
+
execution_context_class.new(example)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def run_before_all(reporter, dry_run)
|
|
143
|
+
errors = []
|
|
144
|
+
unless dry_run
|
|
145
|
+
begin
|
|
146
|
+
@before_and_after_all_context_instance = execution_context(nil)
|
|
147
|
+
@before_and_after_all_context_instance.instance_eval(&before_all_proc)
|
|
148
|
+
rescue => e
|
|
149
|
+
errors << e
|
|
150
|
+
location = "before(:all)"
|
|
151
|
+
reporter.example_finished(location, e, location) if reporter
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
errors
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def run_after_all(reporter, dry_run)
|
|
158
|
+
unless dry_run
|
|
159
|
+
begin
|
|
160
|
+
@before_and_after_all_context_instance ||= execution_context(nil)
|
|
161
|
+
@before_and_after_all_context_instance.instance_eval(&after_all_proc)
|
|
162
|
+
rescue => e
|
|
163
|
+
location = "after(:all)"
|
|
164
|
+
reporter.example_finished(location, e, location) if reporter
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def plugin_mock_framework
|
|
170
|
+
case mock_framework = Spec::Runner.configuration.mock_framework
|
|
171
|
+
when Module
|
|
172
|
+
include mock_framework
|
|
173
|
+
else
|
|
174
|
+
require Spec::Runner.configuration.mock_framework
|
|
175
|
+
include Spec::Plugins::MockFramework
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def description
|
|
180
|
+
@description.to_s
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def described_type
|
|
184
|
+
@description.described_type
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Spec
|
|
2
|
+
module DSL
|
|
3
|
+
module BehaviourCallbacks
|
|
4
|
+
def before(scope=:each, &block)
|
|
5
|
+
case scope
|
|
6
|
+
when :each; before_each_parts << block
|
|
7
|
+
when :all; before_all_parts << block
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def after(scope=:each, &block)
|
|
12
|
+
case scope
|
|
13
|
+
when :each; after_each_parts.unshift(block)
|
|
14
|
+
when :all; after_all_parts.unshift(block)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def setup(&block)
|
|
19
|
+
before(:each, &block)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def teardown(&block)
|
|
23
|
+
after(:each, &block)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def before_all_parts
|
|
27
|
+
@before_all_parts ||= []
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def after_all_parts
|
|
31
|
+
@after_all_parts ||= []
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def before_each_parts
|
|
35
|
+
@before_each_parts ||= []
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def after_each_parts
|
|
39
|
+
@after_each_parts ||= []
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
module Spec
|
|
2
|
+
module DSL
|
|
3
|
+
module BehaviourEval
|
|
4
|
+
module ModuleMethods
|
|
5
|
+
include BehaviourCallbacks
|
|
6
|
+
|
|
7
|
+
attr_writer :behaviour
|
|
8
|
+
attr_accessor :description
|
|
9
|
+
|
|
10
|
+
def inherit(klass)
|
|
11
|
+
raise ArgumentError.new("Shared behaviours cannot inherit from classes") if @behaviour.shared?
|
|
12
|
+
@behaviour_superclass = klass
|
|
13
|
+
derive_execution_context_class_from_behaviour_superclass
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def include(mod)
|
|
17
|
+
included_modules << mod
|
|
18
|
+
mod.send :included, self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def it_should_behave_like(behaviour_description)
|
|
22
|
+
behaviour = @behaviour.class.find_shared_behaviour(behaviour_description)
|
|
23
|
+
if behaviour.nil?
|
|
24
|
+
raise RuntimeError.new("Shared Behaviour '#{behaviour_description}' can not be found")
|
|
25
|
+
end
|
|
26
|
+
behaviour.copy_to(self)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def copy_to(eval_module)
|
|
30
|
+
examples.each { |e| eval_module.examples << e; }
|
|
31
|
+
before_each_parts.each { |p| eval_module.before_each_parts << p }
|
|
32
|
+
after_each_parts.each { |p| eval_module.after_each_parts << p }
|
|
33
|
+
before_all_parts.each { |p| eval_module.before_all_parts << p }
|
|
34
|
+
after_all_parts.each { |p| eval_module.after_all_parts << p }
|
|
35
|
+
included_modules.each { |m| eval_module.included_modules << m }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# :call-seq:
|
|
39
|
+
# predicate_matchers[method_on_object] = matcher_name
|
|
40
|
+
#
|
|
41
|
+
# Dynamically generates a custom matcher that will match
|
|
42
|
+
# a predicate on your class.
|
|
43
|
+
#
|
|
44
|
+
# == Example
|
|
45
|
+
#
|
|
46
|
+
# class Fish
|
|
47
|
+
# def can_swim?
|
|
48
|
+
# true
|
|
49
|
+
# end
|
|
50
|
+
# end
|
|
51
|
+
#
|
|
52
|
+
# describe Fish do
|
|
53
|
+
# predicate_matchers[:can_swim?] = :swim
|
|
54
|
+
# it "should swim" do
|
|
55
|
+
# Fish.new.should swim
|
|
56
|
+
# end
|
|
57
|
+
# end
|
|
58
|
+
def predicate_matchers
|
|
59
|
+
@predicate_matchers ||= {:exist? => :exist}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def define_predicate_matchers(hash=nil) # :nodoc:
|
|
63
|
+
if hash.nil?
|
|
64
|
+
define_predicate_matchers(predicate_matchers)
|
|
65
|
+
define_predicate_matchers(Spec::Runner.configuration.predicate_matchers)
|
|
66
|
+
else
|
|
67
|
+
hash.each_pair do |method_on_object, matcher_method|
|
|
68
|
+
define_method matcher_method do |*args|
|
|
69
|
+
eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def it(description=:__generate_description, opts={}, &block)
|
|
76
|
+
examples << Example.new(description, opts, &block)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def specify(description, opts={}, &block)
|
|
80
|
+
it(description, opts, &block)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def methods
|
|
84
|
+
my_methods = super
|
|
85
|
+
my_methods |= behaviour_superclass.methods
|
|
86
|
+
my_methods
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
protected
|
|
90
|
+
|
|
91
|
+
def method_missing(method_name, *args)
|
|
92
|
+
if behaviour_superclass.respond_to?(method_name)
|
|
93
|
+
return execution_context_class.send(method_name, *args)
|
|
94
|
+
end
|
|
95
|
+
super
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def before_all_proc(&error_handler)
|
|
99
|
+
parts = []
|
|
100
|
+
parts.push(*Behaviour.before_all_parts)
|
|
101
|
+
parts.push(*before_all_parts)
|
|
102
|
+
CompositeProcBuilder.new(parts).proc(&error_handler)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def after_all_proc(&error_handler)
|
|
106
|
+
parts = []
|
|
107
|
+
parts.push(*after_all_parts)
|
|
108
|
+
parts.push(*Behaviour.after_all_parts)
|
|
109
|
+
CompositeProcBuilder.new(parts).proc(&error_handler)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def before_each_proc(&error_handler)
|
|
113
|
+
parts = []
|
|
114
|
+
add_superclass_method(parts, 'setup')
|
|
115
|
+
parts.push(*Behaviour.before_each_parts)
|
|
116
|
+
parts.push(*before_each_parts)
|
|
117
|
+
CompositeProcBuilder.new(parts).proc(&error_handler)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def after_each_proc(&error_handler)
|
|
121
|
+
parts = []
|
|
122
|
+
parts.push(*after_each_parts)
|
|
123
|
+
add_superclass_method(parts, 'teardown')
|
|
124
|
+
parts.push(*Behaviour.after_each_parts)
|
|
125
|
+
CompositeProcBuilder.new(parts).proc(&error_handler)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def add_superclass_method(parts, method_name)
|
|
129
|
+
parts << behaviour_superclass.instance_method(method_name) if behaviour_superclass.instance_methods.include?(method_name)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
private
|
|
133
|
+
|
|
134
|
+
def execution_context_class
|
|
135
|
+
@execution_context_class ||= derive_execution_context_class_from_behaviour_superclass
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def derive_execution_context_class_from_behaviour_superclass
|
|
139
|
+
@execution_context_class = Class.new(behaviour_superclass)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def behaviour_superclass
|
|
143
|
+
@behaviour_superclass ||= Object
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
protected
|
|
147
|
+
def included_modules
|
|
148
|
+
@included_modules ||= [::Spec::Matchers]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def examples
|
|
152
|
+
@examples ||= []
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
module InstanceMethods
|
|
157
|
+
def initialize(*args, &block) #:nodoc:
|
|
158
|
+
# TODO - inheriting from TestUnit::TestCase fails without this
|
|
159
|
+
# - let's figure out why and move this somewhere else
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def violated(message="")
|
|
163
|
+
raise Spec::Expectations::ExpectationNotMetError.new(message)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|