dchelimsky-rspec 1.1.10 → 1.1.11

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.
Files changed (120) hide show
  1. data/History.txt +17 -0
  2. data/Manifest.txt +53 -74
  3. data/Rakefile +0 -1
  4. data/examples/{pure → passing}/autogenerated_docstrings_example.rb +6 -0
  5. data/examples/{pure → passing}/before_and_after_example.rb +0 -0
  6. data/examples/{pure → passing}/behave_as_example.rb +0 -0
  7. data/examples/{pure → passing}/custom_expectation_matchers.rb +0 -0
  8. data/examples/{pure → passing}/custom_formatter.rb +1 -1
  9. data/examples/{pure → passing}/dynamic_spec.rb +2 -2
  10. data/examples/{pure → passing}/file_accessor.rb +0 -0
  11. data/examples/{pure → passing}/file_accessor_spec.rb +0 -0
  12. data/examples/{pure → passing}/greeter_spec.rb +0 -0
  13. data/examples/{pure → passing}/helper_method_example.rb +0 -0
  14. data/examples/{pure → passing}/io_processor.rb +0 -0
  15. data/examples/{pure → passing}/io_processor_spec.rb +0 -0
  16. data/examples/{pure → passing}/legacy_spec.rb +0 -0
  17. data/examples/{pure → passing}/mocking_example.rb +0 -0
  18. data/examples/{pure → passing}/multi_threaded_behaviour_runner.rb +0 -0
  19. data/examples/{pure → passing}/nested_classes_example.rb +0 -0
  20. data/examples/{pure → passing}/partial_mock_example.rb +0 -0
  21. data/examples/{pure → passing}/pending_example.rb +0 -0
  22. data/examples/{pure → passing}/predicate_example.rb +0 -0
  23. data/examples/{pure → passing}/priority.txt +0 -0
  24. data/examples/{pure → passing}/shared_example_group_example.rb +0 -0
  25. data/examples/{pure → passing}/shared_stack_examples.rb +1 -3
  26. data/examples/{pure → passing}/spec_helper.rb +0 -0
  27. data/examples/{pure → passing}/stack.rb +0 -0
  28. data/examples/{pure → passing}/stack_spec.rb +3 -2
  29. data/examples/{pure → passing}/stack_spec_with_nested_example_groups.rb +0 -0
  30. data/examples/{pure → passing}/stubbing_example.rb +0 -0
  31. data/examples/{pure → passing}/yielding_example.rb +0 -0
  32. data/lib/spec/example/before_and_after_hooks.rb +8 -21
  33. data/lib/spec/example/configuration.rb +45 -45
  34. data/lib/spec/example/example_group_factory.rb +10 -9
  35. data/lib/spec/example/example_group_methods.rb +31 -15
  36. data/lib/spec/example/example_methods.rb +74 -22
  37. data/lib/spec/example/shared_example_group.rb +27 -16
  38. data/lib/spec/example.rb +28 -0
  39. data/lib/spec/expectations.rb +1 -0
  40. data/lib/spec/extensions.rb +0 -2
  41. data/lib/spec/matchers/be.rb +96 -114
  42. data/lib/spec/matchers/operator_matcher.rb +2 -9
  43. data/lib/spec/matchers/throw_symbol.rb +41 -15
  44. data/lib/spec/matchers.rb +4 -27
  45. data/lib/spec/runner/formatter/base_text_formatter.rb +1 -1
  46. data/lib/spec/runner/option_parser.rb +2 -2
  47. data/lib/spec/runner/reporter.rb +1 -1
  48. data/lib/spec/runner.rb +1 -1
  49. data/lib/spec/version.rb +1 -1
  50. data/lib/spec.rb +1 -0
  51. data/rspec.gemspec +4 -24
  52. data/spec/spec/example/example_group_factory_spec.rb +29 -9
  53. data/spec/spec/example/example_group_methods_spec.rb +4 -6
  54. data/spec/spec/example/example_group_spec.rb +0 -6
  55. data/spec/spec/example/example_matcher_spec.rb +6 -23
  56. data/spec/spec/example/example_methods_spec.rb +117 -2
  57. data/spec/spec/example/shared_example_group_spec.rb +51 -75
  58. data/spec/spec/matchers/be_spec.rb +40 -7
  59. data/spec/spec/matchers/description_generation_spec.rb +14 -0
  60. data/spec/spec/matchers/throw_symbol_spec.rb +83 -41
  61. data/spec/spec/runner/command_line_spec.rb +4 -4
  62. data/spec/spec/runner/formatter/html_formatted-1.8.4.html +6 -6
  63. data/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html +9 -9
  64. data/spec/spec/runner/formatter/html_formatted-1.8.5.html +6 -6
  65. data/spec/spec/runner/formatter/html_formatted-1.8.6-jruby.html +10 -10
  66. data/spec/spec/runner/formatter/html_formatted-1.8.6.html +6 -6
  67. data/spec/spec/runner/formatter/html_formatter_spec.rb +1 -1
  68. data/spec/spec/runner/formatter/spec_mate_formatter_spec.rb +5 -5
  69. data/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html +6 -6
  70. data/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html +6 -6
  71. data/spec/spec/runner/reporter_spec.rb +1 -1
  72. data/stories/example_groups/autogenerated_docstrings +4 -4
  73. data/stories/example_groups/nested_groups +2 -2
  74. metadata +33 -59
  75. data/examples/stories/adder.rb +0 -13
  76. data/examples/stories/addition +0 -34
  77. data/examples/stories/addition.rb +0 -9
  78. data/examples/stories/calculator.rb +0 -65
  79. data/examples/stories/game-of-life/.loadpath +0 -5
  80. data/examples/stories/game-of-life/README.txt +0 -21
  81. data/examples/stories/game-of-life/behaviour/everything.rb +0 -6
  82. data/examples/stories/game-of-life/behaviour/examples/examples.rb +0 -3
  83. data/examples/stories/game-of-life/behaviour/examples/game_behaviour.rb +0 -35
  84. data/examples/stories/game-of-life/behaviour/examples/grid_behaviour.rb +0 -66
  85. data/examples/stories/game-of-life/behaviour/stories/CellsWithLessThanTwoNeighboursDie.story +0 -21
  86. data/examples/stories/game-of-life/behaviour/stories/CellsWithMoreThanThreeNeighboursDie.story +0 -21
  87. data/examples/stories/game-of-life/behaviour/stories/EmptySpacesWithThreeNeighboursCreateACell.story +0 -42
  88. data/examples/stories/game-of-life/behaviour/stories/ICanCreateACell.story +0 -42
  89. data/examples/stories/game-of-life/behaviour/stories/ICanKillACell.story +0 -17
  90. data/examples/stories/game-of-life/behaviour/stories/TheGridWraps.story +0 -53
  91. data/examples/stories/game-of-life/behaviour/stories/create_a_cell.rb +0 -52
  92. data/examples/stories/game-of-life/behaviour/stories/helper.rb +0 -6
  93. data/examples/stories/game-of-life/behaviour/stories/kill_a_cell.rb +0 -26
  94. data/examples/stories/game-of-life/behaviour/stories/steps.rb +0 -5
  95. data/examples/stories/game-of-life/behaviour/stories/stories.rb +0 -3
  96. data/examples/stories/game-of-life/behaviour/stories/stories.txt +0 -22
  97. data/examples/stories/game-of-life/life/game.rb +0 -23
  98. data/examples/stories/game-of-life/life/grid.rb +0 -43
  99. data/examples/stories/game-of-life/life.rb +0 -3
  100. data/examples/stories/helper.rb +0 -9
  101. data/examples/stories/steps/addition_steps.rb +0 -18
  102. data/failing_examples/README.txt +0 -7
  103. data/failing_examples/diffing_spec.rb +0 -36
  104. data/failing_examples/failing_autogenerated_docstrings_example.rb +0 -19
  105. data/failing_examples/failure_in_setup.rb +0 -10
  106. data/failing_examples/failure_in_teardown.rb +0 -10
  107. data/failing_examples/mocking_example.rb +0 -40
  108. data/failing_examples/mocking_with_flexmock.rb +0 -26
  109. data/failing_examples/mocking_with_mocha.rb +0 -25
  110. data/failing_examples/mocking_with_rr.rb +0 -27
  111. data/failing_examples/partial_mock_example.rb +0 -20
  112. data/failing_examples/predicate_example.rb +0 -29
  113. data/failing_examples/raising_example.rb +0 -47
  114. data/failing_examples/spec_helper.rb +0 -3
  115. data/failing_examples/syntax_error_example.rb +0 -7
  116. data/failing_examples/team_spec.rb +0 -44
  117. data/failing_examples/timeout_behaviour.rb +0 -7
  118. data/lib/spec/extensions/main.rb +0 -87
  119. data/lib/spec/extensions/object.rb +0 -6
  120. data/spec/spec/extensions/main_spec.rb +0 -71
@@ -48,9 +48,9 @@ module Spec
48
48
  options = args.last
49
49
  options[:spec_path] = eval("caller(0)[1]", example_group_block) unless options[:spec_path]
50
50
  if options[:shared]
51
- create_shared_example_group(args, example_group_block)
51
+ create_shared_example_group(*args, &example_group_block)
52
52
  else
53
- create_nested_example_group(args, example_group_block)
53
+ create_nested_example_group(*args, &example_group_block)
54
54
  end
55
55
  else
56
56
  set_description(*args)
@@ -58,13 +58,13 @@ module Spec
58
58
  end
59
59
  alias :context :describe
60
60
 
61
- def create_shared_example_group(args, example_group_block)
62
- SharedExampleGroup.new(*args, &example_group_block)
61
+ def create_shared_example_group(*args, &example_group_block)
62
+ SharedExampleGroup.register(*args, &example_group_block)
63
63
  end
64
64
 
65
- def create_nested_example_group(args, example_group_block)
65
+ def create_nested_example_group(*args, &example_group_block)
66
66
  self.subclass("Subclass") do
67
- describe(*args)
67
+ set_description(*args)
68
68
  module_eval(&example_group_block)
69
69
  end
70
70
  end
@@ -144,15 +144,31 @@ module Spec
144
144
 
145
145
  def description
146
146
  result = ExampleGroupMethods.description_text(*description_parts)
147
- if result.nil? || result == ""
148
- return to_s
149
- else
150
- result
151
- end
147
+ (result.nil? || result == "") ? to_s : result
152
148
  end
153
-
149
+
154
150
  def described_type
155
- description_parts.find {|part| part.is_a?(Module)}
151
+ description_parts.reverse.find {|part| part.is_a?(Module)}
152
+ end
153
+
154
+ # Defines an explicit subject for an example group which can then be the
155
+ # implicit receiver (through delegation) of calls to +should+.
156
+ #
157
+ # == Examples
158
+ #
159
+ # describe CheckingAccount, "with $50" do
160
+ # subject { CheckingAccount.new(:amount => 50, :currency => :USD) }
161
+ # it { should have_a_balance_of(50, :USD)}
162
+ # it { should_not be_overdrawn}
163
+ # end
164
+ #
165
+ # See +ExampleMethods#should+ for more information about this approach.
166
+ def subject(&block)
167
+ if block
168
+ @_subject_block = block
169
+ else
170
+ @_subject_block.call if @_subject_block
171
+ end
156
172
  end
157
173
 
158
174
  def description_parts #:nodoc:
@@ -164,7 +180,7 @@ module Spec
164
180
  end
165
181
 
166
182
  def set_description(*args)
167
- args, options = args_and_options(*args)
183
+ args, options = Spec::Example.args_and_options(*args)
168
184
  @description_args = args
169
185
  @description_options = options
170
186
  @description_text = ExampleGroupMethods.description_text(*args)
@@ -354,7 +370,7 @@ module Spec
354
370
  when SharedExampleGroup
355
371
  include shared_example_group
356
372
  else
357
- example_group = SharedExampleGroup.find_shared_example_group(shared_example_group)
373
+ example_group = SharedExampleGroup.find(shared_example_group)
358
374
  unless example_group
359
375
  raise RuntimeError.new("Shared Example Group '#{shared_example_group}' can not be found")
360
376
  end
@@ -4,6 +4,42 @@ module Spec
4
4
 
5
5
  extend ModuleReopeningFix
6
6
 
7
+ def subject # :nodoc:
8
+ @subject ||= (instance_variable_get(subject_variable_name) || self.class.subject ||
9
+ (described_class ? described_class.new : nil))
10
+ end
11
+
12
+ # When +should+ is called with no explicit receiver, the call is
13
+ # delegated to the *subject* of the example group. This could be either
14
+ # an explicit subject generated by calling the block passed to
15
+ # +ExampleGroupMethods#subject+, or, if the group is describing a class,
16
+ # an implicitly generated instance of that class.
17
+ def should(matcher=nil)
18
+ if matcher
19
+ subject.should(matcher)
20
+ else
21
+ subject.should
22
+ end
23
+ end
24
+
25
+ # Just like +should+, +should_not+ delegates to the subject (implicit or
26
+ # explicit) of the example group.
27
+ def should_not(matcher)
28
+ subject.should_not(matcher)
29
+ end
30
+
31
+ def violated(message="")
32
+ raise Spec::Expectations::ExpectationNotMetError.new(message)
33
+ end
34
+
35
+ def description
36
+ @_defined_description || ::Spec::Matchers.generated_description || "NO NAME"
37
+ end
38
+
39
+ def options
40
+ @_options
41
+ end
42
+
7
43
  def execute(options, instance_variables)
8
44
  options.reporter.example_started(self)
9
45
  set_instance_variables_from_hash(instance_variables)
@@ -34,21 +70,17 @@ module Spec
34
70
  end
35
71
  end
36
72
 
37
- def violated(message="")
38
- raise Spec::Expectations::ExpectationNotMetError.new(message)
39
- end
40
-
41
- def eval_each_fail_fast(procs) #:nodoc:
42
- procs.each do |proc|
43
- instance_eval(&proc)
73
+ def eval_each_fail_fast(examples) #:nodoc:
74
+ examples.each do |example|
75
+ instance_eval(&example)
44
76
  end
45
77
  end
46
78
 
47
- def eval_each_fail_slow(procs) #:nodoc:
79
+ def eval_each_fail_slow(examples) #:nodoc:
48
80
  first_exception = nil
49
- procs.each do |proc|
81
+ examples.each do |example|
50
82
  begin
51
- instance_eval(&proc)
83
+ instance_eval(&example)
52
84
  rescue Exception => e
53
85
  first_exception ||= e
54
86
  end
@@ -56,19 +88,19 @@ module Spec
56
88
  raise first_exception if first_exception
57
89
  end
58
90
 
59
- def description
60
- @_defined_description || ::Spec::Matchers.generated_description || "NO NAME"
61
- end
62
-
63
- def options
64
- @_options
65
- end
66
-
67
- def __full_description
91
+ # Concats the class description with the example description.
92
+ #
93
+ # describe Account do
94
+ # it "should start with a balance of 0" do
95
+ # ...
96
+ #
97
+ # full_description
98
+ # => "Account should start with a balance of 0"
99
+ def full_description
68
100
  "#{self.class.description} #{self.description}"
69
101
  end
70
102
 
71
- def set_instance_variables_from_hash(ivars)
103
+ def set_instance_variables_from_hash(ivars) # :nodoc:
72
104
  ivars.each do |variable_name, value|
73
105
  # Ruby 1.9 requires variable.to_s on the next line
74
106
  unless ['@_implementation', '@_defined_description', '@_matcher_description', '@method_name'].include?(variable_name.to_s)
@@ -84,8 +116,8 @@ module Spec
84
116
  def implementation_backtrace
85
117
  eval("caller", @_implementation)
86
118
  end
87
-
88
- protected
119
+
120
+ private
89
121
  include Matchers
90
122
  include Pending
91
123
 
@@ -100,6 +132,26 @@ module Spec
100
132
  ensure
101
133
  teardown_mocks_for_rspec
102
134
  end
135
+
136
+ def subject_variable_name
137
+ '@' << (described_class ? underscore(described_class.name) : '__this_does_not_exist')
138
+ end
139
+
140
+ def described_class
141
+ Class === described_type ? described_type : nil
142
+ end
143
+
144
+ def described_type
145
+ self.class.described_type
146
+ end
147
+
148
+ def underscore(camel_cased_word)
149
+ camel_cased_word.to_s.gsub(/::/, '_').
150
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
151
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
152
+ tr("-", "_").
153
+ downcase
154
+ end
103
155
  end
104
156
  end
105
157
  end
@@ -2,27 +2,39 @@ module Spec
2
2
  module Example
3
3
  class SharedExampleGroup < Module
4
4
  module ClassMethods
5
- def add_shared_example_group(new_example_group)
6
- guard_against_redefining_existing_example_group(new_example_group)
7
- shared_example_groups << new_example_group
5
+ def register(*args, &block)
6
+ new_example_group = new(*args, &block)
7
+ shared_example_groups << new_example_group unless already_registered?(new_example_group)
8
+ new_example_group
9
+ end
10
+
11
+ def find(example_group_description)
12
+ shared_example_groups.find {|b| b.description == example_group_description}
8
13
  end
9
14
 
10
- def find_shared_example_group(example_group_description)
11
- shared_example_groups.find do |b|
12
- b.description == example_group_description
13
- end
15
+ def clear
16
+ shared_example_groups.clear
17
+ end
18
+
19
+ def include?(group)
20
+ shared_example_groups.include?(group)
21
+ end
22
+
23
+ def count
24
+ shared_example_groups.length
14
25
  end
15
26
 
27
+ private
28
+
16
29
  def shared_example_groups
17
30
  @shared_example_groups ||= []
18
31
  end
19
-
20
- private
21
- def guard_against_redefining_existing_example_group(new_example_group)
22
- existing_example_group = find_shared_example_group(new_example_group.description)
23
- return unless existing_example_group
24
- return if new_example_group.equal?(existing_example_group)
25
- return if spec_path(new_example_group) == spec_path(existing_example_group)
32
+
33
+ def already_registered?(new_example_group)
34
+ existing_example_group = find(new_example_group.description)
35
+ return false unless existing_example_group
36
+ return true if new_example_group.equal?(existing_example_group)
37
+ return true if spec_path(new_example_group) == spec_path(existing_example_group)
26
38
  raise ArgumentError.new("Shared Example '#{existing_example_group.description}' already exists")
27
39
  end
28
40
 
@@ -35,9 +47,8 @@ module Spec
35
47
  include ExampleGroupMethods
36
48
 
37
49
  def initialize(*args, &example_group_block)
38
- describe(*args)
50
+ set_description(*args)
39
51
  @example_group_block = example_group_block
40
- self.class.add_shared_example_group(self)
41
52
  end
42
53
 
43
54
  def included(mod) # :nodoc:
data/lib/spec/example.rb CHANGED
@@ -1,3 +1,30 @@
1
+ module Spec
2
+ module Example
3
+ class << self
4
+ def args_and_options(*args)
5
+ with_options_from(args) do |options|
6
+ return args, options
7
+ end
8
+ end
9
+
10
+ def scope_from(*args)
11
+ args[0] || :each
12
+ end
13
+
14
+ def scope_and_options(*args)
15
+ args, options = args_and_options(*args)
16
+ return scope_from(*args), options
17
+ end
18
+
19
+ private
20
+
21
+ def with_options_from(args)
22
+ yield Hash === args.last ? args.pop : {} if block_given?
23
+ end
24
+ end
25
+ end
26
+ end
27
+
1
28
  require 'timeout'
2
29
  require 'spec/example/before_and_after_hooks'
3
30
  require 'spec/example/pending'
@@ -10,3 +37,4 @@ require 'spec/example/example_group_factory'
10
37
  require 'spec/example/errors'
11
38
  require 'spec/example/configuration'
12
39
  require 'spec/example/example_matcher'
40
+
@@ -2,6 +2,7 @@ require 'spec/matchers'
2
2
  require 'spec/expectations/errors'
3
3
  require 'spec/expectations/extensions'
4
4
  require 'spec/expectations/handler'
5
+ require 'spec/expectations/wrap_expectation'
5
6
 
6
7
  module Spec
7
8
 
@@ -1,4 +1,2 @@
1
- require 'spec/extensions/object'
2
1
  require 'spec/extensions/class'
3
- require 'spec/extensions/main'
4
2
  require 'spec/extensions/metaclass'
@@ -3,137 +3,115 @@ module Spec
3
3
 
4
4
  class Be #:nodoc:
5
5
  def initialize(*args)
6
- if args.empty?
7
- @expected = :satisfy_if
8
- else
9
- @expected = parse_expected(args.shift)
10
- end
6
+ @expected = args.empty? ? true : set_expected(args.shift)
11
7
  @args = args
12
- @comparison = ""
13
8
  end
14
9
 
15
- def matches?(given)
16
- @given = given
17
- if handling_predicate?
18
- begin
19
- return @result = given.__send__(predicate, *@args)
20
- rescue => predicate_error
21
- # This clause should be empty, but rcov will not report it as covered
22
- # unless something (anything) is executed within the clause
23
- rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0"
24
- end
10
+ def matches?(actual)
11
+ @actual = actual
12
+ handling_predicate? ? run_predicate_on(actual) : match_or_compare(actual)
13
+ end
14
+
15
+ def run_predicate_on(actual)
16
+ begin
17
+ return @result = actual.__send__(predicate, *@args)
18
+ rescue NameError => predicate_missing_error
19
+ "this needs to be here or rcov will not count this branch even though it's executed in a code example"
20
+ end
25
21
 
26
- begin
27
- return @result = given.__send__(present_tense_predicate, *@args)
28
- rescue
29
- raise predicate_error
30
- end
31
- else
32
- return match_or_compare
22
+ begin
23
+ return @result = actual.__send__(present_tense_predicate, *@args)
24
+ rescue NameError
25
+ raise predicate_missing_error
33
26
  end
34
27
  end
35
28
 
36
29
  def failure_message
37
- return "expected #{@comparison}#{expected}, got #{@given.inspect}" unless handling_predicate?
38
- return "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}"
30
+ handling_predicate? ?
31
+ "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}" :
32
+ "expected #{@comparison_method} #{expected}, got #{@actual.inspect}".gsub(' ',' ')
39
33
  end
40
34
 
41
35
  def negative_failure_message
42
- return "expected not #{expected}, got #{@given.inspect}" unless handling_predicate?
43
- return "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}"
44
- end
45
-
46
- def expected
47
- return "if to be satisfied" if @expected == :satisfy_if
48
- return true if @expected == :true
49
- return false if @expected == :false
50
- return "nil" if @expected == :nil
51
- return @expected.inspect
52
- end
53
-
54
- def match_or_compare
55
- return @given ? true : false if @expected == :satisfy_if
56
- return @given == true if @expected == :true
57
- return @given == false if @expected == :false
58
- return @given.nil? if @expected == :nil
59
- return @given < @expected if @less_than
60
- return @given <= @expected if @less_than_or_equal
61
- return @given >= @expected if @greater_than_or_equal
62
- return @given > @expected if @greater_than
63
- return @given == @expected if @double_equal
64
- return @given === @expected if @triple_equal
65
- return @given.equal?(@expected)
36
+ if handling_predicate?
37
+ "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}"
38
+ else
39
+ message = <<-MESSAGE
40
+ 'should_not be #{@comparison_method} #{expected}' not only FAILED,
41
+ it reads really poorly.
42
+ MESSAGE
43
+
44
+ raise message << ([:===,:==].include?(@comparison_method) ?
45
+ "Why don't you try expressing it without the \"be\"?" :
46
+ "Why don't you try expressing it in the positive?")
47
+ end
66
48
  end
67
49
 
68
- def ==(expected)
69
- @prefix = "be "
70
- @double_equal = true
71
- @comparison = "== "
72
- @expected = expected
73
- self
74
- end
75
-
76
- def ===(expected)
77
- @prefix = "be "
78
- @triple_equal = true
79
- @comparison = "=== "
80
- @expected = expected
81
- self
82
- end
83
-
84
- def <(expected)
85
- @prefix = "be "
86
- @less_than = true
87
- @comparison = "< "
88
- @expected = expected
89
- self
90
- end
91
-
92
- def <=(expected)
93
- @prefix = "be "
94
- @less_than_or_equal = true
95
- @comparison = "<= "
96
- @expected = expected
97
- self
50
+ def description
51
+ "#{prefix_to_sentence}#{comparison} #{expected_to_sentence}#{args_to_sentence}".gsub(/\s+/,' ')
98
52
  end
99
53
 
100
- def >=(expected)
101
- @prefix = "be "
102
- @greater_than_or_equal = true
103
- @comparison = ">= "
104
- @expected = expected
105
- self
54
+ [:==, :<, :<=, :>=, :>, :===].each do |method|
55
+ define_method method do |expected|
56
+ compare_to(expected, :using => method)
57
+ self
58
+ end
106
59
  end
107
60
 
108
- def >(expected)
109
- @prefix = "be "
110
- @greater_than = true
111
- @comparison = "> "
112
- @expected = expected
113
- self
114
- end
61
+ private
62
+ def match_or_compare(actual)
63
+ case @expected
64
+ when TrueClass
65
+ @actual
66
+ else
67
+ @actual.__send__(comparison_method, @expected)
68
+ end
69
+ end
115
70
 
116
- def description
117
- "#{prefix_to_sentence}#{comparison}#{expected_to_sentence}#{args_to_sentence}"
118
- end
71
+ def comparison_method
72
+ @comparison_method || :equal?
73
+ end
74
+
75
+ def expected
76
+ @expected
77
+ end
119
78
 
120
- private
79
+ def compare_to(expected, opts)
80
+ @expected, @comparison_method = expected, opts[:using]
81
+ end
82
+
83
+ def set_expected(expected)
84
+ Symbol === expected ? parse_expected(expected) : expected
85
+ end
86
+
121
87
  def parse_expected(expected)
122
- if Symbol === expected
123
- @handling_predicate = true
124
- ["be_an_","be_a_","be_"].each do |prefix|
125
- if expected.starts_with?(prefix)
126
- @prefix = prefix
127
- return "#{expected.to_s.sub(@prefix,"")}".to_sym
88
+ ["be_an_","be_a_","be_"].each do |prefix|
89
+ handling_predicate!
90
+ if expected.starts_with?(prefix)
91
+ set_prefix(prefix)
92
+ expected = expected.to_s.sub(prefix,"")
93
+ [true, false, nil].each do |val|
94
+ return val if val.to_s == expected
128
95
  end
96
+ return expected.to_sym
129
97
  end
130
98
  end
131
- @prefix = ""
132
- return expected
99
+ end
100
+
101
+ def set_prefix(prefix)
102
+ @prefix = prefix
103
+ end
104
+
105
+ def prefix
106
+ @prefix
107
+ end
108
+
109
+ def handling_predicate!
110
+ @handling_predicate = true
133
111
  end
134
112
 
135
113
  def handling_predicate?
136
- return false if [:true, :false, :nil].include?(@expected)
114
+ return false if [true, false, nil].include?(expected)
137
115
  return @handling_predicate
138
116
  end
139
117
 
@@ -146,21 +124,27 @@ module Spec
146
124
  end
147
125
 
148
126
  def args_to_s
149
- return "" if @args.empty?
150
- inspected_args = @args.collect{|a| a.inspect}
151
- return "(#{inspected_args.join(', ')})"
127
+ @args.empty? ? "" : parenthesize(inspected_args.join(', '))
128
+ end
129
+
130
+ def parenthesize(string)
131
+ return "(#{string})"
132
+ end
133
+
134
+ def inspected_args
135
+ @args.collect{|a| a.inspect}
152
136
  end
153
137
 
154
138
  def comparison
155
- @comparison
139
+ @comparison_method.nil? ? " " : "be #{@comparison_method.to_s} "
156
140
  end
157
141
 
158
142
  def expected_to_sentence
159
- split_words(@expected)
143
+ split_words(expected)
160
144
  end
161
145
 
162
146
  def prefix_to_sentence
163
- split_words(@prefix)
147
+ split_words(prefix)
164
148
  end
165
149
 
166
150
  def split_words(sym)
@@ -181,7 +165,6 @@ module Spec
181
165
  end
182
166
 
183
167
  # :call-seq:
184
- # should be
185
168
  # should be_true
186
169
  # should be_false
187
170
  # should be_nil
@@ -189,7 +172,7 @@ module Spec
189
172
  # should_not be_nil
190
173
  # should_not be_arbitrary_predicate(*args)
191
174
  #
192
- # Given true, false, or nil, will pass if given value is
175
+ # Given true, false, or nil, will pass if actual value is
193
176
  # true, false or nil (respectively). Given no args means
194
177
  # the caller should satisfy an if condition (to be or not to be).
195
178
  #
@@ -203,7 +186,6 @@ module Spec
203
186
  #
204
187
  # == Examples
205
188
  #
206
- # target.should be
207
189
  # target.should be_true
208
190
  # target.should be_false
209
191
  # target.should be_nil
@@ -1,44 +1,35 @@
1
1
  module Spec
2
2
  module Matchers
3
3
  class BaseOperatorMatcher
4
- attr_reader :generated_description
5
-
6
4
  def initialize(given)
7
5
  @given = given
8
6
  end
9
7
 
10
8
  def ==(expected)
11
- @expected = expected
12
9
  __delegate_method_missing_to_given("==", expected)
13
10
  end
14
11
 
15
12
  def ===(expected)
16
- @expected = expected
17
13
  __delegate_method_missing_to_given("===", expected)
18
14
  end
19
15
 
20
16
  def =~(expected)
21
- @expected = expected
22
17
  __delegate_method_missing_to_given("=~", expected)
23
18
  end
24
19
 
25
20
  def >(expected)
26
- @expected = expected
27
21
  __delegate_method_missing_to_given(">", expected)
28
22
  end
29
23
 
30
24
  def >=(expected)
31
- @expected = expected
32
25
  __delegate_method_missing_to_given(">=", expected)
33
26
  end
34
27
 
35
28
  def <(expected)
36
- @expected = expected
37
29
  __delegate_method_missing_to_given("<", expected)
38
30
  end
39
31
 
40
32
  def <=(expected)
41
- @expected = expected
42
33
  __delegate_method_missing_to_given("<=", expected)
43
34
  end
44
35
 
@@ -55,6 +46,7 @@ module Spec
55
46
  class PositiveOperatorMatcher < BaseOperatorMatcher #:nodoc:
56
47
 
57
48
  def __delegate_method_missing_to_given(operator, expected)
49
+ @expected = expected
58
50
  @operator = operator
59
51
  ::Spec::Matchers.last_matcher = self
60
52
  return true if @given.__send__(operator, expected)
@@ -67,6 +59,7 @@ module Spec
67
59
  class NegativeOperatorMatcher < BaseOperatorMatcher #:nodoc:
68
60
 
69
61
  def __delegate_method_missing_to_given(operator, expected)
62
+ @expected = expected
70
63
  @operator = operator
71
64
  ::Spec::Matchers.last_matcher = self
72
65
  return true unless @given.__send__(operator, expected)