rspec 1.2.4 → 1.2.5

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.tar.gz.sig +0 -0
  2. data/History.rdoc +59 -32
  3. data/Manifest.txt +6 -0
  4. data/Rakefile +2 -2
  5. data/examples/passing/options_example.rb +31 -0
  6. data/examples/passing/options_formatter.rb +20 -0
  7. data/features/expectations/expect_change.feature +65 -0
  8. data/features/expectations/expect_error.feature +44 -0
  9. data/lib/spec/example/example_group_factory.rb +4 -2
  10. data/lib/spec/example/example_group_methods.rb +5 -1
  11. data/lib/spec/example/example_group_proxy.rb +8 -0
  12. data/lib/spec/example/example_matcher.rb +2 -3
  13. data/lib/spec/example/example_methods.rb +14 -1
  14. data/lib/spec/example/example_proxy.rb +3 -4
  15. data/lib/spec/example/subject.rb +7 -7
  16. data/lib/spec/interop/test.rb +2 -1
  17. data/lib/spec/matchers/be_close.rb +5 -5
  18. data/lib/spec/matchers/be_instance_of.rb +2 -2
  19. data/lib/spec/matchers/be_kind_of.rb +2 -2
  20. data/lib/spec/matchers/compatibility.rb +2 -2
  21. data/lib/spec/matchers/eql.rb +4 -4
  22. data/lib/spec/matchers/equal.rb +18 -8
  23. data/lib/spec/matchers/extensions/instance_exec.rb +1 -3
  24. data/lib/spec/matchers/include.rb +4 -4
  25. data/lib/spec/matchers/match.rb +2 -2
  26. data/lib/spec/matchers/operator_matcher.rb +3 -2
  27. data/lib/spec/mocks/methods.rb +9 -0
  28. data/lib/spec/mocks/mock.rb +34 -24
  29. data/lib/spec/mocks/proxy.rb +1 -0
  30. data/lib/spec/mocks/spec_methods.rb +5 -5
  31. data/lib/spec/runner.rb +1 -2
  32. data/lib/spec/runner/configuration.rb +0 -0
  33. data/lib/spec/runner/drb_command_line.rb +2 -0
  34. data/lib/spec/runner/formatter/base_text_formatter.rb +1 -1
  35. data/lib/spec/runner/formatter/no_op_method_missing.rb +1 -1
  36. data/lib/spec/version.rb +1 -1
  37. data/spec/spec/example/example_group_proxy_spec.rb +24 -0
  38. data/spec/spec/example/example_methods_spec.rb +12 -0
  39. data/spec/spec/example/predicate_matcher_spec.rb +0 -0
  40. data/spec/spec/example/subject_spec.rb +16 -6
  41. data/spec/spec/matchers/change_spec.rb +85 -85
  42. data/spec/spec/matchers/compatibility_spec.rb +16 -22
  43. data/spec/spec/matchers/equal_spec.rb +33 -9
  44. data/spec/spec/matchers/have_spec.rb +1 -8
  45. data/spec/spec/mocks/mock_ordering_spec.rb +10 -0
  46. data/spec/spec/mocks/mock_spec.rb +106 -93
  47. data/spec/spec/mocks/stub_chain_spec.rb +27 -0
  48. data/spec/spec/mocks/stub_spec.rb +9 -5
  49. data/spec/spec/runner/configuration_spec.rb +0 -0
  50. data/spec/spec/runner/drb_command_line_spec.rb +1 -1
  51. data/spec/spec/runner/formatter/html_formatted-1.8.7.html +31 -46
  52. data/spec/spec/runner/formatter/html_formatted-1.9.1.html +25 -28
  53. data/spec/spec/runner/formatter/html_formatter_spec.rb +3 -19
  54. data/spec/spec/runner/formatter/profile_formatter_spec.rb +3 -18
  55. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +4 -28
  56. data/spec/spec/runner/formatter/text_mate_formatted-1.8.7.html +31 -46
  57. data/spec/spec/runner/formatter/text_mate_formatted-1.9.1.html +7 -10
  58. data/spec/spec/runner/reporter_spec.rb +1 -1
  59. data/spec/spec_helper.rb +4 -0
  60. data/spec/support/macros.rb +29 -0
  61. metadata +36 -8
  62. metadata.gz.sig +1 -0
@@ -3,6 +3,8 @@ module Spec
3
3
 
4
4
  class ExampleGroupFactory
5
5
  module ClassMethods
6
+ include Spec::Example::ArgsAndOptions
7
+
6
8
  def reset
7
9
  @example_group_types = nil
8
10
  default(ExampleGroup)
@@ -23,8 +25,8 @@ module Spec
23
25
  end
24
26
 
25
27
  def create_example_group(*args, &block)
26
- raise ArgumentError if args.empty?
27
- raise ArgumentError unless block
28
+ raise ArgumentError if args.empty? || block.nil?
29
+ add_options(args)
28
30
  superclass = determine_superclass(args.last)
29
31
  superclass.describe(*args, &block)
30
32
  end
@@ -19,7 +19,11 @@ module Spec
19
19
  include Spec::Example::PredicateMatchers
20
20
  include Spec::Example::ArgsAndOptions
21
21
 
22
- attr_reader :options, :location
22
+ attr_reader :location
23
+
24
+ def options # :nodoc:
25
+ @options ||= {}
26
+ end
23
27
 
24
28
  def inherited(klass) # :nodoc:
25
29
  super
@@ -10,8 +10,16 @@ module Spec
10
10
  @examples = example_group.example_proxies
11
11
  @location = example_group.location
12
12
  @backtrace = example_group.location # deprecated - see the backtrace method below
13
+ @options = example_group.options.dup
14
+ @options.delete(:location)
15
+ @options.delete(:scope)
13
16
  end
14
17
 
18
+ # Optional hash passed to the example group declaration. Note that RSpec uses
19
+ # this hash internally and reserves the keys :location and :scope for its own
20
+ # use (and removes them from this hash)
21
+ attr_reader :options
22
+
15
23
  # This is the description passed to the <tt>describe()</tt> method or any
16
24
  # of its aliases
17
25
  attr_reader :description
@@ -7,10 +7,9 @@ module Spec
7
7
  end
8
8
 
9
9
  def matches?(specified_examples)
10
- specified_examples.each do |specified_example|
11
- return true if matches_literal_example?(specified_example) || matches_example_not_considering_modules?(specified_example)
10
+ specified_examples.any? do |specified_example|
11
+ matches_literal_example?(specified_example) || matches_example_not_considering_modules?(specified_example)
12
12
  end
13
- false
14
13
  end
15
14
 
16
15
  protected
@@ -30,7 +30,6 @@ module Spec
30
30
  end
31
31
 
32
32
  def execute(run_options, instance_variables) # :nodoc:
33
- puts caller unless caller(0)[1] =~ /example_group_methods/
34
33
  run_options.reporter.example_started(@_proxy)
35
34
  set_instance_variables_from_hash(instance_variables)
36
35
 
@@ -52,6 +51,20 @@ module Spec
52
51
  run_options.reporter.example_finished(@_proxy.update(description), execution_error)
53
52
  success = execution_error.nil? || ExamplePendingError === execution_error
54
53
  end
54
+
55
+ module BlockAliases
56
+ alias_method :to, :should
57
+ alias_method :to_not, :should_not
58
+ end
59
+
60
+ # Extends the submitted block with aliases to and to_not
61
+ # for should and should_not. Allows expectations like this:
62
+ #
63
+ # expect { this_block }.to change{this.expression}.from(old_value).to(new_value)
64
+ # expect { this_block }.to raise_error
65
+ def expect(&block)
66
+ block.extend BlockAliases
67
+ end
55
68
 
56
69
  def eval_each_fail_fast(blocks) # :nodoc:
57
70
  blocks.each {|block| instance_eval(&block)}
@@ -8,14 +8,13 @@ module Spec
8
8
  @description, @options, @location = description, options, location
9
9
  end
10
10
 
11
+ # Optional hash passed to the example declaration
12
+ attr_reader :options
13
+
11
14
  # This is the docstring passed to the <tt>it()</tt> method or any
12
15
  # of its aliases
13
16
  attr_reader :description
14
17
 
15
- # Internal use only - used to store options to pass to example
16
- # when it is initialized
17
- attr_reader :options # :nodoc:
18
-
19
18
  # The file and line number at which the represented example
20
19
  # was declared. This is extracted from <tt>caller</tt>, and is therefore
21
20
  # formatted as an individual line in a backtrace.
@@ -16,18 +16,18 @@ module Spec
16
16
  # See +ExampleMethods#should+ for more information about this approach.
17
17
  def subject(&block)
18
18
  block.nil? ?
19
- explicit_subject || implicit_subject : @_explicit_subject_block = block
19
+ explicit_subject || implicit_subject : @explicit_subject_block = block
20
20
  end
21
21
 
22
+ attr_reader :explicit_subject_block # :nodoc:
23
+
22
24
  private
23
25
 
24
26
  def explicit_subject
25
- if defined?(@_explicit_subject_block)
26
- @_explicit_subject_block
27
- elsif super_subject = superclass.instance_variable_get('@_explicit_subject_block')
28
- super_subject
29
- else
30
- nil
27
+ group = self
28
+ while group.respond_to?(:explicit_subject_block)
29
+ return group.explicit_subject_block if group.explicit_subject_block
30
+ group = group.superclass
31
31
  end
32
32
  end
33
33
 
@@ -1,8 +1,9 @@
1
+ require 'spec'
2
+
1
3
  if Spec::Ruby.version.to_f >= 1.9
2
4
  gem 'test-unit','1.2.3'
3
5
  end
4
6
 
5
- require 'spec'
6
7
  require 'test/unit'
7
8
  require 'test/unit/testresult'
8
9
 
@@ -10,21 +10,21 @@ module Spec
10
10
  #
11
11
  # result.should be_close(3.0, 0.5)
12
12
  def be_close(expected, delta)
13
- Matcher.new :be_close, expected, delta do |expected, delta|
13
+ Matcher.new :be_close, expected, delta do |_expected_, _delta_|
14
14
  match do |actual|
15
- (actual - expected).abs < delta
15
+ (actual - _expected_).abs < _delta_
16
16
  end
17
17
 
18
18
  failure_message_for_should do |actual|
19
- "expected #{expected} +/- (< #{delta}), got #{actual}"
19
+ "expected #{_expected_} +/- (< #{_delta_}), got #{actual}"
20
20
  end
21
21
 
22
22
  failure_message_for_should_not do |actual|
23
- "expected #{expected} +/- (< #{delta}), got #{actual}"
23
+ "expected #{_expected_} +/- (< #{_delta_}), got #{actual}"
24
24
  end
25
25
 
26
26
  description do
27
- "be close to #{expected} (within +- #{delta})"
27
+ "be close to #{_expected_} (within +- #{_delta_})"
28
28
  end
29
29
  end
30
30
  end
@@ -14,9 +14,9 @@ module Spec
14
14
  # 5.should_not be_instance_of(Numeric)
15
15
  # 5.should_not be_instance_of(Float)
16
16
  def be_an_instance_of(expected)
17
- Matcher.new :be_an_instance_of, expected do |expected|
17
+ Matcher.new :be_an_instance_of, expected do |_expected_|
18
18
  match do |actual|
19
- actual.instance_of?(expected)
19
+ actual.instance_of?(_expected_)
20
20
  end
21
21
  end
22
22
  end
@@ -14,9 +14,9 @@ module Spec
14
14
  # 5.should be_kind_of(Numeric)
15
15
  # 5.should_not be_kind_of(Float)
16
16
  def be_a_kind_of(expected)
17
- Matcher.new :be_a_kind_of, expected do |expected|
17
+ Matcher.new :be_a_kind_of, expected do |_expected_|
18
18
  match do |actual|
19
- actual.kind_of?(expected)
19
+ actual.kind_of?(_expected_)
20
20
  end
21
21
  end
22
22
  end
@@ -1,11 +1,11 @@
1
1
  Spec::Matchers.constants.each do |c|
2
2
  if Class === (klass = Spec::Matchers.const_get(c))
3
- if klass.public_instance_methods.include?('failure_message_for_should')
3
+ if klass.public_instance_methods.any? {|m| ['failure_message_for_should',:failure_message_for_should].include?(m)}
4
4
  klass.class_eval do
5
5
  alias_method :failure_message, :failure_message_for_should
6
6
  end
7
7
  end
8
- if klass.public_instance_methods.include?('failure_message_for_should_not')
8
+ if klass.public_instance_methods.any? {|m| ['failure_message_for_should_not',:failure_message_for_should_not].include?(m)}
9
9
  klass.class_eval do
10
10
  alias_method :negative_failure_message, :failure_message_for_should_not
11
11
  end
@@ -13,15 +13,15 @@ module Spec
13
13
  # 5.should eql(5)
14
14
  # 5.should_not eql(3)
15
15
  def eql(expected)
16
- Matcher.new :eql, expected do |expected|
16
+ Matcher.new :eql, expected do |_expected_|
17
17
  match do |actual|
18
- actual.eql?(expected)
18
+ actual.eql?(_expected_)
19
19
  end
20
20
 
21
21
  failure_message_for_should do |actual|
22
22
  <<-MESSAGE
23
23
 
24
- expected #{expected.inspect}
24
+ expected #{_expected_.inspect}
25
25
  got #{actual.inspect}
26
26
 
27
27
  (compared using eql?)
@@ -31,7 +31,7 @@ MESSAGE
31
31
  failure_message_for_should_not do |actual|
32
32
  <<-MESSAGE
33
33
 
34
- expected #{actual.inspect} not to equal #{expected.inspect}
34
+ expected #{actual.inspect} not to equal #{_expected_.inspect}
35
35
 
36
36
  (compared using eql?)
37
37
  MESSAGE
@@ -14,27 +14,37 @@ module Spec
14
14
  # 5.should equal(5) #Fixnums are equal
15
15
  # "5".should_not equal("5") #Strings that look the same are not the same object
16
16
  def equal(expected)
17
- Matcher.new :equal, expected do |expected|
17
+ Matcher.new :equal, expected do |_expected_|
18
18
  match do |actual|
19
- actual.equal?(expected)
19
+ actual.equal?(_expected_)
20
+ end
21
+
22
+ def inspect_object(o)
23
+ "#<#{o.class}:#{o.object_id}> => #{o.inspect}"
20
24
  end
21
25
 
22
26
  failure_message_for_should do |actual|
23
27
  <<-MESSAGE
24
28
 
25
- expected #{expected.inspect}
26
- got #{actual.inspect}
27
-
28
- (compared using equal?)
29
+ expected #{inspect_object(_expected_)}
30
+ got #{inspect_object(actual)}
31
+
32
+ Compared using equal?, which compares object identity,
33
+ but expected and actual are not the same object. Use
34
+ 'actual.should == expected' if you don't care about
35
+ object identity in this example.
36
+
29
37
  MESSAGE
30
38
  end
31
39
 
32
40
  failure_message_for_should_not do |actual|
33
41
  <<-MESSAGE
34
42
 
35
- expected #{actual.inspect} not to equal #{expected.inspect}
43
+ expected not #{inspect_object(actual)}
44
+ got #{inspect_object(_expected_)}
45
+
46
+ Compared using equal?, which compares object identity.
36
47
 
37
- (compared using equal?)
38
48
  MESSAGE
39
49
  end
40
50
  end
@@ -1,6 +1,4 @@
1
- require 'spec/ruby'
2
-
3
- if ::Spec::Ruby.version < "1.8.7"
1
+ unless respond_to?(:instance_exec)
4
2
  # based on Bounded Spec InstanceExec (Mauricio Fernandez)
5
3
  # http://eigenclass.org/hiki/bounded+space+instance_exec
6
4
  class Object
@@ -17,13 +17,13 @@ module Spec
17
17
  # "spread".should include("read")
18
18
  # "spread".should_not include("red")
19
19
  def include(*expected)
20
- Matcher.new :include, *expected do |*expecteds|
20
+ Matcher.new :include, *expected do |*_expected_|
21
21
  match do |actual|
22
- helper(actual, *expecteds)
22
+ helper(actual, *_expected_)
23
23
  end
24
24
 
25
- def helper(actual, *expecteds)
26
- expecteds.each do |expected|
25
+ def helper(actual, *_expected_)
26
+ _expected_.each do |expected|
27
27
  if actual.is_a?(Hash)
28
28
  if expected.is_a?(Hash)
29
29
  expected.each_pair do |k,v|
@@ -10,9 +10,9 @@ module Spec
10
10
  #
11
11
  # email.should match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
12
12
  def match(expected)
13
- Matcher.new :match, expected do |expected|
13
+ Matcher.new :match, expected do |_expected_|
14
14
  match do |actual|
15
- actual =~ expected
15
+ actual =~ _expected_
16
16
  end
17
17
  end
18
18
  end
@@ -55,8 +55,9 @@ module Spec
55
55
 
56
56
  class PositiveOperatorMatcher < OperatorMatcher #:nodoc:
57
57
  def __delegate_operator(actual, operator, expected)
58
- return true if actual.__send__(operator, expected)
59
- if ['==','===', '=~'].include?(operator)
58
+ if actual.__send__(operator, expected)
59
+ true
60
+ elsif ['==','===', '=~'].include?(operator)
60
61
  fail_with_message("expected: #{expected.inspect},\n got: #{actual.inspect} (using #{operator})")
61
62
  else
62
63
  fail_with_message("expected: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
@@ -17,6 +17,15 @@ module Spec
17
17
  end
18
18
  end
19
19
 
20
+ alias_method :stub, :stub!
21
+
22
+ def stub_chain(*methods)
23
+ while methods.length > 1
24
+ stub!(methods.shift).and_return(self)
25
+ end
26
+ stub!(methods.shift)
27
+ end
28
+
20
29
  def received_message?(sym, *args, &block) #:nodoc:
21
30
  __mock_proxy.received_message?(sym.to_sym, *args, &block)
22
31
  end
@@ -7,12 +7,17 @@ module Spec
7
7
  # only) == Options:
8
8
  # * <tt>:null_object</tt> - if true, the mock object acts as a forgiving
9
9
  # null object allowing any message to be sent to it.
10
- def initialize(name, stubs_and_options={})
11
- @name = name
10
+ def initialize(name='mock', stubs_and_options={})
11
+ if name.is_a?(Hash) && stubs_and_options.empty?
12
+ stubs_and_options = name
13
+ build_name_from_options stubs_and_options
14
+ else
15
+ @name = name
16
+ end
12
17
  @options = parse_options(stubs_and_options)
13
18
  assign_stubs(stubs_and_options)
14
19
  end
15
-
20
+
16
21
  # This allows for comparing the mock to other objects that proxy such as
17
22
  # ActiveRecords belongs_to proxy objects. By making the other object run
18
23
  # the comparison, we're sure the call gets delegated to the proxy
@@ -24,32 +29,37 @@ module Spec
24
29
  def inspect
25
30
  "#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>"
26
31
  end
27
-
32
+
28
33
  def to_s
29
34
  inspect.gsub('<','[').gsub('>',']')
30
35
  end
31
-
32
- private
33
-
34
- def method_missing(sym, *args, &block)
35
- __mock_proxy.record_message_received(sym, args, block)
36
- begin
37
- return self if __mock_proxy.null_object?
38
- super(sym, *args, &block)
39
- rescue NameError
40
- __mock_proxy.raise_unexpected_message_error sym, *args
41
- end
42
- end
43
-
44
- def parse_options(options)
45
- options.has_key?(:null_object) ? {:null_object => options.delete(:null_object)} : {}
36
+
37
+ private
38
+
39
+ def method_missing(sym, *args, &block)
40
+ __mock_proxy.record_message_received(sym, args, block)
41
+ begin
42
+ return self if __mock_proxy.null_object?
43
+ super(sym, *args, &block)
44
+ rescue NameError
45
+ __mock_proxy.raise_unexpected_message_error sym, *args
46
46
  end
47
-
48
- def assign_stubs(stubs)
49
- stubs.each_pair do |message, response|
50
- stub!(message).and_return(response)
51
- end
47
+ end
48
+
49
+ def parse_options(options)
50
+ options.has_key?(:null_object) ? {:null_object => options.delete(:null_object)} : {}
51
+ end
52
+
53
+ def assign_stubs(stubs)
54
+ stubs.each_pair do |message, response|
55
+ stub!(message).and_return(response)
52
56
  end
57
+ end
58
+
59
+ def build_name_from_options(options)
60
+ vals = options.inject([]) {|coll, pair| coll << "#{pair.first}: #{pair.last.inspect}"}
61
+ @name = '{' + vals.join(', ') + '}'
62
+ end
53
63
  end
54
64
  end
55
65
  end
@@ -213,6 +213,7 @@ module Spec
213
213
  end
214
214
 
215
215
  def find_matching_expectation(sym, *args)
216
+ @expectations.find {|expectation| expectation.matches(sym, args) && !expectation.called_max_times?} ||
216
217
  @expectations.find {|expectation| expectation.matches(sym, args)}
217
218
  end
218
219