rspec 1.1.1 → 1.1.2

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 (36) hide show
  1. data/CHANGES +16 -1
  2. data/README +2 -3
  3. data/Rakefile +0 -1
  4. data/bin/spec +1 -0
  5. data/examples/pure/helper_method_example.rb +9 -6
  6. data/lib/autotest/rspec.rb +17 -23
  7. data/lib/spec/example/example_methods.rb +9 -8
  8. data/lib/spec/matchers.rb +1 -7
  9. data/lib/spec/matchers/be.rb +3 -2
  10. data/lib/spec/matchers/have.rb +3 -0
  11. data/lib/spec/mocks/message_expectation.rb +10 -3
  12. data/lib/spec/runner/formatter/story/html_formatter.rb +3 -2
  13. data/lib/spec/runner/formatter/story/plain_text_formatter.rb +11 -6
  14. data/lib/spec/story/extensions.rb +2 -0
  15. data/lib/spec/story/extensions/regexp.rb +9 -0
  16. data/lib/spec/story/extensions/string.rb +9 -0
  17. data/lib/spec/story/runner/story_parser.rb +8 -8
  18. data/lib/spec/story/runner/story_runner.rb +2 -1
  19. data/lib/spec/story/step.rb +10 -2
  20. data/lib/spec/version.rb +2 -2
  21. data/spec/autotest/rspec_spec.rb +11 -11
  22. data/spec/spec/example/example_methods_spec.rb +16 -0
  23. data/spec/spec/interop/test/unit/test_unit_spec_helper.rb +1 -1
  24. data/spec/spec/interop/test/unit/testcase_spec.rb +1 -1
  25. data/spec/spec/interop/test/unit/testsuite_adapter_spec.rb +1 -1
  26. data/spec/spec/matchers/have_spec.rb +19 -0
  27. data/spec/spec/matchers/match_spec.rb +3 -3
  28. data/spec/spec/runner/formatter/story/html_formatter_spec.rb +5 -0
  29. data/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb +50 -4
  30. data/spec/spec/spec_classes.rb +3 -0
  31. data/spec/spec/story/runner/story_runner_spec.rb +37 -0
  32. data/spec/spec/story/step_spec.rb +31 -0
  33. data/stories/example_groups/autogenerated_docstrings +27 -8
  34. data/stories/example_groups/output +5 -0
  35. data/stories/resources/stories/failing_story.rb +15 -0
  36. metadata +9 -5
data/CHANGES CHANGED
@@ -1,3 +1,18 @@
1
+ == Version 1.1.2
2
+
3
+ Minor bug fixes/enhancements.
4
+
5
+ * RSpec's Autotest subclasses compatible with ZenTest-3.8.0 (thanks to Ryan Davis for making it easier on Autotest subs).
6
+ * Applied patch from idl to add spec/lib to rake stats. Closes #226.
7
+ * calling setup_fixtures and teardown_fixtures for Rails >= r8570. Closes #219.
8
+ * Applied patch from Josh Knowles using ActiveSupport's Inflector (when available) to make 'should have' read a bit better. Closes #197.
9
+ * Fixed regression in 1.1 that caused failing examples to fail to generate their own names. Closes #209.
10
+ * Applied doc patch from Jens Krämer for capturing content_for
11
+ * Applied patch from Alexander Lang to clean up story steps after each story. Closes #198.
12
+ * Applied patch from Josh Knowles to support 'string_or_response.should have_text(...)'. Closes #193.
13
+ * Applied patch from Ian Dees to quiet the Story Runner backtrace. Closes #183.
14
+ * Complete support for defining steps with regexp 'names'.
15
+
1
16
  == Version 1.1.1
2
17
 
3
18
  Bug fix release.
@@ -12,7 +27,7 @@ The "tell me a story and go nest yourself" release.
12
27
  * Applied patch from Mike Vincent to handle generators rails > 2.0.1. Closes LH[#181]
13
28
  * Formatter.pending signature changed so it gets passed an ExampleGroup instance instead of the name ( LH[#180])
14
29
  * Fixed LH[#180] Spec::Rails::Example::ModelExampleGroup and friends show up in rspec/rails output
15
- * Spec::Rails no longer loads ActiveRecord extensions if it's disablet in config/boot.rb
30
+ * Spec::Rails no longer loads ActiveRecord extensions if it's disabled in config/boot.rb
16
31
  * Applied LH[#178] small annoyances running specs with warnings enabled (Patch from Mikko Lehtonen)
17
32
  * Tighter integration with Rails fixtures. Take advantage of fixture caching to get performance improvements (Thanks to Pat Maddox, Nick Kallen, Jonathan Barnes, and Curtis)
18
33
 
data/README CHANGED
@@ -38,9 +38,8 @@ In order to run RSpec's full suite of specs (rake pre_commit) you must install t
38
38
 
39
39
  * rake # Runs the build script
40
40
  * rcov # Verifies that the code is 100% covered by specs
41
- * webgen # Generates the static HTML website
42
- * RedCloth # Required by webgen
43
- * syntax # Required by our own custom webgen extension to highlight ruby code
41
+ * webby # Generates the static HTML website
42
+ * syntax # Required to highlight ruby code
44
43
  * diff-lcs # Required if you use the --diff switch
45
44
  * win32console # Required by the --colour switch if you're on Windows
46
45
  * meta_project # Required in order to make releases at RubyForge
data/Rakefile CHANGED
@@ -87,7 +87,6 @@ spec = Gem::Specification.new do |s|
87
87
  s.rdoc_options = rd.options
88
88
  s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$|^EXAMPLES.rd$/ }.to_a
89
89
 
90
- s.autorequire = 'spec'
91
90
  s.bindir = 'bin'
92
91
  s.executables = ['spec', 'spec_translator']
93
92
  s.default_executable = 'spec'
data/bin/spec CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
2
3
  require 'spec'
3
4
  exit ::Spec::Runner::CommandLine.run(rspec_options)
@@ -1,11 +1,14 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- describe "a context with helper a method" do
4
- def helper_method
5
- "received call"
6
- end
3
+ module HelperMethodExample
4
+ describe "an example group with helper a method" do
5
+ def helper_method
6
+ "received call"
7
+ end
7
8
 
8
- it "should make that method available to specs" do
9
- helper_method.should == "received call"
9
+ it "should make that method available to specs" do
10
+ helper_method.should == "received call"
11
+ end
10
12
  end
11
13
  end
14
+
@@ -1,30 +1,24 @@
1
1
  require 'autotest'
2
2
 
3
+ Autotest.add_hook :initialize do |at|
4
+ at.clear_mappings
5
+ # watch out: Ruby bug (1.8.6):
6
+ # %r(/) != /\//
7
+ at.add_mapping(%r%^spec/.*\.rb$%) { |filename, _|
8
+ filename
9
+ }
10
+ at.add_mapping(%r%^lib/(.*)\.rb$%) { |_, m|
11
+ ["spec/#{m[1]}_spec.rb"]
12
+ }
13
+ at.add_mapping(%r%^spec/(spec_helper|shared/.*)\.rb$%) {
14
+ at.files_matching %r%^spec/.*_spec\.rb$%
15
+ }
16
+ end
17
+
3
18
  class RspecCommandError < StandardError; end
4
19
 
5
20
  class Autotest::Rspec < Autotest
6
21
 
7
- def initialize(kernel=Kernel, separator=File::SEPARATOR, alt_separator=File::ALT_SEPARATOR) # :nodoc:
8
- super()
9
- @kernel, @separator, @alt_separator = kernel, separator, alt_separator
10
- @spec_command = spec_command
11
-
12
- # watch out: Ruby bug (1.8.6):
13
- # %r(/) != /\//
14
- # since Ruby compares the REGEXP source, not the resulting pattern
15
- @test_mappings = {
16
- %r%^spec/.*\.rb$% => kernel.proc { |filename, _|
17
- filename
18
- },
19
- %r%^lib/(.*)\.rb$% => kernel.proc { |_, m|
20
- ["spec/#{m[1]}_spec.rb"]
21
- },
22
- %r%^spec/(spec_helper|shared/.*)\.rb$% => kernel.proc {
23
- files_matching %r%^spec/.*_spec\.rb$%
24
- }
25
- }
26
- end
27
-
28
22
  def tests_for_file(filename)
29
23
  super.select { |f| @files.has_key? f }
30
24
  end
@@ -59,7 +53,7 @@ class Autotest::Rspec < Autotest
59
53
  end
60
54
 
61
55
  def make_test_cmd(files_to_test)
62
- return "#{ruby} -S #{@spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}"
56
+ return "#{ruby} -S #{spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}"
63
57
  end
64
58
 
65
59
  def add_options_if_present
@@ -71,7 +65,7 @@ class Autotest::Rspec < Autotest
71
65
  # that in ~/.autotest to provide a different spec command
72
66
  # then the default paths provided.
73
67
  def spec_command
74
- spec_commands.each do |command|
68
+ @spec_command ||= spec_commands.each do |command|
75
69
  if File.exists?(command)
76
70
  return @alt_separator ? (command.gsub @separator, @alt_separator) : command
77
71
  end
@@ -64,21 +64,22 @@ module Spec
64
64
  @_defined_description || @_matcher_description || "NO NAME"
65
65
  end
66
66
 
67
- def set_instance_variables_from_hash(instance_variables)
68
- instance_variables.each do |variable_name, value|
69
- unless ['@_implementation', '@_defined_description', '@_matcher_description', '@method_name'].index(variable_name)
67
+ def set_instance_variables_from_hash(ivars)
68
+ ivars.each do |variable_name, value|
69
+ # Ruby 1.9 requires variable.to_s on the next line
70
+ unless ['@_implementation', '@_defined_description', '@_matcher_description', '@method_name'].include?(variable_name.to_s)
70
71
  instance_variable_set variable_name, value
71
72
  end
72
73
  end
73
74
  end
74
75
 
75
76
  def run_with_description_capturing
76
- return_value = nil
77
-
78
- @_matcher_description = Matchers.capture_generated_description do
79
- return_value = instance_eval(&(@_implementation || PENDING_EXAMPLE_BLOCK))
77
+ begin
78
+ return instance_eval(&(@_implementation || PENDING_EXAMPLE_BLOCK))
79
+ ensure
80
+ @_matcher_description = Spec::Matchers.generated_description
81
+ Spec::Matchers.clear_generated_description
80
82
  end
81
- return_value
82
83
  end
83
84
 
84
85
  protected
@@ -139,14 +139,8 @@ module Spec
139
139
  def clear_generated_description
140
140
  self.generated_description = nil
141
141
  end
142
-
143
- def capture_generated_description
144
- yield
145
- description = generated_description
146
- clear_generated_description
147
- description
148
- end
149
142
  end
143
+
150
144
  extend ModuleMethods
151
145
 
152
146
  def method_missing(sym, *args, &block) # :nodoc:
@@ -124,8 +124,9 @@ module Spec
124
124
  def parse_expected(expected)
125
125
  if Symbol === expected
126
126
  @handling_predicate = true
127
- ["be_an_","be_a_","be_"].each do |@prefix|
128
- if expected.starts_with?(@prefix)
127
+ ["be_an_","be_a_","be_"].each do |prefix|
128
+ if expected.starts_with?(prefix)
129
+ @prefix = prefix
129
130
  return "#{expected.to_s.sub(@prefix,"")}".to_sym
130
131
  end
131
132
  end
@@ -17,6 +17,7 @@ module Spec
17
17
 
18
18
  def method_missing(sym, *args, &block)
19
19
  @collection_name = sym
20
+ @plural_collection_name = Inflector.pluralize(sym.to_s) if Object.const_defined?(:Inflector)
20
21
  @args = args
21
22
  @block = block
22
23
  self
@@ -25,6 +26,8 @@ module Spec
25
26
  def matches?(collection_owner)
26
27
  if collection_owner.respond_to?(@collection_name)
27
28
  collection = collection_owner.send(@collection_name, *@args, &@block)
29
+ elsif (@plural_collection_name && collection_owner.respond_to?(@plural_collection_name))
30
+ collection = collection_owner.send(@plural_collection_name, *@args, &@block)
28
31
  elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size))
29
32
  collection = collection_owner
30
33
  else
@@ -39,6 +39,8 @@ module Spec
39
39
  @expected_received_count < values.size
40
40
  end
41
41
  @return_block = block_given? ? return_block : lambda { value }
42
+ # Ruby 1.9 - see where this is used below
43
+ @ignore_args = !block_given?
42
44
  end
43
45
 
44
46
  # :call-seq:
@@ -128,9 +130,14 @@ module Spec
128
130
 
129
131
  def invoke_return_block(args, block)
130
132
  args << block unless block.nil?
131
- value = @return_block.call(*args)
132
-
133
- value
133
+ # Ruby 1.9 - when we set @return_block to return values
134
+ # regardless of arguments, any arguments will result in
135
+ # a "wrong number of arguments" error
136
+ if @ignore_args
137
+ @return_block.call()
138
+ else
139
+ @return_block.call(*args)
140
+ end
134
141
  end
135
142
  end
136
143
 
@@ -112,11 +112,12 @@ EOF
112
112
 
113
113
  def print_step(klass, type, description, *args)
114
114
  spans = args.map { |arg| "<span class=\"param\">#{arg}</span>" }
115
+ desc_string = description.step_name
116
+ arg_regexp = description.arg_regexp
115
117
  i = -1
116
- inner = type.to_s.capitalize + ' ' + description.gsub(::Spec::Story::Step::PARAM_PATTERN) { |param| spans[i+=1] }
118
+ inner = type.to_s.capitalize + ' ' + desc_string.gsub(arg_regexp) { |param| spans[i+=1] }
117
119
  @output.puts " <li class=\"#{klass}\">#{inner}</li>"
118
120
  end
119
-
120
121
  end
121
122
  end
122
123
  end
@@ -20,6 +20,7 @@ module Spec
20
20
  end
21
21
 
22
22
  def story_started(title, narrative)
23
+ @current_story_title = title
23
24
  @output.puts "Story: #{title}\n\n"
24
25
  narrative.each_line do |line|
25
26
  @output.print " "
@@ -33,6 +34,7 @@ module Spec
33
34
  end
34
35
 
35
36
  def scenario_started(story_title, scenario_name)
37
+ @current_scenario_name = scenario_name
36
38
  @scenario_already_failed = false
37
39
  @output.print "\n\n Scenario: #{scenario_name}"
38
40
  @scenario_ok = true
@@ -43,12 +45,12 @@ module Spec
43
45
  end
44
46
 
45
47
  def scenario_failed(story_title, scenario_name, err)
48
+ @options.backtrace_tweaker.tweak_backtrace(err)
46
49
  @failed_scenarios << [story_title, scenario_name, err] unless @scenario_already_failed
47
50
  @scenario_already_failed = true
48
51
  end
49
52
 
50
53
  def scenario_pending(story_title, scenario_name, msg)
51
- @pending_steps << [story_title, scenario_name, msg]
52
54
  @pending_scenario_count += 1 unless @scenario_already_failed
53
55
  @scenario_already_failed = true
54
56
  end
@@ -58,8 +60,8 @@ module Spec
58
60
  unless @pending_steps.empty?
59
61
  @output.puts "\nPending Steps:"
60
62
  @pending_steps.each_with_index do |pending, i|
61
- title, scenario_name, msg = pending
62
- @output.puts "#{i+1}) #{title} (#{scenario_name}): #{msg}"
63
+ story_name, scenario_name, msg = pending
64
+ @output.puts "#{i+1}) #{story_name} (#{scenario_name}): #{msg}"
63
65
  end
64
66
  end
65
67
  unless @failed_scenarios.empty?
@@ -70,9 +72,9 @@ module Spec
70
72
  #{i+1}) #{title} (#{scenario_name}) FAILED
71
73
  #{err.class}: #{err.message}
72
74
  #{err.backtrace.join("\n")}
73
- ]
75
+ ]
74
76
  end
75
- end
77
+ end
76
78
  end
77
79
 
78
80
  def step_succeeded(type, description, *args)
@@ -81,6 +83,7 @@ module Spec
81
83
 
82
84
  def step_pending(type, description, *args)
83
85
  found_step(type, description, false, *args)
86
+ @pending_steps << [@current_story_title, @current_scenario_name, description]
84
87
  @output.print " (PENDING)"
85
88
  @scenario_ok = false
86
89
  end
@@ -101,13 +104,15 @@ module Spec
101
104
  private
102
105
 
103
106
  def found_step(type, description, failed, *args)
107
+ desc_string = description.step_name
108
+ arg_regexp = description.arg_regexp
104
109
  text = if(type == @previous_type)
105
110
  "\n And "
106
111
  else
107
112
  "\n\n #{type.to_s.capitalize} "
108
113
  end
109
114
  i = -1
110
- text << description.gsub(::Spec::Story::Step::PARAM_PATTERN) { |param| args[i+=1] }
115
+ text << desc_string.gsub(arg_regexp) { |param| args[i+=1] }
111
116
  @output.print(failed ? red(text) : green(text))
112
117
 
113
118
  if type == :'given scenario'
@@ -1 +1,3 @@
1
1
  require 'spec/story/extensions/main'
2
+ require 'spec/story/extensions/string'
3
+ require 'spec/story/extensions/regexp'
@@ -0,0 +1,9 @@
1
+ class Regexp
2
+ def step_name
3
+ self.source
4
+ end
5
+
6
+ def arg_regexp
7
+ ::Spec::Story::Step::PARAM_OR_GROUP_PATTERN
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class String
2
+ def step_name
3
+ self
4
+ end
5
+
6
+ def arg_regexp
7
+ ::Spec::Story::Step::PARAM_PATTERN
8
+ end
9
+ end
@@ -26,14 +26,14 @@ module Spec
26
26
  def process_line(line)
27
27
  line.strip!
28
28
  case line
29
- when /^Story: / : @state.story(line)
30
- when /^Scenario: / : @state.scenario(line)
31
- when /^Given:? / : @state.given(line)
32
- when /^GivenScenario:? / : @state.given_scenario(line)
33
- when /^When:? / : @state.event(line)
34
- when /^Then:? / : @state.outcome(line)
35
- when /^And:? / : @state.one_more_of_the_same(line)
36
- else @state.other(line)
29
+ when /^Story: / then @state.story(line)
30
+ when /^Scenario: / then @state.scenario(line)
31
+ when /^Given:? / then @state.given(line)
32
+ when /^GivenScenario:? / then @state.given_scenario(line)
33
+ when /^When:? / then @state.event(line)
34
+ when /^Then:? / then @state.outcome(line)
35
+ when /^And:? / then @state.one_more_of_the_same(line)
36
+ else @state.other(line)
37
37
  end
38
38
  end
39
39
 
@@ -48,8 +48,9 @@ module Spec
48
48
  @scenario_runner.run(scenario, world)
49
49
  end
50
50
  @listeners.each { |l| l.story_ended(story.title, story.narrative) }
51
+ World.step_mother.clear
51
52
  end
52
- unique_steps = World.step_names.uniq.sort
53
+ unique_steps = (World.step_names.collect {|n| Regexp === n ? n.source : n.to_s}).uniq.sort
53
54
  @listeners.each { |l| l.collected_steps(unique_steps) }
54
55
  @listeners.each { |l| l.run_ended }
55
56
  end
@@ -2,6 +2,7 @@ module Spec
2
2
  module Story
3
3
  class Step
4
4
  PARAM_PATTERN = /(\$\w*)/
5
+ PARAM_OR_GROUP_PATTERN = /(\$\w*)|\(.*?\)/
5
6
 
6
7
  attr_reader :name
7
8
  def initialize(name, &block)
@@ -12,14 +13,21 @@ module Spec
12
13
 
13
14
  def perform(instance, *args)
14
15
  instance.extend(@mod)
15
- instance.__send__(@name, *args)
16
+ instance.__send__(sanitize(@name), *args)
16
17
  end
17
18
 
18
19
  def init_module(name, &block)
20
+ sanitized_name = sanitize(name)
19
21
  @mod = Module.new do
20
- define_method(name.to_s, &block)
22
+ define_method(sanitized_name, &block)
21
23
  end
22
24
  end
25
+
26
+ def sanitize(a_string_or_regexp)
27
+ return a_string_or_regexp.source if Regexp == a_string_or_regexp
28
+ a_string_or_regexp.to_s
29
+ end
30
+
23
31
 
24
32
  def matches?(name)
25
33
  !(matches = name.match(@expression)).nil?
@@ -3,10 +3,10 @@ module Spec
3
3
  unless defined? MAJOR
4
4
  MAJOR = 1
5
5
  MINOR = 1
6
- TINY = 1
6
+ TINY = 2
7
7
  RELEASE_CANDIDATE = nil
8
8
 
9
- BUILD_TIME_UTC = 20071217181808
9
+ BUILD_TIME_UTC = 20080114022430
10
10
 
11
11
  STRING = [MAJOR, MINOR, TINY].join('.')
12
12
  TAG = "REL_#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('_')}".upcase.gsub(/\.|-/, '_')
@@ -51,7 +51,7 @@ HERE
51
51
 
52
52
  before :each do
53
53
  common_setup
54
- @rspec_autotest = Rspec.new(@kernel)
54
+ @rspec_autotest = Rspec.new
55
55
  end
56
56
 
57
57
  it "should try to find the spec command if it exists in ./bin and use it above everything else" do
@@ -88,7 +88,8 @@ HERE
88
88
  end
89
89
 
90
90
  it "should use the ALT_SEPARATOR if it is non-nil" do
91
- @rspec_autotest = Rspec.new(@kernel, @posix_separator, @windows_alt_separator)
91
+ pending("autotest got re-worked so this is failing for the moment")
92
+ @rspec_autotest = Rspec.new
92
93
  spec_command = File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec")
93
94
  @rspec_autotest.stub!(:spec_commands).and_return [spec_command]
94
95
  @rspec_autotest.spec_command.should == spec_command.gsub('/', '\\')
@@ -96,7 +97,7 @@ HERE
96
97
 
97
98
  it "should not use the ALT_SEPATOR if it is nil" do
98
99
  @windows_alt_separator = nil
99
- @rspec_autotest = Rspec.new(@kernel, @posix_separator, @windows_alt_separator)
100
+ @rspec_autotest = Rspec.new
100
101
  spec_command = File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec")
101
102
  @rspec_autotest.stub!(:spec_commands).and_return [spec_command]
102
103
  @rspec_autotest.spec_command.should == spec_command
@@ -144,22 +145,20 @@ HERE
144
145
 
145
146
  describe Rspec, "test mappings" do
146
147
  before :each do
147
- @proc = mock Proc
148
- @kernel = mock Kernel
149
- @kernel.stub!(:proc).and_return @proc
150
- @rspec_autotest = Rspec.new(@kernel)
148
+ @rspec_autotest = Rspec.new
149
+ @rspec_autotest.hook :initialize
151
150
  end
152
151
 
153
152
  it "should map all filenames in spec/ which end in .rb" do
154
- @rspec_autotest.test_mappings[%r%^spec/.*\.rb$%].should == @proc
153
+ @rspec_autotest.instance_eval{@test_mappings}.should have_key(%r%^spec/.*\.rb$%)
155
154
  end
156
155
 
157
156
  it "should map all names in lib which end in .rb to the corresponding ones in spec/" do
158
- @rspec_autotest.test_mappings[%r%^lib/(.*)\.rb$%].should == @proc
157
+ @rspec_autotest.instance_eval{@test_mappings}.should have_key(%r%^lib/(.*)\.rb$%)
159
158
  end
160
159
 
161
160
  it "should find all files in spec/shares/* and the spec helper in spec/spec_helper" do
162
- @rspec_autotest.test_mappings[%r%^spec/(spec_helper|shared/.*)\.rb$%].should == @proc
161
+ @rspec_autotest.instance_eval{@test_mappings}.should have_key(%r%^spec/(spec_helper|shared/.*)\.rb$%)
163
162
  end
164
163
  end
165
164
 
@@ -168,7 +167,7 @@ HERE
168
167
 
169
168
  before :each do
170
169
  common_setup
171
- @rspec_autotest = Rspec.new(@kernel, @posix_separator, @windows_alt_separator)
170
+ @rspec_autotest = Rspec.new
172
171
  @rspec_autotest.stub!(:hook)
173
172
 
174
173
  @results = mock String
@@ -214,6 +213,7 @@ HERE
214
213
  @lib_file = "lib/something.rb"
215
214
  @spec_file = "spec/something_spec.rb"
216
215
  @rspec_autotest = Rspec.new
216
+ @rspec_autotest.hook :initialize
217
217
 
218
218
  @rspec_autotest.instance_variable_set("@files", {@lib_file => Time.now, @spec_file => Time.now})
219
219
  @rspec_autotest.stub!(:find_files_to_test).and_return true
@@ -70,6 +70,22 @@ module Spec
70
70
  @example_group.run
71
71
  ExampleMethods.count.should == 5
72
72
  end
73
+
74
+ describe "run_with_description_capturing" do
75
+ before(:each) do
76
+ @example_group = Class.new(ExampleGroup) do end
77
+ @example = @example_group.new("foo", &(lambda { 2.should == 2 }))
78
+ @example.run_with_description_capturing
79
+ end
80
+
81
+ it "should provide the generated description" do
82
+ @example.instance_eval { @_matcher_description }.should == "should == 2"
83
+ end
84
+
85
+ it "should clear the global generated_description" do
86
+ Spec::Matchers.generated_description.should == nil
87
+ end
88
+ end
73
89
  end
74
90
  end
75
91
  end
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../../../../spec_helper'
2
2
  require File.dirname(__FILE__) + '/../../../../ruby_forker'
3
3
 
4
- describe "Test::Unit interop", :shared => true do
4
+ module TestUnitSpecHelper
5
5
  include RubyForker
6
6
 
7
7
  def run_script(file_name)
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/test_unit_spec_helper'
2
2
 
3
3
  describe "Test::Unit::TestCase" do
4
- it_should_behave_like "Test::Unit interop"
4
+ include TestUnitSpecHelper
5
5
  it "should pass" do
6
6
  dir = File.dirname(__FILE__)
7
7
  output = run_script("#{dir}/testcase_spec_with_test_unit.rb")
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/test_unit_spec_helper'
2
2
 
3
3
  describe "TestSuiteAdapter" do
4
- it_should_behave_like "Test::Unit interop"
4
+ include TestUnitSpecHelper
5
5
  it "should pass" do
6
6
  dir = File.dirname(__FILE__)
7
7
  run_script "#{dir}/testsuite_adapter_spec_with_test_unit.rb"
@@ -47,6 +47,25 @@ describe "should have(n).items" do
47
47
  end
48
48
  end
49
49
 
50
+ describe 'should have(1).item when Inflector is defined' do
51
+ include HaveSpecHelper
52
+
53
+ before do
54
+ unless Object.const_defined?(:Inflector)
55
+ class Inflector
56
+ def self.pluralize(string)
57
+ string.to_s + 's'
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ it 'should pluralize the collection name' do
64
+ owner = create_collection_owner_with(1)
65
+ owner.should have(1).item
66
+ end
67
+ end
68
+
50
69
  describe "should have(n).items where result responds to items but returns something other than a collection" do
51
70
  it "should provide a meaningful error" do
52
71
  owner = Class.new do
@@ -5,12 +5,12 @@ describe "should match(expected)" do
5
5
  "string".should match(/tri/)
6
6
  end
7
7
 
8
- it "should fail when target (String) matches expected (Regexp)" do
8
+ it "should fail when target (String) does not match expected (Regexp)" do
9
9
  lambda {
10
10
  "string".should match(/rings/)
11
11
  }.should fail
12
12
  end
13
-
13
+
14
14
  it "should provide message, expected and actual on failure" do
15
15
  matcher = match(/rings/)
16
16
  matcher.matches?("string")
@@ -19,7 +19,7 @@ describe "should match(expected)" do
19
19
  end
20
20
 
21
21
  describe "should_not match(expected)" do
22
- it "should pass when target (String) matches expected (Regexp)" do
22
+ it "should pass when target (String) matches does not match (Regexp)" do
23
23
  "string".should_not match(/rings/)
24
24
  end
25
25
 
@@ -40,6 +40,11 @@ module Spec
40
40
  @out.string.should == " <li class=\"passed\">Given a <span class=\"param\">brown</span> <span class=\"param\">dog</span></li>\n"
41
41
  end
42
42
 
43
+ it 'should create spanes for params in regexp steps' do
44
+ @reporter.step_succeeded :given, /a (pink|blue) (.*)/, 'brown', 'dog'
45
+ @out.string.should == " <li class=\"passed\">Given a <span class=\"param\">brown</span> <span class=\"param\">dog</span></li>\n"
46
+ end
47
+
43
48
  it "should create a ul for collected_steps" do
44
49
  @reporter.collected_steps(['Given a $coloured $animal', 'Given a $n legged eel'])
45
50
  @out.string.should == (<<-EOF)
@@ -9,8 +9,11 @@ module Spec
9
9
  before :each do
10
10
  # given
11
11
  @out = StringIO.new
12
+ @tweaker = mock('tweaker')
13
+ @tweaker.stub!(:tweak_backtrace)
12
14
  @options = mock('options')
13
15
  @options.stub!(:colour).and_return(false)
16
+ @options.stub!(:backtrace_tweaker).and_return(@tweaker)
14
17
  @formatter = PlainTextFormatter.new(@options, @out)
15
18
  end
16
19
 
@@ -59,6 +62,40 @@ module Spec
59
62
  @out.string.should include("3 scenarios: 1 succeeded, 2 failed")
60
63
  end
61
64
 
65
+ it 'should end cleanly (no characters on the last line) with successes' do
66
+ # when
67
+ @formatter.run_started(1)
68
+ @formatter.scenario_started(nil, nil)
69
+ @formatter.scenario_succeeded('story', 'scenario')
70
+ @formatter.run_ended
71
+
72
+ # then
73
+ @out.string.should =~ /\n\z/
74
+ end
75
+
76
+ it 'should end cleanly (no characters on the last line) with failures' do
77
+ # when
78
+ @formatter.run_started(1)
79
+ @formatter.scenario_started(nil, nil)
80
+ @formatter.scenario_failed('story', 'scenario', exception_from { raise RuntimeError, 'oops' })
81
+ @formatter.run_ended
82
+
83
+ # then
84
+ @out.string.should =~ /\n\z/
85
+ end
86
+
87
+ it 'should end cleanly (no characters on the last line) with pending steps' do
88
+ # when
89
+ @formatter.run_started(1)
90
+ @formatter.scenario_started(nil, nil)
91
+ @formatter.step_pending(:then, 'do pend')
92
+ @formatter.scenario_pending('story', 'scenario', exception_from { raise RuntimeError, 'oops' })
93
+ @formatter.run_ended
94
+
95
+ # then
96
+ @out.string.should =~ /\n\z/
97
+ end
98
+
62
99
  it 'should summarize the number of pending scenarios when the run ends' do
63
100
  # when
64
101
  @formatter.run_started(3)
@@ -146,14 +183,18 @@ module Spec
146
183
  it 'should produce details of each pending step when the run ends' do
147
184
  # when
148
185
  @formatter.run_started(2)
149
- @formatter.scenario_pending('story', 'scenario2', 'todo2')
150
- @formatter.scenario_pending('story', 'scenario3', 'todo3')
186
+ @formatter.story_started('story 1', 'narrative')
187
+ @formatter.scenario_started('story 1', 'scenario 1')
188
+ @formatter.step_pending(:given, 'todo 1', [])
189
+ @formatter.story_started('story 2', 'narrative')
190
+ @formatter.scenario_started('story 2', 'scenario 2')
191
+ @formatter.step_pending(:given, 'todo 2', [])
151
192
  @formatter.run_ended
152
193
 
153
194
  # then
154
195
  @out.string.should include("Pending Steps:\n")
155
- @out.string.should include("1) story (scenario2): todo2")
156
- @out.string.should include("2) story (scenario3): todo3")
196
+ @out.string.should include("1) story 1 (scenario 1): todo 1")
197
+ @out.string.should include("2) story 2 (scenario 2): todo 2")
157
198
  end
158
199
 
159
200
  it 'should document a story title and narrative' do
@@ -226,6 +267,11 @@ module Spec
226
267
  @out.string.should include(" Given a pink dog with 21 legs")
227
268
  end
228
269
 
270
+ it 'should document regexp steps with replaced params' do
271
+ @formatter.step_succeeded :given, /a (pink|blue) dog with (.*) legs/, 'pink', 21
272
+ @out.string.should include(" Given a pink dog with 21 legs")
273
+ end
274
+
229
275
  it "should append PENDING for the first pending step" do
230
276
  @formatter.scenario_started('','')
231
277
  @formatter.step_pending(:given, 'a context')
@@ -51,6 +51,9 @@ module Spec
51
51
  [1]
52
52
  end
53
53
 
54
+ def items
55
+ @items_in_collection_with_size_method
56
+ end
54
57
  end
55
58
 
56
59
  class HandCodedMock
@@ -213,6 +213,43 @@ module Spec
213
213
  # then
214
214
  $scenario.name.should == 'first scenario'
215
215
  end
216
+
217
+ it "should clean the steps between stories" do
218
+ #given
219
+ story_runner = StoryRunner.new(ScenarioRunner.new)
220
+ result = mock 'result'
221
+
222
+ step1 = Step.new('step') do
223
+ result.one
224
+ end
225
+ steps1 = StepGroup.new
226
+ steps1.add :when, step1
227
+
228
+ story_runner.Story 'title', 'narrative', :steps => steps1 do
229
+ Scenario 'first scenario' do
230
+ When 'step'
231
+ end
232
+ end
233
+
234
+ step2 = Step.new('step') do
235
+ result.two
236
+ end
237
+ steps2 = StepGroup.new
238
+ steps2.add :when, step2
239
+
240
+ story_runner.Story 'title2', 'narrative', :steps => steps2 do
241
+ Scenario 'second scenario' do
242
+ When 'step'
243
+ end
244
+ end
245
+
246
+ #then
247
+ result.should_receive(:one)
248
+ result.should_receive(:two)
249
+
250
+ #when
251
+ story_runner.run_stories
252
+ end
216
253
  end
217
254
  end
218
255
  end
@@ -68,6 +68,18 @@ module Spec
68
68
  step.matches?("before () after").should be_true
69
69
  end
70
70
 
71
+ it "should match any option of an alteration" do
72
+ step = Step.new(/(he|she) is cool/) {}
73
+ step.matches?("he is cool").should be_true
74
+ step.matches?("she is cool").should be_true
75
+ end
76
+
77
+ it "should match alteration as well as a variable" do
78
+ step = Step.new(/(he|she) is (.*)/) {}
79
+ step.matches?("he is cool").should be_true
80
+ step.parse_args("he is cool").should == ['he', 'cool']
81
+ end
82
+
71
83
  end
72
84
 
73
85
  describe Step do
@@ -142,6 +154,25 @@ module Spec
142
154
  $amount.should == "3"
143
155
  end
144
156
 
157
+ it "should perform itself when defined with a regexp with 2 parameters" do
158
+ # given
159
+ $pronoun = nil
160
+ $adjective = nil
161
+ step = Step.new /(he|she) is (.*)/ do |pronoun, adjective|
162
+ $pronoun = pronoun
163
+ $adjective = adjective
164
+ end
165
+ instance = Object.new
166
+
167
+ # when
168
+ args = step.parse_args("he is cool")
169
+ step.perform(instance, *args)
170
+
171
+ # then
172
+ $pronoun.should == "he"
173
+ $adjective.should == "cool"
174
+ end
175
+
145
176
  end
146
177
  end
147
178
  end
@@ -4,7 +4,7 @@ Story: autogenerated docstrings
4
4
  I want examples to generate their own names
5
5
  So that I can reduce duplication between example names and example code
6
6
 
7
- Scenario: run with ruby
7
+ Scenario: run passing examples with ruby
8
8
  Given the file ../../examples/pure/autogenerated_docstrings_example.rb
9
9
 
10
10
  When I run it with the ruby interpreter -fs
@@ -14,13 +14,32 @@ Story: autogenerated docstrings
14
14
  And the stdout should match /should include "a"/
15
15
  And the stdout should match /should respond to #size/
16
16
 
17
- Scenario: run with spec
18
- Given the file ../../examples/pure/autogenerated_docstrings_example.rb
17
+ Scenario: run failing examples with ruby
18
+ Given the file ../../failing_examples/failing_autogenerated_docstrings_example.rb
19
19
 
20
- When I run it with the spec script -fs
20
+ When I run it with the ruby interpreter -fs
21
+
22
+ Then the stdout should match /should equal 2/
23
+ And the stdout should match /should be > 5/
24
+ And the stdout should match /should include "b"/
25
+ And the stdout should match /should not respond to #size/
26
+
27
+ Scenario: run passing examples with spec
28
+ Given the file ../../examples/pure/autogenerated_docstrings_example.rb
29
+
30
+ When I run it with the spec script -fs
31
+
32
+ Then the stdout should match /should equal 5/
33
+ And the stdout should match /should be < 5/
34
+ And the stdout should match /should include "a"/
35
+ And the stdout should match /should respond to #size/
36
+
37
+ Scenario: run failing examples with spec
38
+ Given the file ../../failing_examples/failing_autogenerated_docstrings_example.rb
21
39
 
22
- Then the stdout should match /should equal 5/
23
- And the stdout should match /should be < 5/
24
- And the stdout should match /should include "a"/
25
- And the stdout should match /should respond to #size/
40
+ When I run it with the spec script -fs
26
41
 
42
+ Then the stdout should match /should equal 2/
43
+ And the stdout should match /should be > 5/
44
+ And the stdout should match /should include "b"/
45
+ And the stdout should match /should not respond to #size/
@@ -18,3 +18,8 @@ Story: Getting correct output
18
18
  And the stdout should not match "Loaded suite"
19
19
  And the stdout should not match /\d+ tests, \d+ assertions, \d+ failures, \d+ errors/m
20
20
  And the stdout should match "1 example, 0 failures"
21
+
22
+ Scenario: Tweak backtrace
23
+ Given the file stories/failing_story.rb
24
+ When I run it with the ruby interpreter
25
+ Then the stdout should not match /\/lib\/spec\//
@@ -0,0 +1,15 @@
1
+ $:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
2
+
3
+ require 'spec/story'
4
+
5
+ Story "Failing story",
6
+ %(As an RSpec user
7
+ I want a failing test
8
+ So that I can observe the output) do
9
+
10
+ Scenario "Failing scenario" do
11
+ Then "true should be false" do
12
+ true.should == false
13
+ end
14
+ end
15
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - RSpec Development Team
8
- autorequire: spec
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2007-12-17 00:00:00 -06:00
12
+ date: 2008-01-15 00:00:00 -06:00
13
13
  default_executable: spec
14
14
  dependencies: []
15
15
 
@@ -119,6 +119,8 @@ files:
119
119
  - lib/spec/runner/spec_parser.rb
120
120
  - lib/spec/runner.rb
121
121
  - lib/spec/story/extensions/main.rb
122
+ - lib/spec/story/extensions/regexp.rb
123
+ - lib/spec/story/extensions/string.rb
122
124
  - lib/spec/story/extensions.rb
123
125
  - lib/spec/story/given_scenario.rb
124
126
  - lib/spec/story/runner/plain_text_story_runner.rb
@@ -352,6 +354,8 @@ files:
352
354
  - stories/resources/spec/simple_spec.rb
353
355
  - stories/resources/steps
354
356
  - stories/resources/steps/running_rspec.rb
357
+ - stories/resources/stories
358
+ - stories/resources/stories/failing_story.rb
355
359
  - stories/resources/test
356
360
  - stories/resources/test/spec_and_test_together.rb
357
361
  - stories/resources/test/test_case_with_should_methods.rb
@@ -382,9 +386,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
382
386
  requirements: []
383
387
 
384
388
  rubyforge_project: rspec
385
- rubygems_version: 0.9.5
389
+ rubygems_version: 1.0.1
386
390
  signing_key:
387
391
  specification_version: 2
388
- summary: RSpec-1.1.1 (build 20071217181808) - BDD for Ruby http://rspec.rubyforge.org/
392
+ summary: RSpec-1.1.2 (build 20080114022430) - BDD for Ruby http://rspec.rubyforge.org/
389
393
  test_files: []
390
394