rspec-core 3.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.document +5 -0
  5. data/.yardopts +8 -0
  6. data/Changelog.md +2243 -0
  7. data/LICENSE.md +26 -0
  8. data/README.md +384 -0
  9. data/exe/rspec +4 -0
  10. data/lib/rspec/autorun.rb +3 -0
  11. data/lib/rspec/core.rb +185 -0
  12. data/lib/rspec/core/backtrace_formatter.rb +65 -0
  13. data/lib/rspec/core/bisect/coordinator.rb +62 -0
  14. data/lib/rspec/core/bisect/example_minimizer.rb +173 -0
  15. data/lib/rspec/core/bisect/fork_runner.rb +134 -0
  16. data/lib/rspec/core/bisect/server.rb +61 -0
  17. data/lib/rspec/core/bisect/shell_command.rb +126 -0
  18. data/lib/rspec/core/bisect/shell_runner.rb +73 -0
  19. data/lib/rspec/core/bisect/utilities.rb +58 -0
  20. data/lib/rspec/core/configuration.rb +2308 -0
  21. data/lib/rspec/core/configuration_options.rb +233 -0
  22. data/lib/rspec/core/drb.rb +113 -0
  23. data/lib/rspec/core/dsl.rb +98 -0
  24. data/lib/rspec/core/example.rb +656 -0
  25. data/lib/rspec/core/example_group.rb +889 -0
  26. data/lib/rspec/core/example_status_persister.rb +235 -0
  27. data/lib/rspec/core/filter_manager.rb +231 -0
  28. data/lib/rspec/core/flat_map.rb +20 -0
  29. data/lib/rspec/core/formatters.rb +269 -0
  30. data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
  31. data/lib/rspec/core/formatters/base_formatter.rb +70 -0
  32. data/lib/rspec/core/formatters/base_text_formatter.rb +75 -0
  33. data/lib/rspec/core/formatters/bisect_drb_formatter.rb +29 -0
  34. data/lib/rspec/core/formatters/bisect_progress_formatter.rb +157 -0
  35. data/lib/rspec/core/formatters/console_codes.rb +68 -0
  36. data/lib/rspec/core/formatters/deprecation_formatter.rb +223 -0
  37. data/lib/rspec/core/formatters/documentation_formatter.rb +70 -0
  38. data/lib/rspec/core/formatters/exception_presenter.rb +508 -0
  39. data/lib/rspec/core/formatters/fallback_message_formatter.rb +28 -0
  40. data/lib/rspec/core/formatters/helpers.rb +110 -0
  41. data/lib/rspec/core/formatters/html_formatter.rb +153 -0
  42. data/lib/rspec/core/formatters/html_printer.rb +414 -0
  43. data/lib/rspec/core/formatters/html_snippet_extractor.rb +120 -0
  44. data/lib/rspec/core/formatters/json_formatter.rb +102 -0
  45. data/lib/rspec/core/formatters/profile_formatter.rb +68 -0
  46. data/lib/rspec/core/formatters/progress_formatter.rb +29 -0
  47. data/lib/rspec/core/formatters/protocol.rb +182 -0
  48. data/lib/rspec/core/formatters/snippet_extractor.rb +134 -0
  49. data/lib/rspec/core/formatters/syntax_highlighter.rb +91 -0
  50. data/lib/rspec/core/hooks.rb +624 -0
  51. data/lib/rspec/core/invocations.rb +87 -0
  52. data/lib/rspec/core/memoized_helpers.rb +554 -0
  53. data/lib/rspec/core/metadata.rb +498 -0
  54. data/lib/rspec/core/metadata_filter.rb +255 -0
  55. data/lib/rspec/core/minitest_assertions_adapter.rb +31 -0
  56. data/lib/rspec/core/mocking_adapters/flexmock.rb +31 -0
  57. data/lib/rspec/core/mocking_adapters/mocha.rb +57 -0
  58. data/lib/rspec/core/mocking_adapters/null.rb +14 -0
  59. data/lib/rspec/core/mocking_adapters/rr.rb +31 -0
  60. data/lib/rspec/core/mocking_adapters/rspec.rb +32 -0
  61. data/lib/rspec/core/notifications.rb +521 -0
  62. data/lib/rspec/core/option_parser.rb +309 -0
  63. data/lib/rspec/core/ordering.rb +158 -0
  64. data/lib/rspec/core/output_wrapper.rb +29 -0
  65. data/lib/rspec/core/pending.rb +165 -0
  66. data/lib/rspec/core/profiler.rb +34 -0
  67. data/lib/rspec/core/project_initializer.rb +48 -0
  68. data/lib/rspec/core/project_initializer/.rspec +1 -0
  69. data/lib/rspec/core/project_initializer/spec/spec_helper.rb +100 -0
  70. data/lib/rspec/core/rake_task.rb +168 -0
  71. data/lib/rspec/core/reporter.rb +257 -0
  72. data/lib/rspec/core/ruby_project.rb +53 -0
  73. data/lib/rspec/core/runner.rb +199 -0
  74. data/lib/rspec/core/sandbox.rb +37 -0
  75. data/lib/rspec/core/set.rb +54 -0
  76. data/lib/rspec/core/shared_context.rb +55 -0
  77. data/lib/rspec/core/shared_example_group.rb +269 -0
  78. data/lib/rspec/core/shell_escape.rb +49 -0
  79. data/lib/rspec/core/test_unit_assertions_adapter.rb +30 -0
  80. data/lib/rspec/core/version.rb +9 -0
  81. data/lib/rspec/core/warnings.rb +40 -0
  82. data/lib/rspec/core/world.rb +275 -0
  83. metadata +292 -0
  84. metadata.gz.sig +0 -0
@@ -0,0 +1,29 @@
1
+ module RSpec
2
+ module Core
3
+ # @private
4
+ class OutputWrapper
5
+ # @private
6
+ attr_accessor :output
7
+
8
+ # @private
9
+ def initialize(output)
10
+ @output = output
11
+ end
12
+
13
+ def respond_to?(name, priv=false)
14
+ output.respond_to?(name, priv)
15
+ end
16
+
17
+ def method_missing(name, *args, &block)
18
+ output.send(name, *args, &block)
19
+ end
20
+
21
+ # Redirect calls for IO interface methods
22
+ IO.instance_methods(false).each do |method|
23
+ define_method(method) do |*args, &block|
24
+ output.send(method, *args, &block)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,165 @@
1
+ module RSpec
2
+ module Core
3
+ # Provides methods to mark examples as pending. These methods are available
4
+ # to be called from within any example or hook.
5
+ module Pending
6
+ # Raised in the middle of an example to indicate that it should be marked
7
+ # as skipped.
8
+ class SkipDeclaredInExample < StandardError
9
+ attr_reader :argument
10
+
11
+ def initialize(argument)
12
+ @argument = argument
13
+ end
14
+ end
15
+
16
+ # If Test::Unit is loaded, we'll use its error as baseclass, so that
17
+ # Test::Unit will report unmet RSpec expectations as failures rather than
18
+ # errors.
19
+ begin
20
+ class PendingExampleFixedError < Test::Unit::AssertionFailedError; end
21
+ rescue
22
+ class PendingExampleFixedError < StandardError; end
23
+ end
24
+
25
+ # @private
26
+ NO_REASON_GIVEN = 'No reason given'
27
+
28
+ # @private
29
+ NOT_YET_IMPLEMENTED = 'Not yet implemented'
30
+
31
+ # @overload pending()
32
+ # @overload pending(message)
33
+ #
34
+ # Marks an example as pending. The rest of the example will still be
35
+ # executed, and if it passes the example will fail to indicate that the
36
+ # pending can be removed.
37
+ #
38
+ # @param message [String] optional message to add to the summary report.
39
+ #
40
+ # @example
41
+ # describe "an example" do
42
+ # # reported as "Pending: no reason given"
43
+ # it "is pending with no message" do
44
+ # pending
45
+ # raise "broken"
46
+ # end
47
+ #
48
+ # # reported as "Pending: something else getting finished"
49
+ # it "is pending with a custom message" do
50
+ # pending("something else getting finished")
51
+ # raise "broken"
52
+ # end
53
+ # end
54
+ #
55
+ # @note `before(:example)` hooks are eval'd when you use the `pending`
56
+ # method within an example. If you want to declare an example `pending`
57
+ # and bypass the `before` hooks as well, you can pass `:pending => true`
58
+ # to the `it` method:
59
+ #
60
+ # it "does something", :pending => true do
61
+ # # ...
62
+ # end
63
+ #
64
+ # or pass `:pending => "something else getting finished"` to add a
65
+ # message to the summary report:
66
+ #
67
+ # it "does something", :pending => "something else getting finished" do
68
+ # # ...
69
+ # end
70
+ def pending(message=nil)
71
+ current_example = RSpec.current_example
72
+
73
+ if block_given?
74
+ raise ArgumentError, <<-EOS.gsub(/^\s+\|/, '')
75
+ |The semantics of `RSpec::Core::Pending#pending` have changed in
76
+ |RSpec 3. In RSpec 2.x, it caused the example to be skipped. In
77
+ |RSpec 3, the rest of the example is still run but is expected to
78
+ |fail, and will be marked as a failure (rather than as pending) if
79
+ |the example passes.
80
+ |
81
+ |Passing a block within an example is now deprecated. Marking the
82
+ |example as pending provides the same behavior in RSpec 3 which was
83
+ |provided only by the block in RSpec 2.x.
84
+ |
85
+ |Move the code in the block provided to `pending` into the rest of
86
+ |the example body.
87
+ |
88
+ |Called from #{CallerFilter.first_non_rspec_line}.
89
+ |
90
+ EOS
91
+ elsif current_example
92
+ Pending.mark_pending! current_example, message
93
+ else
94
+ raise "`pending` may not be used outside of examples, such as in " \
95
+ "before(:context). Maybe you want `skip`?"
96
+ end
97
+ end
98
+
99
+ # @overload skip()
100
+ # @overload skip(message)
101
+ #
102
+ # Marks an example as pending and skips execution.
103
+ #
104
+ # @param message [String] optional message to add to the summary report.
105
+ #
106
+ # @example
107
+ # describe "an example" do
108
+ # # reported as "Pending: no reason given"
109
+ # it "is skipped with no message" do
110
+ # skip
111
+ # end
112
+ #
113
+ # # reported as "Pending: something else getting finished"
114
+ # it "is skipped with a custom message" do
115
+ # skip "something else getting finished"
116
+ # end
117
+ # end
118
+ def skip(message=nil)
119
+ current_example = RSpec.current_example
120
+
121
+ Pending.mark_skipped!(current_example, message) if current_example
122
+
123
+ raise SkipDeclaredInExample.new(message)
124
+ end
125
+
126
+ # @private
127
+ #
128
+ # Mark example as skipped.
129
+ #
130
+ # @param example [RSpec::Core::Example] the example to mark as skipped
131
+ # @param message_or_bool [Boolean, String] the message to use, or true
132
+ def self.mark_skipped!(example, message_or_bool)
133
+ Pending.mark_pending! example, message_or_bool
134
+ example.metadata[:skip] = true
135
+ end
136
+
137
+ # @private
138
+ #
139
+ # Mark example as pending.
140
+ #
141
+ # @param example [RSpec::Core::Example] the example to mark as pending
142
+ # @param message_or_bool [Boolean, String] the message to use, or true
143
+ def self.mark_pending!(example, message_or_bool)
144
+ message = if !message_or_bool || !(String === message_or_bool)
145
+ NO_REASON_GIVEN
146
+ else
147
+ message_or_bool
148
+ end
149
+
150
+ example.metadata[:pending] = true
151
+ example.execution_result.pending_message = message
152
+ example.execution_result.pending_fixed = false
153
+ end
154
+
155
+ # @private
156
+ #
157
+ # Mark example as fixed.
158
+ #
159
+ # @param example [RSpec::Core::Example] the example to mark as fixed
160
+ def self.mark_fixed!(example)
161
+ example.execution_result.pending_fixed = true
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,34 @@
1
+ module RSpec
2
+ module Core
3
+ # @private
4
+ class Profiler
5
+ NOTIFICATIONS = [:example_group_started, :example_group_finished, :example_started]
6
+
7
+ def initialize
8
+ @example_groups = Hash.new { |h, k| h[k] = { :count => 0 } }
9
+ end
10
+
11
+ attr_reader :example_groups
12
+
13
+ def example_group_started(notification)
14
+ return unless notification.group.top_level?
15
+
16
+ @example_groups[notification.group][:start] = Time.now
17
+ @example_groups[notification.group][:description] = notification.group.top_level_description
18
+ end
19
+
20
+ def example_group_finished(notification)
21
+ return unless notification.group.top_level?
22
+
23
+ group = @example_groups[notification.group]
24
+ return unless group.key?(:start)
25
+ group[:total_time] = Time.now - group[:start]
26
+ end
27
+
28
+ def example_started(notification)
29
+ group = notification.example.example_group.parent_groups.last
30
+ @example_groups[group][:count] += 1
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,48 @@
1
+ RSpec::Support.require_rspec_support "directory_maker"
2
+
3
+ module RSpec
4
+ module Core
5
+ # @private
6
+ # Generates conventional files for an RSpec project.
7
+ class ProjectInitializer
8
+ attr_reader :destination, :stream, :template_path
9
+
10
+ DOT_RSPEC_FILE = '.rspec'
11
+ SPEC_HELPER_FILE = 'spec/spec_helper.rb'
12
+
13
+ def initialize(opts={})
14
+ @destination = opts.fetch(:destination, Dir.getwd)
15
+ @stream = opts.fetch(:report_stream, $stdout)
16
+ @template_path = opts.fetch(:template_path) do
17
+ File.expand_path("../project_initializer", __FILE__)
18
+ end
19
+ end
20
+
21
+ def run
22
+ copy_template DOT_RSPEC_FILE
23
+ copy_template SPEC_HELPER_FILE
24
+ end
25
+
26
+ private
27
+
28
+ def copy_template(file)
29
+ destination_file = File.join(destination, file)
30
+ return report_exists(file) if File.exist?(destination_file)
31
+
32
+ report_creating(file)
33
+ RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(destination_file))
34
+ File.open(destination_file, 'w') do |f|
35
+ f.write File.read(File.join(template_path, file))
36
+ end
37
+ end
38
+
39
+ def report_exists(file)
40
+ stream.puts " exist #{file}"
41
+ end
42
+
43
+ def report_creating(file)
44
+ stream.puts " create #{file}"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -0,0 +1,100 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
4
+ # this file to always be loaded, without a need to explicitly require it in any
5
+ # files.
6
+ #
7
+ # Given that it is always loaded, you are encouraged to keep this file as
8
+ # light-weight as possible. Requiring heavyweight dependencies from this file
9
+ # will add to the boot time of your test suite on EVERY test run, even for an
10
+ # individual file that may not need all of that loaded. Instead, consider making
11
+ # a separate helper file that requires the additional dependencies and performs
12
+ # the additional setup, and require it from the spec files that actually need
13
+ # it.
14
+ #
15
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
16
+ RSpec.configure do |config|
17
+ # rspec-expectations config goes here. You can use an alternate
18
+ # assertion/expectation library such as wrong or the stdlib/minitest
19
+ # assertions if you prefer.
20
+ config.expect_with :rspec do |expectations|
21
+ # This option will default to `true` in RSpec 4. It makes the `description`
22
+ # and `failure_message` of custom matchers include text for helper methods
23
+ # defined using `chain`, e.g.:
24
+ # be_bigger_than(2).and_smaller_than(4).description
25
+ # # => "be bigger than 2 and smaller than 4"
26
+ # ...rather than:
27
+ # # => "be bigger than 2"
28
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
29
+ end
30
+
31
+ # rspec-mocks config goes here. You can use an alternate test double
32
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
33
+ config.mock_with :rspec do |mocks|
34
+ # Prevents you from mocking or stubbing a method that does not exist on
35
+ # a real object. This is generally recommended, and will default to
36
+ # `true` in RSpec 4.
37
+ mocks.verify_partial_doubles = true
38
+ end
39
+
40
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
41
+ # have no way to turn it off -- the option exists only for backwards
42
+ # compatibility in RSpec 3). It causes shared context metadata to be
43
+ # inherited by the metadata hash of host groups and examples, rather than
44
+ # triggering implicit auto-inclusion in groups with matching metadata.
45
+ config.shared_context_metadata_behavior = :apply_to_host_groups
46
+
47
+ # The settings below are suggested to provide a good initial experience
48
+ # with RSpec, but feel free to customize to your heart's content.
49
+ =begin
50
+ # This allows you to limit a spec run to individual examples or groups
51
+ # you care about by tagging them with `:focus` metadata. When nothing
52
+ # is tagged with `:focus`, all examples get run. RSpec also provides
53
+ # aliases for `it`, `describe`, and `context` that include `:focus`
54
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
55
+ config.filter_run_when_matching :focus
56
+
57
+ # Allows RSpec to persist some state between runs in order to support
58
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
59
+ # you configure your source control system to ignore this file.
60
+ config.example_status_persistence_file_path = "spec/examples.txt"
61
+
62
+ # Limits the available syntax to the non-monkey patched syntax that is
63
+ # recommended. For more details, see:
64
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
65
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
66
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
67
+ config.disable_monkey_patching!
68
+
69
+ # This setting enables warnings. It's recommended, but in some cases may
70
+ # be too noisy due to issues in dependencies.
71
+ config.warnings = true
72
+
73
+ # Many RSpec users commonly either run the entire suite or an individual
74
+ # file, and it's useful to allow more verbose output when running an
75
+ # individual spec file.
76
+ if config.files_to_run.one?
77
+ # Use the documentation formatter for detailed output,
78
+ # unless a formatter has already been configured
79
+ # (e.g. via a command-line flag).
80
+ config.default_formatter = "doc"
81
+ end
82
+
83
+ # Print the 10 slowest examples and example groups at the
84
+ # end of the spec run, to help surface which specs are running
85
+ # particularly slow.
86
+ config.profile_examples = 10
87
+
88
+ # Run specs in random order to surface order dependencies. If you find an
89
+ # order dependency and want to debug it, you can fix the order by providing
90
+ # the seed, which is printed after each run.
91
+ # --seed 1234
92
+ config.order = :random
93
+
94
+ # Seed global randomization in this process using the `--seed` CLI option.
95
+ # Setting this allows you to use `--seed` to deterministically reproduce
96
+ # test failures related to randomization by passing the same `--seed` value
97
+ # as the one that triggered the failure.
98
+ Kernel.srand config.seed
99
+ =end
100
+ end
@@ -0,0 +1,168 @@
1
+ require 'rake'
2
+ require 'rake/tasklib'
3
+ require 'rspec/support'
4
+
5
+ RSpec::Support.require_rspec_support "ruby_features"
6
+
7
+ # :nocov:
8
+ unless RSpec::Support.respond_to?(:require_rspec_core)
9
+ RSpec::Support.define_optimized_require_for_rspec(:core) { |f| require_relative "../#{f}" }
10
+ end
11
+ # :nocov:
12
+
13
+ RSpec::Support.require_rspec_core "shell_escape"
14
+
15
+ module RSpec
16
+ module Core
17
+ # RSpec rake task
18
+ #
19
+ # @see Rakefile
20
+ class RakeTask < ::Rake::TaskLib
21
+ include ::Rake::DSL if defined?(::Rake::DSL)
22
+ include RSpec::Core::ShellEscape
23
+
24
+ # Default path to the RSpec executable.
25
+ DEFAULT_RSPEC_PATH = File.expand_path('../../../../exe/rspec', __FILE__)
26
+
27
+ # Default pattern for spec files.
28
+ DEFAULT_PATTERN = 'spec/**{,/*/**}/*_spec.rb'
29
+
30
+ # Name of task. Defaults to `:spec`.
31
+ attr_accessor :name
32
+
33
+ # Files matching this pattern will be loaded.
34
+ # Defaults to `'spec/**{,/*/**}/*_spec.rb'`.
35
+ attr_accessor :pattern
36
+
37
+ # Files matching this pattern will be excluded.
38
+ # Defaults to `nil`.
39
+ attr_accessor :exclude_pattern
40
+
41
+ # Whether or not to fail Rake when an error occurs (typically when
42
+ # examples fail). Defaults to `true`.
43
+ attr_accessor :fail_on_error
44
+
45
+ # A message to print to stderr when there are failures.
46
+ attr_accessor :failure_message
47
+
48
+ # Use verbose output. If this is set to true, the task will print the
49
+ # executed spec command to stdout. Defaults to `true`.
50
+ attr_accessor :verbose
51
+
52
+ # Command line options to pass to ruby. Defaults to `nil`.
53
+ attr_accessor :ruby_opts
54
+
55
+ # Path to RSpec. Defaults to the absolute path to the
56
+ # rspec binary from the loaded rspec-core gem.
57
+ attr_accessor :rspec_path
58
+
59
+ # Command line options to pass to RSpec. Defaults to `nil`.
60
+ attr_accessor :rspec_opts
61
+
62
+ def initialize(*args, &task_block)
63
+ @name = args.shift || :spec
64
+ @ruby_opts = nil
65
+ @rspec_opts = nil
66
+ @verbose = true
67
+ @fail_on_error = true
68
+ @rspec_path = DEFAULT_RSPEC_PATH
69
+ @pattern = DEFAULT_PATTERN
70
+
71
+ define(args, &task_block)
72
+ end
73
+
74
+ # @private
75
+ def run_task(verbose)
76
+ command = spec_command
77
+ puts command if verbose
78
+
79
+ return if system(command)
80
+ puts failure_message if failure_message
81
+
82
+ return unless fail_on_error
83
+ $stderr.puts "#{command} failed" if verbose
84
+ exit $?.exitstatus || 1
85
+ end
86
+
87
+ private
88
+
89
+ # @private
90
+ def define(args, &task_block)
91
+ desc "Run RSpec code examples" unless ::Rake.application.last_description
92
+
93
+ task name, *args do |_, task_args|
94
+ RakeFileUtils.__send__(:verbose, verbose) do
95
+ task_block.call(*[self, task_args].slice(0, task_block.arity)) if task_block
96
+ run_task verbose
97
+ end
98
+ end
99
+ end
100
+
101
+ def file_inclusion_specification
102
+ if ENV['SPEC']
103
+ FileList[ENV['SPEC']].sort
104
+ elsif String === pattern && !File.exist?(pattern)
105
+ return if rspec_opts =~ /--pattern/
106
+ "--pattern #{escape pattern}"
107
+ else
108
+ # Before RSpec 3.1, we used `FileList` to get the list of matched
109
+ # files, and then pass that along to the `rspec` command. Starting
110
+ # with 3.1, we prefer to pass along the pattern as-is to the `rspec`
111
+ # command, for 3 reasons:
112
+ #
113
+ # * It's *much* less verbose to pass one `--pattern` option than a
114
+ # long list of files.
115
+ # * It ensures `task.pattern` and `--pattern` have the same
116
+ # behavior.
117
+ # * It fixes a bug, where
118
+ # `task.pattern = pattern_that_matches_no_files` would run *all*
119
+ # files because it would cause no pattern or file args to get
120
+ # passed to `rspec`, which causes all files to get run.
121
+ #
122
+ # However, `FileList` is *far* more flexible than the `--pattern`
123
+ # option. Specifically, it supports individual files and directories,
124
+ # as well as arrays of files, directories and globs, as well as other
125
+ # `FileList` objects.
126
+ #
127
+ # For backwards compatibility, we have to fall back to using FileList
128
+ # if the user has passed a `pattern` option that will not work with
129
+ # `--pattern`.
130
+ #
131
+ # TODO: consider deprecating support for this and removing it in
132
+ # RSpec 4.
133
+ FileList[pattern].sort.map { |file| escape file }
134
+ end
135
+ end
136
+
137
+ def file_exclusion_specification
138
+ " --exclude-pattern #{escape exclude_pattern}" if exclude_pattern
139
+ end
140
+
141
+ def spec_command
142
+ cmd_parts = []
143
+ cmd_parts << RUBY
144
+ cmd_parts << ruby_opts
145
+ cmd_parts << rspec_load_path
146
+ cmd_parts << escape(rspec_path)
147
+ cmd_parts << file_inclusion_specification
148
+ cmd_parts << file_exclusion_specification
149
+ cmd_parts << rspec_opts
150
+ cmd_parts.flatten.reject(&blank).join(" ")
151
+ end
152
+
153
+ def blank
154
+ lambda { |s| s.nil? || s == "" }
155
+ end
156
+
157
+ def rspec_load_path
158
+ @rspec_load_path ||= begin
159
+ core_and_support = $LOAD_PATH.grep(
160
+ /#{File::SEPARATOR}rspec-(core|support)[^#{File::SEPARATOR}]*#{File::SEPARATOR}lib/
161
+ ).uniq
162
+
163
+ "-I#{core_and_support.map { |file| escape file }.join(File::PATH_SEPARATOR)}"
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end