rspec-core 3.0.0.beta1 → 3.0.0.beta2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. data.tar.gz.sig +0 -0
  2. data/Changelog.md +137 -0
  3. data/README.md +2 -2
  4. data/exe/rspec +2 -23
  5. data/features/README.md +1 -5
  6. data/features/command_line/README.md +7 -10
  7. data/features/command_line/exit_status.feature +1 -1
  8. data/features/command_line/format_option.feature +1 -1
  9. data/features/command_line/init.feature +40 -1
  10. data/features/command_line/line_number_option.feature +2 -2
  11. data/features/command_line/ruby.feature +5 -4
  12. data/features/configuration/enable_global_dsl.feature +54 -0
  13. data/features/example_groups/aliasing.feature +48 -0
  14. data/features/example_groups/basic_structure.feature +1 -1
  15. data/features/expectation_framework_integration/configure_expectation_framework.feature +1 -1
  16. data/features/filtering/if_and_unless.feature +0 -30
  17. data/features/formatters/custom_formatter.feature +32 -0
  18. data/features/formatters/regression_tests.feature +95 -0
  19. data/features/hooks/around_hooks.feature +1 -0
  20. data/features/hooks/before_and_after_hooks.feature +2 -2
  21. data/features/mock_framework_integration/use_flexmock.feature +11 -13
  22. data/features/mock_framework_integration/use_mocha.feature +11 -13
  23. data/features/mock_framework_integration/use_rr.feature +11 -13
  24. data/features/mock_framework_integration/use_rspec.feature +11 -13
  25. data/features/pending_and_skipped_examples/README.md +3 -0
  26. data/features/pending_and_skipped_examples/pending_examples.feature +118 -0
  27. data/features/pending_and_skipped_examples/skipped_examples.feature +106 -0
  28. data/features/step_definitions/additional_cli_steps.rb +34 -0
  29. data/features/subject/explicit_subject.feature +1 -1
  30. data/features/subject/one_liner_syntax.feature +71 -0
  31. data/lib/rspec/core.rb +6 -14
  32. data/lib/rspec/core/backtrace_formatter.rb +16 -4
  33. data/lib/rspec/core/command_line.rb +2 -3
  34. data/lib/rspec/core/configuration.rb +114 -125
  35. data/lib/rspec/core/configuration_options.rb +32 -18
  36. data/lib/rspec/core/dsl.rb +80 -18
  37. data/lib/rspec/core/example.rb +84 -33
  38. data/lib/rspec/core/example_group.rb +95 -43
  39. data/lib/rspec/core/filter_manager.rb +31 -40
  40. data/lib/rspec/core/formatters.rb +137 -0
  41. data/lib/rspec/core/formatters/base_formatter.rb +28 -41
  42. data/lib/rspec/core/formatters/base_text_formatter.rb +26 -37
  43. data/lib/rspec/core/formatters/deprecation_formatter.rb +48 -27
  44. data/lib/rspec/core/formatters/documentation_formatter.rb +27 -22
  45. data/lib/rspec/core/formatters/html_formatter.rb +48 -56
  46. data/lib/rspec/core/formatters/html_printer.rb +11 -18
  47. data/lib/rspec/core/formatters/json_formatter.rb +18 -22
  48. data/lib/rspec/core/formatters/legacy_formatter.rb +227 -0
  49. data/lib/rspec/core/formatters/progress_formatter.rb +7 -10
  50. data/lib/rspec/core/hooks.rb +250 -217
  51. data/lib/rspec/core/memoized_helpers.rb +43 -9
  52. data/lib/rspec/core/mocking_adapters/flexmock.rb +29 -0
  53. data/lib/rspec/core/{mocking/with_mocha.rb → mocking_adapters/mocha.rb} +19 -16
  54. data/lib/rspec/core/mocking_adapters/null.rb +12 -0
  55. data/lib/rspec/core/mocking_adapters/rr.rb +28 -0
  56. data/lib/rspec/core/mocking_adapters/rspec.rb +30 -0
  57. data/lib/rspec/core/notifications.rb +100 -0
  58. data/lib/rspec/core/option_parser.rb +11 -18
  59. data/lib/rspec/core/pending.rb +78 -47
  60. data/lib/rspec/core/project_initializer.rb +2 -49
  61. data/lib/rspec/core/project_initializer/dot_rspec +3 -0
  62. data/lib/rspec/core/project_initializer/spec_helper.rb +82 -0
  63. data/lib/rspec/core/rake_task.rb +5 -14
  64. data/lib/rspec/core/reporter.rb +24 -32
  65. data/lib/rspec/core/ruby_project.rb +1 -1
  66. data/lib/rspec/core/runner.rb +14 -4
  67. data/lib/rspec/core/shared_example_group.rb +40 -13
  68. data/lib/rspec/core/version.rb +1 -1
  69. data/spec/command_line/order_spec.rb +15 -15
  70. data/spec/rspec/core/backtrace_formatter_spec.rb +15 -1
  71. data/spec/rspec/core/command_line_spec.rb +18 -17
  72. data/spec/rspec/core/configuration_options_spec.rb +57 -34
  73. data/spec/rspec/core/configuration_spec.rb +162 -184
  74. data/spec/rspec/core/drb_command_line_spec.rb +5 -7
  75. data/spec/rspec/core/drb_options_spec.rb +2 -2
  76. data/spec/rspec/core/dsl_spec.rb +79 -15
  77. data/spec/rspec/core/example_group_spec.rb +253 -39
  78. data/spec/rspec/core/example_spec.rb +149 -33
  79. data/spec/rspec/core/filter_manager_spec.rb +9 -26
  80. data/spec/rspec/core/formatters/base_formatter_spec.rb +2 -5
  81. data/spec/rspec/core/formatters/base_text_formatter_spec.rb +42 -145
  82. data/spec/rspec/core/formatters/deprecation_formatter_spec.rb +64 -34
  83. data/spec/rspec/core/formatters/documentation_formatter_spec.rb +15 -28
  84. data/spec/rspec/core/formatters/helpers_spec.rb +2 -2
  85. data/spec/rspec/core/formatters/{html_formatted-1.8.7.html → html_formatted-2.1.0.html} +22 -44
  86. data/spec/rspec/core/formatters/{html_formatted-1.8.7-jruby.html → html_formatted.html} +30 -49
  87. data/spec/rspec/core/formatters/html_formatter_spec.rb +35 -19
  88. data/spec/rspec/core/formatters/json_formatter_spec.rb +42 -40
  89. data/spec/rspec/core/formatters/legacy_formatter_spec.rb +137 -0
  90. data/spec/rspec/core/formatters/progress_formatter_spec.rb +38 -25
  91. data/spec/rspec/core/formatters/snippet_extractor_spec.rb +1 -1
  92. data/spec/rspec/core/formatters_spec.rb +120 -0
  93. data/spec/rspec/core/hooks_filtering_spec.rb +1 -1
  94. data/spec/rspec/core/hooks_spec.rb +13 -2
  95. data/spec/rspec/core/memoized_helpers_spec.rb +17 -8
  96. data/spec/rspec/core/metadata_spec.rb +3 -3
  97. data/spec/rspec/core/option_parser_spec.rb +53 -46
  98. data/spec/rspec/core/ordering_spec.rb +4 -4
  99. data/spec/rspec/core/pending_example_spec.rb +23 -126
  100. data/spec/rspec/core/pending_spec.rb +8 -0
  101. data/spec/rspec/core/project_initializer_spec.rb +8 -41
  102. data/spec/rspec/core/rake_task_spec.rb +15 -4
  103. data/spec/rspec/core/random_spec.rb +1 -1
  104. data/spec/rspec/core/reporter_spec.rb +50 -37
  105. data/spec/rspec/core/resources/formatter_specs.rb +9 -11
  106. data/spec/rspec/core/rspec_matchers_spec.rb +1 -1
  107. data/spec/rspec/core/ruby_project_spec.rb +3 -3
  108. data/spec/rspec/core/runner_spec.rb +65 -23
  109. data/spec/rspec/core/shared_context_spec.rb +4 -4
  110. data/spec/rspec/core/shared_example_group/collection_spec.rb +1 -1
  111. data/spec/rspec/core/shared_example_group_spec.rb +20 -11
  112. data/spec/rspec/core/warnings_spec.rb +1 -1
  113. data/spec/rspec/core/world_spec.rb +10 -10
  114. data/spec/rspec/core_spec.rb +2 -2
  115. data/spec/spec_helper.rb +12 -24
  116. data/spec/support/config_options_helper.rb +1 -3
  117. data/spec/support/formatter_support.rb +83 -0
  118. data/spec/support/isolate_load_path_mutation.rb +1 -2
  119. data/spec/support/isolated_directory.rb +1 -1
  120. data/spec/support/isolated_home_directory.rb +1 -1
  121. data/spec/support/legacy_formatter_using_sub_classing_example.rb +87 -0
  122. data/spec/support/matchers.rb +20 -0
  123. data/spec/support/mathn_integration_support.rb +2 -2
  124. data/spec/support/old_style_formatter_example.rb +69 -0
  125. data/spec/support/shared_example_groups.rb +1 -1
  126. data/spec/support/spec_files.rb +3 -3
  127. metadata +192 -69
  128. metadata.gz.sig +3 -1
  129. checksums.yaml +0 -15
  130. checksums.yaml.gz.sig +0 -2
  131. data/features/configuration/show_failures_in_pending_blocks.feature +0 -61
  132. data/features/pending/pending_examples.feature +0 -229
  133. data/features/subject/implicit_receiver.feature +0 -29
  134. data/lib/rspec/core/mocking/with_absolutely_nothing.rb +0 -11
  135. data/lib/rspec/core/mocking/with_flexmock.rb +0 -27
  136. data/lib/rspec/core/mocking/with_rr.rb +0 -27
  137. data/lib/rspec/core/mocking/with_rspec.rb +0 -27
  138. data/spec/rspec/core/formatters/html_formatted-1.8.7-rbx.html +0 -477
  139. data/spec/rspec/core/formatters/html_formatted-1.9.2.html +0 -425
  140. data/spec/rspec/core/formatters/html_formatted-1.9.3-jruby.html +0 -416
  141. data/spec/rspec/core/formatters/html_formatted-1.9.3-rbx.html +0 -477
  142. data/spec/rspec/core/formatters/html_formatted-1.9.3.html +0 -419
  143. data/spec/rspec/core/formatters/html_formatted-2.0.0.html +0 -425
  144. data/spec/support/in_sub_process.rb +0 -37
  145. data/spec/support/sandboxed_mock_space.rb +0 -100
@@ -0,0 +1,106 @@
1
+ Feature: skipped examples
2
+
3
+ RSpec offers a number of ways to indicate that an example should be skipped
4
+ and not executed.
5
+
6
+ Scenario: no implementation provided
7
+ Given a file named "example_without_block_spec.rb" with:
8
+ """ruby
9
+ describe "an example" do
10
+ it "is a skipped example"
11
+ end
12
+ """
13
+ When I run `rspec example_without_block_spec.rb`
14
+ Then the exit status should be 0
15
+ And the output should contain "1 example, 0 failures, 1 pending"
16
+ And the output should contain "Not yet implemented"
17
+ And the output should contain "example_without_block_spec.rb:2"
18
+
19
+ Scenario: skipping using `skip`
20
+ Given a file named "skipped_spec.rb" with:
21
+ """ruby
22
+ describe "an example" do
23
+ skip "is skipped" do
24
+ end
25
+ end
26
+ """
27
+ When I run `rspec skipped_spec.rb`
28
+ Then the exit status should be 0
29
+ And the output should contain "1 example, 0 failures, 1 pending"
30
+ And the output should contain:
31
+ """
32
+ Pending:
33
+ an example is skipped
34
+ # No reason given
35
+ # ./skipped_spec.rb:2
36
+ """
37
+
38
+ Scenario: skipping using `skip` inside an example
39
+ Given a file named "skipped_spec.rb" with:
40
+ """ruby
41
+ describe "an example" do
42
+ it "is skipped" do
43
+ skip
44
+ end
45
+ end
46
+ """
47
+ When I run `rspec skipped_spec.rb`
48
+ Then the exit status should be 0
49
+ And the output should contain "1 example, 0 failures, 1 pending"
50
+ And the output should contain:
51
+ """
52
+ Pending:
53
+ an example is skipped
54
+ # No reason given
55
+ # ./skipped_spec.rb:2
56
+ """
57
+
58
+ Scenario: temporarily skipping by prefixing `it`, `specify`, or `example` with an x
59
+ Given a file named "temporarily_skipped_spec.rb" with:
60
+ """ruby
61
+ describe "an example" do
62
+ xit "is skipped using xit" do
63
+ end
64
+
65
+ xspecify "is skipped using xspecify" do
66
+ end
67
+
68
+ xexample "is skipped using xexample" do
69
+ end
70
+ end
71
+ """
72
+ When I run `rspec temporarily_skipped_spec.rb`
73
+ Then the exit status should be 0
74
+ And the output should contain "3 examples, 0 failures, 3 pending"
75
+ And the output should contain:
76
+ """
77
+ Pending:
78
+ an example is skipped using xit
79
+ # Temporarily skipped with xit
80
+ # ./temporarily_skipped_spec.rb:2
81
+ an example is skipped using xspecify
82
+ # Temporarily skipped with xspecify
83
+ # ./temporarily_skipped_spec.rb:5
84
+ an example is skipped using xexample
85
+ # Temporarily skipped with xexample
86
+ # ./temporarily_skipped_spec.rb:8
87
+ """
88
+
89
+ Scenario: skipping using metadata
90
+ Given a file named "skipped_spec.rb" with:
91
+ """ruby
92
+ describe "an example" do
93
+ example "is skipped", :skip => true do
94
+ end
95
+ end
96
+ """
97
+ When I run `rspec skipped_spec.rb`
98
+ Then the exit status should be 0
99
+ And the output should contain "1 example, 0 failures, 1 pending"
100
+ And the output should contain:
101
+ """
102
+ Pending:
103
+ an example is skipped
104
+ # No reason given
105
+ # ./skipped_spec.rb:2
106
+ """
@@ -41,9 +41,43 @@ Then /^the backtrace\-normalized output should contain:$/ do |partial_output|
41
41
  expect(normalized_output).to match(regexp(partial_output))
42
42
  end
43
43
 
44
+ Then /^the output should not contain any error backtraces$/ do
45
+ step %q{the output should not contain "lib/rspec/core"}
46
+ end
47
+
44
48
  # This step can be generalized if it's ever used to test other colors
45
49
  Then /^the failing example is printed in magenta$/ do
46
50
  # \e[35m = enable magenta
47
51
  # \e[0m = reset colors
48
52
  expect(all_output).to include("\e[35m" + "F" + "\e[0m")
49
53
  end
54
+
55
+ Given /^I have a brand new project with no files$/ do
56
+ in_current_dir do
57
+ expect(Dir["**/*"]).to eq([])
58
+ end
59
+ end
60
+
61
+ Given /^I have run `([^`]*)`$/ do |cmd|
62
+ fail_on_error = true
63
+ run_simple(unescape(cmd), fail_on_error)
64
+ end
65
+
66
+ When "I accept the recommended settings by removing `=begin` and `=end` from `spec/spec_helper.rb`" do
67
+ in_current_dir do
68
+ spec_helper = File.read("spec/spec_helper.rb")
69
+ expect(spec_helper).to include("=begin", "=end")
70
+
71
+ to_keep = spec_helper.lines.reject do |line|
72
+ line.start_with?("=begin") || line.start_with?("=end")
73
+ end
74
+
75
+ File.open("spec/spec_helper.rb", "w") { |f| f.write(to_keep.join) }
76
+ expect(File.read("spec/spec_helper.rb")).not_to include("=begin", "=end")
77
+ end
78
+ end
79
+
80
+ When /^I create "([^"]*)" with the following content:$/ do |file_name, content|
81
+ write_file(file_name, content)
82
+ end
83
+
@@ -73,7 +73,7 @@ Feature: explicit subject
73
73
  context "with index out of bounds" do
74
74
  before { expect(Array).to receive(:one_two_three).once.and_return([1,2,3]) }
75
75
  subject { Array.one_two_three[42] }
76
- it { should be_nil }
76
+ it { is_expected.to be_nil }
77
77
  end
78
78
  end
79
79
  end
@@ -0,0 +1,71 @@
1
+ Feature: One-liner syntax
2
+
3
+ RSpec supports a one-liner syntax for setting an expectation
4
+ on the `subject`. RSpec will give the examples a doc string
5
+ that is auto-generated from the matcher used in the example.
6
+ This is designed specifically to help avoid duplication in
7
+ situations where the doc string and the matcher used in the
8
+ example mirror each other exactly. When used excessively,
9
+ it can produce documentation output that does not read well
10
+ or contribute to understanding the object you are describing.
11
+
12
+ This comes in two flavors:
13
+
14
+ * `is_expected` is defined simply as `expect(subject)` and is
15
+ designed for when you are using rspec-expectations with its
16
+ newer expect-based syntax.
17
+ * `should` was designed back when rspec-expectations only had
18
+ a should-based syntax. However, it continues to be available
19
+ and work even if the `:should` syntax is disabled (since that
20
+ merely removes `Object#should` but this is
21
+ `RSpec::Core::ExampleGroup#should`).
22
+
23
+ Note: this feature is only available when using rspec-expectations.
24
+
25
+ Scenario: implicit subject
26
+ Given a file named "example_spec.rb" with:
27
+ """ruby
28
+ describe Array do
29
+ describe "when first created" do
30
+ # Rather than:
31
+ # it "should be empty" do
32
+ # subject.should be_empty
33
+ # end
34
+
35
+ it { should be_empty }
36
+ # or
37
+ it { is_expected.to be_empty }
38
+ end
39
+ end
40
+ """
41
+ When I run `rspec example_spec.rb --format doc`
42
+ Then the examples should all pass
43
+ And the output should contain:
44
+ """
45
+ Array
46
+ when first created
47
+ should be empty
48
+ should be empty
49
+ """
50
+
51
+ Scenario: explicit subject
52
+ Given a file named "example_spec.rb" with:
53
+ """ruby
54
+ describe Array do
55
+ describe "with 3 items" do
56
+ subject { [1,2,3] }
57
+ it { should_not be_empty }
58
+ # or
59
+ it { is_expected.not_to be_empty }
60
+ end
61
+ end
62
+ """
63
+ When I run `rspec example_spec.rb --format doc`
64
+ Then the examples should all pass
65
+ And the output should contain:
66
+ """
67
+ Array
68
+ with 3 items
69
+ should not be empty
70
+ should not be empty
71
+ """
@@ -21,6 +21,7 @@ require 'rspec/support/warnings'
21
21
  require_rspec['core/flat_map']
22
22
  require_rspec['core/filter_manager']
23
23
  require_rspec['core/dsl']
24
+ require_rspec['core/notifications']
24
25
  require_rspec['core/reporter']
25
26
 
26
27
  require_rspec['core/hooks']
@@ -85,21 +86,12 @@ module RSpec
85
86
  # @see RSpec.configure
86
87
  # @see Core::Configuration
87
88
  def self.configuration
88
- if block_given?
89
- RSpec.warn_deprecation <<-WARNING
89
+ @configuration ||= begin
90
+ config = RSpec::Core::Configuration.new
91
+ config.expose_dsl_globally = true
92
+ config
93
+ end
90
94
 
91
- *****************************************************************
92
- DEPRECATION WARNING
93
-
94
- * RSpec.configuration with a block is deprecated and has no effect.
95
- * please use RSpec.configure with a block instead.
96
-
97
- Called from #{CallerFilter.first_non_rspec_line}
98
- *****************************************************************
99
-
100
- WARNING
101
- end
102
- @configuration ||= RSpec::Core::Configuration.new
103
95
  end
104
96
 
105
97
  # @private
@@ -12,14 +12,14 @@ module RSpec
12
12
 
13
13
  def initialize
14
14
  @full_backtrace = false
15
- @exclusion_patterns = [] << Regexp.union(
15
+ @system_exclusion_patterns = [] << Regexp.union(
16
16
  *["/lib\d*/ruby/",
17
17
  "org/jruby/",
18
18
  "bin/",
19
19
  "/gems/",
20
20
  "lib/rspec/(core|expectations|matchers|mocks)"].
21
- map {|s| Regexp.new(s.gsub("/", File::SEPARATOR))}
22
- )
21
+ map {|s| Regexp.new(s.gsub("/", File::SEPARATOR))})
22
+ @exclusion_patterns = [] + @system_exclusion_patterns
23
23
  @inclusion_patterns = [Regexp.new(Dir.getwd)]
24
24
  end
25
25
 
@@ -58,8 +58,20 @@ module RSpec
58
58
  # @api private
59
59
  def exclude?(line)
60
60
  return false if @full_backtrace
61
- @exclusion_patterns.any? {|p| p =~ line} && @inclusion_patterns.none? {|p| p =~ line}
61
+ matches_an_exclusion_pattern?(line) &&
62
+ doesnt_match_inclusion_pattern_unless_system_exclusion?(line)
62
63
  end
64
+
65
+ private
66
+
67
+ def matches_an_exclusion_pattern?(line)
68
+ @exclusion_patterns.any? { |p| line =~ p }
69
+ end
70
+
71
+ def doesnt_match_inclusion_pattern_unless_system_exclusion?(line)
72
+ @system_exclusion_patterns.any? { |p| line =~ p } || @inclusion_patterns.none? { |p| p =~ line }
73
+ end
74
+
63
75
  end
64
76
  end
65
77
  end
@@ -4,7 +4,6 @@ module RSpec
4
4
  def initialize(options, configuration=RSpec::configuration, world=RSpec::world)
5
5
  if Array === options
6
6
  options = ConfigurationOptions.new(options)
7
- options.parse_options
8
7
  end
9
8
  @options = options
10
9
  @configuration = configuration
@@ -24,10 +23,10 @@ module RSpec
24
23
 
25
24
  @configuration.reporter.report(@world.example_count) do |reporter|
26
25
  begin
27
- @configuration.run_hook(:before, :suite)
26
+ @configuration.hooks.run(:before, :suite)
28
27
  @world.ordered_example_groups.map {|g| g.run(reporter) }.all? ? 0 : @configuration.failure_exit_code
29
28
  ensure
30
- @configuration.run_hook(:after, :suite)
29
+ @configuration.hooks.run(:after, :suite)
31
30
  end
32
31
  end
33
32
  end
@@ -41,11 +41,6 @@ module RSpec
41
41
  end
42
42
  end
43
43
 
44
- # @private
45
- def self.deprecate_alias_key
46
- RSpec.deprecate("add_setting with :alias option", :replacement => ":alias_with")
47
- end
48
-
49
44
  # @private
50
45
  def self.define_aliases(name, alias_name)
51
46
  alias_method alias_name, name
@@ -64,19 +59,23 @@ module RSpec
64
59
  # `Configuration` instance rather than this class method.
65
60
  def self.add_setting(name, opts={})
66
61
  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
62
+ attr_writer name
63
+ add_read_only_setting name
64
+
75
65
  Array(opts[:alias_with]).each do |alias_name|
76
66
  define_aliases(name, alias_name)
77
67
  end
78
68
  end
79
69
 
70
+ # @private
71
+ #
72
+ # As `add_setting` but only add the reader
73
+ def self.add_read_only_setting(name, opts={})
74
+ raise "Use the instance add_setting method if you want to set a default" if opts.has_key?(:default)
75
+ define_reader name
76
+ define_predicate_for name
77
+ end
78
+
80
79
  # @macro [attach] add_setting
81
80
  # @attribute $1
82
81
  #
@@ -102,6 +101,26 @@ module RSpec
102
101
  # Default: `$stderr`.
103
102
  add_setting :error_stream
104
103
 
104
+ # Indicates if the DSL has been exposed off of modules and `main`.
105
+ # Default: true
106
+ def expose_dsl_globally?
107
+ Core::DSL.exposed_globally?
108
+ end
109
+
110
+ # Use this to expose the core RSpec DSL via `Module` and the `main`
111
+ # object. It will be set automatically but you can override it to
112
+ # remove the DSL.
113
+ # Default: true
114
+ def expose_dsl_globally=(value)
115
+ if value
116
+ Core::DSL.expose_globally!
117
+ Core::SharedExampleGroup::TopLevelDSL.expose_globally!
118
+ else
119
+ Core::DSL.remove_globally!
120
+ Core::SharedExampleGroup::TopLevelDSL.remove_globally!
121
+ end
122
+ end
123
+
105
124
  # @macro add_setting
106
125
  # Default: `$stderr`.
107
126
  add_setting :deprecation_stream
@@ -193,16 +212,13 @@ module RSpec
193
212
  # @param [Symbol] color one of the following: [:black, :white, :red, :green, :yellow, :blue, :magenta, :cyan]
194
213
  add_setting :detail_color
195
214
 
196
- # @macro add_setting
197
- # When a block passed to pending fails (as expected), display the failure
198
- # without reporting it as a failure (default: false).
199
- add_setting :show_failures_in_pending_blocks
200
-
201
215
  # Deprecated. This config option was added in RSpec 2 to pave the way
202
216
  # for this being the default behavior in RSpec 3. Now this option is
203
217
  # a no-op.
204
218
  def treat_symbols_as_metadata_keys_with_true_values=(value)
205
- RSpec.deprecate("RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values=")
219
+ RSpec.deprecate("RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values=",
220
+ :message => "RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values=" +
221
+ "is deprecated, it is now set to true as default and setting it to false has no effect.")
206
222
  end
207
223
 
208
224
  # @private
@@ -210,7 +226,7 @@ module RSpec
210
226
  # @private
211
227
  add_setting :include_or_extend_modules
212
228
  # @private
213
- add_setting :files_to_run
229
+ attr_writer :files_to_run
214
230
  # @private
215
231
  add_setting :expecting_with_rspec
216
232
  # @private
@@ -227,8 +243,7 @@ module RSpec
227
243
  @expectation_frameworks = []
228
244
  @include_or_extend_modules = []
229
245
  @mock_framework = nil
230
- @files_to_run = []
231
- @formatters = []
246
+ @files_or_directories_to_run = []
232
247
  @color = false
233
248
  @pattern = '**/*_spec.rb'
234
249
  @failure_exit_code = 1
@@ -267,7 +282,7 @@ module RSpec
267
282
  def reset
268
283
  @spec_files_loaded = false
269
284
  @reporter = nil
270
- @formatters.clear
285
+ @formatter_loader = nil
271
286
  end
272
287
 
273
288
  # @overload add_setting(name)
@@ -310,7 +325,7 @@ module RSpec
310
325
  (class << self; self; end).class_eval do
311
326
  add_setting(name, opts)
312
327
  end
313
- send("#{name}=", default) if default
328
+ __send__("#{name}=", default) if default
314
329
  end
315
330
 
316
331
  # Returns the configured mock framework adapter module
@@ -359,6 +374,15 @@ module RSpec
359
374
  @backtrace_formatter.inclusion_patterns = patterns
360
375
  end
361
376
 
377
+ # @api private
378
+ MOCKING_ADAPTERS = {
379
+ :rspec => :RSpec,
380
+ :flexmock => :Flexmock,
381
+ :rr => :RR,
382
+ :mocha => :Mocha,
383
+ :nothing => :Null
384
+ }
385
+
362
386
  # Sets the mock framework adapter module.
363
387
  #
364
388
  # `framework` can be a Symbol or a Module.
@@ -389,23 +413,17 @@ module RSpec
389
413
  # mod_config.custom_setting = true
390
414
  # end
391
415
  def mock_with(framework)
392
- framework_module = case framework
393
- when Module
394
- framework
395
- when String, Symbol
396
- require case framework.to_s
397
- when /rspec/i
398
- 'rspec/core/mocking/with_rspec'
399
- when /mocha/i
400
- 'rspec/core/mocking/with_mocha'
401
- when /rr/i
402
- 'rspec/core/mocking/with_rr'
403
- when /flexmock/i
404
- 'rspec/core/mocking/with_flexmock'
405
- else
406
- 'rspec/core/mocking/with_absolutely_nothing'
407
- end
408
- RSpec::Core::MockFrameworkAdapter
416
+ framework_module = if framework.is_a?(Module)
417
+ framework
418
+ else
419
+ const_name = MOCKING_ADAPTERS.fetch(framework) do
420
+ raise ArgumentError,
421
+ "Unknown mocking framework: #{framework.inspect}. " +
422
+ "Pass a module or one of #{MOCKING_ADAPTERS.keys.inspect}"
423
+ end
424
+
425
+ require "rspec/core/mocking_adapters/#{const_name.to_s.downcase}"
426
+ RSpec::Core::MockingAdapters.const_get(const_name)
409
427
  end
410
428
 
411
429
  new_name, old_name = [framework_module, @mock_framework].map do |mod|
@@ -527,13 +545,6 @@ module RSpec
527
545
  end
528
546
  end
529
547
 
530
- def requires=(paths)
531
- RSpec.deprecate("RSpec::Core::Configuration#requires=(paths)",
532
- :replacement => "paths.each {|path| require path}")
533
- paths.map {|path| require path}
534
- @requires += paths
535
- end
536
-
537
548
  # Run examples defined on `line_numbers` in all files to run.
538
549
  def line_numbers=(line_numbers)
539
550
  filter_run :line_numbers => line_numbers.map{|l| l.to_i}
@@ -563,27 +574,28 @@ module RSpec
563
574
  # and paths to use for output streams, but you should consider that a
564
575
  # private api that may change at any time without notice.
565
576
  def add_formatter(formatter_to_use, *paths)
566
- formatter_class =
567
- built_in_formatter(formatter_to_use) ||
568
- custom_formatter(formatter_to_use) ||
569
- (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.")
570
-
571
577
  paths << output_stream if paths.empty?
572
- formatters << formatter_class.new(*paths.map {|p| String === p ? file_at(p) : p})
578
+ formatter_loader.add formatter_to_use, *paths
573
579
  end
574
-
575
580
  alias_method :formatter=, :add_formatter
576
581
 
582
+ # @api private
577
583
  def formatters
578
- @formatters ||= []
584
+ formatter_loader.formatters
579
585
  end
580
586
 
587
+ # @api private
588
+ def formatter_loader
589
+ @formatter_loader ||= Formatters::Loader.new(Reporter.new(self))
590
+ end
591
+
592
+ # @api private
581
593
  def reporter
582
- @reporter ||= begin
583
- add_formatter('progress') if formatters.empty?
584
- add_formatter(RSpec::Core::Formatters::DeprecationFormatter, deprecation_stream, output_stream)
585
- Reporter.new(self, *formatters)
586
- end
594
+ @reporter ||=
595
+ begin
596
+ formatter_loader.setup_default output_stream, deprecation_stream
597
+ formatter_loader.reporter
598
+ end
587
599
  end
588
600
 
589
601
  # @api private
@@ -603,7 +615,12 @@ module RSpec
603
615
  def files_or_directories_to_run=(*files)
604
616
  files = files.flatten
605
617
  files << default_path if (command == 'rspec' || Runner.running_in_drb?) && default_path && files.empty?
606
- self.files_to_run = get_files_to_run(files)
618
+ @files_or_directories_to_run = files
619
+ @files_to_run = nil
620
+ end
621
+
622
+ def files_to_run
623
+ @files_to_run ||= get_files_to_run(@files_or_directories_to_run)
607
624
  end
608
625
 
609
626
  # Creates a method that delegates to `example` including the submitted
@@ -632,6 +649,35 @@ module RSpec
632
649
  RSpec::Core::ExampleGroup.alias_example_to(new_name, extra_options)
633
650
  end
634
651
 
652
+ # Creates a method that defines an example group with the provided
653
+ # metadata. Can be used to define example group/metadata shortcuts.
654
+ #
655
+ # @example
656
+ # alias_example_group_to :describe_model, :type => :model
657
+ # shared_context_for "model tests", :type => :model do
658
+ # # define common model test helper methods, `let` declarations, etc
659
+ # end
660
+ #
661
+ # # This lets you do this:
662
+ #
663
+ # RSpec.describe_model User do
664
+ # end
665
+ #
666
+ # # ... which is the equivalent of
667
+ #
668
+ # RSpec.describe User, :type => :model do
669
+ # end
670
+ #
671
+ # @note The defined aliased will also be added to the top level
672
+ # (e.g. `main` and from within modules) if
673
+ # `expose_dsl_globally` is set to true.
674
+ # @see #alias_example_to
675
+ # @see #expose_dsl_globally=
676
+ def alias_example_group_to(new_name, *args)
677
+ extra_options = Metadata.build_hash_from(args)
678
+ RSpec::Core::ExampleGroup.alias_example_group_to(new_name, extra_options)
679
+ end
680
+
635
681
  # Define an alias for it_should_behave_like that allows different
636
682
  # language (like "it_has_behavior" or "it_behaves_like") to be
637
683
  # employed when including shared examples.
@@ -841,17 +887,17 @@ module RSpec
841
887
  def configure_group(group)
842
888
  include_or_extend_modules.each do |include_or_extend, mod, filters|
843
889
  next unless filters.empty? || group.any_apply?(filters)
844
- send("safe_#{include_or_extend}", mod, group)
890
+ __send__("safe_#{include_or_extend}", mod, group)
845
891
  end
846
892
  end
847
893
 
848
894
  # @private
849
895
  def safe_include(mod, host)
850
- host.send(:include,mod) unless host < mod
896
+ host.__send__(:include, mod) unless host < mod
851
897
  end
852
898
 
853
899
  # @private
854
- def setup_load_path_and_require(paths)
900
+ def requires=(paths)
855
901
  directories = ['lib', default_path].select { |p| File.directory? p }
856
902
  RSpec::Core::RubyProject.add_to_load_path(*directories)
857
903
  paths.each {|path| require path}
@@ -861,7 +907,7 @@ module RSpec
861
907
  # @private
862
908
  if RUBY_VERSION.to_f >= 1.9
863
909
  def safe_extend(mod, host)
864
- host.extend(mod) unless (class << host; self; end) < mod
910
+ host.extend(mod) unless host.singleton_class < mod
865
911
  end
866
912
  else
867
913
  def safe_extend(mod, host)
@@ -871,13 +917,13 @@ module RSpec
871
917
 
872
918
  # @private
873
919
  def configure_mock_framework
874
- RSpec::Core::ExampleGroup.send(:include, mock_framework)
920
+ RSpec::Core::ExampleGroup.__send__(:include, mock_framework)
875
921
  end
876
922
 
877
923
  # @private
878
924
  def configure_expectation_framework
879
925
  expectation_frameworks.each do |framework|
880
- RSpec::Core::ExampleGroup.send(:include, framework)
926
+ RSpec::Core::ExampleGroup.__send__(:include, framework)
881
927
  end
882
928
  end
883
929
 
@@ -1067,63 +1113,6 @@ module RSpec
1067
1113
  def output_to_tty?(output=output_stream)
1068
1114
  tty? || (output.respond_to?(:tty?) && output.tty?)
1069
1115
  end
1070
-
1071
- def built_in_formatter(key)
1072
- case key.to_s
1073
- when 'd', 'doc', 'documentation', 's', 'n', 'spec', 'nested'
1074
- require 'rspec/core/formatters/documentation_formatter'
1075
- RSpec::Core::Formatters::DocumentationFormatter
1076
- when 'h', 'html'
1077
- require 'rspec/core/formatters/html_formatter'
1078
- RSpec::Core::Formatters::HtmlFormatter
1079
- when 'p', 'progress'
1080
- require 'rspec/core/formatters/progress_formatter'
1081
- RSpec::Core::Formatters::ProgressFormatter
1082
- when 'j', 'json'
1083
- require 'rspec/core/formatters/json_formatter'
1084
- RSpec::Core::Formatters::JsonFormatter
1085
- end
1086
- end
1087
-
1088
- def custom_formatter(formatter_ref)
1089
- if Class === formatter_ref
1090
- formatter_ref
1091
- elsif string_const?(formatter_ref)
1092
- begin
1093
- formatter_ref.gsub(/^::/,'').split('::').inject(Object) { |const,string| const.const_get string }
1094
- rescue NameError
1095
- require( path_for(formatter_ref) ) ? retry : raise
1096
- end
1097
- end
1098
- end
1099
-
1100
- def string_const?(str)
1101
- str.is_a?(String) && /\A[A-Z][a-zA-Z0-9_:]*\z/ =~ str
1102
- end
1103
-
1104
- def path_for(const_ref)
1105
- underscore_with_fix_for_non_standard_rspec_naming(const_ref)
1106
- end
1107
-
1108
- def underscore_with_fix_for_non_standard_rspec_naming(string)
1109
- underscore(string).sub(%r{(^|/)r_spec($|/)}, '\\1rspec\\2')
1110
- end
1111
-
1112
- # activesupport/lib/active_support/inflector/methods.rb, line 48
1113
- def underscore(camel_cased_word)
1114
- word = camel_cased_word.to_s.dup
1115
- word.gsub!(/::/, '/')
1116
- word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
1117
- word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
1118
- word.tr!("-", "_")
1119
- word.downcase!
1120
- word
1121
- end
1122
-
1123
- def file_at(path)
1124
- FileUtils.mkdir_p(File.dirname(path))
1125
- File.new(path, 'w')
1126
- end
1127
1116
  end
1128
1117
  end
1129
1118
  end