rspec-core 2.11.1 → 3.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/.document +1 -1
- data/.yardopts +3 -1
- data/Changelog.md +1814 -29
- data/{License.txt → LICENSE.md} +6 -4
- data/README.md +197 -48
- data/exe/rspec +2 -23
- data/lib/rspec/autorun.rb +1 -0
- data/lib/rspec/core/backtrace_formatter.rb +65 -0
- data/lib/rspec/core/bisect/coordinator.rb +62 -0
- data/lib/rspec/core/bisect/example_minimizer.rb +173 -0
- data/lib/rspec/core/bisect/fork_runner.rb +138 -0
- data/lib/rspec/core/bisect/server.rb +61 -0
- data/lib/rspec/core/bisect/shell_command.rb +126 -0
- data/lib/rspec/core/bisect/shell_runner.rb +73 -0
- data/lib/rspec/core/bisect/utilities.rb +69 -0
- data/lib/rspec/core/configuration.rb +1846 -407
- data/lib/rspec/core/configuration_options.rb +154 -50
- data/lib/rspec/core/did_you_mean.rb +46 -0
- data/lib/rspec/core/drb.rb +120 -0
- data/lib/rspec/core/dsl.rb +90 -18
- data/lib/rspec/core/example.rb +488 -152
- data/lib/rspec/core/example_group.rb +733 -294
- data/lib/rspec/core/example_status_persister.rb +235 -0
- data/lib/rspec/core/filter_manager.rb +175 -147
- data/lib/rspec/core/flat_map.rb +20 -0
- data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
- data/lib/rspec/core/formatters/base_formatter.rb +32 -130
- data/lib/rspec/core/formatters/base_text_formatter.rb +62 -190
- data/lib/rspec/core/formatters/bisect_drb_formatter.rb +29 -0
- data/lib/rspec/core/formatters/bisect_progress_formatter.rb +157 -0
- data/lib/rspec/core/formatters/console_codes.rb +76 -0
- data/lib/rspec/core/formatters/deprecation_formatter.rb +223 -0
- data/lib/rspec/core/formatters/documentation_formatter.rb +62 -27
- data/lib/rspec/core/formatters/exception_presenter.rb +521 -0
- data/lib/rspec/core/formatters/failure_list_formatter.rb +23 -0
- data/lib/rspec/core/formatters/fallback_message_formatter.rb +28 -0
- data/lib/rspec/core/formatters/helpers.rb +93 -14
- data/lib/rspec/core/formatters/html_formatter.rb +104 -415
- data/lib/rspec/core/formatters/html_printer.rb +414 -0
- data/lib/rspec/core/formatters/html_snippet_extractor.rb +120 -0
- data/lib/rspec/core/formatters/json_formatter.rb +102 -0
- data/lib/rspec/core/formatters/profile_formatter.rb +68 -0
- data/lib/rspec/core/formatters/progress_formatter.rb +12 -15
- data/lib/rspec/core/formatters/protocol.rb +182 -0
- data/lib/rspec/core/formatters/snippet_extractor.rb +115 -39
- data/lib/rspec/core/formatters/syntax_highlighter.rb +91 -0
- data/lib/rspec/core/formatters.rb +279 -0
- data/lib/rspec/core/hooks.rb +451 -300
- data/lib/rspec/core/invocations.rb +87 -0
- data/lib/rspec/core/memoized_helpers.rb +580 -0
- data/lib/rspec/core/metadata.rb +395 -173
- data/lib/rspec/core/metadata_filter.rb +255 -0
- data/lib/rspec/core/minitest_assertions_adapter.rb +31 -0
- data/lib/rspec/core/mocking_adapters/flexmock.rb +31 -0
- data/lib/rspec/core/mocking_adapters/mocha.rb +57 -0
- data/lib/rspec/core/mocking_adapters/null.rb +14 -0
- data/lib/rspec/core/mocking_adapters/rr.rb +31 -0
- data/lib/rspec/core/mocking_adapters/rspec.rb +32 -0
- data/lib/rspec/core/notifications.rb +521 -0
- data/lib/rspec/core/option_parser.rb +208 -64
- data/lib/rspec/core/ordering.rb +169 -0
- data/lib/rspec/core/output_wrapper.rb +29 -0
- data/lib/rspec/core/pending.rb +115 -59
- data/lib/rspec/core/profiler.rb +34 -0
- data/lib/rspec/core/project_initializer/.rspec +1 -0
- data/lib/rspec/core/project_initializer/spec/spec_helper.rb +98 -0
- data/lib/rspec/core/project_initializer.rb +26 -65
- data/lib/rspec/core/rake_task.rb +140 -131
- data/lib/rspec/core/reporter.rb +207 -44
- data/lib/rspec/core/ruby_project.rb +15 -6
- data/lib/rspec/core/runner.rb +180 -44
- data/lib/rspec/core/sandbox.rb +37 -0
- data/lib/rspec/core/set.rb +54 -0
- data/lib/rspec/core/shared_context.rb +25 -19
- data/lib/rspec/core/shared_example_group.rb +229 -54
- data/lib/rspec/core/shell_escape.rb +49 -0
- data/lib/rspec/core/test_unit_assertions_adapter.rb +30 -0
- data/lib/rspec/core/version.rb +3 -1
- data/lib/rspec/core/warnings.rb +40 -0
- data/lib/rspec/core/world.rb +208 -49
- data/lib/rspec/core.rb +166 -80
- data.tar.gz.sig +0 -0
- metadata +230 -445
- metadata.gz.sig +0 -0
- data/exe/autospec +0 -13
- data/features/Autotest.md +0 -38
- data/features/README.md +0 -17
- data/features/Upgrade.md +0 -364
- data/features/command_line/README.md +0 -28
- data/features/command_line/example_name_option.feature +0 -101
- data/features/command_line/exit_status.feature +0 -83
- data/features/command_line/format_option.feature +0 -81
- data/features/command_line/init.feature +0 -18
- data/features/command_line/line_number_appended_to_path.feature +0 -140
- data/features/command_line/line_number_option.feature +0 -58
- data/features/command_line/order.feature +0 -29
- data/features/command_line/pattern_option.feature +0 -31
- data/features/command_line/rake_task.feature +0 -68
- data/features/command_line/ruby.feature +0 -22
- data/features/command_line/tag.feature +0 -91
- data/features/configuration/alias_example_to.feature +0 -48
- data/features/configuration/custom_settings.feature +0 -84
- data/features/configuration/default_path.feature +0 -38
- data/features/configuration/fail_fast.feature +0 -77
- data/features/configuration/read_options_from_file.feature +0 -87
- data/features/example_groups/basic_structure.feature +0 -55
- data/features/example_groups/shared_context.feature +0 -74
- data/features/example_groups/shared_examples.feature +0 -204
- data/features/expectation_framework_integration/configure_expectation_framework.feature +0 -102
- data/features/filtering/exclusion_filters.feature +0 -139
- data/features/filtering/if_and_unless.feature +0 -168
- data/features/filtering/inclusion_filters.feature +0 -105
- data/features/filtering/run_all_when_everything_filtered.feature +0 -46
- data/features/formatters/custom_formatter.feature +0 -36
- data/features/formatters/text_formatter.feature +0 -46
- data/features/helper_methods/arbitrary_methods.feature +0 -40
- data/features/helper_methods/let.feature +0 -50
- data/features/helper_methods/modules.feature +0 -149
- data/features/hooks/around_hooks.feature +0 -343
- data/features/hooks/before_and_after_hooks.feature +0 -423
- data/features/hooks/filtering.feature +0 -234
- data/features/metadata/current_example.feature +0 -17
- data/features/metadata/described_class.feature +0 -17
- data/features/metadata/user_defined.feature +0 -113
- data/features/mock_framework_integration/use_any_framework.feature +0 -106
- data/features/mock_framework_integration/use_flexmock.feature +0 -96
- data/features/mock_framework_integration/use_mocha.feature +0 -97
- data/features/mock_framework_integration/use_rr.feature +0 -98
- data/features/mock_framework_integration/use_rspec.feature +0 -97
- data/features/pending/pending_examples.feature +0 -229
- data/features/spec_files/arbitrary_file_suffix.feature +0 -13
- data/features/step_definitions/additional_cli_steps.rb +0 -30
- data/features/subject/attribute_of_subject.feature +0 -124
- data/features/subject/explicit_subject.feature +0 -82
- data/features/subject/implicit_receiver.feature +0 -29
- data/features/subject/implicit_subject.feature +0 -63
- data/features/support/env.rb +0 -12
- data/lib/autotest/discover.rb +0 -1
- data/lib/autotest/rspec2.rb +0 -73
- data/lib/rspec/core/backward_compatibility.rb +0 -65
- data/lib/rspec/core/command_line.rb +0 -36
- data/lib/rspec/core/deprecation.rb +0 -36
- data/lib/rspec/core/drb_command_line.rb +0 -26
- data/lib/rspec/core/drb_options.rb +0 -87
- data/lib/rspec/core/extensions/instance_eval_with_args.rb +0 -44
- data/lib/rspec/core/extensions/kernel.rb +0 -9
- data/lib/rspec/core/extensions/module_eval_with_args.rb +0 -38
- data/lib/rspec/core/extensions/ordered.rb +0 -21
- data/lib/rspec/core/extensions.rb +0 -4
- data/lib/rspec/core/formatters/text_mate_formatter.rb +0 -34
- data/lib/rspec/core/let.rb +0 -110
- data/lib/rspec/core/load_path.rb +0 -3
- data/lib/rspec/core/metadata_hash_builder.rb +0 -97
- data/lib/rspec/core/mocking/with_absolutely_nothing.rb +0 -11
- data/lib/rspec/core/mocking/with_flexmock.rb +0 -27
- data/lib/rspec/core/mocking/with_mocha.rb +0 -29
- data/lib/rspec/core/mocking/with_rr.rb +0 -27
- data/lib/rspec/core/mocking/with_rspec.rb +0 -23
- data/lib/rspec/core/subject.rb +0 -219
- data/spec/autotest/discover_spec.rb +0 -19
- data/spec/autotest/failed_results_re_spec.rb +0 -45
- data/spec/autotest/rspec_spec.rb +0 -123
- data/spec/command_line/order_spec.rb +0 -137
- data/spec/rspec/core/command_line_spec.rb +0 -108
- data/spec/rspec/core/command_line_spec_output.txt +0 -0
- data/spec/rspec/core/configuration_options_spec.rb +0 -377
- data/spec/rspec/core/configuration_spec.rb +0 -1196
- data/spec/rspec/core/deprecations_spec.rb +0 -66
- data/spec/rspec/core/drb_command_line_spec.rb +0 -108
- data/spec/rspec/core/drb_options_spec.rb +0 -180
- data/spec/rspec/core/dsl_spec.rb +0 -17
- data/spec/rspec/core/example_group_spec.rb +0 -1098
- data/spec/rspec/core/example_spec.rb +0 -370
- data/spec/rspec/core/filter_manager_spec.rb +0 -256
- data/spec/rspec/core/formatters/base_formatter_spec.rb +0 -80
- data/spec/rspec/core/formatters/base_text_formatter_spec.rb +0 -363
- data/spec/rspec/core/formatters/documentation_formatter_spec.rb +0 -88
- data/spec/rspec/core/formatters/helpers_spec.rb +0 -66
- data/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html +0 -410
- data/spec/rspec/core/formatters/html_formatted-1.8.7.html +0 -409
- data/spec/rspec/core/formatters/html_formatted-1.9.2.html +0 -416
- data/spec/rspec/core/formatters/html_formatted-1.9.3.html +0 -416
- data/spec/rspec/core/formatters/html_formatter_spec.rb +0 -82
- data/spec/rspec/core/formatters/progress_formatter_spec.rb +0 -30
- data/spec/rspec/core/formatters/snippet_extractor_spec.rb +0 -18
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html +0 -410
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +0 -409
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +0 -416
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.3.html +0 -416
- data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +0 -83
- data/spec/rspec/core/hooks_filtering_spec.rb +0 -227
- data/spec/rspec/core/hooks_spec.rb +0 -250
- data/spec/rspec/core/kernel_extensions_spec.rb +0 -9
- data/spec/rspec/core/let_spec.rb +0 -55
- data/spec/rspec/core/metadata_spec.rb +0 -447
- data/spec/rspec/core/option_parser_spec.rb +0 -166
- data/spec/rspec/core/pending_example_spec.rb +0 -220
- data/spec/rspec/core/project_initializer_spec.rb +0 -130
- data/spec/rspec/core/rake_task_spec.rb +0 -138
- data/spec/rspec/core/reporter_spec.rb +0 -103
- data/spec/rspec/core/resources/a_bar.rb +0 -0
- data/spec/rspec/core/resources/a_foo.rb +0 -0
- data/spec/rspec/core/resources/a_spec.rb +0 -1
- data/spec/rspec/core/resources/custom_example_group_runner.rb +0 -14
- data/spec/rspec/core/resources/formatter_specs.rb +0 -60
- data/spec/rspec/core/resources/utf8_encoded.rb +0 -8
- data/spec/rspec/core/rspec_matchers_spec.rb +0 -45
- data/spec/rspec/core/ruby_project_spec.rb +0 -24
- data/spec/rspec/core/runner_spec.rb +0 -81
- data/spec/rspec/core/shared_context_spec.rb +0 -67
- data/spec/rspec/core/shared_example_group_spec.rb +0 -84
- data/spec/rspec/core/subject_spec.rb +0 -244
- data/spec/rspec/core/world_spec.rb +0 -144
- data/spec/rspec/core_spec.rb +0 -35
- data/spec/spec_helper.rb +0 -98
- data/spec/support/config_options_helper.rb +0 -24
- data/spec/support/helper_methods.rb +0 -5
- data/spec/support/matchers.rb +0 -65
- data/spec/support/shared_example_groups.rb +0 -41
- data/spec/support/spec_files.rb +0 -44
data/lib/rspec/core/rake_task.rb
CHANGED
@@ -1,178 +1,187 @@
|
|
1
|
-
require 'rspec/core'
|
2
|
-
require 'rspec/core/deprecation'
|
3
1
|
require 'rake'
|
4
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"
|
5
14
|
|
6
15
|
module RSpec
|
7
16
|
module Core
|
17
|
+
# RSpec rake task
|
18
|
+
#
|
19
|
+
# @see Rakefile
|
8
20
|
class RakeTask < ::Rake::TaskLib
|
9
21
|
include ::Rake::DSL if defined?(::Rake::DSL)
|
22
|
+
include RSpec::Core::ShellEscape
|
10
23
|
|
11
|
-
#
|
12
|
-
|
13
|
-
# default:
|
14
|
-
# :spec
|
15
|
-
attr_accessor :name
|
24
|
+
# Default path to the RSpec executable.
|
25
|
+
DEFAULT_RSPEC_PATH = File.expand_path('../../../../exe/rspec', __FILE__)
|
16
26
|
|
17
|
-
#
|
18
|
-
|
19
|
-
# default:
|
20
|
-
# 'spec/**/*_spec.rb'
|
21
|
-
attr_accessor :pattern
|
27
|
+
# Default pattern for spec files.
|
28
|
+
DEFAULT_PATTERN = 'spec/**{,/*/**}/*_spec.rb'
|
22
29
|
|
23
|
-
#
|
24
|
-
|
25
|
-
def skip_bundler=(*)
|
26
|
-
RSpec.deprecate("RSpec::Core::RakeTask#skip_bundler=")
|
27
|
-
end
|
30
|
+
# Name of task. Defaults to `:spec`.
|
31
|
+
attr_accessor :name
|
28
32
|
|
29
|
-
#
|
30
|
-
#
|
31
|
-
|
32
|
-
RSpec.deprecate("RSpec::Core::RakeTask#gemfile=", 'ENV["BUNDLE_GEMFILE"]')
|
33
|
-
end
|
33
|
+
# Files matching this pattern will be loaded.
|
34
|
+
# Defaults to `'spec/**{,/*/**}/*_spec.rb'`.
|
35
|
+
attr_accessor :pattern
|
34
36
|
|
35
|
-
#
|
36
|
-
#
|
37
|
-
|
38
|
-
# When true, requests that the specs be run with the warning flag set.
|
39
|
-
# e.g. "ruby -w"
|
40
|
-
#
|
41
|
-
# default:
|
42
|
-
# false
|
43
|
-
def warning=(true_or_false)
|
44
|
-
RSpec.deprecate("RSpec::Core::RakeTask#warning=", 'ruby_opts="-w"')
|
45
|
-
@warning = true_or_false
|
46
|
-
end
|
37
|
+
# Files matching this pattern will be excluded.
|
38
|
+
# Defaults to `nil`.
|
39
|
+
attr_accessor :exclude_pattern
|
47
40
|
|
48
|
-
# Whether or not to fail Rake when an error occurs (typically when
|
49
|
-
#
|
50
|
-
# default:
|
51
|
-
# true
|
41
|
+
# Whether or not to fail Rake when an error occurs (typically when
|
42
|
+
# examples fail). Defaults to `true`.
|
52
43
|
attr_accessor :fail_on_error
|
53
44
|
|
54
45
|
# A message to print to stderr when there are failures.
|
55
46
|
attr_accessor :failure_message
|
56
47
|
|
48
|
+
if RUBY_VERSION < "1.9.0" || Support::Ruby.jruby?
|
49
|
+
# Run RSpec with a clean (empty) environment is not supported
|
50
|
+
def with_clean_environment=(_value)
|
51
|
+
raise ArgumentError, "Running in a clean environment is not supported on Ruby versions before 1.9.0"
|
52
|
+
end
|
53
|
+
|
54
|
+
# Run RSpec with a clean (empty) environment is not supported
|
55
|
+
def with_clean_environment
|
56
|
+
false
|
57
|
+
end
|
58
|
+
else
|
59
|
+
# Run RSpec with a clean (empty) environment.
|
60
|
+
attr_accessor :with_clean_environment
|
61
|
+
end
|
62
|
+
|
57
63
|
# Use verbose output. If this is set to true, the task will print the
|
58
|
-
# executed spec command to stdout.
|
59
|
-
#
|
60
|
-
# default:
|
61
|
-
# true
|
64
|
+
# executed spec command to stdout. Defaults to `true`.
|
62
65
|
attr_accessor :verbose
|
63
66
|
|
64
|
-
#
|
65
|
-
#
|
66
|
-
# default:
|
67
|
-
# false
|
68
|
-
attr_accessor :rcov
|
69
|
-
|
70
|
-
# Path to rcov.
|
71
|
-
#
|
72
|
-
# default:
|
73
|
-
# 'rcov'
|
74
|
-
attr_accessor :rcov_path
|
75
|
-
|
76
|
-
# Command line options to pass to rcov.
|
77
|
-
#
|
78
|
-
# default:
|
79
|
-
# nil
|
80
|
-
attr_accessor :rcov_opts
|
81
|
-
|
82
|
-
# Command line options to pass to ruby.
|
83
|
-
#
|
84
|
-
# default:
|
85
|
-
# nil
|
67
|
+
# Command line options to pass to ruby. Defaults to `nil`.
|
86
68
|
attr_accessor :ruby_opts
|
87
69
|
|
88
|
-
# Path to
|
89
|
-
#
|
90
|
-
# default:
|
91
|
-
# 'rspec'
|
70
|
+
# Path to RSpec. Defaults to the absolute path to the
|
71
|
+
# rspec binary from the loaded rspec-core gem.
|
92
72
|
attr_accessor :rspec_path
|
93
73
|
|
94
|
-
# Command line options to pass to
|
95
|
-
#
|
96
|
-
# default:
|
97
|
-
# nil
|
74
|
+
# Command line options to pass to RSpec. Defaults to `nil`.
|
98
75
|
attr_accessor :rspec_opts
|
99
76
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
77
|
+
def initialize(*args, &task_block)
|
78
|
+
@name = args.shift || :spec
|
79
|
+
@ruby_opts = nil
|
80
|
+
@rspec_opts = nil
|
81
|
+
@verbose = true
|
82
|
+
@fail_on_error = true
|
83
|
+
@rspec_path = DEFAULT_RSPEC_PATH
|
84
|
+
@pattern = DEFAULT_PATTERN
|
85
|
+
|
86
|
+
define(args, &task_block)
|
110
87
|
end
|
111
88
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
@rspec_path ||= 'rspec'
|
122
|
-
@pattern ||= './spec{,/*/**}/*_spec.rb'
|
123
|
-
|
124
|
-
desc("Run RSpec code examples") unless ::Rake.application.last_comment
|
125
|
-
|
126
|
-
task name do
|
127
|
-
RakeFileUtils.send(:verbose, verbose) do
|
128
|
-
if files_to_run.empty?
|
129
|
-
puts "No examples matching #{pattern} could be found"
|
130
|
-
else
|
131
|
-
begin
|
132
|
-
puts spec_command if verbose
|
133
|
-
success = system(spec_command)
|
134
|
-
rescue
|
135
|
-
puts failure_message if failure_message
|
136
|
-
end
|
137
|
-
raise("#{spec_command} failed") if fail_on_error unless success
|
138
|
-
end
|
139
|
-
end
|
89
|
+
# @private
|
90
|
+
def run_task(verbose)
|
91
|
+
command = spec_command
|
92
|
+
puts command if verbose
|
93
|
+
|
94
|
+
if with_clean_environment
|
95
|
+
return if system({}, command, :unsetenv_others => true)
|
96
|
+
else
|
97
|
+
return if system(command)
|
140
98
|
end
|
99
|
+
|
100
|
+
puts failure_message if failure_message
|
101
|
+
|
102
|
+
return unless fail_on_error
|
103
|
+
$stderr.puts "#{command} failed" if verbose
|
104
|
+
exit $?.exitstatus || 1
|
141
105
|
end
|
142
106
|
|
143
107
|
private
|
144
108
|
|
145
|
-
|
109
|
+
# @private
|
110
|
+
def define(args, &task_block)
|
111
|
+
desc "Run RSpec code examples" unless ::Rake.application.last_description
|
112
|
+
|
113
|
+
task name, *args do |_, task_args|
|
114
|
+
RakeFileUtils.__send__(:verbose, verbose) do
|
115
|
+
task_block.call(*[self, task_args].slice(0, task_block.arity)) if task_block
|
116
|
+
run_task verbose
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def file_inclusion_specification
|
146
122
|
if ENV['SPEC']
|
147
|
-
FileList[
|
123
|
+
FileList[ENV['SPEC']].sort
|
124
|
+
elsif String === pattern && !File.exist?(pattern)
|
125
|
+
return if [*rspec_opts].any? { |opt| opt =~ /--pattern/ }
|
126
|
+
"--pattern #{escape pattern}"
|
148
127
|
else
|
149
|
-
|
128
|
+
# Before RSpec 3.1, we used `FileList` to get the list of matched
|
129
|
+
# files, and then pass that along to the `rspec` command. Starting
|
130
|
+
# with 3.1, we prefer to pass along the pattern as-is to the `rspec`
|
131
|
+
# command, for 3 reasons:
|
132
|
+
#
|
133
|
+
# * It's *much* less verbose to pass one `--pattern` option than a
|
134
|
+
# long list of files.
|
135
|
+
# * It ensures `task.pattern` and `--pattern` have the same
|
136
|
+
# behavior.
|
137
|
+
# * It fixes a bug, where
|
138
|
+
# `task.pattern = pattern_that_matches_no_files` would run *all*
|
139
|
+
# files because it would cause no pattern or file args to get
|
140
|
+
# passed to `rspec`, which causes all files to get run.
|
141
|
+
#
|
142
|
+
# However, `FileList` is *far* more flexible than the `--pattern`
|
143
|
+
# option. Specifically, it supports individual files and directories,
|
144
|
+
# as well as arrays of files, directories and globs, as well as other
|
145
|
+
# `FileList` objects.
|
146
|
+
#
|
147
|
+
# For backwards compatibility, we have to fall back to using FileList
|
148
|
+
# if the user has passed a `pattern` option that will not work with
|
149
|
+
# `--pattern`.
|
150
|
+
#
|
151
|
+
# TODO: consider deprecating support for this and removing it in
|
152
|
+
# RSpec 4.
|
153
|
+
FileList[pattern].sort.map { |file| escape file }
|
150
154
|
end
|
151
155
|
end
|
152
156
|
|
153
|
-
def
|
154
|
-
|
155
|
-
cmd_parts = []
|
156
|
-
cmd_parts << RUBY
|
157
|
-
cmd_parts << ruby_opts
|
158
|
-
cmd_parts << "-w" if @warning
|
159
|
-
cmd_parts << "-S" << runner
|
160
|
-
cmd_parts << "-Ispec:lib" << rcov_opts if rcov
|
161
|
-
cmd_parts << files_to_run
|
162
|
-
cmd_parts << "--" if rcov && rspec_opts
|
163
|
-
cmd_parts << rspec_opts
|
164
|
-
cmd_parts.flatten.reject(&blank).join(" ")
|
165
|
-
end
|
157
|
+
def file_exclusion_specification
|
158
|
+
" --exclude-pattern #{escape exclude_pattern}" if exclude_pattern
|
166
159
|
end
|
167
160
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
161
|
+
def spec_command
|
162
|
+
cmd_parts = []
|
163
|
+
cmd_parts << RUBY
|
164
|
+
cmd_parts << ruby_opts
|
165
|
+
cmd_parts << rspec_load_path
|
166
|
+
cmd_parts << escape(rspec_path)
|
167
|
+
cmd_parts << file_inclusion_specification
|
168
|
+
cmd_parts << file_exclusion_specification
|
169
|
+
cmd_parts << rspec_opts
|
170
|
+
cmd_parts.flatten.reject(&blank).join(" ")
|
172
171
|
end
|
173
172
|
|
174
173
|
def blank
|
175
|
-
lambda {|s| s.nil? || s == ""}
|
174
|
+
lambda { |s| s.nil? || s == "" }
|
175
|
+
end
|
176
|
+
|
177
|
+
def rspec_load_path
|
178
|
+
@rspec_load_path ||= begin
|
179
|
+
core_and_support = $LOAD_PATH.grep(
|
180
|
+
/#{File::SEPARATOR}rspec-(core|support)[^#{File::SEPARATOR}]*#{File::SEPARATOR}lib/
|
181
|
+
).uniq
|
182
|
+
|
183
|
+
"-I#{core_and_support.map { |file| escape file }.join(File::PATH_SEPARATOR)}"
|
184
|
+
end
|
176
185
|
end
|
177
186
|
end
|
178
187
|
end
|
data/lib/rspec/core/reporter.rb
CHANGED
@@ -1,102 +1,265 @@
|
|
1
1
|
module RSpec::Core
|
2
|
+
# A reporter will send notifications to listeners, usually formatters for the
|
3
|
+
# spec suite run.
|
2
4
|
class Reporter
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
# @private
|
6
|
+
RSPEC_NOTIFICATIONS = Set.new(
|
7
|
+
[
|
8
|
+
:close, :deprecation, :deprecation_summary, :dump_failures, :dump_pending,
|
9
|
+
:dump_profile, :dump_summary, :example_failed, :example_group_finished,
|
10
|
+
:example_group_started, :example_passed, :example_pending, :example_started,
|
11
|
+
:message, :seed, :start, :start_dump, :stop, :example_finished
|
12
|
+
])
|
13
|
+
|
14
|
+
def initialize(configuration)
|
15
|
+
@configuration = configuration
|
16
|
+
@listeners = Hash.new { |h, k| h[k] = Set.new }
|
17
|
+
@examples = []
|
18
|
+
@failed_examples = []
|
19
|
+
@pending_examples = []
|
20
|
+
@duration = @start = @load_time = nil
|
21
|
+
@non_example_exception_count = 0
|
22
|
+
@setup_default = lambda {}
|
23
|
+
@setup = false
|
24
|
+
@profiler = nil
|
7
25
|
end
|
8
26
|
|
9
|
-
# @
|
27
|
+
# @private
|
28
|
+
attr_reader :examples, :failed_examples, :pending_examples
|
29
|
+
|
30
|
+
# Registers a listener to a list of notifications. The reporter will send
|
31
|
+
# notification of events to all registered listeners.
|
32
|
+
#
|
33
|
+
# @param listener [Object] An obect that wishes to be notified of reporter
|
34
|
+
# events
|
35
|
+
# @param notifications [Array] Array of symbols represents the events a
|
36
|
+
# listener wishes to subscribe too
|
37
|
+
def register_listener(listener, *notifications)
|
38
|
+
notifications.each do |notification|
|
39
|
+
@listeners[notification.to_sym] << listener
|
40
|
+
end
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
# @private
|
45
|
+
def prepare_default(loader, output_stream, deprecation_stream)
|
46
|
+
@setup_default = lambda do
|
47
|
+
loader.setup_default output_stream, deprecation_stream
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# @private
|
52
|
+
def registered_listeners(notification)
|
53
|
+
@listeners[notification].to_a
|
54
|
+
end
|
55
|
+
|
56
|
+
# @overload report(count, &block)
|
10
57
|
# @overload report(count, &block)
|
11
|
-
# @
|
12
|
-
# @
|
13
|
-
# @param [Integer] seed the seed used to randomize the spec run
|
14
|
-
# @param [Block] block yields itself for further reporting.
|
58
|
+
# @param expected_example_count [Integer] the number of examples being run
|
59
|
+
# @yield [Block] block yields itself for further reporting.
|
15
60
|
#
|
16
61
|
# Initializes the report run and yields itself for further reporting. The
|
17
62
|
# block is required, so that the reporter can manage cleaning up after the
|
18
63
|
# run.
|
19
64
|
#
|
20
|
-
# ### Warning:
|
21
|
-
#
|
22
|
-
# The `seed` argument is an internal API and is not guaranteed to be
|
23
|
-
# supported in the future.
|
24
|
-
#
|
25
65
|
# @example
|
26
66
|
#
|
27
67
|
# reporter.report(group.examples.size) do |r|
|
28
68
|
# example_groups.map {|g| g.run(r) }
|
29
69
|
# end
|
30
70
|
#
|
31
|
-
def report(expected_example_count
|
71
|
+
def report(expected_example_count)
|
32
72
|
start(expected_example_count)
|
33
73
|
begin
|
34
74
|
yield self
|
35
75
|
ensure
|
36
|
-
finish
|
76
|
+
finish
|
37
77
|
end
|
38
78
|
end
|
39
79
|
|
40
|
-
|
41
|
-
|
42
|
-
|
80
|
+
# @param exit_code [Integer] the exit_code to be return by the reporter
|
81
|
+
#
|
82
|
+
# Reports a run that exited early without having run any examples.
|
83
|
+
#
|
84
|
+
def exit_early(exit_code)
|
85
|
+
report(0) { exit_code }
|
43
86
|
end
|
44
87
|
|
88
|
+
# @private
|
89
|
+
def start(expected_example_count, time=RSpec::Core::Time.now)
|
90
|
+
@start = time
|
91
|
+
@load_time = (@start - @configuration.start_time).to_f
|
92
|
+
notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?)
|
93
|
+
notify :start, Notifications::StartNotification.new(expected_example_count, @load_time)
|
94
|
+
end
|
95
|
+
|
96
|
+
# @param message [#to_s] A message object to send to formatters
|
97
|
+
#
|
98
|
+
# Send a custom message to supporting formatters.
|
45
99
|
def message(message)
|
46
|
-
notify :message, message
|
100
|
+
notify :message, Notifications::MessageNotification.new(message)
|
47
101
|
end
|
48
102
|
|
103
|
+
# @param event [Symbol] Name of the custom event to trigger on formatters
|
104
|
+
# @param options [Hash] Hash of arguments to provide via `CustomNotification`
|
105
|
+
#
|
106
|
+
# Publish a custom event to supporting registered formatters.
|
107
|
+
# @see RSpec::Core::Notifications::CustomNotification
|
108
|
+
def publish(event, options={})
|
109
|
+
if RSPEC_NOTIFICATIONS.include? event
|
110
|
+
raise "RSpec::Core::Reporter#publish is intended for sending custom " \
|
111
|
+
"events not internal RSpec ones, please rename your custom event."
|
112
|
+
end
|
113
|
+
notify event, Notifications::CustomNotification.for(options)
|
114
|
+
end
|
115
|
+
|
116
|
+
# @private
|
49
117
|
def example_group_started(group)
|
50
|
-
notify :example_group_started, group unless group.descendant_filtered_examples.empty?
|
118
|
+
notify :example_group_started, Notifications::GroupNotification.new(group) unless group.descendant_filtered_examples.empty?
|
51
119
|
end
|
52
120
|
|
121
|
+
# @private
|
53
122
|
def example_group_finished(group)
|
54
|
-
notify :example_group_finished, group unless group.descendant_filtered_examples.empty?
|
123
|
+
notify :example_group_finished, Notifications::GroupNotification.new(group) unless group.descendant_filtered_examples.empty?
|
55
124
|
end
|
56
125
|
|
126
|
+
# @private
|
57
127
|
def example_started(example)
|
58
|
-
@
|
59
|
-
notify :example_started, example
|
128
|
+
@examples << example
|
129
|
+
notify :example_started, Notifications::ExampleNotification.for(example)
|
60
130
|
end
|
61
131
|
|
132
|
+
# @private
|
133
|
+
def example_finished(example)
|
134
|
+
notify :example_finished, Notifications::ExampleNotification.for(example)
|
135
|
+
end
|
136
|
+
|
137
|
+
# @private
|
62
138
|
def example_passed(example)
|
63
|
-
notify :example_passed, example
|
139
|
+
notify :example_passed, Notifications::ExampleNotification.for(example)
|
64
140
|
end
|
65
141
|
|
142
|
+
# @private
|
66
143
|
def example_failed(example)
|
67
|
-
@
|
68
|
-
notify :example_failed, example
|
144
|
+
@failed_examples << example
|
145
|
+
notify :example_failed, Notifications::ExampleNotification.for(example)
|
69
146
|
end
|
70
147
|
|
148
|
+
# @private
|
71
149
|
def example_pending(example)
|
72
|
-
@
|
73
|
-
notify :example_pending, example
|
150
|
+
@pending_examples << example
|
151
|
+
notify :example_pending, Notifications::ExampleNotification.for(example)
|
74
152
|
end
|
75
153
|
|
76
|
-
|
77
|
-
|
154
|
+
# @private
|
155
|
+
def deprecation(hash)
|
156
|
+
notify :deprecation, Notifications::DeprecationNotification.from_hash(hash)
|
157
|
+
end
|
158
|
+
|
159
|
+
# @private
|
160
|
+
# Provides a way to notify of an exception that is not tied to any
|
161
|
+
# particular example (such as an exception encountered in a :suite hook).
|
162
|
+
# Exceptions will be formatted the same way they normally are.
|
163
|
+
def notify_non_example_exception(exception, context_description)
|
164
|
+
@configuration.world.non_example_failure = true
|
165
|
+
@non_example_exception_count += 1
|
166
|
+
|
167
|
+
example = Example.new(AnonymousExampleGroup, context_description, {})
|
168
|
+
presenter = Formatters::ExceptionPresenter.new(exception, example, :indentation => 0)
|
169
|
+
message presenter.fully_formatted(nil)
|
170
|
+
end
|
171
|
+
|
172
|
+
# @private
|
173
|
+
def finish
|
174
|
+
close_after do
|
78
175
|
stop
|
79
|
-
notify :start_dump
|
80
|
-
notify :dump_pending
|
81
|
-
notify :dump_failures
|
82
|
-
notify :
|
83
|
-
|
84
|
-
|
85
|
-
|
176
|
+
notify :start_dump, Notifications::NullNotification
|
177
|
+
notify :dump_pending, Notifications::ExamplesNotification.new(self)
|
178
|
+
notify :dump_failures, Notifications::ExamplesNotification.new(self)
|
179
|
+
notify :deprecation_summary, Notifications::NullNotification
|
180
|
+
unless mute_profile_output?
|
181
|
+
notify :dump_profile, Notifications::ProfileNotification.new(@duration, @examples,
|
182
|
+
@configuration.profile_examples,
|
183
|
+
@profiler.example_groups)
|
184
|
+
end
|
185
|
+
notify :dump_summary, Notifications::SummaryNotification.new(@duration, @examples, @failed_examples,
|
186
|
+
@pending_examples, @load_time,
|
187
|
+
@non_example_exception_count)
|
188
|
+
notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?)
|
86
189
|
end
|
87
190
|
end
|
88
191
|
|
89
|
-
|
192
|
+
# @private
|
193
|
+
def close_after
|
194
|
+
yield
|
195
|
+
ensure
|
196
|
+
close
|
197
|
+
end
|
90
198
|
|
199
|
+
# @private
|
91
200
|
def stop
|
92
|
-
@duration = Time.now - @start if @start
|
93
|
-
notify :stop
|
201
|
+
@duration = (RSpec::Core::Time.now - @start).to_f if @start
|
202
|
+
notify :stop, Notifications::ExamplesNotification.new(self)
|
94
203
|
end
|
95
204
|
|
96
|
-
|
97
|
-
|
98
|
-
|
205
|
+
# @private
|
206
|
+
def notify(event, notification)
|
207
|
+
ensure_listeners_ready
|
208
|
+
registered_listeners(event).each do |formatter|
|
209
|
+
formatter.__send__(event, notification)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# @private
|
214
|
+
def abort_with(msg, exit_status)
|
215
|
+
message(msg)
|
216
|
+
close
|
217
|
+
exit!(exit_status)
|
218
|
+
end
|
219
|
+
|
220
|
+
# @private
|
221
|
+
def fail_fast_limit_met?
|
222
|
+
return false unless (fail_fast = @configuration.fail_fast)
|
223
|
+
|
224
|
+
if fail_fast == true
|
225
|
+
@failed_examples.any?
|
226
|
+
else
|
227
|
+
fail_fast <= @failed_examples.size
|
99
228
|
end
|
100
229
|
end
|
230
|
+
|
231
|
+
private
|
232
|
+
|
233
|
+
def ensure_listeners_ready
|
234
|
+
return if @setup
|
235
|
+
|
236
|
+
@setup_default.call
|
237
|
+
@profiler = Profiler.new
|
238
|
+
register_listener @profiler, *Profiler::NOTIFICATIONS
|
239
|
+
@setup = true
|
240
|
+
end
|
241
|
+
|
242
|
+
def close
|
243
|
+
notify :close, Notifications::NullNotification
|
244
|
+
end
|
245
|
+
|
246
|
+
def mute_profile_output?
|
247
|
+
# Don't print out profiled info if there are failures and `--fail-fast` is
|
248
|
+
# used, it just clutters the output.
|
249
|
+
!@configuration.profile_examples? || fail_fast_limit_met?
|
250
|
+
end
|
251
|
+
|
252
|
+
def seed_used?
|
253
|
+
@configuration.seed && @configuration.seed_used?
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# @private
|
258
|
+
# # Used in place of a {Reporter} for situations where we don't want reporting output.
|
259
|
+
class NullReporter
|
260
|
+
def self.method_missing(*)
|
261
|
+
# ignore
|
262
|
+
end
|
263
|
+
private_class_method :method_missing
|
101
264
|
end
|
102
265
|
end
|
@@ -1,14 +1,12 @@
|
|
1
1
|
# This is borrowed (slightly modified) from Scott Taylor's
|
2
2
|
# project_path project:
|
3
3
|
# http://github.com/smtlaissezfaire/project_path
|
4
|
-
|
5
|
-
require 'pathname'
|
6
|
-
|
7
4
|
module RSpec
|
8
5
|
module Core
|
6
|
+
# @private
|
9
7
|
module RubyProject
|
10
8
|
def add_to_load_path(*dirs)
|
11
|
-
dirs.
|
9
|
+
dirs.each { |dir| add_dir_to_load_path(File.join(root, dir)) }
|
12
10
|
end
|
13
11
|
|
14
12
|
def add_dir_to_load_path(dir)
|
@@ -24,12 +22,23 @@ module RSpec
|
|
24
22
|
end
|
25
23
|
|
26
24
|
def find_first_parent_containing(dir)
|
27
|
-
ascend_until {|path| File.
|
25
|
+
ascend_until { |path| File.exist?(File.join(path, dir)) }
|
28
26
|
end
|
29
27
|
|
30
28
|
def ascend_until
|
31
|
-
|
29
|
+
fs = File::SEPARATOR
|
30
|
+
escaped_slash = "\\#{fs}"
|
31
|
+
special = "_RSPEC_ESCAPED_SLASH_"
|
32
|
+
project_path = File.expand_path(".")
|
33
|
+
parts = project_path.gsub(escaped_slash, special).squeeze(fs).split(fs).map do |x|
|
34
|
+
x.gsub(special, escaped_slash)
|
35
|
+
end
|
36
|
+
|
37
|
+
until parts.empty?
|
38
|
+
path = parts.join(fs)
|
39
|
+
path = fs if path == ""
|
32
40
|
return path if yield(path)
|
41
|
+
parts.pop
|
33
42
|
end
|
34
43
|
end
|
35
44
|
|