dchelimsky-rspec 1.1.99.9 → 1.1.99.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.autotest +2 -1
  2. data/.document +7 -0
  3. data/History.txt +17 -4
  4. data/Manifest.txt +12 -2
  5. data/README.txt +1 -4
  6. data/Rakefile +1 -12
  7. data/Upgrade.markdown +62 -0
  8. data/examples/failing/pending_example.rb +9 -0
  9. data/features/matchers/create_matcher.feature +115 -0
  10. data/features/mocks/mix_stubs_and_mocks.feature +22 -0
  11. data/features/pending/pending_examples.feature +81 -0
  12. data/features/support/matchers/smart_match.rb +2 -2
  13. data/lib/spec.rb +1 -1
  14. data/lib/spec/dsl.rb +3 -1
  15. data/lib/spec/dsl/matchers.rb +13 -0
  16. data/lib/spec/example/example_group_methods.rb +6 -1
  17. data/lib/spec/example/example_methods.rb +5 -6
  18. data/lib/spec/example/subject.rb +1 -1
  19. data/lib/spec/expectations/handler.rb +13 -11
  20. data/lib/spec/matchers.rb +14 -3
  21. data/lib/spec/matchers/be.rb +2 -2
  22. data/lib/spec/matchers/be_close.rb +1 -1
  23. data/lib/spec/matchers/be_instance_of.rb +2 -2
  24. data/lib/spec/matchers/be_kind_of.rb +2 -2
  25. data/lib/spec/matchers/change.rb +3 -3
  26. data/lib/spec/matchers/eql.rb +2 -2
  27. data/lib/spec/matchers/equal.rb +2 -2
  28. data/lib/spec/matchers/exist.rb +2 -2
  29. data/lib/spec/matchers/extensions/instance_exec.rb +25 -0
  30. data/lib/spec/matchers/has.rb +2 -2
  31. data/lib/spec/matchers/have.rb +2 -2
  32. data/lib/spec/matchers/include.rb +2 -2
  33. data/lib/spec/matchers/match.rb +2 -2
  34. data/lib/spec/matchers/match_array.rb +2 -2
  35. data/lib/spec/matchers/matcher.rb +51 -0
  36. data/lib/spec/matchers/raise_error.rb +2 -2
  37. data/lib/spec/matchers/respond_to.rb +2 -2
  38. data/lib/spec/matchers/satisfy.rb +2 -2
  39. data/lib/spec/matchers/throw_symbol.rb +2 -2
  40. data/lib/spec/mocks/error_generator.rb +3 -2
  41. data/lib/spec/mocks/message_expectation.rb +1 -1
  42. data/lib/spec/mocks/proxy.rb +4 -4
  43. data/lib/spec/runner/option_parser.rb +1 -1
  44. data/lib/spec/version.rb +1 -1
  45. data/rspec.gemspec +6 -6
  46. data/spec/spec/dsl/matchers_spec.rb +25 -0
  47. data/spec/spec/example/example_methods_spec.rb +11 -5
  48. data/spec/spec/example/pending_module_spec.rb +66 -41
  49. data/spec/spec/{matchers → expectations}/handler_spec.rb +46 -5
  50. data/spec/spec/interop/test/unit/testcase_spec.rb +0 -4
  51. data/spec/spec/matchers/be_close_spec.rb +1 -1
  52. data/spec/spec/matchers/change_spec.rb +12 -0
  53. data/spec/spec/matchers/eql_spec.rb +2 -2
  54. data/spec/spec/matchers/equal_spec.rb +2 -2
  55. data/spec/spec/matchers/have_spec.rb +4 -4
  56. data/spec/spec/matchers/match_spec.rb +2 -2
  57. data/spec/spec/matchers/matcher_spec.rb +97 -0
  58. data/spec/spec/matchers/throw_symbol_spec.rb +8 -8
  59. data/spec/spec/mocks/mock_spec.rb +2 -2
  60. data/spec/spec/mocks/stubbed_message_expectations_spec.rb +13 -1
  61. metadata +16 -10
  62. data/examples/passing/priority.txt +0 -1
@@ -22,11 +22,11 @@ module Spec
22
22
  end
23
23
 
24
24
  def failure_message
25
- "expected #{@actual.inspect} to smart_match #{@expected.inspect}, but it didn't"
25
+ "expected #{@actual} to smart_match #{@expected}"
26
26
  end
27
27
 
28
28
  def negative_failure_message
29
- "expected #{@actual.inspect} not to smart_match #{@expected.inspect}, but it did"
29
+ "expected #{@actual} not to smart_match #{@expected}"
30
30
  end
31
31
  end
32
32
 
data/lib/spec.rb CHANGED
@@ -1,7 +1,7 @@
1
+ require 'spec/ruby'
1
2
  require 'spec/matchers'
2
3
  require 'spec/expectations'
3
4
  require 'spec/example'
4
5
  require 'spec/runner'
5
6
  require 'spec/version'
6
7
  require 'spec/dsl'
7
- require 'spec/ruby'
data/lib/spec/dsl.rb CHANGED
@@ -1 +1,3 @@
1
- require 'spec/dsl/main'
1
+ require 'spec/dsl/main'
2
+ require 'spec/dsl/matchers'
3
+
@@ -0,0 +1,13 @@
1
+ module Spec
2
+ module DSL
3
+ module Matchers
4
+ def create(name, &block_passed_to_create)
5
+ define_method name do |expected|
6
+ Spec::Matchers::Matcher.new name, expected, &block_passed_to_create
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ Spec::Matchers.extend Spec::DSL::Matchers
@@ -72,9 +72,14 @@ WARNING
72
72
  def example(description=nil, options={}, backtrace=nil, &implementation)
73
73
  example_description = ExampleDescription.new(description, options, backtrace || caller(0)[1])
74
74
  example_descriptions << example_description
75
- example_implementations[example_description] = implementation
75
+ example_implementations[example_description] = implementation || pending_implementation
76
76
  example_description
77
77
  end
78
+
79
+ def pending_implementation
80
+ error = Spec::Example::NotYetImplementedError.new(caller)
81
+ lambda { raise(error) }
82
+ end
78
83
 
79
84
  alias_method :it, :example
80
85
  alias_method :specify, :example
@@ -110,7 +110,7 @@ WARNING
110
110
  def initialize(description, options={}, &implementation)
111
111
  @_options = options
112
112
  @_defined_description = description
113
- @_implementation = implementation || pending_implementation
113
+ @_implementation = implementation
114
114
  @_backtrace = caller
115
115
  end
116
116
 
@@ -134,16 +134,15 @@ WARNING
134
134
  def described_class # :nodoc:
135
135
  self.class.described_class
136
136
  end
137
+
138
+ def description_args
139
+ self.class.description_args
140
+ end
137
141
 
138
142
  def example_group_hierarchy
139
143
  self.class.example_group_hierarchy
140
144
  end
141
145
 
142
- def pending_implementation
143
- error = Spec::Example::NotYetImplementedError.new(caller)
144
- lambda { raise(error) }
145
- end
146
-
147
146
  end
148
147
  end
149
148
  end
@@ -16,7 +16,7 @@ module Spec
16
16
  # See +ExampleMethods#should+ for more information about this approach.
17
17
  def subject(&block)
18
18
  if block.nil?
19
- @_subject_block || (described_class ? lambda {described_class.new} : lambda {})
19
+ @_subject_block || (described_class ? lambda {described_class.new} : lambda {description_args.first})
20
20
  else
21
21
  @_subject_block = block
22
22
  end
@@ -6,12 +6,14 @@ module Spec
6
6
  def self.handle_matcher(actual, matcher, &block)
7
7
  ::Spec::Matchers.last_should = :should
8
8
  ::Spec::Matchers.last_matcher = matcher
9
-
10
9
  return ::Spec::Matchers::PositiveOperatorMatcher.new(actual) if matcher.nil?
11
10
 
12
11
  match = matcher.matches?(actual, &block)
13
- ::Spec::Expectations.fail_with(matcher.failure_message) unless match
14
- match
12
+ return match if match
13
+
14
+ ::Spec::Expectations.fail_with matcher.respond_to?(:failure_message_for_should) ?
15
+ matcher.failure_message_for_should :
16
+ matcher.failure_message
15
17
  end
16
18
  end
17
19
 
@@ -22,14 +24,14 @@ module Spec
22
24
 
23
25
  return ::Spec::Matchers::NegativeOperatorMatcher.new(actual) if matcher.nil?
24
26
 
25
- match = if matcher.respond_to?(:does_not_match?)
26
- !matcher.does_not_match?(actual, &block)
27
- else
28
- matcher.matches?(actual, &block)
29
- end
30
-
31
- ::Spec::Expectations.fail_with(matcher.negative_failure_message) if match
32
- match
27
+ match = matcher.respond_to?(:does_not_match?) ?
28
+ !matcher.does_not_match?(actual, &block) :
29
+ matcher.matches?(actual, &block)
30
+ return match unless match
31
+
32
+ ::Spec::Expectations.fail_with matcher.respond_to?(:failure_message_for_should_not) ?
33
+ matcher.failure_message_for_should_not :
34
+ matcher.negative_failure_message
33
35
  end
34
36
  end
35
37
  end
data/lib/spec/matchers.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'spec/matchers/extensions/instance_exec'
2
+ require 'spec/matchers/matcher'
1
3
  require 'spec/matchers/operator_matcher'
2
4
  require 'spec/matchers/be'
3
5
  require 'spec/matchers/be_close'
@@ -28,12 +30,21 @@ module Spec
28
30
  # is any object that responds to the following methods:
29
31
  #
30
32
  # matches?(actual)
31
- # failure_message
32
- # negative_failure_message #optional
33
+ # failure_message_for_should
34
+ #
35
+ # These methods are also part of the matcher protocol, but are optional:
36
+ #
37
+ # does_not_match?(actual)
38
+ # failure_message_for_should_not
33
39
  # description #optional
34
40
  #
41
+ # These methods are from older versions of the protocol. They are still supported,
42
+ # but are not recommended:
43
+ #
44
+ # failure_message (use failure_message_for_should instead)
45
+ # negative_failure_message (use failure_message_for_should_not instead)
46
+ #
35
47
  # See Spec::Expectations to learn how to use these as Expectation Matchers.
36
- # See Spec::Mocks to learn how to use them as Mock Argument Matchers.
37
48
  #
38
49
  # == Predicates
39
50
  #
@@ -26,13 +26,13 @@ module Spec
26
26
  end
27
27
  end
28
28
 
29
- def failure_message
29
+ def failure_message_for_should
30
30
  handling_predicate? ?
31
31
  "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}" :
32
32
  "expected #{@comparison_method} #{expected}, got #{@actual.inspect}".gsub(' ',' ')
33
33
  end
34
34
 
35
- def negative_failure_message
35
+ def failure_message_for_should_not
36
36
  if handling_predicate?
37
37
  "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}"
38
38
  else
@@ -11,7 +11,7 @@ module Spec
11
11
  (@actual - @expected).abs < @delta
12
12
  end
13
13
 
14
- def failure_message
14
+ def failure_message_for_should
15
15
  "expected #{@expected} +/- (< #{@delta}), got #{@actual}"
16
16
  end
17
17
 
@@ -14,11 +14,11 @@ module Spec
14
14
  "be an instance of #{@expected}"
15
15
  end
16
16
 
17
- def failure_message
17
+ def failure_message_for_should
18
18
  "expected instance of #{@expected}, got #{@actual.inspect}"
19
19
  end
20
20
 
21
- def negative_failure_message
21
+ def failure_message_for_should_not
22
22
  "expected #{@actual.inspect} not to be an instance of #{@expected}"
23
23
  end
24
24
  end
@@ -14,11 +14,11 @@ module Spec
14
14
  "be a kind of #{@expected}"
15
15
  end
16
16
 
17
- def failure_message
17
+ def failure_message_for_should
18
18
  "expected kind of #{@expected}, got #{@actual.inspect}"
19
19
  end
20
20
 
21
- def negative_failure_message
21
+ def failure_message_for_should_not
22
22
  "expected #{@actual.inspect} not to be a kind of #{@expected}"
23
23
  end
24
24
  end
@@ -15,7 +15,7 @@ module Spec
15
15
  event_proc.call
16
16
  @after = evaluate_value_proc
17
17
 
18
- return false if @from unless @from == @before
18
+ return (@to = false) if @from unless @from == @before
19
19
  return false if @to unless @to == @after
20
20
  return (@before + @amount == @after) if @amount
21
21
  return ((@after - @before) >= @minimum) if @minimum
@@ -34,7 +34,7 @@ MESSAGE
34
34
  @value_proc.call
35
35
  end
36
36
 
37
- def failure_message
37
+ def failure_message_for_should
38
38
  if @to
39
39
  "#{@message} should have been changed to #{@to.inspect}, but is now #{@after.inspect}"
40
40
  elsif @from
@@ -54,7 +54,7 @@ MESSAGE
54
54
  @after - @before
55
55
  end
56
56
 
57
- def negative_failure_message
57
+ def failure_message_for_should_not
58
58
  "#{@message} should not have changed, but did change from #{@before.inspect} to #{@after.inspect}"
59
59
  end
60
60
 
@@ -10,11 +10,11 @@ module Spec
10
10
  @actual.eql?(@expected)
11
11
  end
12
12
 
13
- def failure_message
13
+ def failure_message_for_should
14
14
  return "expected #{@expected.inspect}, got #{@actual.inspect} (using .eql?)", @expected, @actual
15
15
  end
16
16
 
17
- def negative_failure_message
17
+ def failure_message_for_should_not
18
18
  return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .eql?)", @expected, @actual
19
19
  end
20
20
 
@@ -11,11 +11,11 @@ module Spec
11
11
  @actual.equal?(@expected)
12
12
  end
13
13
 
14
- def failure_message
14
+ def failure_message_for_should
15
15
  return "expected #{@expected.inspect}, got #{@actual.inspect} (using .equal?)", @expected, @actual
16
16
  end
17
17
 
18
- def negative_failure_message
18
+ def failure_message_for_should_not
19
19
  return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .equal?)", @expected, @actual
20
20
  end
21
21
 
@@ -7,11 +7,11 @@ module Spec
7
7
  actual.exist?
8
8
  end
9
9
 
10
- def failure_message
10
+ def failure_message_for_should
11
11
  "expected #{@actual.inspect} to exist, but it doesn't."
12
12
  end
13
13
 
14
- def negative_failure_message
14
+ def failure_message_for_should_not
15
15
  "expected #{@actual.inspect} to not exist, but it does."
16
16
  end
17
17
 
@@ -0,0 +1,25 @@
1
+ require 'spec/ruby'
2
+
3
+ if ::Spec::Ruby.version < "1.8.7"
4
+ # based on Bounded Spec InstanceExec (Mauricio Fernandez)
5
+ # http://eigenclass.org/hiki/bounded+space+instance_exec
6
+ class Object
7
+ module InstanceExecHelper; end
8
+ include InstanceExecHelper
9
+ def instance_exec(*args, &block)
10
+ begin
11
+ orig_critical, Thread.critical = Thread.critical, true
12
+ n = 0
13
+ n += 1 while respond_to?(method_name="__instance_exec#{n}")
14
+ InstanceExecHelper.module_eval{ define_method(method_name, &block) }
15
+ ensure
16
+ Thread.critical = orig_critical
17
+ end
18
+ begin
19
+ return send(method_name, *args)
20
+ ensure
21
+ InstanceExecHelper.module_eval{ remove_method(method_name) } rescue nil
22
+ end
23
+ end
24
+ end
25
+ end
@@ -11,11 +11,11 @@ module Spec
11
11
  actual.__send__(predicate(@expected), *@args)
12
12
  end
13
13
 
14
- def failure_message
14
+ def failure_message_for_should
15
15
  "expected ##{predicate(@expected)}(#{@args[0].inspect}) to return true, got false"
16
16
  end
17
17
 
18
- def negative_failure_message
18
+ def failure_message_for_should_not
19
19
  "expected ##{predicate(@expected)}(#{@args[0].inspect}) to return false, got true"
20
20
  end
21
21
 
@@ -36,11 +36,11 @@ module Spec
36
36
  "expected #{@collection_name} to be a collection but it does not respond to #length or #size"
37
37
  end
38
38
 
39
- def failure_message
39
+ def failure_message_for_should
40
40
  "expected #{relative_expectation} #{@collection_name}, got #{@given}"
41
41
  end
42
42
 
43
- def negative_failure_message
43
+ def failure_message_for_should_not
44
44
  if @relativity == :exactly
45
45
  return "expected target not to have #{@expected} #{@collection_name}, got #{@given}"
46
46
  elsif @relativity == :at_most
@@ -25,11 +25,11 @@ module Spec
25
25
  true
26
26
  end
27
27
 
28
- def failure_message
28
+ def failure_message_for_should
29
29
  _message
30
30
  end
31
31
 
32
- def negative_failure_message
32
+ def failure_message_for_should_not
33
33
  _message("not ")
34
34
  end
35
35
 
@@ -10,11 +10,11 @@ module Spec
10
10
  actual =~ @expected
11
11
  end
12
12
 
13
- def failure_message
13
+ def failure_message_for_should
14
14
  return "expected #{@actual.inspect} to match #{@expected.inspect}", @expected, @actual
15
15
  end
16
16
 
17
- def negative_failure_message
17
+ def failure_message_for_should_not
18
18
  return "expected #{@actual.inspect} not to match #{@expected.inspect}", @expected, @actual
19
19
  end
20
20
 
@@ -14,7 +14,7 @@ module Spec
14
14
  @extra_items.empty? & @missing_items.empty?
15
15
  end
16
16
 
17
- def failure_message
17
+ def failure_message_for_should
18
18
  message = "expected collection contained: #{@expected.sort.inspect}\n"
19
19
  message += "actual collection contained: #{@actual.sort.inspect}\n"
20
20
  message += "the missing elements were: #{@missing_items.sort.inspect}\n" unless @missing_items.empty?
@@ -22,7 +22,7 @@ module Spec
22
22
  message
23
23
  end
24
24
 
25
- def negative_failure_message
25
+ def failure_message_for_should_not
26
26
  "Matcher does not support should_not"
27
27
  end
28
28
 
@@ -0,0 +1,51 @@
1
+ module Spec
2
+ module Matchers
3
+ class Matcher
4
+ def initialize(name, expected=nil, &block_passed_to_init)
5
+ @name = name
6
+ @expected = expected
7
+ @block = block_passed_to_init
8
+ @messages = {
9
+ :description => lambda {"#{name_to_sentence} #{expected}"},
10
+ :failure_message_for_should => lambda {|actual| "expected #{actual} to #{name_to_sentence} #{expected}"},
11
+ :failure_message_for_should_not => lambda {|actual| "expected #{actual} not to #{name_to_sentence} #{expected}"}
12
+ }
13
+ end
14
+
15
+ def matches?(actual)
16
+ @actual = actual
17
+ instance_exec @expected, &@block
18
+ instance_exec @actual, &@match_block
19
+ end
20
+
21
+ def description(&block)
22
+ cache_or_call_cached(:description, &block)
23
+ end
24
+
25
+ def failure_message_for_should(&block)
26
+ cache_or_call_cached(:failure_message_for_should, @actual, &block)
27
+ end
28
+
29
+ def failure_message_for_should_not(&block)
30
+ cache_or_call_cached(:failure_message_for_should_not, @actual, &block)
31
+ end
32
+
33
+ def match(&block)
34
+ @match_block = block
35
+ end
36
+
37
+ private
38
+
39
+ def cache_or_call_cached(key, actual=nil, &block)
40
+ block ? @messages[key] = block :
41
+ actual.nil? ? @messages[key].call :
42
+ @messages[key].call(actual)
43
+ end
44
+
45
+ def name_to_sentence
46
+ @name_to_sentence ||= @name.to_s.gsub(/_/,' ')
47
+ end
48
+
49
+ end
50
+ end
51
+ end