rspec 1.2.0 → 1.2.1

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 (100) hide show
  1. data/.document +4 -4
  2. data/{History.txt → History.rdoc} +27 -4
  3. data/Manifest.txt +18 -7
  4. data/{README.txt → README.rdoc} +0 -0
  5. data/Rakefile +16 -9
  6. data/{Ruby1.9.markdown → Ruby1.9.rdoc} +3 -3
  7. data/TODO.txt +0 -7
  8. data/Upgrade.rdoc +110 -0
  9. data/features/matchers/create_matcher.feature +40 -0
  10. data/features/matchers/create_matcher_outside_rspec.feature +39 -0
  11. data/features/pending/pending_examples.feature +5 -5
  12. data/features/step_definitions/running_rspec.rb +13 -0
  13. data/features/subject/explicit_subject.feature +31 -0
  14. data/features/subject/implicit_subject.feature +31 -0
  15. data/lib/spec/adapters/mock_frameworks/flexmock.rb +1 -0
  16. data/lib/spec/adapters/mock_frameworks/mocha.rb +1 -0
  17. data/lib/spec/adapters/mock_frameworks/rr.rb +1 -0
  18. data/lib/spec/adapters/mock_frameworks/rspec.rb +12 -10
  19. data/lib/spec/dsl.rb +0 -1
  20. data/lib/spec/dsl/main.rb +3 -3
  21. data/lib/spec/example.rb +4 -3
  22. data/lib/spec/example/example_group_factory.rb +1 -3
  23. data/lib/spec/example/example_group_methods.rb +22 -28
  24. data/lib/spec/example/example_group_proxy.rb +64 -0
  25. data/lib/spec/example/example_methods.rb +8 -11
  26. data/lib/spec/example/example_proxy.rb +42 -0
  27. data/lib/spec/example/shared_example_group.rb +1 -1
  28. data/lib/spec/example/subject.rb +14 -3
  29. data/lib/spec/expectations.rb +1 -1
  30. data/lib/spec/expectations/differs/default.rb +46 -49
  31. data/lib/spec/expectations/differs/load-diff-lcs.rb +12 -0
  32. data/lib/spec/interop/test/unit/testcase.rb +2 -2
  33. data/lib/spec/matchers.rb +49 -9
  34. data/lib/spec/matchers/be.rb +12 -15
  35. data/lib/spec/matchers/change.rb +1 -0
  36. data/lib/spec/matchers/dsl.rb +15 -0
  37. data/lib/spec/matchers/have.rb +9 -8
  38. data/lib/spec/matchers/include.rb +2 -16
  39. data/lib/spec/matchers/match_array.rb +2 -14
  40. data/lib/spec/matchers/matcher.rb +16 -11
  41. data/lib/spec/matchers/pretty.rb +36 -0
  42. data/lib/spec/matchers/raise_error.rb +9 -8
  43. data/lib/spec/matchers/simple_matcher.rb +1 -0
  44. data/lib/spec/matchers/throw_symbol.rb +1 -1
  45. data/lib/spec/mocks/argument_expectation.rb +2 -0
  46. data/lib/spec/mocks/message_expectation.rb +2 -0
  47. data/lib/spec/mocks/proxy.rb +9 -10
  48. data/lib/spec/runner.rb +1 -0
  49. data/lib/spec/runner/extensions/kernel.rb +9 -0
  50. data/lib/spec/runner/formatter/base_formatter.rb +22 -9
  51. data/lib/spec/runner/formatter/html_formatter.rb +2 -1
  52. data/lib/spec/runner/heckle_runner.rb +1 -0
  53. data/lib/spec/runner/option_parser.rb +4 -1
  54. data/lib/spec/runner/options.rb +11 -0
  55. data/lib/spec/runner/spec_parser.rb +15 -22
  56. data/lib/spec/version.rb +4 -6
  57. data/spec/autotest/autotest_helper.rb +6 -1
  58. data/spec/spec/dsl/main_spec.rb +3 -3
  59. data/spec/spec/example/example_group_factory_spec.rb +11 -23
  60. data/spec/spec/example/example_group_methods_spec.rb +45 -20
  61. data/spec/spec/example/example_group_proxy_spec.rb +63 -0
  62. data/spec/spec/example/example_group_spec.rb +15 -0
  63. data/spec/spec/example/example_methods_spec.rb +5 -35
  64. data/spec/spec/example/example_proxy_spec.rb +47 -0
  65. data/spec/spec/example/nested_example_group_spec.rb +3 -3
  66. data/spec/spec/example/shared_example_group_spec.rb +4 -4
  67. data/spec/spec/example/subject_spec.rb +77 -0
  68. data/spec/spec/matchers/be_close_spec.rb +10 -10
  69. data/spec/spec/matchers/be_instance_of_spec.rb +13 -8
  70. data/spec/spec/matchers/be_kind_of_spec.rb +10 -8
  71. data/spec/spec/{dsl/matchers_spec.rb → matchers/dsl_spec.rb} +4 -4
  72. data/spec/spec/matchers/matcher_spec.rb +53 -1
  73. data/spec/spec/matchers/matchers_spec.rb +2 -0
  74. data/spec/spec/package/bin_spec_spec.rb +4 -4
  75. data/spec/spec/runner/command_line_spec.rb +2 -2
  76. data/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb +4 -4
  77. data/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +2 -2
  78. data/spec/spec/runner/formatter/html_formatted-1.8.4.html +1 -1
  79. data/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html +1 -1
  80. data/spec/spec/runner/formatter/html_formatted-1.8.5.html +1 -1
  81. data/spec/spec/runner/formatter/html_formatted-1.8.6-jruby.html +1 -1
  82. data/spec/spec/runner/formatter/html_formatted-1.8.6.html +1 -1
  83. data/spec/spec/runner/formatter/html_formatted-1.8.7.html +1 -1
  84. data/spec/spec/runner/formatter/html_formatted-1.9.1.html +1 -1
  85. data/spec/spec/runner/formatter/nested_text_formatter_spec.rb +12 -11
  86. data/spec/spec/runner/formatter/profile_formatter_spec.rb +2 -2
  87. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +2 -2
  88. data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +2 -2
  89. data/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html +1 -1
  90. data/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html +1 -1
  91. data/spec/spec/runner/formatter/text_mate_formatted-1.8.7.html +1 -1
  92. data/spec/spec/runner/formatter/text_mate_formatted-1.9.1.html +1 -1
  93. data/spec/spec/runner/option_parser_spec.rb +20 -0
  94. data/spec/spec/runner/options_spec.rb +23 -1
  95. data/spec/spec/runner/reporter_spec.rb +20 -17
  96. data/spec/spec/runner/spec_parser_spec.rb +1 -1
  97. metadata +33 -15
  98. data/Upgrade.markdown +0 -63
  99. data/lib/spec/dsl/matchers.rb +0 -13
  100. data/lib/spec/example/example_description.rb +0 -15
@@ -0,0 +1,15 @@
1
+ module Spec
2
+ module Matchers
3
+ module DSL
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::Matchers::DSL
14
+
15
+
@@ -4,6 +4,7 @@ module Spec
4
4
  def initialize(expected, relativity=:exactly)
5
5
  @expected = (expected == :no ? 0 : expected)
6
6
  @relativity = relativity
7
+ @actual = nil
7
8
  end
8
9
 
9
10
  def relativities
@@ -24,12 +25,12 @@ module Spec
24
25
  else
25
26
  collection_owner.__send__(@collection_name, *@args, &@block)
26
27
  end
27
- @given = collection.size if collection.respond_to?(:size)
28
- @given = collection.length if collection.respond_to?(:length)
29
- raise not_a_collection if @given.nil?
30
- return @given >= @expected if @relativity == :at_least
31
- return @given <= @expected if @relativity == :at_most
32
- return @given == @expected
28
+ @actual = collection.size if collection.respond_to?(:size)
29
+ @actual = collection.length if collection.respond_to?(:length)
30
+ raise not_a_collection if @actual.nil?
31
+ return @actual >= @expected if @relativity == :at_least
32
+ return @actual <= @expected if @relativity == :at_most
33
+ return @actual == @expected
33
34
  end
34
35
 
35
36
  def not_a_collection
@@ -37,12 +38,12 @@ module Spec
37
38
  end
38
39
 
39
40
  def failure_message_for_should
40
- "expected #{relative_expectation} #{@collection_name}, got #{@given}"
41
+ "expected #{relative_expectation} #{@collection_name}, got #{@actual}"
41
42
  end
42
43
 
43
44
  def failure_message_for_should_not
44
45
  if @relativity == :exactly
45
- return "expected target not to have #{@expected} #{@collection_name}, got #{@given}"
46
+ return "expected target not to have #{@expected} #{@collection_name}, got #{@actual}"
46
47
  elsif @relativity == :at_most
47
48
  return <<-EOF
48
49
  Isn't life confusing enough?
@@ -1,8 +1,8 @@
1
1
  module Spec
2
2
  module Matchers
3
-
4
3
  class Include #:nodoc:
5
-
4
+ include Spec::Matchers::Pretty
5
+
6
6
  def initialize(*expecteds)
7
7
  @expecteds = expecteds
8
8
  end
@@ -41,20 +41,6 @@ module Spec
41
41
  def _message(maybe_not="")
42
42
  "expected #{@actual.inspect} #{maybe_not}to include #{_pretty_print(@expecteds)}"
43
43
  end
44
-
45
- def _pretty_print(array)
46
- result = ""
47
- array.each_with_index do |item, index|
48
- if index < (array.length - 2)
49
- result << "#{item.inspect}, "
50
- elsif index < (array.length - 1)
51
- result << "#{item.inspect} and "
52
- else
53
- result << "#{item.inspect}"
54
- end
55
- end
56
- result
57
- end
58
44
  end
59
45
 
60
46
  # :call-seq:
@@ -2,7 +2,8 @@ module Spec
2
2
  module Matchers
3
3
 
4
4
  class MatchArray #:nodoc:
5
-
5
+ include Spec::Matchers::Pretty
6
+
6
7
  def initialize(expected)
7
8
  @expected = expected
8
9
  end
@@ -42,19 +43,6 @@ module Spec
42
43
  difference
43
44
  end
44
45
 
45
- def _pretty_print(array)
46
- result = ""
47
- array.each_with_index do |item, index|
48
- if index < (array.length - 2)
49
- result << "#{item.inspect}, "
50
- elsif index < (array.length - 1)
51
- result << "#{item.inspect} and "
52
- else
53
- result << "#{item.inspect}"
54
- end
55
- end
56
- result
57
- end
58
46
 
59
47
  end
60
48
 
@@ -1,21 +1,23 @@
1
1
  module Spec
2
2
  module Matchers
3
3
  class Matcher
4
- def initialize(name, expected=nil, &block_passed_to_init)
4
+ include Spec::Matchers::Pretty
5
+
6
+ def initialize(name, *expected, &declarations)
5
7
  @name = name
6
8
  @expected = expected
7
- @block = block_passed_to_init
9
+ @declarations = declarations
8
10
  @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}"}
11
+ :description => lambda {"#{name_to_sentence}#{expected_to_sentence}"},
12
+ :failure_message_for_should => lambda {|actual| "expected #{actual} to #{name_to_sentence}#{expected_to_sentence}"},
13
+ :failure_message_for_should_not => lambda {|actual| "expected #{actual} not to #{name_to_sentence}#{expected_to_sentence}"}
12
14
  }
13
15
  end
14
16
 
15
17
  def matches?(actual)
16
18
  @actual = actual
17
- instance_exec @expected, &@block
18
- instance_exec @actual, &@match_block
19
+ instance_exec(*@expected, &@declarations)
20
+ instance_exec(@actual, &@match_block)
19
21
  end
20
22
 
21
23
  def description(&block)
@@ -37,13 +39,16 @@ module Spec
37
39
  private
38
40
 
39
41
  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)
42
+ block ? @messages[key] = block :
43
+ actual.nil? ? @messages[key].call : @messages[key].call(actual)
43
44
  end
44
45
 
45
46
  def name_to_sentence
46
- @name_to_sentence ||= @name.to_s.gsub(/_/,' ')
47
+ split_words(@name)
48
+ end
49
+
50
+ def expected_to_sentence
51
+ to_sentence(@expected)
47
52
  end
48
53
 
49
54
  end
@@ -0,0 +1,36 @@
1
+ module Spec
2
+ module Matchers
3
+ module Pretty
4
+ def split_words(sym)
5
+ sym.to_s.gsub(/_/,' ')
6
+ end
7
+
8
+ def to_sentence(words)
9
+ case words.length
10
+ when 0
11
+ ""
12
+ when 1
13
+ " #{words[0]}"
14
+ when 2
15
+ " #{words[0]} and #{words[1]}"
16
+ else
17
+ " #{words[0...-1].join(', ')}, and #{words[-1]}"
18
+ end
19
+ end
20
+
21
+ def _pretty_print(array)
22
+ result = ""
23
+ array.each_with_index do |item, index|
24
+ if index < (array.length - 2)
25
+ result << "#{item.inspect}, "
26
+ elsif index < (array.length - 1)
27
+ result << "#{item.inspect} and "
28
+ else
29
+ result << "#{item.inspect}"
30
+ end
31
+ end
32
+ result
33
+ end
34
+ end
35
+ end
36
+ end
@@ -3,6 +3,7 @@ module Spec
3
3
  class RaiseError #:nodoc:
4
4
  def initialize(expected_error_or_message=Exception, expected_message=nil, &block)
5
5
  @block = block
6
+ @actual_error = nil
6
7
  case expected_error_or_message
7
8
  when String, Regexp
8
9
  @expected_error, @expected_message = Exception, expected_error_or_message
@@ -18,10 +19,10 @@ module Spec
18
19
  @eval_block_passed = false
19
20
  begin
20
21
  given_proc.call
21
- rescue @expected_error => @given_error
22
+ rescue @expected_error => @actual_error
22
23
  @raised_expected_error = true
23
24
  @with_expected_message = verify_message
24
- rescue Exception => @given_error
25
+ rescue Exception => @actual_error
25
26
  # This clause should be empty, but rcov will not report it as covered
26
27
  # unless something (anything) is executed within the clause
27
28
  rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0"
@@ -37,10 +38,10 @@ module Spec
37
38
  def eval_block
38
39
  @eval_block = true
39
40
  begin
40
- @block[@given_error]
41
+ @block[@actual_error]
41
42
  @eval_block_passed = true
42
43
  rescue Exception => err
43
- @given_error = err
44
+ @actual_error = err
44
45
  end
45
46
  end
46
47
 
@@ -49,14 +50,14 @@ module Spec
49
50
  when nil
50
51
  true
51
52
  when Regexp
52
- @expected_message =~ @given_error.message
53
+ @expected_message =~ @actual_error.message
53
54
  else
54
- @expected_message == @given_error.message
55
+ @expected_message == @actual_error.message
55
56
  end
56
57
  end
57
58
 
58
59
  def failure_message_for_should
59
- @eval_block ? @given_error.message : "expected #{expected_error}#{given_error}"
60
+ @eval_block ? @actual_error.message : "expected #{expected_error}#{given_error}"
60
61
  end
61
62
 
62
63
  def failure_message_for_should_not
@@ -80,7 +81,7 @@ module Spec
80
81
  end
81
82
 
82
83
  def given_error
83
- @given_error.nil? ? " but nothing was raised" : ", got #{@given_error.inspect}"
84
+ @actual_error.nil? ? " but nothing was raised" : ", got #{@actual_error.inspect}"
84
85
  end
85
86
 
86
87
  def negative_expectation?
@@ -6,6 +6,7 @@ module Spec
6
6
  def initialize(description, &match_block)
7
7
  @description = description
8
8
  @match_block = match_block
9
+ @failure_message = @negative_failure_message = nil
9
10
  end
10
11
 
11
12
  def matches?(given)
@@ -5,7 +5,7 @@ module Spec
5
5
  def initialize(expected_symbol = nil, expected_arg=nil)
6
6
  @expected_symbol = expected_symbol
7
7
  @expected_arg = expected_arg
8
- @caught_symbol = nil
8
+ @caught_symbol = @caught_arg = nil
9
9
  end
10
10
 
11
11
  def matches?(given_proc)
@@ -7,6 +7,8 @@ module Spec
7
7
  def initialize(args, &block)
8
8
  @args = args
9
9
  @matchers_block = block
10
+ @match_any_args = false
11
+ @matchers = nil
10
12
 
11
13
  if ArgumentMatchers::AnyArgsMatcher === args.first
12
14
  @match_any_args = true
@@ -25,6 +25,8 @@ module Spec
25
25
  @at_least = nil
26
26
  @at_most = nil
27
27
  @args_to_yield = []
28
+ @failed_fast = nil
29
+ @args_to_yield_were_cloned = false
28
30
  end
29
31
 
30
32
  def build_child(expected_from, method_block, expected_received_count, opts={})
@@ -25,6 +25,7 @@ module Spec
25
25
  @stubs = []
26
26
  @proxied_methods = []
27
27
  @options = options ? DEFAULT_OPTIONS.dup.merge(options) : DEFAULT_OPTIONS
28
+ @already_proxied_respond_to = false
28
29
  end
29
30
 
30
31
  def null_object?
@@ -128,8 +129,8 @@ module Spec
128
129
  end
129
130
 
130
131
  def define_expected_method(sym)
131
- visibility_string = "#{visibility(sym)} :#{sym}"
132
132
  unless @proxied_methods.include?(sym)
133
+ visibility_string = "#{visibility(sym)} :#{sym}"
133
134
  if target_responds_to?(sym)
134
135
  munged_sym = munge(sym)
135
136
  target_metaclass.instance_eval do
@@ -137,14 +138,13 @@ module Spec
137
138
  end
138
139
  @proxied_methods << sym
139
140
  end
141
+ target_metaclass.class_eval(<<-EOF, __FILE__, __LINE__)
142
+ def #{sym}(*args, &block)
143
+ __mock_proxy.message_received :#{sym}, *args, &block
144
+ end
145
+ #{visibility_string}
146
+ EOF
140
147
  end
141
-
142
- target_metaclass.class_eval(<<-EOF, __FILE__, __LINE__)
143
- def #{sym}(*args, &block)
144
- __mock_proxy.message_received :#{sym}, *args, &block
145
- end
146
- #{visibility_string}
147
- EOF
148
148
  end
149
149
 
150
150
  def target_responds_to?(sym)
@@ -195,11 +195,10 @@ module Spec
195
195
  @proxied_methods.each do |sym|
196
196
  munged_sym = munge(sym)
197
197
  target_metaclass.instance_eval do
198
+ remove_method sym
198
199
  if method_defined?(munged_sym)
199
200
  alias_method sym, munged_sym
200
201
  remove_method munged_sym
201
- else
202
- remove_method sym
203
202
  end
204
203
  end
205
204
  end
@@ -8,6 +8,7 @@ require 'spec/runner/backtrace_tweaker'
8
8
  require 'spec/runner/reporter'
9
9
  require 'spec/runner/spec_parser'
10
10
  require 'spec/runner/class_and_arguments_parser'
11
+ require 'spec/runner/extensions/kernel'
11
12
 
12
13
  module Spec
13
14
  module Runner
@@ -0,0 +1,9 @@
1
+ module Kernel
2
+ unless respond_to?(:debugger)
3
+ # Start a debugging session if ruby-debug is loaded with the -u/--debugger option
4
+ def debugger(steps=1)
5
+ # If not then just comment and proceed
6
+ $stderr.puts "debugger statement ignored, use -u or --debugger option on rspec to enable debugging"
7
+ end
8
+ end
9
+ end
@@ -1,7 +1,9 @@
1
1
  module Spec
2
2
  module Runner
3
3
  module Formatter
4
- # Baseclass for formatters that implements all required methods as no-ops.
4
+ # Formatter base-class, which implements all required methods.
5
+ # Almost all of the implementations are no-ops, with the exception
6
+ # of +add_example_group+ (see below).
5
7
  class BaseFormatter
6
8
  attr_accessor :example_group, :options, :where
7
9
  def initialize(options, where)
@@ -19,26 +21,35 @@ module Spec
19
21
  end
20
22
 
21
23
  # This method is invoked at the beginning of the execution of each example_group.
22
- # +example_group+ is the example_group.
24
+ # +example_group_proxy+ is an instance of Spec::Example::ExampleGroupProxy, and
25
+ # is assigned as the value returned by subsequent calls to +example_group()+
23
26
  #
24
- # The next method to be invoked after this is #example_failed or #example_finished
25
- def add_example_group(example_group)
26
- @example_group = example_group
27
+ # The next method to be invoked after this is #example_started
28
+ def add_example_group(example_group_proxy)
29
+ @example_group = example_group_proxy
27
30
  end
28
31
 
29
32
  # This method is invoked when an +example+ starts.
30
- def example_started(example)
33
+ # +example_proxy+ is an instance of Spec::Example::ExampleProxy
34
+ #
35
+ # The next method to be invoked after this is #example_passed, #example_failed,
36
+ # or #example_pending
37
+ def example_started(example_proxy)
31
38
  end
32
39
 
33
40
  # This method is invoked when an +example+ passes.
34
- def example_passed(example)
41
+ # +example_proxy+ is the same instance of Spec::Example::ExampleProxy
42
+ # that was passed to example_started
43
+ def example_passed(example_proxy)
35
44
  end
36
45
 
37
46
  # This method is invoked when an +example+ fails, i.e. an exception occurred
38
47
  # inside it (such as a failed should or other exception). +counter+ is the
39
48
  # sequence number of the failure (starting at 1) and +failure+ is the associated
40
49
  # Failure object.
41
- def example_failed(example, counter, failure)
50
+ # +example_proxy+ is the same instance of Spec::Example::ExampleProxy
51
+ # that was passed to example_started
52
+ def example_failed(example_proxy, counter, failure)
42
53
  end
43
54
 
44
55
  # This method is invoked when an example is not yet implemented (i.e. has not
@@ -47,7 +58,9 @@ module Spec
47
58
  # default value of "Not Yet Implemented"
48
59
  # +pending_caller+ is the file and line number of the spec which
49
60
  # has called the pending method
50
- def example_pending(example, message, pending_caller)
61
+ # +example_proxy+ is the same instance of Spec::Example::ExampleProxy
62
+ # that was passed to example_started
63
+ def example_pending(example_proxy, message, pending_caller)
51
64
  end
52
65
 
53
66
  # This method is invoked after all of the examples have executed. The next method
@@ -11,6 +11,7 @@ module Spec
11
11
  super
12
12
  @example_group_number = 0
13
13
  @example_number = 0
14
+ @header_red = nil
14
15
  end
15
16
 
16
17
  def method_missing(sym, *args)
@@ -172,7 +173,7 @@ EOF
172
173
 
173
174
  <div id="rspec-header">
174
175
  <div id="label">
175
- <h1>RSpec Results</h1>
176
+ <h1>RSpec Code Examples</h1>
176
177
  </div>
177
178
 
178
179
  <div id="summary">