rspec-core 2.10.1 → 2.11.0

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