dchelimsky-rspec 1.1.99.9 → 1.1.99.13

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 (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