rspec 1.2.4 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
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