rspec 1.0.5 → 1.0.6

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 (87) hide show
  1. data/CHANGES +78 -1
  2. data/EXAMPLES.rd +8 -5
  3. data/README +1 -0
  4. data/Rakefile +1 -1
  5. data/examples/pending_example.rb +20 -0
  6. data/lib/autotest/rspec.rb +46 -18
  7. data/lib/spec/dsl.rb +1 -0
  8. data/lib/spec/dsl/behaviour.rb +37 -27
  9. data/lib/spec/dsl/behaviour_callbacks.rb +4 -0
  10. data/lib/spec/dsl/behaviour_eval.rb +27 -16
  11. data/lib/spec/dsl/behaviour_factory.rb +2 -2
  12. data/lib/spec/dsl/composite_proc_builder.rb +9 -4
  13. data/lib/spec/dsl/configuration.rb +20 -4
  14. data/lib/spec/dsl/description.rb +7 -0
  15. data/lib/spec/dsl/errors.rb +9 -0
  16. data/lib/spec/dsl/example.rb +18 -10
  17. data/lib/spec/matchers/have.rb +10 -13
  18. data/lib/spec/matchers/operator_matcher.rb +3 -3
  19. data/lib/spec/matchers/raise_error.rb +8 -3
  20. data/lib/spec/mocks/error_generator.rb +1 -1
  21. data/lib/spec/mocks/message_expectation.rb +11 -0
  22. data/lib/spec/mocks/methods.rb +9 -5
  23. data/lib/spec/mocks/proxy.rb +13 -9
  24. data/lib/spec/rake/spectask.rb +80 -38
  25. data/lib/spec/runner/backtrace_tweaker.rb +2 -1
  26. data/lib/spec/runner/behaviour_runner.rb +37 -16
  27. data/lib/spec/runner/formatter/base_formatter.rb +23 -15
  28. data/lib/spec/runner/formatter/base_text_formatter.rb +39 -11
  29. data/lib/spec/runner/formatter/failing_behaviours_formatter.rb +7 -3
  30. data/lib/spec/runner/formatter/failing_examples_formatter.rb +3 -3
  31. data/lib/spec/runner/formatter/html_formatter.rb +32 -25
  32. data/lib/spec/runner/formatter/progress_bar_formatter.rb +6 -5
  33. data/lib/spec/runner/formatter/rdoc_formatter.rb +6 -6
  34. data/lib/spec/runner/formatter/specdoc_formatter.rb +7 -6
  35. data/lib/spec/runner/option_parser.rb +6 -5
  36. data/lib/spec/runner/options.rb +60 -43
  37. data/lib/spec/runner/reporter.rb +17 -6
  38. data/lib/spec/runner/spec_parser.rb +1 -1
  39. data/lib/spec/translator.rb +8 -0
  40. data/lib/spec/version.rb +3 -3
  41. data/plugins/mock_frameworks/flexmock.rb +14 -18
  42. data/plugins/mock_frameworks/mocha.rb +0 -2
  43. data/plugins/mock_frameworks/rr.rb +21 -0
  44. data/spec/autotest/discover_spec.rb +19 -0
  45. data/spec/autotest/rspec_spec.rb +257 -0
  46. data/spec/autotest_helper.rb +4 -0
  47. data/spec/spec/dsl/behaviour_eval_spec.rb +30 -0
  48. data/spec/spec/dsl/behaviour_factory_spec.rb +18 -0
  49. data/spec/spec/dsl/behaviour_spec.rb +95 -58
  50. data/spec/spec/dsl/composite_proc_builder_spec.rb +0 -13
  51. data/spec/spec/dsl/configuration_spec.rb +6 -1
  52. data/spec/spec/dsl/description_spec.rb +9 -1
  53. data/spec/spec/dsl/example_class_spec.rb +3 -3
  54. data/spec/spec/dsl/example_instance_spec.rb +26 -28
  55. data/spec/spec/dsl/example_matcher_spec.rb +91 -0
  56. data/spec/spec/dsl/shared_behaviour_spec.rb +24 -0
  57. data/spec/spec/expectations/extensions/object_spec.rb +2 -2
  58. data/spec/spec/expectations/fail_with_spec.rb +2 -2
  59. data/spec/spec/matchers/have_spec.rb +1 -1
  60. data/spec/spec/matchers/operator_matcher_spec.rb +10 -10
  61. data/spec/spec/matchers/raise_error_spec.rb +38 -0
  62. data/spec/spec/mocks/argument_expectation_spec.rb +18 -14
  63. data/spec/spec/mocks/at_most_spec.rb +1 -1
  64. data/spec/spec/mocks/bug_report_11545_spec.rb +31 -0
  65. data/spec/spec/mocks/partial_mock_spec.rb +33 -1
  66. data/spec/spec/runner/behaviour_runner_spec.rb +72 -49
  67. data/spec/spec/runner/command_line_spec.rb +1 -1
  68. data/spec/spec/runner/context_matching_spec.rb +10 -10
  69. data/spec/spec/runner/drb_command_line_spec.rb +62 -59
  70. data/spec/spec/runner/extensions/bug_report_10577_spec.rb +35 -0
  71. data/spec/spec/runner/formatter/failing_behaviours_formatter_spec.rb +15 -2
  72. data/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +3 -3
  73. data/spec/spec/runner/formatter/html_formatter_spec.rb +1 -1
  74. data/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb +14 -15
  75. data/spec/spec/runner/formatter/progress_bar_formatter_failure_dump_spec.rb +1 -1
  76. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +42 -9
  77. data/spec/spec/runner/formatter/rdoc_formatter_spec.rb +40 -40
  78. data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +55 -49
  79. data/spec/spec/runner/option_parser_spec.rb +16 -15
  80. data/spec/spec/runner/options_spec.rb +64 -31
  81. data/spec/spec/runner/reporter_spec.rb +67 -15
  82. data/spec/spec/spec_classes.rb +9 -1
  83. data/spec/spec/translator_spec.rb +48 -0
  84. data/spec/spec_helper.rb +5 -2
  85. metadata +13 -6
  86. data/examples/not_yet_implemented_spec.rb +0 -12
  87. data/spec/spec/runner/example_matcher_spec.rb +0 -127
@@ -6,17 +6,17 @@ module Spec
6
6
  @output.puts "# #{name}"
7
7
  end
8
8
 
9
- def example_passed(name)
10
- @output.puts "# * #{name}"
9
+ def example_passed(example)
10
+ @output.puts "# * #{example.description}"
11
11
  @output.flush
12
12
  end
13
13
 
14
- def example_failed(name, counter, failure)
15
- @output.puts "# * #{name} [#{counter} - FAILED]"
14
+ def example_failed(example, counter, failure)
15
+ @output.puts "# * #{example.description} [#{counter} - FAILED]"
16
16
  end
17
17
 
18
- def example_not_implemented(name)
19
- @output.puts "# * #{name} [NOT IMPLEMENTED]"
18
+ def example_pending(behaviour_name, example_name, message)
19
+ @output.puts "# * #{behaviour_name} #{example_name} [PENDING: #{message}]"
20
20
  end
21
21
  end
22
22
  end
@@ -8,18 +8,19 @@ module Spec
8
8
  @output.flush
9
9
  end
10
10
 
11
- def example_failed(name, counter, failure)
12
- @output.puts failure.expectation_not_met? ? red("- #{name} (FAILED - #{counter})") : magenta("- #{name} (ERROR - #{counter})")
11
+ def example_failed(example, counter, failure)
12
+ @output.puts failure.expectation_not_met? ? red("- #{example.description} (FAILED - #{counter})") : magenta("- #{example.description} (ERROR - #{counter})")
13
13
  @output.flush
14
14
  end
15
15
 
16
- def example_passed(name)
17
- @output.puts green("- #{name}")
16
+ def example_passed(example)
17
+ @output.puts green("- #{example.description}")
18
18
  @output.flush
19
19
  end
20
20
 
21
- def example_not_implemented(name)
22
- @output.puts yellow("- #{name} (NOT IMPLEMENTED)")
21
+ def example_pending(behaviour_name, example_name, message)
22
+ super
23
+ @output.puts yellow("- #{example_name} (PENDING: #{message})")
23
24
  @output.flush
24
25
  end
25
26
  end
@@ -89,13 +89,14 @@ module Spec
89
89
  # Some exit points in parse (--generate-options, --drb) don't return the options,
90
90
  # but hand over control. In that case we don't want to continue.
91
91
  return nil unless options.is_a?(Options)
92
- options.create_behaviour_runner
92
+ options.configure
93
+ options.behaviour_runner
93
94
  end
94
95
 
95
96
  def parse(args, err, out, warn_if_no_files)
96
97
  options_file = nil
97
98
  args_copy = args.dup
98
- options = Options.new
99
+ options = Options.new(err, out)
99
100
 
100
101
  opts = ::OptionParser.new do |opts|
101
102
  opts.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]"
@@ -105,7 +106,7 @@ module Spec
105
106
  on(*COMMAND_LINE[name], &block)
106
107
  end
107
108
 
108
- opts.rspec_on(:diff) {|diff| options.parse_diff(diff, out, err)}
109
+ opts.rspec_on(:diff) {|diff| options.parse_diff(diff)}
109
110
 
110
111
  opts.rspec_on(:colour) {options.colour = true}
111
112
 
@@ -115,7 +116,7 @@ module Spec
115
116
 
116
117
  opts.rspec_on(:line) {|line_number| options.line_number = line_number.to_i}
117
118
 
118
- opts.rspec_on(:format) {|format| options.parse_format(format, out, err)}
119
+ opts.rspec_on(:format) {|format| options.parse_format(format)}
119
120
 
120
121
  opts.rspec_on(:require) {|req| options.parse_require(req)}
121
122
 
@@ -140,7 +141,7 @@ module Spec
140
141
  end
141
142
 
142
143
  opts.rspec_on(:runner) do |runner|
143
- options.parse_runner(runner, out, err)
144
+ options.runner_arg = runner
144
145
  end
145
146
 
146
147
  opts.rspec_on(:drb) do
@@ -32,12 +32,14 @@ module Spec
32
32
  :loadby,
33
33
  :reporter,
34
34
  :reverse,
35
- :runner_type,
36
35
  :timeout,
37
- :verbose
36
+ :verbose,
37
+ :runner_arg,
38
+ :behaviour_runner
38
39
  )
39
40
 
40
- def initialize
41
+ def initialize(err, out)
42
+ @err, @out = err, out
41
43
  @backtrace_tweaker = QuietBacktraceTweaker.new
42
44
  @examples = []
43
45
  @formatters = []
@@ -45,29 +47,42 @@ module Spec
45
47
  @dry_run = false
46
48
  end
47
49
 
50
+ def configure
51
+ configure_formatters
52
+ create_reporter
53
+ configure_differ
54
+ create_behaviour_runner
55
+ end
56
+
48
57
  def create_behaviour_runner
58
+ return nil if @generate
59
+ @behaviour_runner = if @runner_arg
60
+ klass_name, arg = split_at_colon(@runner_arg)
61
+ runner_type = load_class(klass_name, 'behaviour runner', '--runner')
62
+ runner_type.new(self, arg)
63
+ else
64
+ BehaviourRunner.new(self)
65
+ end
66
+ end
67
+
68
+ def configure_formatters
49
69
  @formatters.each do |formatter|
50
70
  formatter.colour = @colour if formatter.respond_to?(:colour=)
51
71
  formatter.dry_run = @dry_run if formatter.respond_to?(:dry_run=)
52
72
  end
73
+ end
74
+
75
+ def create_reporter
53
76
  @reporter = Reporter.new(@formatters, @backtrace_tweaker)
77
+ end
54
78
 
55
- # this doesn't really belong here.
56
- # it should, but the way things are coupled, it doesn't
79
+ def configure_differ
57
80
  if @differ_class
58
81
  Spec::Expectations.differ = @differ_class.new(@diff_format, @context_lines, @colour)
59
82
  end
60
-
61
- return nil if @generate
62
-
63
- if @runner_type
64
- @runner_type.new(self)
65
- else
66
- BehaviourRunner.new(self)
67
- end
68
83
  end
69
84
 
70
- def parse_diff(format, out_stream, error_stream)
85
+ def parse_diff(format)
71
86
  @context_lines = 3
72
87
  case format
73
88
  when :context, 'context', 'c'
@@ -80,14 +95,8 @@ module Spec
80
95
  require 'spec/expectations/differs/default'
81
96
  @differ_class = Spec::Expectations::Differs::Default
82
97
  else
83
- begin
84
- @diff_format = :custom
85
- @differ_class = eval(format)
86
- rescue NameError
87
- error_stream.puts "Couldn't find differ class #{format}"
88
- error_stream.puts "Make sure the --require option is specified *before* --diff"
89
- exit if out_stream == $stdout
90
- end
98
+ @diff_format = :custom
99
+ @differ_class = load_class(format, 'differ', '--diff')
91
100
  end
92
101
  end
93
102
 
@@ -99,25 +108,17 @@ module Spec
99
108
  end
100
109
  end
101
110
 
102
- def parse_format(format, out_stream, error_stream)
103
- where = out_stream
111
+ def parse_format(format_arg)
112
+ format, where = split_at_colon(format_arg)
104
113
  # This funky regexp checks whether we have a FILE_NAME or not
105
- if (format =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/) && ($2 != '')
106
- format = $1
107
- where = $2
108
- else
114
+ if where.nil?
109
115
  raise "When using several --format options only one of them can be without a file" if @out_used
116
+ where = @out
110
117
  @out_used = true
111
118
  end
112
119
 
113
- begin
114
- formatter_type = BUILT_IN_FORMATTERS[format] || eval(format)
115
- @formatters << formatter_type.new(where)
116
- rescue NameError
117
- error_stream.puts "Couldn't find formatter class #{format}"
118
- error_stream.puts "Make sure the --require option is specified *before* --format"
119
- exit if out_stream == $stdout
120
- end
120
+ formatter_type = BUILT_IN_FORMATTERS[format] || load_class(format, 'formatter', '--format')
121
+ @formatters << formatter_type.new(where)
121
122
  end
122
123
 
123
124
  def parse_require(req)
@@ -135,7 +136,6 @@ module Spec
135
136
  index = args_copy.index("-G") || args_copy.index("--generate-options")
136
137
  args_copy.delete_at(index)
137
138
  args_copy.delete_at(index)
138
-
139
139
  File.open(options_file, 'w') do |io|
140
140
  io.puts args_copy.join("\n")
141
141
  end
@@ -144,13 +144,30 @@ module Spec
144
144
  @generate = true
145
145
  end
146
146
 
147
- def parse_runner(runner, out_stream, error_stream)
147
+ def split_at_colon(s)
148
+ if s =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/
149
+ arg = $2 == "" ? nil : $2
150
+ [$1, arg]
151
+ else
152
+ raise "Couldn't parse #{s.inspect}"
153
+ end
154
+ end
155
+
156
+ def load_class(name, kind, option)
157
+ if name =~ /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/
158
+ arg = $2 == "" ? nil : $2
159
+ [$1, arg]
160
+ else
161
+ m = "#{name.inspect} is not a valid class name"
162
+ @err.puts m
163
+ raise m
164
+ end
148
165
  begin
149
- @runner_type = eval(runner)
150
- rescue NameError
151
- error_stream.puts "Couldn't find behaviour runner class #{runner}"
152
- error_stream.puts "Make sure the --require option is specified."
153
- exit if out_stream == $stdout
166
+ eval(name, binding, __FILE__, __LINE__)
167
+ rescue NameError => e
168
+ @err.puts "Couldn't find #{kind} class #{name}"
169
+ @err.puts "Make sure the --require option is specified *before* #{option}"
170
+ if $_spec_spec ; raise e ; else exit(1) ; end
154
171
  end
155
172
  end
156
173
  end
@@ -21,9 +21,11 @@ module Spec
21
21
  @example_names << name
22
22
 
23
23
  if not_implemented
24
- example_not_implemented(name)
24
+ example_pending(@behaviour_names.last, name)
25
25
  elsif error.nil?
26
26
  example_passed(name)
27
+ elsif Spec::DSL::ExamplePendingError === error
28
+ example_pending(@behaviour_names.last, name, error.message)
27
29
  else
28
30
  example_failed(name, error, failure_location)
29
31
  end
@@ -43,7 +45,10 @@ module Spec
43
45
  def dump
44
46
  @formatters.each{|f| f.start_dump}
45
47
  dump_failures
46
- @formatters.each{|f| f.dump_summary(duration, @example_names.length, @failures.length, @not_implemented_count)}
48
+ @formatters.each do |f|
49
+ f.dump_summary(duration, @example_names.length, @failures.length, @pending_count)
50
+ f.close
51
+ end
47
52
  @failures.length
48
53
  end
49
54
 
@@ -52,7 +57,7 @@ module Spec
52
57
  def clear!
53
58
  @behaviour_names = []
54
59
  @failures = []
55
- @not_implemented_count = 0
60
+ @pending_count = 0
56
61
  @example_names = []
57
62
  @start_time = nil
58
63
  @end_time = nil
@@ -83,9 +88,9 @@ module Spec
83
88
  @formatters.each{|f| f.example_failed(name, @failures.length, failure)}
84
89
  end
85
90
 
86
- def example_not_implemented(name)
87
- @not_implemented_count += 1
88
- @formatters.each{|f| f.example_not_implemented(name)}
91
+ def example_pending(behaviour_name, example_name, message="Not Yet Implemented")
92
+ @pending_count += 1
93
+ @formatters.each{|f| f.example_pending(behaviour_name, example_name, message)}
89
94
  end
90
95
 
91
96
  class Failure
@@ -99,11 +104,17 @@ module Spec
99
104
  def header
100
105
  if expectation_not_met?
101
106
  "'#{@example_name}' FAILED"
107
+ elsif pending_fixed?
108
+ "'#{@example_name}' FIXED"
102
109
  else
103
110
  "#{@exception.class.name} in '#{@example_name}'"
104
111
  end
105
112
  end
106
113
 
114
+ def pending_fixed?
115
+ @exception.is_a?(Spec::DSL::PendingFixedError)
116
+ end
117
+
107
118
  def expectation_not_met?
108
119
  @exception.is_a?(Spec::Expectations::ExpectationNotMetError)
109
120
  end
@@ -35,7 +35,7 @@ module Spec
35
35
 
36
36
  def lines_above_reversed(source, line_number)
37
37
  lines = source.split("\n")
38
- lines[0...line_number].reverse
38
+ lines[0...line_number].reverse
39
39
  end
40
40
 
41
41
  def parse_description(str)
@@ -34,6 +34,14 @@ module Spec
34
34
  end
35
35
 
36
36
  def translate_line(line)
37
+ # Translate deprecated mock constraints
38
+ line.gsub!(/:any_args/, 'any_args')
39
+ line.gsub!(/:anything/, 'anything')
40
+ line.gsub!(/:boolean/, 'boolean')
41
+ line.gsub!(/:no_args/, 'no_args')
42
+ line.gsub!(/:numeric/, 'an_instance_of(Numeric)')
43
+ line.gsub!(/:string/, 'an_instance_of(String)')
44
+
37
45
  return line if line =~ /(should_not|should)_receive/
38
46
 
39
47
  line.gsub!(/(^\s*)context([\s*|\(]['|"|A-Z])/, '\1describe\2')
data/lib/spec/version.rb CHANGED
@@ -3,11 +3,11 @@ module Spec
3
3
  unless defined? MAJOR
4
4
  MAJOR = 1
5
5
  MINOR = 0
6
- TINY = 5
6
+ TINY = 6
7
7
  RELEASE_CANDIDATE = nil
8
8
 
9
- # RANDOM_TOKEN: 0.956731547671535
10
- REV = "$LastChangedRevision: 2081 $".match(/LastChangedRevision: (\d+)/)[1]
9
+ # RANDOM_TOKEN: 0.450848541683348
10
+ REV = "$LastChangedRevision: 2326 $".match(/LastChangedRevision: (\d+)/)[1]
11
11
 
12
12
  STRING = [MAJOR, MINOR, TINY].join('.')
13
13
  TAG = "REL_#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('_')}".upcase.gsub(/\.|-/, '_')
@@ -3,25 +3,21 @@
3
3
  # Created by Jim Weirich on 2007-04-10.
4
4
  # Copyright (c) 2007. All rights reserved.
5
5
 
6
- begin
7
- require 'rubygems'
8
- rescue LoadError => ex
9
- end
10
6
  require 'flexmock/rspec'
11
7
 
12
8
  module Spec
13
- module Plugins
14
- module MockFramework
15
- include FlexMock::MockContainer
16
- def setup_mocks_for_rspec
17
- # No setup required
18
- end
19
- def verify_mocks_for_rspec
20
- flexmock_verify
21
- end
22
- def teardown_mocks_for_rspec
23
- flexmock_close
24
- end
25
- end
26
- end
9
+ module Plugins
10
+ module MockFramework
11
+ include FlexMock::MockContainer
12
+ def setup_mocks_for_rspec
13
+ # No setup required
14
+ end
15
+ def verify_mocks_for_rspec
16
+ flexmock_verify
17
+ end
18
+ def teardown_mocks_for_rspec
19
+ flexmock_close
20
+ end
21
+ end
22
+ end
27
23
  end
@@ -1,5 +1,3 @@
1
- require 'rubygems'
2
- gem 'mocha'
3
1
  require 'mocha/standalone'
4
2
  require 'mocha/object'
5
3
 
@@ -0,0 +1,21 @@
1
+ require 'rr'
2
+
3
+ patterns = ::Spec::Runner::QuietBacktraceTweaker::IGNORE_PATTERNS
4
+ patterns.push(RR::Errors::BACKTRACE_IDENTIFIER)
5
+
6
+ module Spec
7
+ module Plugins
8
+ module MockFramework
9
+ include RR::Extensions::InstanceMethods
10
+ def setup_mocks_for_rspec
11
+ RR::Space.instance.reset
12
+ end
13
+ def verify_mocks_for_rspec
14
+ RR::Space.instance.verify_doubles
15
+ end
16
+ def teardown_mocks_for_rspec
17
+ RR::Space.instance.reset
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + "/../autotest_helper"
2
+
3
+ module DiscoveryHelper
4
+ def load_discovery
5
+ require File.dirname(__FILE__) + "/../../lib/autotest/discover"
6
+ end
7
+ end
8
+
9
+
10
+ class Autotest
11
+ describe Rspec, "discovery" do
12
+ include DiscoveryHelper
13
+
14
+ it "should add the rspec autotest plugin" do
15
+ Autotest.should_receive(:add_discovery).and_yield
16
+ load_discovery
17
+ end
18
+ end
19
+ end