rspec-core 2.10.1 → 2.11.0

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 (37) hide show
  1. data/Changelog.md +35 -2
  2. data/README.md +14 -13
  3. data/features/command_line/example_name_option.feature +15 -0
  4. data/features/helper_methods/modules.feature +3 -3
  5. data/lib/rspec/core.rb +6 -2
  6. data/lib/rspec/core/configuration.rb +61 -26
  7. data/lib/rspec/core/configuration_options.rb +5 -1
  8. data/lib/rspec/core/deprecation.rb +0 -15
  9. data/lib/rspec/core/drb_command_line.rb +3 -0
  10. data/lib/rspec/core/drb_options.rb +3 -1
  11. data/lib/rspec/core/dsl.rb +4 -2
  12. data/lib/rspec/core/example.rb +85 -23
  13. data/lib/rspec/core/example_group.rb +103 -78
  14. data/lib/rspec/core/hooks.rb +68 -33
  15. data/lib/rspec/core/let.rb +0 -1
  16. data/lib/rspec/core/mocking/with_mocha.rb +10 -4
  17. data/lib/rspec/core/option_parser.rb +3 -2
  18. data/lib/rspec/core/project_initializer.rb +7 -1
  19. data/lib/rspec/core/runner.rb +2 -2
  20. data/lib/rspec/core/shared_context.rb +2 -2
  21. data/lib/rspec/core/shared_example_group.rb +38 -14
  22. data/lib/rspec/core/subject.rb +67 -52
  23. data/lib/rspec/core/version.rb +1 -1
  24. data/spec/rspec/core/command_line_spec.rb +68 -126
  25. data/spec/rspec/core/configuration_options_spec.rb +20 -4
  26. data/spec/rspec/core/configuration_spec.rb +61 -21
  27. data/spec/rspec/core/drb_command_line_spec.rb +1 -0
  28. data/spec/rspec/core/drb_options_spec.rb +1 -0
  29. data/spec/rspec/core/dsl_spec.rb +17 -0
  30. data/spec/rspec/core/example_group_spec.rb +19 -11
  31. data/spec/rspec/core/example_spec.rb +34 -0
  32. data/spec/rspec/core/option_parser_spec.rb +2 -1
  33. data/spec/rspec/core/shared_example_group_spec.rb +9 -9
  34. data/spec/rspec/core/subject_spec.rb +14 -0
  35. data/spec/rspec/core_spec.rb +18 -8
  36. data/spec/spec_helper.rb +1 -2
  37. metadata +7 -5
@@ -105,7 +105,6 @@ module RSpec
105
105
  mod.extend ExampleGroupMethods
106
106
  mod.__send__ :include, ExampleMethods
107
107
  end
108
-
109
108
  end
110
109
  end
111
110
  end
@@ -4,7 +4,6 @@ require 'mocha/object'
4
4
  module RSpec
5
5
  module Core
6
6
  module MockFrameworkAdapter
7
-
8
7
  def self.framework_name; :mocha end
9
8
 
10
9
  # Mocha::Standalone was deprecated as of Mocha 0.9.7.
@@ -14,10 +13,17 @@ module RSpec
14
13
  include Mocha::Standalone
15
14
  end
16
15
 
17
- alias :setup_mocks_for_rspec :mocha_setup
18
- alias :verify_mocks_for_rspec :mocha_verify
19
- alias :teardown_mocks_for_rspec :mocha_teardown
16
+ def setup_mocks_for_rspec
17
+ mocha_setup
18
+ end
19
+
20
+ def verify_mocks_for_rspec
21
+ mocha_verify
22
+ end
20
23
 
24
+ def teardown_mocks_for_rspec
25
+ mocha_teardown
26
+ end
21
27
  end
22
28
  end
23
29
  end
@@ -134,8 +134,9 @@ FILTERING
134
134
  options[:pattern] = o
135
135
  end
136
136
 
137
- parser.on('-e', '--example STRING', "Run examples whose full nested names include STRING") do |o|
138
- options[:full_description] = Regexp.compile(Regexp.escape(o))
137
+ parser.on('-e', '--example STRING', "Run examples whose full nested names include STRING (may be',
138
+ ' used more than once)") do |o|
139
+ (options[:full_description] ||= []) << Regexp.compile(Regexp.escape(o))
139
140
  end
140
141
 
141
142
  parser.on('-l', '--line_number LINE', 'Specify line number of an example or group (may be',
@@ -44,7 +44,7 @@ CONTENT
44
44
  f.write <<-CONTENT
45
45
  # This file was generated by the `rspec --init` command. Conventionally, all
46
46
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
47
- # Require this file using `require "spec_helper.rb"` to ensure that it is only
47
+ # Require this file using `require "spec_helper"` to ensure that it is only
48
48
  # loaded once.
49
49
  #
50
50
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
@@ -52,6 +52,12 @@ RSpec.configure do |config|
52
52
  config.treat_symbols_as_metadata_keys_with_true_values = true
53
53
  config.run_all_when_everything_filtered = true
54
54
  config.filter_run :focus
55
+
56
+ # Run specs in random order to surface order dependencies. If you find an
57
+ # order dependency and want to debug it, you can fix the order by providing
58
+ # the seed, which is printed after each run.
59
+ # --seed 1234
60
+ config.order = 'random'
55
61
  end
56
62
  CONTENT
57
63
  end
@@ -1,5 +1,3 @@
1
- require 'drb/drb'
2
-
3
1
  module RSpec
4
2
  module Core
5
3
  class Runner
@@ -25,6 +23,7 @@ module RSpec
25
23
  end
26
24
 
27
25
  def self.running_in_drb?
26
+ defined?(DRb) &&
28
27
  (DRb.current_server rescue false) &&
29
28
  DRb.current_server.uri =~ /druby\:\/\/127.0.0.1\:/
30
29
  end
@@ -59,6 +58,7 @@ module RSpec
59
58
  options.parse_options
60
59
 
61
60
  if options.options[:drb]
61
+ require 'rspec/core/drb_command_line'
62
62
  begin
63
63
  DRbCommandLine.new(options).run(err, out)
64
64
  rescue DRb::DRbConnError
@@ -1,7 +1,7 @@
1
1
  module RSpec
2
2
  module Core
3
- # Exposes [ExampleGroup](ExampleGroup)-level methods to a module, so you
4
- # can include that module in an [ExampleGroup](ExampleGroup).
3
+ # Exposes {ExampleGroup}-level methods to a module, so you can include that
4
+ # module in an {ExampleGroup}.
5
5
  #
6
6
  # @example
7
7
  #
@@ -1,27 +1,46 @@
1
1
  module RSpec
2
2
  module Core
3
3
  module SharedExampleGroup
4
-
5
4
  # @overload shared_examples(name, &block)
6
5
  # @overload shared_examples(name, tags, &block)
7
6
  #
8
- # Creates and stores (but does not evaluate) the block.
7
+ # Wraps the `block` in a module which can then be included in example
8
+ # groups using `include_examples`, `include_context`, or
9
+ # `it_behaves_like`.
10
+ #
11
+ # @param [String] name to match when looking up this shared group
12
+ # @param block to be eval'd in a nested example group generated by `it_behaves_like`
13
+ #
14
+ # @example
15
+ #
16
+ # shared_examples "auditable" do
17
+ # it "stores an audit record on save!" do
18
+ # lambda { auditable.save! }.should change(Audit, :count).by(1)
19
+ # end
20
+ # end
21
+ #
22
+ # class Account do
23
+ # it_behaves_like "auditable" do
24
+ # def auditable; Account.new; end
25
+ # end
26
+ # end
9
27
  #
28
+ # @see ExampleGroup.it_behaves_like
10
29
  # @see ExampleGroup.include_examples
11
30
  # @see ExampleGroup.include_context
12
- def shared_examples(*args, &block)
13
- if [String, Symbol, Module].any? {|cls| cls === args.first }
14
- object = args.shift
15
- ensure_shared_example_group_name_not_taken(object)
16
- RSpec.world.shared_example_groups[object] = block
31
+ def shared_examples *args, &block
32
+ if key? args.first
33
+ key = args.shift
34
+ raise_key_taken key if key_taken? key
35
+ RSpec.world.shared_example_groups[key] = block
17
36
  end
18
37
 
19
38
  unless args.empty?
20
39
  mod = Module.new
21
- (class << mod; self; end).send(:define_method, :extended) do |host|
22
- host.class_eval(&block)
40
+ (class << mod; self; end).send :define_method, :extended do |host|
41
+ host.class_eval &block
23
42
  end
24
- RSpec.configuration.extend(mod, *args)
43
+ RSpec.configuration.extend mod, *args
25
44
  end
26
45
  end
27
46
 
@@ -55,16 +74,21 @@ module RSpec
55
74
 
56
75
  private
57
76
 
77
+ def key? candidate
78
+ [String, Symbol, Module].any? { |cls| cls === candidate }
79
+ end
80
+
58
81
  def raise_name_error
59
82
  raise NameError, "The first argument (#{name}) to share_as must be a legal name for a constant not already in use."
60
83
  end
61
84
 
62
- def ensure_shared_example_group_name_not_taken(name)
63
- if RSpec.world.shared_example_groups.has_key?(name)
64
- raise ArgumentError.new("Shared example group '#{name}' already exists")
65
- end
85
+ def raise_key_taken key
86
+ raise ArgumentError, "Shared example group '#{key}' already exists"
66
87
  end
67
88
 
89
+ def key_taken? key
90
+ RSpec.world.shared_example_groups.has_key?(key)
91
+ end
68
92
  end
69
93
  end
70
94
  end
@@ -2,14 +2,7 @@ module RSpec
2
2
  module Core
3
3
  module Subject
4
4
  module ExampleMethods
5
-
6
- # Returns the subject defined by the example group. The subject block
7
- # is only executed once per example, the result of which is cached and
8
- # returned by any subsequent calls to `subject`.
9
- #
10
- # If a class is passed to `describe` and no subject is explicitly
11
- # declared in the example group, then `subject` will return a new
12
- # instance of that class.
5
+ # Returns the example group's `subject`.
13
6
  #
14
7
  # @note `subject` was contributed by Joe Ferris to support the one-liner
15
8
  # syntax embraced by shoulda matchers:
@@ -19,9 +12,8 @@ module RSpec
19
12
  # end
20
13
  #
21
14
  # While the examples below demonstrate how to use `subject`
22
- # explicitly in specs, we think it works best for extensions like
23
- # shoulda, custom matchers, and shared example groups, where it is
24
- # not referenced explicitly in specs.
15
+ # explicitly in examples, we recommend that you define a method with
16
+ # an intention revealing name instead.
25
17
  #
26
18
  # @example
27
19
  #
@@ -30,6 +22,7 @@ module RSpec
30
22
  # subject { Person.new(:birthdate => 19.years.ago) }
31
23
  # it "should be eligible to vote" do
32
24
  # subject.should be_eligible_to_vote
25
+ # # ^ ^ explicit reference to subject not recommended
33
26
  # end
34
27
  # end
35
28
  #
@@ -37,13 +30,17 @@ module RSpec
37
30
  # describe Person do
38
31
  # it "should be eligible to vote" do
39
32
  # subject.should be_eligible_to_vote
33
+ # # ^ ^ explicit reference to subject not recommended
40
34
  # end
41
35
  # end
42
36
  #
37
+ # # one-liner syntax - should is invoked on subject
43
38
  # describe Person do
44
- # # one liner syntax - should is invoked on subject
45
39
  # it { should be_eligible_to_vote }
46
40
  # end
41
+ #
42
+ # @see ExampleGroupMethods#subject
43
+ # @see #should
47
44
  def subject
48
45
  if defined?(@original_subject)
49
46
  @original_subject
@@ -52,37 +49,37 @@ module RSpec
52
49
  end
53
50
  end
54
51
 
55
- begin
56
- require 'rspec/expectations/handler'
57
-
58
- # When +should+ is called with no explicit receiver, the call is
59
- # delegated to the object returned by +subject+. Combined with
60
- # an implicit subject (see +subject+), this supports very concise
61
- # expressions.
62
- #
63
- # @example
64
- #
65
- # describe Person do
66
- # it { should be_eligible_to_vote }
67
- # end
68
- def should(matcher=nil, message=nil)
69
- RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message)
70
- end
52
+ # When `should` is called with no explicit receiver, the call is
53
+ # delegated to the object returned by `subject`. Combined with an
54
+ # implicit subject this supports very concise expressions.
55
+ #
56
+ # @example
57
+ #
58
+ # describe Person do
59
+ # it { should be_eligible_to_vote }
60
+ # end
61
+ #
62
+ # @see #subject
63
+ def should(matcher=nil, message=nil)
64
+ RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message)
65
+ end
71
66
 
72
- # Just like +should+, +should_not+ delegates to the subject (implicit or
73
- # explicit) of the example group.
74
- #
75
- # @example
76
- #
77
- # describe Person do
78
- # it { should_not be_eligible_to_vote }
79
- # end
80
- def should_not(matcher=nil, message=nil)
81
- RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message)
82
- end
83
- rescue LoadError
67
+ # Just like `should`, `should_not` delegates to the subject (implicit or
68
+ # explicit) of the example group.
69
+ #
70
+ # @example
71
+ #
72
+ # describe Person do
73
+ # it { should_not be_eligible_to_vote }
74
+ # end
75
+ #
76
+ # @see #subject
77
+ def should_not(matcher=nil, message=nil)
78
+ RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message)
84
79
  end
85
80
 
81
+ private
82
+
86
83
  def _attribute_chain(attribute)
87
84
  attribute.to_s.split('.')
88
85
  end
@@ -95,7 +92,7 @@ module RSpec
95
92
  end
96
93
 
97
94
  module ExampleGroupMethods
98
- # Creates a nested example group named by the submitted +attribute+,
95
+ # Creates a nested example group named by the submitted `attribute`,
99
96
  # and then generates an example using the submitted block.
100
97
  #
101
98
  # @example
@@ -114,8 +111,8 @@ module RSpec
114
111
  # end
115
112
  # end
116
113
  #
117
- # The attribute can be a +Symbol+ or a +String+. Given a +String+
118
- # with dots, the result is as though you concatenated that +String+
114
+ # The attribute can be a `Symbol` or a `String`. Given a `String`
115
+ # with dots, the result is as though you concatenated that `String`
119
116
  # onto the subject in an expression.
120
117
  #
121
118
  # @example
@@ -130,8 +127,8 @@ module RSpec
130
127
  # its("phone_numbers.first") { should eq("555-1212") }
131
128
  # end
132
129
  #
133
- # When the subject is a +Hash+, you can refer to the Hash keys by
134
- # specifying a +Symbol+ or +String+ in an array.
130
+ # When the subject is a `Hash`, you can refer to the Hash keys by
131
+ # specifying a `Symbol` or `String` in an array.
135
132
  #
136
133
  # @example
137
134
  #
@@ -165,19 +162,38 @@ module RSpec
165
162
  end
166
163
  end
167
164
 
168
- # Defines an explicit subject for an example group which can then be the
169
- # implicit receiver (through delegation) of calls to +should+.
165
+ # Declares a `subject` for an example group which can then be the
166
+ # implicit receiver (through delegation) of calls to `should`.
167
+ #
168
+ # Given a `name`, defines a method with that name which returns the
169
+ # `subject`. This lets you declare the subject once and access it
170
+ # implicitly in one-liners and explicitly using an intention revealing
171
+ # name.
172
+ #
173
+ # @param [String,Symbol] name used to define an accessor with an
174
+ # intention revealing name
175
+ # @param block defines the value to be returned by `subject` in examples
170
176
  #
171
177
  # @example
172
178
  #
173
179
  # describe CheckingAccount, "with $50" do
174
- # subject { CheckingAccount.new(:amount => 50, :currency => :USD) }
175
- # it { should have_a_balance_of(50, :USD) }
180
+ # subject { CheckingAccount.new(Money.new(50, :USD)) }
181
+ # it { should have_a_balance_of(Money.new(50, :USD)) }
176
182
  # it { should_not be_overdrawn }
177
183
  # end
178
184
  #
179
- # See +ExampleMethods#should+ for more information about this approach.
180
- def subject(&block)
185
+ # describe CheckingAccount, "with a non-zero starting balance" do
186
+ # subject(:account) { CheckingAccount.new(Money.new(50, :USD)) }
187
+ # it { should_not be_overdrawn }
188
+ # it "has a balance equal to the starting balance" do
189
+ # account.balance.should eq(Money.new(50, :USD))
190
+ # end
191
+ # end
192
+ #
193
+ # @see ExampleMethods#subject
194
+ # @see ExampleMethods#should
195
+ def subject(name=nil, &block)
196
+ define_method(name) { subject } if name
181
197
  block ? @explicit_subject_block = block : explicit_subject || implicit_subject
182
198
  end
183
199
 
@@ -198,7 +214,6 @@ module RSpec
198
214
  Class === described ? proc { described.new } : proc { described }
199
215
  end
200
216
  end
201
-
202
217
  end
203
218
  end
204
219
  end
@@ -1,7 +1,7 @@
1
1
  module RSpec
2
2
  module Core
3
3
  module Version
4
- STRING = '2.10.1'
4
+ STRING = '2.11.0'
5
5
  end
6
6
  end
7
7
  end
@@ -5,162 +5,104 @@ require 'tmpdir'
5
5
  module RSpec::Core
6
6
  describe CommandLine do
7
7
 
8
- describe "#run" do
9
- include_context "spec files"
10
-
11
- let(:out) { StringIO.new }
12
- let(:err) { StringIO.new }
8
+ let(:out) { StringIO.new }
9
+ let(:err) { StringIO.new }
10
+ let(:config) { RSpec::configuration }
11
+ let(:world) { RSpec::world }
13
12
 
14
- def command_line(args)
15
- RSpec::Core::CommandLine.new(config_options(args))
16
- end
13
+ before { config.stub :run_hook }
17
14
 
18
- def config_options(argv=[])
19
- options = RSpec::Core::ConfigurationOptions.new(argv)
20
- options.parse_options
21
- options
22
- end
15
+ it "configures streams before command line options" do
16
+ config.stub :load_spec_files
23
17
 
24
- it "returns 0 if spec passes" do
25
- result = command_line([passing_spec_filename]).run(err, out)
26
- result.should be(0)
27
- end
18
+ # this is necessary to ensure that color works correctly on windows
19
+ config.should_receive(:error_stream=).ordered
20
+ config.should_receive(:output_stream=).ordered
21
+ config.should_receive(:force).at_least(:once).ordered
28
22
 
29
- it "returns 1 if spec fails" do
30
- result = command_line([failing_spec_filename]).run(err, out)
31
- result.should be(1)
32
- end
33
-
34
- it "returns 2 if spec fails and --failure-exit-code is 2" do
35
- result = command_line([failing_spec_filename, "--failure-exit-code", "2"]).run(err, out)
36
- result.should be(2)
37
- end
23
+ command_line = build_command_line
24
+ command_line.run err, out
38
25
  end
39
26
 
40
- context "given an Array of options" do
41
- it "assigns ConfigurationOptions built from Array to @options" do
42
- config_options = ConfigurationOptions.new(%w[--color])
43
- config_options.parse_options
44
-
45
- array_options = %w[--color]
46
- command_line = CommandLine.new(array_options)
47
- command_line.instance_eval { @options.options }.should eq(config_options.options)
48
- end
27
+ it "assigns ConfigurationOptions built from Array of options to @options" do
28
+ config_options = ConfigurationOptions.new(%w[--color])
29
+ command_line = CommandLine.new(%w[--color])
30
+ command_line.instance_eval { @options.options }.should eq(config_options.parse_options)
49
31
  end
50
32
 
51
- context "given a ConfigurationOptions object" do
52
- it "assigns it to @options" do
53
- config_options = ConfigurationOptions.new(%w[--color])
54
- config_options.parse_options
55
- command_line = CommandLine.new(config_options)
56
- command_line.instance_eval { @options }.should be(config_options)
57
- end
33
+ it "assigns submitted ConfigurationOptions to @options" do
34
+ config_options = ConfigurationOptions.new(%w[--color])
35
+ command_line = CommandLine.new(config_options)
36
+ command_line.instance_eval { @options }.should be(config_options)
58
37
  end
59
38
 
60
39
  describe "#run" do
61
- let(:config_options) do
62
- config_options = ConfigurationOptions.new(%w[--color])
63
- config_options.parse_options
64
- config_options
65
- end
66
-
67
- let(:config) do
68
- RSpec::Core::Configuration.new
69
- end
70
-
71
- let(:world) do
72
- RSpec::Core::World.new
73
- end
40
+ context "running files" do
41
+ include_context "spec files"
74
42
 
75
- let(:command_line) do
76
- CommandLine.new(config_options, config, world)
77
- end
78
-
79
- let(:out) { ::StringIO.new }
80
- let(:err) { ::StringIO.new }
81
-
82
- before do
83
- config.stub(:run_hook)
43
+ it "returns 0 if spec passes" do
44
+ command_line = build_command_line passing_spec_filename
45
+ command_line.run(err, out).should eq 0
46
+ end
84
47
 
85
- config.should_receive(:load_spec_files)
48
+ it "returns 1 if spec fails" do
49
+ command_line = build_command_line failing_spec_filename
50
+ command_line.run(err, out).should eq 1
51
+ end
86
52
 
87
- world.should_receive(:announce_inclusion_filter)
88
- world.should_receive(:announce_exclusion_filter)
53
+ it "returns 2 if spec fails and --failure-exit-code is 2" do
54
+ command_line = build_command_line failing_spec_filename, "--failure-exit-code", "2"
55
+ command_line.run(err, out).should eq 2
56
+ end
89
57
  end
90
58
 
91
- it "configures streams before command line options" do
92
- # this is necessary to ensure that color works correctly on windows
93
- config.should_receive(:error_stream=).ordered
94
- config.should_receive(:output_stream=).ordered
95
- config.should_receive(:force).any_number_of_times.ordered
96
- command_line.run(err, out) rescue nil
97
- end
59
+ context "running hooks" do
60
+ before { config.stub :load_spec_files }
98
61
 
99
- it "runs before suite hooks" do
100
- config.should_receive(:run_hook).with(:before, :suite)
101
- command_line.run(err, out)
102
- end
62
+ it "runs before suite hooks" do
63
+ config.should_receive(:run_hook).with(:before, :suite)
64
+ command_line = build_command_line
65
+ command_line.run err, out
66
+ end
103
67
 
104
- it "runs after suite hooks" do
105
- config.should_receive(:run_hook).with(:after, :suite)
106
- command_line.run(err, out)
107
- end
68
+ it "runs after suite hooks" do
69
+ config.should_receive(:run_hook).with(:after, :suite)
70
+ command_line = build_command_line
71
+ command_line.run err, out
72
+ end
108
73
 
109
- it "runs after suite hooks even after an error" do
110
- after_suite_called = false
111
- config.stub(:run_hook) do |*args|
112
- case args.first
113
- when :before
114
- raise "this error"
115
- when :after
116
- after_suite_called = true
117
- end
74
+ it "runs after suite hooks even after an error" do
75
+ config.should_receive(:run_hook).with(:before, :suite).and_raise "this error"
76
+ config.should_receive(:run_hook).with(:after , :suite)
77
+ expect do
78
+ command_line = build_command_line
79
+ command_line.run err, out
80
+ end.to raise_error
118
81
  end
119
- expect do
120
- command_line.run(err, out)
121
- end.to raise_error
122
- after_suite_called.should be_true
123
82
  end
124
-
125
83
  end
126
84
 
127
85
  describe "#run with custom output" do
128
- let(:config_options) do
129
- config_options = ConfigurationOptions.new(%w[--color])
130
- config_options.parse_options
131
- config_options
132
- end
86
+ before { config.stub :files_to_run => [] }
133
87
 
134
- let(:command_line) do
135
- CommandLine.new(config_options, config)
136
- end
137
-
138
- let(:output_file_path) do
139
- Dir.tmpdir + "/command_line_spec_output.txt"
140
- end
88
+ let(:output_file) { File.new("#{Dir.tmpdir}/command_line_spec_output.txt", 'w') }
141
89
 
142
- let(:output_file) do
143
- File.new(output_file_path, 'w')
144
- end
145
-
146
- let(:config) do
147
- config = RSpec::Core::Configuration.new
90
+ it "doesn't override output_stream" do
148
91
  config.output_stream = output_file
149
- config
150
- end
151
-
152
- let(:out) { ::StringIO.new }
153
-
154
- before do
155
- config.stub(:run_hook)
156
- config.stub(:files_to_run) { [] }
92
+ command_line = build_command_line
93
+ command_line.run err, out
94
+ command_line.instance_eval { @configuration.output_stream }.should eq output_file
157
95
  end
96
+ end
158
97
 
159
- it "doesn't override output_stream" do
160
- command_line.run(out, out)
161
- command_line.instance_eval { @configuration.output_stream }.should eql(output_file)
162
- end
98
+ def build_command_line *args
99
+ CommandLine.new build_config_options(*args)
163
100
  end
164
101
 
102
+ def build_config_options *args
103
+ options = ConfigurationOptions.new args
104
+ options.parse_options
105
+ options
106
+ end
165
107
  end
166
108
  end