opal-rspec 0.0.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ed072aad1768de7d20b2cabb9f11f670976874fc
4
+ data.tar.gz: 0a4f28128a5b045a1b0b385d2d4ca38b776075d7
5
+ SHA512:
6
+ metadata.gz: 7ab1aad04e561cc0a8c45701b2edde80be2d5ad00cf3d02c60dcd00f21d7684a74f6d57c69ae4081f3eb2d77be7dd5b8a04712ece70d86485ad87c4bb5715958
7
+ data.tar.gz: b086f9fff0bdc56e51a4f9a3f8ef858f9af4116cae085f15ddbda6a26cfafd7fb5215219d62395e57acf7844352b7ba350243cb14135e667ac07e414868b932a
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ Gemfile.lock
3
+ opal/opal/rspec/rspec.js
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'rake'
5
+
6
+ gem 'opal', :github => 'opal/opal'
7
+ gem 'opal-sprockets', :github => 'opal/opal-sprockets'
8
+
9
+ # As we monkey patch a lot, work of a specific commit on github
10
+ gem 'rspec-support', :github => 'rspec/rspec-support', :ref => 'f235ccb129'
11
+ gem 'rspec-expectations', :github => 'rspec/rspec-expectations', :ref => 'd3277fd42e'
12
+ gem 'rspec-core', :github => 'rspec/rspec-core', :ref => 'ed8898c58b'
13
+ gem 'rspec-mocks', :github => 'rspec/rspec-mocks', :ref => 'a2f952a025'
14
+
15
+ gem 'rspec', :github => 'rspec/rspec'
data/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # opal-rspec
2
+
3
+ An attempt at a compatibility layer of rspec for opal.
4
+
5
+ ## Usage
6
+
7
+ Install required gems at required versions:
8
+
9
+ $ bundle install
10
+
11
+ opal-rspec uses a prebuilt version of rspec to fix the areas where
12
+ opal cannot handle certain features of rspec. To build that file,
13
+ which is needed to run specs, use:
14
+
15
+ $ bundle exec rake build
16
+
17
+ This should build `opal/opal/rspec/rspec.js` ready to use.
18
+
19
+ ### Run on command line
20
+
21
+ A simple rake task should run the example specs in `spec/`:
22
+
23
+ $ bundle exec rake
24
+
25
+ ### Run in the browser
26
+
27
+ Run attached rack app to handle building:
28
+
29
+ $ bundle exec rackup
30
+
31
+ Visit the page in any browser and view the console:
32
+
33
+ $ open http://localhost:9292
34
+
35
+ ## Things to fix
36
+
37
+ `opal/opal-rspec/fixes.rb` contains a few bug fixes that need to be merged upstream
38
+ to opal itself. In app/rspec we have to stub various rspec files.
39
+
40
+ ### rspec/core.rb
41
+
42
+ * **line 1**: `require_rspec` to fake require_relative doesnt work at runtime.
43
+ opal has to include all dependencies into build.
44
+
45
+ * **line 90**: heredoc fails to parse in opal as EOS is used within heredoc
46
+
47
+ * **line 171**: `&::Time.method(:now)` doesnt work so wrong method is set
48
+
49
+ ### rspec/core/configuration.rb
50
+
51
+ * **line ?**: something in that file is causing opal to generate bad javascript.
52
+ This is possible a require statement used as an expression which generates empty
53
+ code.
54
+
55
+ ### rspec/core/example_group.rb
56
+
57
+ * **line 434**: cannot parse heredoc as it uses EOS inline before string ends
58
+
59
+ * **line 547**: opal cannot use mutable strings (see opal/rspec/fixes.rb)
60
+
61
+ * **line 564**: opal cannot use mutable strings (see opal/rspec/fixes.rb)
62
+
63
+ ### rspec/core/project_initializer.rb
64
+
65
+ * **line 1**: opal cannot parse these heredocs (EOS used before last line of string)
66
+
67
+ ### rspec/core/shared_example_group.rb
68
+
69
+ * **line 112**: opal cannot parse this heredoc
70
+
71
+ ### rspec/core/shared_example_group/collection.rb
72
+
73
+ * **line 17**: opal cannot parse command call inside aref
74
+
75
+ ### rspec/matchers/built_in/have.rb
76
+
77
+ * **line 1**: this is an error in rspec. This autoload does not exist so we must
78
+ stub the file.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ require 'bundler'
2
+ Bundler.require
3
+
4
+ require 'opal/rspec/rake_task'
5
+ Opal::RSpec::RakeTask.new(:default)
6
+
7
+ desc "Build opal/opal/rspec/rspec.js"
8
+ task :build do
9
+ File.open('opal/opal/rspec/rspec.js', 'w+') do |out|
10
+ out << build_rspec
11
+ end
12
+ end
13
+
14
+ desc "Show dev/min sizes"
15
+ task :sizes do
16
+ code = build_rspec
17
+ min = uglify code
18
+
19
+ puts "\ndevelopment: #{code.size}, minified: #{min.size}"
20
+ end
21
+
22
+ def build_rspec
23
+ Opal::Processor.dynamic_require_severity = :warning
24
+ Opal.append_path 'app'
25
+
26
+ Opal.use_gem 'rspec'
27
+ Opal.use_gem 'rspec-expectations'
28
+
29
+ %w[fileutils test/unit/assertions coderay optparse shellwords socket uri
30
+ drb/drb diff/lcs diff/lcs/hunk].each do |asset|
31
+ Opal::Processor.stub_file asset
32
+ end
33
+
34
+ Opal.process('rspec-builder')
35
+ end
36
+
37
+ def uglify(str)
38
+ IO.popen('uglifyjs', 'r+') do |i|
39
+ i.puts str
40
+ i.close_write
41
+ return i.read
42
+ end
43
+ rescue Errno::ENOENT
44
+ $stderr.puts '"uglifyjs" command not found (install with: "npm install -g uglify-js")'
45
+ nil
46
+ end
@@ -0,0 +1,10 @@
1
+ require 'rspec/support'
2
+ require 'rspec/core'
3
+ require 'rspec/mocks'
4
+ require 'rspec-expectations'
5
+
6
+ # we want access to BaseFormatter
7
+ require 'rspec/core/formatters/base_formatter'
8
+
9
+ # For now, we don't support mocking. This placeholder in rspec-core allows that.
10
+ require 'rspec/core/mocking/with_absolutely_nothing'
data/app/rspec/core.rb ADDED
@@ -0,0 +1,202 @@
1
+ require_rspec = if defined?(require_relative)
2
+ lambda do |path|
3
+ require_relative path
4
+ end
5
+ else # for 1.8.7
6
+ lambda do |path|
7
+ require "rspec/#{path}"
8
+ end
9
+ end
10
+
11
+ require 'set'
12
+ require 'time'
13
+ require 'rbconfig'
14
+
15
+ require 'rspec/core/version'
16
+
17
+ require 'rspec/support/caller_filter'
18
+
19
+ require 'rspec/core/flat_map'
20
+ require 'rspec/core/filter_manager'
21
+ require 'rspec/core/dsl'
22
+ require 'rspec/core/warnings'
23
+ require 'rspec/core/reporter'
24
+
25
+ require 'rspec/core/hooks'
26
+ require 'rspec/core/memoized_helpers'
27
+ require 'rspec/core/metadata'
28
+ require 'rspec/core/pending'
29
+ require 'rspec/core/formatters'
30
+ require 'rspec/core/ordering'
31
+
32
+ require 'rspec/core/world'
33
+ require 'rspec/core/configuration'
34
+ require 'rspec/core/option_parser'
35
+ require 'rspec/core/configuration_options'
36
+ require 'rspec/core/command_line'
37
+ require 'rspec/core/runner'
38
+ require 'rspec/core/example'
39
+ require 'rspec/core/shared_example_group/collection'
40
+ require 'rspec/core/shared_example_group'
41
+ require 'rspec/core/example_group'
42
+
43
+ module RSpec
44
+ autoload :SharedContext, 'rspec/core/shared_context'
45
+
46
+ # @private
47
+ def self.wants_to_quit
48
+ # Used internally to determine what to do when a SIGINT is received
49
+ world.wants_to_quit
50
+ end
51
+
52
+ # @private
53
+ # Used internally to determine what to do when a SIGINT is received
54
+ def self.wants_to_quit=(maybe)
55
+ world.wants_to_quit=(maybe)
56
+ end
57
+
58
+ # @private
59
+ # Internal container for global non-configuration data
60
+ def self.world
61
+ @world ||= RSpec::Core::World.new
62
+ end
63
+
64
+ # @private
65
+ # Used internally to set the global object
66
+ def self.world=(new_world)
67
+ @world = new_world
68
+ end
69
+
70
+ # @private
71
+ # Used internally to ensure examples get reloaded between multiple runs in
72
+ # the same process.
73
+ def self.reset
74
+ @world = nil
75
+ @configuration = nil
76
+ end
77
+
78
+ # Returns the global [Configuration](RSpec/Core/Configuration) object. While you
79
+ # _can_ use this method to access the configuration, the more common
80
+ # convention is to use [RSpec.configure](RSpec#configure-class_method).
81
+ #
82
+ # @example
83
+ # RSpec.configuration.drb_port = 1234
84
+ # @see RSpec.configure
85
+ # @see Core::Configuration
86
+ def self.configuration
87
+ if block_given?
88
+ RSpec.warn_deprecation <<-WARNING
89
+
90
+ *****************************************************************
91
+ DEPRECATION WARN
92
+
93
+ * RSpec.configuration with a block is deprecated and has no effect.
94
+ * please use RSpec.configure with a block instead.
95
+
96
+ Called from
97
+ *****************************************************************
98
+
99
+ WARNING
100
+ end
101
+ @configuration ||= RSpec::Core::Configuration.new
102
+ end
103
+
104
+ # @private
105
+ # Used internally to set the global object
106
+ def self.configuration=(new_configuration)
107
+ @configuration = new_configuration
108
+ end
109
+
110
+ # Yields the global configuration to a block.
111
+ # @yield [Configuration] global configuration
112
+ #
113
+ # @example
114
+ # RSpec.configure do |config|
115
+ # config.add_formatter 'documentation'
116
+ # end
117
+ # @see Core::Configuration
118
+ def self.configure
119
+ yield configuration if block_given?
120
+ end
121
+
122
+ # @private
123
+ # Used internally to clear remaining groups when fail_fast is set
124
+ def self.clear_remaining_example_groups
125
+ world.example_groups.clear
126
+ end
127
+
128
+ # The example being executed.
129
+ #
130
+ # The primary audience for this method is library authors who need access
131
+ # to the example currently being executed and also want to support all
132
+ # versions of RSpec 2 and 3.
133
+ #
134
+ # @example
135
+ #
136
+ # RSpec.configure do |c|
137
+ # # context.example is deprecated, but RSpec.current_example is not
138
+ # # available until RSpec 3.0.
139
+ # fetch_current_example = RSpec.respond_to?(:current_example) ?
140
+ # proc { RSpec.current_example } : proc { |context| context.example }
141
+ #
142
+ # c.before(:each) do
143
+ # example = fetch_current_example.call(self)
144
+ #
145
+ # # ...
146
+ # end
147
+ # end
148
+ #
149
+ def self.current_example
150
+ Thread.current[:_rspec_current_example]
151
+ end
152
+
153
+ # Set the current example being executed.
154
+ # @api private
155
+ def self.current_example=(example)
156
+ Thread.current[:_rspec_current_example] = example
157
+ end
158
+
159
+ # @private
160
+ def self.windows_os?
161
+ RbConfig::CONFIG['host_os'] =~ /cygwin|mswin|mingw|bccwin|wince|emx/
162
+ end
163
+
164
+ module Core
165
+ # @private
166
+ # This avoids issues with reporting time caused by examples that
167
+ # change the value/meaning of Time.now without properly restoring
168
+ # it.
169
+ class Time
170
+ class << self
171
+ def now; ::Time.now; end #define_method(:now, &::Time.method(:now))
172
+ end
173
+ end
174
+
175
+ # @private path to executable file
176
+ def self.path_to_executable
177
+ @path_to_executable ||= File.expand_path('../../../exe/rspec', __FILE__)
178
+ end
179
+ end
180
+
181
+ MODULES_TO_AUTOLOAD = {
182
+ :Matchers => "rspec/expectations",
183
+ :Expectations => "rspec/expectations",
184
+ :Mocks => "rspec/mocks"
185
+ }
186
+
187
+ def self.const_missing(name)
188
+ # Load rspec-expectations when RSpec::Matchers is referenced. This allows
189
+ # people to define custom matchers (using `RSpec::Matchers.define`) before
190
+ # rspec-core has loaded rspec-expectations (since it delays the loading of
191
+ # it to allow users to configure a different assertion/expectation
192
+ # framework). `autoload` can't be used since it works with ruby's built-in
193
+ # require (e.g. for files that are available relative to a load path dir),
194
+ # but not with rubygems' extended require.
195
+ #
196
+ # As of rspec 2.14.1, we no longer require `rspec/mocks` and
197
+ # `rspec/expectations` when `rspec` is required, so we want
198
+ # to make them available as an autoload. For more info, see:
199
+ # require MODULES_TO_AUTOLOAD.fetch(name) { return super }
200
+ ::RSpec.const_get(name)
201
+ end
202
+ end
@@ -0,0 +1,1070 @@
1
+ require 'fileutils'
2
+ require 'rspec/core/backtrace_formatter'
3
+ require 'rspec/core/ruby_project'
4
+ require 'rspec/core/formatters/deprecation_formatter.rb'
5
+
6
+ module RSpec
7
+ module Core
8
+ # Stores runtime configuration information.
9
+ #
10
+ # Configuration options are loaded from `~/.rspec`, `.rspec`,
11
+ # `.rspec-local`, command line switches, and the `SPEC_OPTS` environment
12
+ # variable (listed in lowest to highest precedence; for example, an option
13
+ # in `~/.rspec` can be overridden by an option in `.rspec-local`).
14
+ #
15
+ # @example Standard settings
16
+ # RSpec.configure do |c|
17
+ # c.drb = true
18
+ # c.drb_port = 1234
19
+ # c.default_path = 'behavior'
20
+ # end
21
+ #
22
+ # @example Hooks
23
+ # RSpec.configure do |c|
24
+ # c.before(:suite) { establish_connection }
25
+ # c.before(:each) { log_in_as :authorized }
26
+ # c.around(:each) { |ex| Database.transaction(&ex) }
27
+ # end
28
+ #
29
+ # @see RSpec.configure
30
+ # @see Hooks
31
+ class Configuration
32
+ include RSpec::Core::Hooks
33
+
34
+ class MustBeConfiguredBeforeExampleGroupsError < StandardError; end
35
+
36
+ # @private
37
+ def self.define_reader(name)
38
+ define_method(name) do
39
+ variable = instance_variable_defined?("@#{name}") ? instance_variable_get("@#{name}") : nil
40
+ value_for(name, variable)
41
+ end
42
+ end
43
+
44
+ # @private
45
+ def self.deprecate_alias_key
46
+ RSpec.deprecate("add_setting with :alias option", :replacement => ":alias_with")
47
+ end
48
+
49
+ # @private
50
+ def self.define_aliases(name, alias_name)
51
+ alias_method alias_name, name
52
+ alias_method "#{alias_name}=", "#{name}="
53
+ define_predicate_for alias_name
54
+ end
55
+
56
+ # @private
57
+ def self.define_predicate_for(*names)
58
+ names.each {|name| alias_method "#{name}?", name}
59
+ end
60
+
61
+ # @private
62
+ #
63
+ # Invoked by the `add_setting` instance method. Use that method on a
64
+ # `Configuration` instance rather than this class method.
65
+ def self.add_setting(name, opts={})
66
+ raise "Use the instance add_setting method if you want to set a default" if opts.has_key?(:default)
67
+ if opts[:alias]
68
+ deprecate_alias_key
69
+ define_aliases(opts[:alias], name)
70
+ else
71
+ attr_writer name
72
+ define_reader name
73
+ define_predicate_for name
74
+ end
75
+ Array(opts[:alias_with]).each do |alias_name|
76
+ define_aliases(name, alias_name)
77
+ end
78
+ end
79
+
80
+ # @macro [attach] add_setting
81
+ # @attribute $1
82
+ #
83
+ # @macro [attach] define_reader
84
+ # @attribute $1
85
+
86
+ # @macro add_setting
87
+ # Path to use if no path is provided to the `rspec` command (default:
88
+ # `"spec"`). Allows you to just type `rspec` instead of `rspec spec` to
89
+ # run all the examples in the `spec` directory.
90
+ add_setting :default_path
91
+
92
+ # @macro add_setting
93
+ # Run examples over DRb (default: `false`). RSpec doesn't supply the DRb
94
+ # server, but you can use tools like spork.
95
+ add_setting :drb
96
+
97
+ # @macro add_setting
98
+ # The drb_port (default: nil).
99
+ add_setting :drb_port
100
+
101
+ # @macro add_setting
102
+ # Default: `$stderr`.
103
+ add_setting :error_stream
104
+
105
+ # @macro add_setting
106
+ # Default: `$stderr`.
107
+ add_setting :deprecation_stream
108
+
109
+ # @macro add_setting
110
+ # Clean up and exit after the first failure (default: `false`).
111
+ add_setting :fail_fast
112
+
113
+ # @macro add_setting
114
+ # Prints the formatter output of your suite without running any
115
+ # examples or hooks.
116
+ add_setting :dry_run
117
+
118
+ # @macro add_setting
119
+ # The exit code to return if there are any failures (default: 1).
120
+ add_setting :failure_exit_code
121
+
122
+ # @macro define_reader
123
+ # Indicates files configured to be required
124
+ define_reader :requires
125
+
126
+ # @macro define_reader
127
+ # Returns dirs that have been prepended to the load path by #lib=
128
+ define_reader :libs
129
+
130
+ # @macro add_setting
131
+ # Default: `$stdout`.
132
+ # Also known as `output` and `out`
133
+ add_setting :output_stream, :alias_with => [:output, :out]
134
+
135
+ # @macro add_setting
136
+ # Load files matching this pattern (default: `'**/*_spec.rb'`)
137
+ add_setting :pattern, :alias_with => :filename_pattern
138
+
139
+ def pattern= value
140
+ if @spec_files_loaded
141
+ RSpec.warning "Configuring `pattern` to #{value} has no effect since RSpec has already loaded the spec files."
142
+ end
143
+ @pattern = value
144
+ end
145
+ alias :filename_pattern= :pattern=
146
+
147
+ # @macro add_setting
148
+ # Report the times for the slowest examples (default: `false`).
149
+ # Use this to specify the number of examples to include in the profile.
150
+ add_setting :profile_examples
151
+
152
+ # @macro add_setting
153
+ # Run all examples if none match the configured filters (default: `false`).
154
+ add_setting :run_all_when_everything_filtered
155
+
156
+ # @macro add_setting
157
+ # Color to use to indicate success.
158
+ # @param [Symbol] color one of the following: [:black, :white, :red, :green, :yellow, :blue, :magenta, :cyan]
159
+ add_setting :success_color
160
+
161
+ # @macro add_setting
162
+ # Color to use to print pending examples.
163
+ # @param [Symbol] color one of the following: [:black, :white, :red, :green, :yellow, :blue, :magenta, :cyan]
164
+ add_setting :pending_color
165
+
166
+ # @macro add_setting
167
+ # Color to use to indicate failure.
168
+ # @param [Symbol] color one of the following: [:black, :white, :red, :green, :yellow, :blue, :magenta, :cyan]
169
+ add_setting :failure_color
170
+
171
+ # @macro add_setting
172
+ # The default output color.
173
+ # @param [Symbol] color one of the following: [:black, :white, :red, :green, :yellow, :blue, :magenta, :cyan]
174
+ add_setting :default_color
175
+
176
+ # @macro add_setting
177
+ # Color used when a pending example is fixed.
178
+ # @param [Symbol] color one of the following: [:black, :white, :red, :green, :yellow, :blue, :magenta, :cyan]
179
+ add_setting :fixed_color
180
+
181
+ # @macro add_setting
182
+ # Color used to print details.
183
+ # @param [Symbol] color one of the following: [:black, :white, :red, :green, :yellow, :blue, :magenta, :cyan]
184
+ add_setting :detail_color
185
+
186
+ # @macro add_setting
187
+ # When a block passed to pending fails (as expected), display the failure
188
+ # without reporting it as a failure (default: false).
189
+ add_setting :show_failures_in_pending_blocks
190
+
191
+ # Deprecated. This config option was added in RSpec 2 to pave the way
192
+ # for this being the default behavior in RSpec 3. Now this option is
193
+ # a no-op.
194
+ def treat_symbols_as_metadata_keys_with_true_values=(value)
195
+ RSpec.deprecate("RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values=")
196
+ end
197
+
198
+ # @private
199
+ add_setting :tty
200
+ # @private
201
+ add_setting :include_or_extend_modules
202
+ # @private
203
+ add_setting :files_to_run
204
+ # @private
205
+ add_setting :expecting_with_rspec
206
+ # @private
207
+ attr_accessor :filter_manager
208
+ # @private
209
+ attr_reader :backtrace_formatter, :ordering_manager
210
+
211
+ # Alias for rspec-2.x's backtrace_cleaner (now backtrace_formatter)
212
+ #
213
+ # TODO: consider deprecating and removing this rather than aliasing in rspec-3?
214
+ alias backtrace_cleaner backtrace_formatter
215
+
216
+ def initialize
217
+ @expectation_frameworks = []
218
+ @include_or_extend_modules = []
219
+ @mock_framework = nil
220
+ @files_to_run = []
221
+ @formatters = []
222
+ @color = false
223
+ @pattern = '**/*_spec.rb'
224
+ @failure_exit_code = 1
225
+ @spec_files_loaded = false
226
+
227
+ @backtrace_formatter = BacktraceFormatter.new
228
+
229
+ @default_path = 'spec'
230
+ @deprecation_stream = $stderr
231
+ @filter_manager = FilterManager.new
232
+ @ordering_manager = Ordering::ConfigurationManager.new
233
+ @preferred_options = {}
234
+ @failure_color = :red
235
+ @success_color = :green
236
+ @pending_color = :yellow
237
+ @default_color = :white
238
+ @fixed_color = :blue
239
+ @detail_color = :cyan
240
+ @profile_examples = false
241
+ @requires = []
242
+ @libs = []
243
+ end
244
+
245
+ # @private
246
+ #
247
+ # Used to set higher priority option values from the command line.
248
+ def force(hash)
249
+ ordering_manager.force(hash)
250
+ @preferred_options.merge!(hash)
251
+ self.warnings = value_for :warnings, nil
252
+ end
253
+
254
+ # @private
255
+ def reset
256
+ @spec_files_loaded = false
257
+ @reporter = nil
258
+ @formatters.clear
259
+ end
260
+
261
+ # @overload add_setting(name)
262
+ # @overload add_setting(name, opts)
263
+ # @option opts [Symbol] :default
264
+ #
265
+ # set a default value for the generated getter and predicate methods:
266
+ #
267
+ # add_setting(:foo, :default => "default value")
268
+ #
269
+ # @option opts [Symbol] :alias_with
270
+ #
271
+ # Use `:alias_with` to alias the setter, getter, and predicate to another
272
+ # name, or names:
273
+ #
274
+ # add_setting(:foo, :alias_with => :bar)
275
+ # add_setting(:foo, :alias_with => [:bar, :baz])
276
+ #
277
+ # Adds a custom setting to the RSpec.configuration object.
278
+ #
279
+ # RSpec.configuration.add_setting :foo
280
+ #
281
+ # Used internally and by extension frameworks like rspec-rails, so they
282
+ # can add config settings that are domain specific. For example:
283
+ #
284
+ # RSpec.configure do |c|
285
+ # c.add_setting :use_transactional_fixtures,
286
+ # :default => true,
287
+ # :alias_with => :use_transactional_examples
288
+ # end
289
+ #
290
+ # `add_setting` creates three methods on the configuration object, a
291
+ # setter, a getter, and a predicate:
292
+ #
293
+ # RSpec.configuration.foo=(value)
294
+ # RSpec.configuration.foo
295
+ # RSpec.configuration.foo? # returns true if foo returns anything but nil or false
296
+ def add_setting(name, opts={})
297
+ default = opts.delete(:default)
298
+ (class << self; self; end).class_eval do
299
+ add_setting(name, opts)
300
+ end
301
+ send("#{name}=", default) if default
302
+ end
303
+
304
+ # Returns the configured mock framework adapter module
305
+ def mock_framework
306
+ mock_with :rspec unless @mock_framework
307
+ @mock_framework
308
+ end
309
+
310
+ # Delegates to mock_framework=(framework)
311
+ def mock_framework=(framework)
312
+ mock_with framework
313
+ end
314
+
315
+ # Regexps used to exclude lines from backtraces.
316
+ #
317
+ # Excludes lines from ruby (and jruby) source, installed gems, anything
318
+ # in any "bin" directory, and any of the rspec libs (outside gem
319
+ # installs) by default.
320
+ #
321
+ # You can modify the list via the getter, or replace it with the setter.
322
+ #
323
+ # To override this behaviour and display a full backtrace, use
324
+ # `--backtrace`on the command line, in a `.rspec` file, or in the
325
+ # `rspec_options` attribute of RSpec's rake task.
326
+ def backtrace_exclusion_patterns
327
+ @backtrace_formatter.exclusion_patterns
328
+ end
329
+
330
+ def backtrace_exclusion_patterns=(patterns)
331
+ @backtrace_formatter.exclusion_patterns = patterns
332
+ end
333
+
334
+ # Regexps used to include lines in backtraces.
335
+ #
336
+ # Defaults to [Regexp.new Dir.getwd].
337
+ #
338
+ # Lines that match an exclusion _and_ an inclusion pattern
339
+ # will be included.
340
+ #
341
+ # You can modify the list via the getter, or replace it with the setter.
342
+ def backtrace_inclusion_patterns
343
+ @backtrace_formatter.inclusion_patterns
344
+ end
345
+
346
+ def backtrace_inclusion_patterns=(patterns)
347
+ @backtrace_formatter.inclusion_patterns = patterns
348
+ end
349
+
350
+ # Sets the mock framework adapter module.
351
+ #
352
+ # `framework` can be a Symbol or a Module.
353
+ #
354
+ # Given any of `:rspec`, `:mocha`, `:flexmock`, or `:rr`, configures the
355
+ # named framework.
356
+ #
357
+ # Given `:nothing`, configures no framework. Use this if you don't use
358
+ # any mocking framework to save a little bit of overhead.
359
+ #
360
+ # Given a Module, includes that module in every example group. The module
361
+ # should adhere to RSpec's mock framework adapter API:
362
+ #
363
+ # setup_mocks_for_rspec
364
+ # - called before each example
365
+ #
366
+ # verify_mocks_for_rspec
367
+ # - called after each example. Framework should raise an exception
368
+ # when expectations fail
369
+ #
370
+ # teardown_mocks_for_rspec
371
+ # - called after verify_mocks_for_rspec (even if there are errors)
372
+ #
373
+ # If the module responds to `configuration` and `mock_with` receives a block,
374
+ # it will yield the configuration object to the block e.g.
375
+ #
376
+ # config.mock_with OtherMockFrameworkAdapter do |mod_config|
377
+ # mod_config.custom_setting = true
378
+ # end
379
+ def mock_with(framework)
380
+ framework_module = case framework
381
+ when Module
382
+ framework
383
+ when String, Symbol
384
+ require case framework.to_s
385
+ when /rspec/i
386
+ 'rspec/core/mocking/with_rspec'
387
+ when /mocha/i
388
+ 'rspec/core/mocking/with_mocha'
389
+ when /rr/i
390
+ 'rspec/core/mocking/with_rr'
391
+ when /flexmock/i
392
+ 'rspec/core/mocking/with_flexmock'
393
+ else
394
+ 'rspec/core/mocking/with_absolutely_nothing'
395
+ end
396
+ RSpec::Core::MockFrameworkAdapter
397
+ end
398
+
399
+ new_name, old_name = [framework_module, @mock_framework].map do |mod|
400
+ mod.respond_to?(:framework_name) ? mod.framework_name : :unnamed
401
+ end
402
+
403
+ unless new_name == old_name
404
+ assert_no_example_groups_defined(:mock_framework)
405
+ end
406
+
407
+ if block_given?
408
+ raise "#{framework_module} must respond to `configuration` so that mock_with can yield it." unless framework_module.respond_to?(:configuration)
409
+ yield framework_module.configuration
410
+ end
411
+
412
+ @mock_framework = framework_module
413
+ end
414
+
415
+ # Returns the configured expectation framework adapter module(s)
416
+ def expectation_frameworks
417
+ expect_with :rspec if @expectation_frameworks.empty?
418
+ @expectation_frameworks
419
+ end
420
+
421
+ # Delegates to expect_with(framework)
422
+ def expectation_framework=(framework)
423
+ expect_with(framework)
424
+ end
425
+
426
+ # Sets the expectation framework module(s) to be included in each example
427
+ # group.
428
+ #
429
+ # `frameworks` can be `:rspec`, `:stdlib`, a custom module, or any
430
+ # combination thereof:
431
+ #
432
+ # config.expect_with :rspec
433
+ # config.expect_with :stdlib
434
+ # config.expect_with :rspec, :stdlib
435
+ # config.expect_with OtherExpectationFramework
436
+ #
437
+ # RSpec will translate `:rspec` and `:stdlib` into the appropriate
438
+ # modules.
439
+ #
440
+ # ## Configuration
441
+ #
442
+ # If the module responds to `configuration`, `expect_with` will
443
+ # yield the `configuration` object if given a block:
444
+ #
445
+ # config.expect_with OtherExpectationFramework do |custom_config|
446
+ # custom_config.custom_setting = true
447
+ # end
448
+ def expect_with(*frameworks)
449
+ modules = frameworks.map do |framework|
450
+ case framework
451
+ when Module
452
+ framework
453
+ when :rspec
454
+ require 'rspec/expectations'
455
+ self.expecting_with_rspec = true
456
+ ::RSpec::Matchers
457
+ when :stdlib
458
+ require 'test/unit/assertions'
459
+ ::Test::Unit::Assertions
460
+ else
461
+ raise ArgumentError, "#{framework.inspect} is not supported"
462
+ end
463
+ end
464
+
465
+ if (modules - @expectation_frameworks).any?
466
+ assert_no_example_groups_defined(:expect_with)
467
+ end
468
+
469
+ if block_given?
470
+ raise "expect_with only accepts a block with a single argument. Call expect_with #{modules.length} times, once with each argument, instead." if modules.length > 1
471
+ raise "#{modules.first} must respond to `configuration` so that expect_with can yield it." unless modules.first.respond_to?(:configuration)
472
+ yield modules.first.configuration
473
+ end
474
+
475
+ @expectation_frameworks.push(*modules)
476
+ end
477
+
478
+ def full_backtrace?
479
+ @backtrace_formatter.full_backtrace?
480
+ end
481
+
482
+ def full_backtrace=(true_or_false)
483
+ @backtrace_formatter.full_backtrace = true_or_false
484
+ end
485
+
486
+ def color(output=output_stream)
487
+ # rspec's built-in formatters all call this with the output argument,
488
+ # but defaulting to output_stream for backward compatibility with
489
+ # formatters in extension libs
490
+ return false unless output_to_tty?(output)
491
+ value_for(:color, @color)
492
+ end
493
+
494
+ def color=(bool)
495
+ if bool
496
+ if RSpec.windows_os? and not ENV['ANSICON']
497
+ RSpec.warning "You must use ANSICON 1.31 or later (http://adoxa.3eeweb.com/ansicon/) to use colour on Windows"
498
+ @color = false
499
+ else
500
+ @color = true
501
+ end
502
+ end
503
+ end
504
+
505
+ # TODO - deprecate color_enabled - probably not until the last 2.x
506
+ # release before 3.0
507
+ alias_method :color_enabled, :color
508
+ alias_method :color_enabled=, :color=
509
+ define_predicate_for :color_enabled, :color
510
+
511
+ def libs=(libs)
512
+ libs.map do |lib|
513
+ @libs.unshift lib
514
+ $LOAD_PATH.unshift lib
515
+ end
516
+ end
517
+
518
+ def requires=(paths)
519
+ RSpec.deprecate("RSpec::Core::Configuration#requires=(paths)",
520
+ :replacement => "paths.each {|path| require path}")
521
+ paths.map {|path| require path}
522
+ @requires += paths
523
+ end
524
+
525
+ # Run examples defined on `line_numbers` in all files to run.
526
+ def line_numbers=(line_numbers)
527
+ filter_run :line_numbers => line_numbers.map{|l| l.to_i}
528
+ end
529
+
530
+ def line_numbers
531
+ filter.fetch(:line_numbers,[])
532
+ end
533
+
534
+ def full_description=(description)
535
+ filter_run :full_description => Regexp.union(*Array(description).map {|d| Regexp.new(d) })
536
+ end
537
+
538
+ def full_description
539
+ filter.fetch :full_description, nil
540
+ end
541
+
542
+ # @overload add_formatter(formatter)
543
+ #
544
+ # Adds a formatter to the formatters collection. `formatter` can be a
545
+ # string representing any of the built-in formatters (see
546
+ # `built_in_formatter`), or a custom formatter class.
547
+ #
548
+ # ### Note
549
+ #
550
+ # For internal purposes, `add_formatter` also accepts the name of a class
551
+ # and paths to use for output streams, but you should consider that a
552
+ # private api that may change at any time without notice.
553
+ def add_formatter(formatter_to_use, *paths)
554
+ formatter_class =
555
+ built_in_formatter(formatter_to_use) ||
556
+ custom_formatter(formatter_to_use) ||
557
+ (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.")
558
+
559
+ paths << output if paths.empty?
560
+ formatters << formatter_class.new(*paths.map {|p| String === p ? file_at(p) : p})
561
+ end
562
+
563
+ alias_method :formatter=, :add_formatter
564
+
565
+ def formatters
566
+ @formatters ||= []
567
+ end
568
+
569
+ def reporter
570
+ @reporter ||= begin
571
+ add_formatter('progress') if formatters.empty?
572
+ add_formatter(RSpec::Core::Formatters::DeprecationFormatter, deprecation_stream, output_stream)
573
+ Reporter.new(self, *formatters)
574
+ end
575
+ end
576
+
577
+ # @api private
578
+ #
579
+ # Defaults `profile_examples` to 10 examples when `@profile_examples` is `true`.
580
+ #
581
+ def profile_examples
582
+ profile = value_for(:profile_examples, @profile_examples)
583
+ if profile && !profile.is_a?(Integer)
584
+ 10
585
+ else
586
+ profile
587
+ end
588
+ end
589
+
590
+ # @private
591
+ def files_or_directories_to_run=(*files)
592
+ files = files.flatten
593
+ files << default_path if (command == 'rspec' || Runner.running_in_drb?) && default_path && files.empty?
594
+ self.files_to_run = get_files_to_run(files)
595
+ end
596
+
597
+ # Creates a method that delegates to `example` including the submitted
598
+ # `args`. Used internally to add variants of `example` like `pending`:
599
+ #
600
+ # @example
601
+ # alias_example_to :pending, :pending => true
602
+ #
603
+ # # This lets you do this:
604
+ #
605
+ # describe Thing do
606
+ # pending "does something" do
607
+ # thing = Thing.new
608
+ # end
609
+ # end
610
+ #
611
+ # # ... which is the equivalent of
612
+ #
613
+ # describe Thing do
614
+ # it "does something", :pending => true do
615
+ # thing = Thing.new
616
+ # end
617
+ # end
618
+ def alias_example_to(new_name, *args)
619
+ extra_options = Metadata.build_hash_from(args)
620
+ RSpec::Core::ExampleGroup.alias_example_to(new_name, extra_options)
621
+ end
622
+
623
+ # Define an alias for it_should_behave_like that allows different
624
+ # language (like "it_has_behavior" or "it_behaves_like") to be
625
+ # employed when including shared examples.
626
+ #
627
+ # Example:
628
+ #
629
+ # alias_it_behaves_like_to(:it_has_behavior, 'has behavior:')
630
+ #
631
+ # allows the user to include a shared example group like:
632
+ #
633
+ # describe Entity do
634
+ # it_has_behavior 'sortability' do
635
+ # let(:sortable) { Entity.new }
636
+ # end
637
+ # end
638
+ #
639
+ # which is reported in the output as:
640
+ #
641
+ # Entity
642
+ # has behavior: sortability
643
+ # # sortability examples here
644
+ def alias_it_behaves_like_to(new_name, report_label = '')
645
+ RSpec::Core::ExampleGroup.alias_it_behaves_like_to(new_name, report_label)
646
+ end
647
+
648
+ alias_method :alias_it_should_behave_like_to, :alias_it_behaves_like_to
649
+
650
+ # Adds key/value pairs to the `inclusion_filter`. If `args`
651
+ # includes any symbols that are not part of the hash, each symbol
652
+ # is treated as a key in the hash with the value `true`.
653
+ #
654
+ # ### Note
655
+ #
656
+ # Filters set using this method can be overridden from the command line
657
+ # or config files (e.g. `.rspec`).
658
+ #
659
+ # @example
660
+ # # given this declaration
661
+ # describe "something", :foo => 'bar' do
662
+ # # ...
663
+ # end
664
+ #
665
+ # # any of the following will include that group
666
+ # config.filter_run_including :foo => 'bar'
667
+ # config.filter_run_including :foo => /^ba/
668
+ # config.filter_run_including :foo => lambda {|v| v == 'bar'}
669
+ # config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
670
+ #
671
+ # # given a proc with an arity of 1, the lambda is passed the value related to the key, e.g.
672
+ # config.filter_run_including :foo => lambda {|v| v == 'bar'}
673
+ #
674
+ # # given a proc with an arity of 2, the lambda is passed the value related to the key,
675
+ # # and the metadata itself e.g.
676
+ # config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
677
+ #
678
+ # filter_run_including :foo # same as filter_run_including :foo => true
679
+ def filter_run_including(*args)
680
+ filter_manager.include_with_low_priority Metadata.build_hash_from(args)
681
+ end
682
+
683
+ alias_method :filter_run, :filter_run_including
684
+
685
+ # Clears and reassigns the `inclusion_filter`. Set to `nil` if you don't
686
+ # want any inclusion filter at all.
687
+ #
688
+ # ### Warning
689
+ #
690
+ # This overrides any inclusion filters/tags set on the command line or in
691
+ # configuration files.
692
+ def inclusion_filter=(filter)
693
+ filter_manager.include! Metadata.build_hash_from([filter])
694
+ end
695
+
696
+ alias_method :filter=, :inclusion_filter=
697
+
698
+ # Returns the `inclusion_filter`. If none has been set, returns an empty
699
+ # hash.
700
+ def inclusion_filter
701
+ filter_manager.inclusions
702
+ end
703
+
704
+ alias_method :filter, :inclusion_filter
705
+
706
+ # Adds key/value pairs to the `exclusion_filter`. If `args`
707
+ # includes any symbols that are not part of the hash, each symbol
708
+ # is treated as a key in the hash with the value `true`.
709
+ #
710
+ # ### Note
711
+ #
712
+ # Filters set using this method can be overridden from the command line
713
+ # or config files (e.g. `.rspec`).
714
+ #
715
+ # @example
716
+ # # given this declaration
717
+ # describe "something", :foo => 'bar' do
718
+ # # ...
719
+ # end
720
+ #
721
+ # # any of the following will exclude that group
722
+ # config.filter_run_excluding :foo => 'bar'
723
+ # config.filter_run_excluding :foo => /^ba/
724
+ # config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
725
+ # config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
726
+ #
727
+ # # given a proc with an arity of 1, the lambda is passed the value related to the key, e.g.
728
+ # config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
729
+ #
730
+ # # given a proc with an arity of 2, the lambda is passed the value related to the key,
731
+ # # and the metadata itself e.g.
732
+ # config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
733
+ #
734
+ # filter_run_excluding :foo # same as filter_run_excluding :foo => true
735
+ def filter_run_excluding(*args)
736
+ filter_manager.exclude_with_low_priority Metadata.build_hash_from(args)
737
+ end
738
+
739
+ # Clears and reassigns the `exclusion_filter`. Set to `nil` if you don't
740
+ # want any exclusion filter at all.
741
+ #
742
+ # ### Warning
743
+ #
744
+ # This overrides any exclusion filters/tags set on the command line or in
745
+ # configuration files.
746
+ def exclusion_filter=(filter)
747
+ filter_manager.exclude! Metadata.build_hash_from([filter])
748
+ end
749
+
750
+ # Returns the `exclusion_filter`. If none has been set, returns an empty
751
+ # hash.
752
+ def exclusion_filter
753
+ filter_manager.exclusions
754
+ end
755
+
756
+ # Tells RSpec to include `mod` in example groups. Methods defined in
757
+ # `mod` are exposed to examples (not example groups). Use `filters` to
758
+ # constrain the groups in which to include the module.
759
+ #
760
+ # @example
761
+ #
762
+ # module AuthenticationHelpers
763
+ # def login_as(user)
764
+ # # ...
765
+ # end
766
+ # end
767
+ #
768
+ # module UserHelpers
769
+ # def users(username)
770
+ # # ...
771
+ # end
772
+ # end
773
+ #
774
+ # RSpec.configure do |config|
775
+ # config.include(UserHelpers) # included in all modules
776
+ # config.include(AuthenticationHelpers, :type => :request)
777
+ # end
778
+ #
779
+ # describe "edit profile", :type => :request do
780
+ # it "can be viewed by owning user" do
781
+ # login_as users(:jdoe)
782
+ # get "/profiles/jdoe"
783
+ # assert_select ".username", :text => 'jdoe'
784
+ # end
785
+ # end
786
+ #
787
+ # @see #extend
788
+ def include(mod, *filters)
789
+ include_or_extend_modules << [:include, mod, Metadata.build_hash_from(filters)]
790
+ end
791
+
792
+ # Tells RSpec to extend example groups with `mod`. Methods defined in
793
+ # `mod` are exposed to example groups (not examples). Use `filters` to
794
+ # constrain the groups to extend.
795
+ #
796
+ # Similar to `include`, but behavior is added to example groups, which
797
+ # are classes, rather than the examples, which are instances of those
798
+ # classes.
799
+ #
800
+ # @example
801
+ #
802
+ # module UiHelpers
803
+ # def run_in_browser
804
+ # # ...
805
+ # end
806
+ # end
807
+ #
808
+ # RSpec.configure do |config|
809
+ # config.extend(UiHelpers, :type => :request)
810
+ # end
811
+ #
812
+ # describe "edit profile", :type => :request do
813
+ # run_in_browser
814
+ #
815
+ # it "does stuff in the client" do
816
+ # # ...
817
+ # end
818
+ # end
819
+ #
820
+ # @see #include
821
+ def extend(mod, *filters)
822
+ include_or_extend_modules << [:extend, mod, Metadata.build_hash_from(filters)]
823
+ end
824
+
825
+ # @private
826
+ #
827
+ # Used internally to extend a group with modules using `include` and/or
828
+ # `extend`.
829
+ def configure_group(group)
830
+ include_or_extend_modules.each do |include_or_extend, mod, filters|
831
+ next unless filters.empty? || group.any_apply?(filters)
832
+ send("safe_#{include_or_extend}", mod, group)
833
+ end
834
+ end
835
+
836
+ # @private
837
+ def safe_include(mod, host)
838
+ host.send(:include,mod) unless host < mod
839
+ end
840
+
841
+ # @private
842
+ def setup_load_path_and_require(paths)
843
+ directories = ['lib', default_path].select { |p| File.directory? p }
844
+ RSpec::Core::RubyProject.add_to_load_path(*directories)
845
+ paths.each {|path| require path}
846
+ @requires += paths
847
+ end
848
+
849
+ # @private
850
+ if RUBY_VERSION.to_f >= 1.9
851
+ def safe_extend(mod, host)
852
+ host.extend(mod) unless (class << host; self; end) < mod
853
+ end
854
+ else
855
+ def safe_extend(mod, host)
856
+ host.extend(mod) unless (class << host; self; end).included_modules.include?(mod)
857
+ end
858
+ end
859
+
860
+ # @private
861
+ def configure_mock_framework
862
+ RSpec::Core::ExampleGroup.send(:include, mock_framework)
863
+ end
864
+
865
+ # @private
866
+ def configure_expectation_framework
867
+ expectation_frameworks.each do |framework|
868
+ RSpec::Core::ExampleGroup.send(:include, framework)
869
+ end
870
+ end
871
+
872
+ # @private
873
+ def load_spec_files
874
+ files_to_run.uniq.each {|f| load File.expand_path(f) }
875
+ @spec_files_loaded = true
876
+ end
877
+
878
+ # @private
879
+ DEFAULT_FORMATTER = lambda { |string| string }
880
+
881
+ # Formats the docstring output using the block provided.
882
+ #
883
+ # @example
884
+ # # This will strip the descriptions of both examples and example groups.
885
+ # RSpec.configure do |config|
886
+ # config.format_docstrings { |s| s.strip }
887
+ # end
888
+ def format_docstrings(&block)
889
+ @format_docstrings_block = block_given? ? block : DEFAULT_FORMATTER
890
+ end
891
+
892
+ # @private
893
+ def format_docstrings_block
894
+ @format_docstrings_block ||= DEFAULT_FORMATTER
895
+ end
896
+
897
+ # @private
898
+ def self.delegate_to_ordering_manager(*methods)
899
+ methods.each do |method|
900
+ define_method method do |*args, &block|
901
+ ordering_manager.__send__(method, *args, &block)
902
+ end
903
+ end
904
+ end
905
+
906
+ # @macro delegate_to_ordering_manager
907
+ #
908
+ # Sets the seed value and sets the default global ordering to random.
909
+ delegate_to_ordering_manager :seed=
910
+
911
+ # @macro delegate_to_ordering_manager
912
+ # Seed for random ordering (default: generated randomly each run).
913
+ #
914
+ # When you run specs with `--order random`, RSpec generates a random seed
915
+ # for the randomization and prints it to the `output_stream` (assuming
916
+ # you're using RSpec's built-in formatters). If you discover an ordering
917
+ # dependency (i.e. examples fail intermittently depending on order), set
918
+ # this (on Configuration or on the command line with `--seed`) to run
919
+ # using the same seed while you debug the issue.
920
+ #
921
+ # We recommend, actually, that you use the command line approach so you
922
+ # don't accidentally leave the seed encoded.
923
+ delegate_to_ordering_manager :seed
924
+
925
+ # @macro delegate_to_ordering_manager
926
+ #
927
+ # Sets the default global order and, if order is `'rand:<seed>'`, also sets the seed.
928
+ delegate_to_ordering_manager :order=
929
+
930
+ # @macro delegate_to_ordering_manager
931
+ # Registers a named ordering strategy that can later be
932
+ # used to order an example group's subgroups by adding
933
+ # `:order => <name>` metadata to the example group.
934
+ #
935
+ # @param name [Symbol] The name of the ordering.
936
+ # @yield Block that will order the given examples or example groups
937
+ # @yieldparam list [Array<RSpec::Core::Example>, Array<RSpec::Core::ExampleGropu>] The examples or groups to order
938
+ # @yieldreturn [Array<RSpec::Core::Example>, Array<RSpec::Core::ExampleGroup>] The re-ordered examples or groups
939
+ #
940
+ # @example
941
+ # RSpec.configure do |rspec|
942
+ # rspec.register_ordering :reverse do |list|
943
+ # list.reverse
944
+ # end
945
+ # end
946
+ #
947
+ # describe MyClass, :order => :reverse do
948
+ # # ...
949
+ # end
950
+ #
951
+ # @note Pass the symbol `:global` to set the ordering strategy that
952
+ # will be used to order the top-level example groups and any example
953
+ # groups that do not have declared `:order` metadata.
954
+ delegate_to_ordering_manager :register_ordering
955
+
956
+ # @private
957
+ delegate_to_ordering_manager :seed_used?, :ordering_registry
958
+
959
+ # Set Ruby warnings on or off
960
+ def warnings= value
961
+ $VERBOSE = !!value
962
+ end
963
+
964
+ def warnings
965
+ $VERBOSE
966
+ end
967
+
968
+ private
969
+
970
+ def get_files_to_run(paths)
971
+ FlatMap.flat_map(paths) do |path|
972
+ path = path.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
973
+ File.directory?(path) ? gather_directories(path) : extract_location(path)
974
+ end.sort
975
+ end
976
+
977
+ def gather_directories(path)
978
+ stripped = "{#{pattern.gsub(/\s*,\s*/, ',')}}"
979
+ files = pattern =~ /^#{Regexp.escape path}/ ? Dir[stripped] : Dir["#{path}/#{stripped}"]
980
+ files.sort
981
+ end
982
+
983
+ def extract_location(path)
984
+ if path =~ /^(.*?)((?:\:\d+)+)$/
985
+ path, lines = $1, $2[1..-1].split(":").map{|n| n.to_i}
986
+ filter_manager.add_location path, lines
987
+ end
988
+ path
989
+ end
990
+
991
+ def command
992
+ $0.split(File::SEPARATOR).last
993
+ end
994
+
995
+ def value_for(key, default=nil)
996
+ @preferred_options.has_key?(key) ? @preferred_options[key] : default
997
+ end
998
+
999
+ def assert_no_example_groups_defined(config_option)
1000
+ if RSpec.world.example_groups.any?
1001
+ raise MustBeConfiguredBeforeExampleGroupsError.new(
1002
+ "RSpec's #{config_option} configuration option must be configured before " +
1003
+ "any example groups are defined, but you have already defined a group."
1004
+ )
1005
+ end
1006
+ end
1007
+
1008
+ def output_to_tty?(output=output_stream)
1009
+ tty? || (output.respond_to?(:tty?) && output.tty?)
1010
+ end
1011
+
1012
+ def built_in_formatter(key)
1013
+ case key.to_s
1014
+ when 'd', 'doc', 'documentation', 's', 'n', 'spec', 'nested'
1015
+ require 'rspec/core/formatters/documentation_formatter'
1016
+ RSpec::Core::Formatters::DocumentationFormatter
1017
+ when 'h', 'html'
1018
+ require 'rspec/core/formatters/html_formatter'
1019
+ RSpec::Core::Formatters::HtmlFormatter
1020
+ when 'p', 'progress'
1021
+ require 'rspec/core/formatters/progress_formatter'
1022
+ RSpec::Core::Formatters::ProgressFormatter
1023
+ when 'j', 'json'
1024
+ require 'rspec/core/formatters/json_formatter'
1025
+ RSpec::Core::Formatters::JsonFormatter
1026
+ end
1027
+ end
1028
+
1029
+ def custom_formatter(formatter_ref)
1030
+ if Class === formatter_ref
1031
+ formatter_ref
1032
+ elsif string_const?(formatter_ref)
1033
+ begin
1034
+ formatter_ref.gsub(/^::/,'').split('::').inject(Object) { |const,string| const.const_get string }
1035
+ rescue NameError
1036
+ # require( path_for(formatter_ref) ) ? retry : raise
1037
+ end
1038
+ end
1039
+ end
1040
+
1041
+ def string_const?(str)
1042
+ str.is_a?(String) && /\A[A-Z][a-zA-Z0-9_:]*\z/ =~ str
1043
+ end
1044
+
1045
+ def path_for(const_ref)
1046
+ underscore_with_fix_for_non_standard_rspec_naming(const_ref)
1047
+ end
1048
+
1049
+ def underscore_with_fix_for_non_standard_rspec_naming(string)
1050
+ underscore(string).sub(%r{(^|/)r_spec($|/)}, '\\1rspec\\2')
1051
+ end
1052
+
1053
+ # activesupport/lib/active_support/inflector/methods.rb, line 48
1054
+ def underscore(camel_cased_word)
1055
+ word = camel_cased_word.to_s.dup
1056
+ word.gsub!(/::/, '/')
1057
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
1058
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
1059
+ word.tr!("-", "_")
1060
+ word.downcase!
1061
+ word
1062
+ end
1063
+
1064
+ def file_at(path)
1065
+ FileUtils.mkdir_p(File.dirname(path))
1066
+ File.new(path, 'w')
1067
+ end
1068
+ end
1069
+ end
1070
+ end