rspec-core 2.0.0.beta.22 → 2.6.0
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.
- data/.gitignore +1 -0
- data/.rspec +0 -1
- data/.travis.yml +7 -0
- data/Gemfile +46 -20
- data/Guardfile +5 -0
- data/License.txt +2 -1
- data/{README.markdown → README.md} +23 -5
- data/Rakefile +58 -31
- data/bin/autospec +13 -0
- data/bin/rspec +24 -2
- data/cucumber.yml +1 -1
- data/features/.nav +57 -0
- data/features/Autotest.md +38 -0
- data/features/Changelog.md +269 -0
- data/features/README.md +17 -0
- data/features/Upgrade.md +320 -0
- data/features/command_line/README.md +28 -0
- data/features/command_line/configure.feature +18 -15
- data/features/command_line/example_name_option.feature +37 -23
- data/features/command_line/exit_status.feature +16 -31
- data/features/command_line/format_option.feature +73 -0
- data/features/command_line/line_number_appended_to_path.feature +25 -27
- data/features/command_line/line_number_option.feature +11 -10
- data/features/command_line/rake_task.feature +68 -0
- data/features/command_line/tag.feature +90 -0
- data/features/configuration/alias_example_to.feature +48 -0
- data/features/configuration/custom_settings.feature +8 -10
- data/features/configuration/fail_fast.feature +77 -0
- data/features/configuration/read_options_from_file.feature +42 -26
- data/features/example_groups/basic_structure.feature +55 -0
- data/features/example_groups/shared_context.feature +74 -0
- data/features/example_groups/shared_example_group.feature +56 -41
- data/features/expectation_framework_integration/configure_expectation_framework.feature +73 -0
- data/features/filtering/exclusion_filters.feature +69 -9
- data/features/filtering/if_and_unless.feature +168 -0
- data/features/filtering/inclusion_filters.feature +58 -26
- data/features/filtering/run_all_when_everything_filtered.feature +46 -0
- data/features/formatters/custom_formatter.feature +17 -13
- data/features/formatters/text_formatter.feature +43 -0
- data/features/helper_methods/arbitrary_methods.feature +40 -0
- data/features/helper_methods/let.feature +50 -0
- data/features/helper_methods/modules.feature +149 -0
- data/features/hooks/around_hooks.feature +99 -69
- data/features/hooks/before_and_after_hooks.feature +74 -40
- data/features/hooks/filtering.feature +227 -0
- data/features/metadata/current_example.feature +17 -0
- data/features/metadata/described_class.feature +17 -0
- data/features/metadata/user_defined.feature +111 -0
- data/features/mock_framework_integration/use_any_framework.feature +106 -0
- data/features/mock_framework_integration/use_flexmock.feature +84 -11
- data/features/mock_framework_integration/use_mocha.feature +85 -11
- data/features/mock_framework_integration/use_rr.feature +86 -11
- data/features/mock_framework_integration/use_rspec.feature +85 -11
- data/features/pending/pending_examples.feature +143 -5
- data/features/spec_files/arbitrary_file_suffix.feature +2 -2
- data/features/step_definitions/additional_cli_steps.rb +30 -0
- data/features/subject/attribute_of_subject.feature +93 -15
- data/features/subject/explicit_subject.feature +28 -17
- data/features/subject/implicit_receiver.feature +29 -0
- data/features/subject/implicit_subject.feature +9 -10
- data/features/support/env.rb +6 -1
- data/lib/autotest/discover.rb +1 -0
- data/lib/autotest/rspec2.rb +15 -11
- data/lib/rspec/autorun.rb +2 -0
- data/lib/rspec/core/backward_compatibility.rb +33 -4
- data/lib/rspec/core/command_line.rb +4 -28
- data/lib/rspec/core/command_line_configuration.rb +16 -16
- data/lib/rspec/core/configuration.rb +279 -89
- data/lib/rspec/core/configuration_options.rb +46 -35
- data/lib/rspec/core/deprecation.rb +1 -1
- data/lib/rspec/core/drb_command_line.rb +5 -11
- data/lib/rspec/core/example.rb +63 -39
- data/lib/rspec/core/example_group.rb +109 -59
- data/lib/rspec/core/expecting/with_rspec.rb +11 -0
- data/lib/rspec/core/expecting/with_stdlib.rb +9 -0
- data/lib/rspec/core/extensions/kernel.rb +1 -1
- data/lib/rspec/core/extensions/object.rb +1 -3
- data/lib/rspec/core/formatters/base_formatter.rb +22 -11
- data/lib/rspec/core/formatters/base_text_formatter.rb +46 -30
- data/lib/rspec/core/formatters/documentation_formatter.rb +4 -2
- data/lib/rspec/core/formatters/helpers.rb +0 -4
- data/lib/rspec/core/formatters/html_formatter.rb +146 -41
- data/lib/rspec/core/formatters/progress_formatter.rb +1 -0
- data/lib/rspec/core/formatters/snippet_extractor.rb +1 -1
- data/lib/rspec/core/formatters/text_mate_formatter.rb +3 -1
- data/lib/rspec/core/hooks.rb +55 -17
- data/lib/rspec/core/metadata.rb +75 -64
- data/lib/rspec/core/metadata_hash_builder.rb +93 -0
- data/lib/rspec/core/mocking/with_flexmock.rb +2 -0
- data/lib/rspec/core/mocking/with_mocha.rb +2 -0
- data/lib/rspec/core/mocking/with_rr.rb +2 -0
- data/lib/rspec/core/mocking/with_rspec.rb +3 -1
- data/lib/rspec/core/option_parser.rb +48 -5
- data/lib/rspec/core/pending.rb +22 -4
- data/lib/rspec/core/rake_task.rb +64 -28
- data/lib/rspec/core/reporter.rb +3 -2
- data/lib/rspec/core/ruby_project.rb +2 -2
- data/lib/rspec/core/runner.rb +50 -6
- data/lib/rspec/core/shared_context.rb +16 -0
- data/lib/rspec/core/shared_example_group.rb +19 -4
- data/lib/rspec/core/subject.rb +92 -65
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/world.rb +83 -25
- data/lib/rspec/core.rb +40 -24
- data/lib/rspec/monkey/spork/test_framework/rspec.rb +1 -0
- data/rspec-core.gemspec +4 -25
- data/script/FullBuildRakeFile +63 -0
- data/script/cucumber +1 -0
- data/script/full_build +1 -0
- data/script/spec +1 -0
- data/spec/autotest/discover_spec.rb +19 -0
- data/spec/autotest/failed_results_re_spec.rb +25 -9
- data/spec/autotest/rspec_spec.rb +32 -41
- data/spec/rspec/core/command_line_spec.rb +62 -7
- data/spec/rspec/core/configuration_options_spec.rb +184 -148
- data/spec/rspec/core/configuration_spec.rb +406 -108
- data/spec/rspec/core/deprecations_spec.rb +38 -1
- data/spec/rspec/core/drb_command_line_spec.rb +21 -56
- data/spec/rspec/core/example_group_spec.rb +366 -127
- data/spec/rspec/core/example_spec.rb +125 -45
- data/spec/rspec/core/formatters/base_formatter_spec.rb +61 -1
- data/spec/rspec/core/formatters/base_text_formatter_spec.rb +39 -5
- data/spec/rspec/core/formatters/documentation_formatter_spec.rb +7 -6
- data/spec/rspec/core/formatters/helpers_spec.rb +1 -1
- data/spec/rspec/core/formatters/html_formatted-1.8.6.html +199 -81
- data/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html +199 -83
- data/spec/rspec/core/formatters/html_formatted-1.8.7.html +199 -81
- data/spec/rspec/core/formatters/html_formatted-1.9.1.html +206 -81
- data/spec/rspec/core/formatters/html_formatted-1.9.2.html +206 -61
- data/spec/rspec/core/formatters/html_formatter_spec.rb +17 -9
- data/spec/rspec/core/formatters/progress_formatter_spec.rb +1 -1
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html +199 -81
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html +199 -81
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +199 -81
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html +206 -81
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +206 -81
- data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +22 -7
- data/spec/rspec/core/hooks_filtering_spec.rb +128 -5
- data/spec/rspec/core/hooks_spec.rb +90 -4
- data/spec/rspec/core/metadata_spec.rb +176 -163
- data/spec/rspec/core/option_parser_spec.rb +73 -6
- data/spec/rspec/core/pending_example_spec.rb +137 -35
- data/spec/rspec/core/rake_task_spec.rb +62 -29
- data/spec/rspec/core/reporter_spec.rb +20 -4
- data/spec/rspec/core/resources/formatter_specs.rb +25 -1
- data/spec/rspec/core/rspec_matchers_spec.rb +45 -0
- data/spec/rspec/core/runner_spec.rb +60 -10
- data/spec/rspec/core/shared_context_spec.rb +30 -0
- data/spec/rspec/core/shared_example_group_spec.rb +59 -23
- data/spec/rspec/core/subject_spec.rb +136 -0
- data/spec/rspec/core/world_spec.rb +211 -68
- data/spec/rspec/core_spec.rb +28 -0
- data/spec/spec_helper.rb +41 -23
- data/spec/support/matchers.rb +44 -13
- data/spec/support/shared_example_groups.rb +41 -0
- data/spec/support/spec_files.rb +44 -0
- data/spec.txt +1126 -0
- metadata +99 -168
- data/.treasure_map.rb +0 -23
- data/History.md +0 -30
- data/Upgrade.markdown +0 -150
- data/autotest/discover.rb +0 -2
- data/features/README.markdown +0 -12
- data/features/example_groups/describe_aliases.feature +0 -25
- data/features/example_groups/nested_groups.feature +0 -44
- data/features/hooks/described_class.feature +0 -14
- data/features/hooks/halt.feature +0 -26
- data/lib/rspec/core/around_proxy.rb +0 -14
- data/lib/rspec/core/formatters.rb +0 -8
- data/spec/ruby_forker.rb +0 -13
- data/specs.watchr +0 -59
data/lib/rspec/core/reporter.rb
CHANGED
|
@@ -3,6 +3,7 @@ module RSpec::Core
|
|
|
3
3
|
def initialize(*formatters)
|
|
4
4
|
@formatters = formatters
|
|
5
5
|
@example_count = @failure_count = @pending_count = 0
|
|
6
|
+
@duration = @start = nil
|
|
6
7
|
end
|
|
7
8
|
|
|
8
9
|
def report(count)
|
|
@@ -38,11 +39,11 @@ module RSpec::Core
|
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
def example_group_started(group)
|
|
41
|
-
notify :example_group_started, group
|
|
42
|
+
notify :example_group_started, group unless group.descendant_filtered_examples.empty?
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
def example_group_finished(group)
|
|
45
|
-
notify :example_group_finished, group
|
|
46
|
+
notify :example_group_finished, group unless group.descendant_filtered_examples.empty?
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def example_started(example)
|
|
@@ -27,9 +27,9 @@ module RSpec
|
|
|
27
27
|
ascend_until {|path| File.exists?(File.join(path, dir))}
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
def ascend_until
|
|
30
|
+
def ascend_until # :nodoc:
|
|
31
31
|
Pathname(File.expand_path('.')).ascend do |path|
|
|
32
|
-
return path if
|
|
32
|
+
return path if yield(path)
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
data/lib/rspec/core/runner.rb
CHANGED
|
@@ -4,11 +4,32 @@ module RSpec
|
|
|
4
4
|
module Core
|
|
5
5
|
class Runner
|
|
6
6
|
|
|
7
|
+
# Register an at_exit hook that runs the suite.
|
|
8
|
+
def self.autorun
|
|
9
|
+
return if autorun_disabled? || installed_at_exit? || running_in_drb?
|
|
10
|
+
@installed_at_exit = true
|
|
11
|
+
at_exit { exit(run(ARGV, $stderr, $stdout)) }
|
|
12
|
+
end
|
|
13
|
+
AT_EXIT_HOOK_BACKTRACE_LINE = "#{__FILE__}:#{__LINE__ - 2}:in `autorun'"
|
|
14
|
+
|
|
7
15
|
def self.disable_autorun!
|
|
8
|
-
|
|
16
|
+
@autorun_disabled = true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.autorun_disabled? # :nodoc:
|
|
20
|
+
@autorun_disabled ||= false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.installed_at_exit? # :nodoc:
|
|
24
|
+
@installed_at_exit ||= false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.running_in_drb? # :nodoc:
|
|
28
|
+
(DRb.current_server rescue false) &&
|
|
29
|
+
DRb.current_server.uri =~ /druby\:\/\/127.0.0.1\:/
|
|
9
30
|
end
|
|
10
31
|
|
|
11
|
-
def self.trap_interrupt
|
|
32
|
+
def self.trap_interrupt # :nodoc:
|
|
12
33
|
trap('INT') do
|
|
13
34
|
exit!(1) if RSpec.wants_to_quit
|
|
14
35
|
RSpec.wants_to_quit = true
|
|
@@ -16,23 +37,46 @@ module RSpec
|
|
|
16
37
|
end
|
|
17
38
|
end
|
|
18
39
|
|
|
19
|
-
|
|
40
|
+
# Run a suite of RSpec examples.
|
|
41
|
+
#
|
|
42
|
+
# This is used internally by RSpec to run a suite, but is available
|
|
43
|
+
# for use by any other automation tool.
|
|
44
|
+
#
|
|
45
|
+
# If you want to run this multiple times in the same process, and you
|
|
46
|
+
# want files like spec_helper.rb to be reloaded, be sure to load `load`
|
|
47
|
+
# instead of `require`.
|
|
48
|
+
#
|
|
49
|
+
# ==== Parameters
|
|
50
|
+
# * +args+ - an array of command-line-supported arguments
|
|
51
|
+
# * +err+ - error stream (Default: $stderr)
|
|
52
|
+
# * +out+ - output stream (Default: $stdout)
|
|
53
|
+
#
|
|
54
|
+
# ==== Returns
|
|
55
|
+
# * +Fixnum+ - exit status code (0/1)
|
|
56
|
+
def self.run(args, err=$stderr, out=$stdout)
|
|
20
57
|
trap_interrupt
|
|
21
58
|
options = ConfigurationOptions.new(args)
|
|
22
59
|
options.parse_options
|
|
23
60
|
|
|
24
61
|
if options.options[:drb]
|
|
25
|
-
|
|
62
|
+
begin
|
|
63
|
+
run_over_drb(options, err, out)
|
|
64
|
+
rescue DRb::DRbConnError
|
|
65
|
+
err.puts "No DRb server is running. Running in local process instead ..."
|
|
66
|
+
run_in_process(options, err, out)
|
|
67
|
+
end
|
|
26
68
|
else
|
|
27
69
|
run_in_process(options, err, out)
|
|
28
70
|
end
|
|
71
|
+
ensure
|
|
72
|
+
RSpec.reset
|
|
29
73
|
end
|
|
30
74
|
|
|
31
|
-
def self.run_over_drb(options, err, out)
|
|
75
|
+
def self.run_over_drb(options, err, out) # :nodoc:
|
|
32
76
|
DRbCommandLine.new(options).run(err, out)
|
|
33
77
|
end
|
|
34
78
|
|
|
35
|
-
def self.run_in_process(options, err, out)
|
|
79
|
+
def self.run_in_process(options, err, out) # :nodoc:
|
|
36
80
|
CommandLine.new(options, RSpec::configuration, RSpec::world).run(err, out)
|
|
37
81
|
end
|
|
38
82
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module RSpec
|
|
2
|
+
module Core
|
|
3
|
+
module SharedContext
|
|
4
|
+
include Hooks
|
|
5
|
+
|
|
6
|
+
def included(group)
|
|
7
|
+
[:before, :after].each do |type|
|
|
8
|
+
[:all, :each].each do |scope|
|
|
9
|
+
group.hooks[type][scope].concat hooks[type][scope]
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -2,11 +2,27 @@ module RSpec
|
|
|
2
2
|
module Core
|
|
3
3
|
module SharedExampleGroup
|
|
4
4
|
|
|
5
|
-
def
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
def shared_context(*args, &block)
|
|
6
|
+
if String === args.first || Symbol === args.first
|
|
7
|
+
name = args.shift
|
|
8
|
+
ensure_shared_example_group_name_not_taken(name)
|
|
9
|
+
RSpec.world.shared_example_groups[name] = block
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
unless args.empty?
|
|
13
|
+
mod = Module.new
|
|
14
|
+
(class << mod; self; end).send(:define_method, :extended) do |host|
|
|
15
|
+
host.class_eval(&block)
|
|
16
|
+
end
|
|
17
|
+
RSpec.configuration.extend(mod, *args)
|
|
18
|
+
else
|
|
19
|
+
end
|
|
8
20
|
end
|
|
9
21
|
|
|
22
|
+
alias :shared_examples :shared_context
|
|
23
|
+
alias :share_examples_for :shared_context
|
|
24
|
+
alias :shared_examples_for :shared_context
|
|
25
|
+
|
|
10
26
|
def share_as(name, &block)
|
|
11
27
|
if Object.const_defined?(name)
|
|
12
28
|
mod = Object.const_get(name)
|
|
@@ -31,7 +47,6 @@ module RSpec
|
|
|
31
47
|
RSpec.world.shared_example_groups[shared_const] = block
|
|
32
48
|
end
|
|
33
49
|
|
|
34
|
-
alias :shared_examples_for :share_examples_for
|
|
35
50
|
|
|
36
51
|
private
|
|
37
52
|
|
data/lib/rspec/core/subject.rb
CHANGED
|
@@ -1,67 +1,72 @@
|
|
|
1
1
|
module RSpec
|
|
2
2
|
module Core
|
|
3
3
|
module Subject
|
|
4
|
+
module InstanceMethods
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
# Returns the subject defined by the example group. The subject block is
|
|
7
|
+
# only executed once per example, the result of which is cached and
|
|
8
|
+
# returned by any subsequent calls to +subject+.
|
|
9
|
+
#
|
|
10
|
+
# If a class is passed to +describe+ and no subject is explicitly
|
|
11
|
+
# declared in the example group, then +subject+ will return a new
|
|
12
|
+
# instance of that class.
|
|
13
|
+
#
|
|
14
|
+
# == Examples
|
|
15
|
+
#
|
|
16
|
+
# # explicit subject defined by the subject method
|
|
17
|
+
# describe Person do
|
|
18
|
+
# subject { Person.new(:birthdate => 19.years.ago) }
|
|
19
|
+
# it "should be eligible to vote" do
|
|
20
|
+
# subject.should be_eligible_to_vote
|
|
21
|
+
# end
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
# # implicit subject => { Person.new }
|
|
25
|
+
# describe Person do
|
|
26
|
+
# it "should be eligible to vote" do
|
|
27
|
+
# subject.should be_eligible_to_vote
|
|
28
|
+
# end
|
|
29
|
+
# end
|
|
30
|
+
def subject
|
|
31
|
+
if defined?(@original_subject)
|
|
32
|
+
@original_subject
|
|
33
|
+
else
|
|
34
|
+
@original_subject = instance_eval(&self.class.subject)
|
|
35
|
+
end
|
|
10
36
|
end
|
|
11
|
-
end
|
|
12
37
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
# If a class is passed to +describe+ and no subject is explicitly
|
|
18
|
-
# declared in the example group, then +subject+ will return a new
|
|
19
|
-
# instance of that class.
|
|
20
|
-
#
|
|
21
|
-
# == Examples
|
|
22
|
-
#
|
|
23
|
-
# # explicit subject defined by the subject method
|
|
24
|
-
# describe Person do
|
|
25
|
-
# subject { Person.new(:birthdate => 19.years.ago) }
|
|
26
|
-
# it "should be eligible to vote" do
|
|
27
|
-
# subject.should be_eligible_to_vote
|
|
28
|
-
# end
|
|
29
|
-
# end
|
|
30
|
-
#
|
|
31
|
-
# # implicit subject => { Person.new }
|
|
32
|
-
# describe Person do
|
|
33
|
-
# it "should be eligible to vote" do
|
|
34
|
-
# subject.should be_eligible_to_vote
|
|
35
|
-
# end
|
|
36
|
-
# end
|
|
37
|
-
def subject
|
|
38
|
-
@original_subject ||= instance_eval(&self.class.subject)
|
|
39
|
-
end
|
|
38
|
+
begin
|
|
39
|
+
require 'rspec/expectations/extensions/kernel'
|
|
40
|
+
alias_method :__should_for_example_group__, :should
|
|
41
|
+
alias_method :__should_not_for_example_group__, :should_not
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
# When +should+ is called with no explicit receiver, the call is
|
|
44
|
+
# delegated to the object returned by +subject+. Combined with
|
|
45
|
+
# an implicit subject (see +subject+), this supports very concise
|
|
46
|
+
# expressions.
|
|
47
|
+
#
|
|
48
|
+
# == Examples
|
|
49
|
+
#
|
|
50
|
+
# describe Person do
|
|
51
|
+
# it { should be_eligible_to_vote }
|
|
52
|
+
# end
|
|
53
|
+
def should(matcher=nil, message=nil)
|
|
54
|
+
self == subject ? self.__should_for_example_group__(matcher) : subject.should(matcher,message)
|
|
55
|
+
end
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
# Just like +should+, +should_not+ delegates to the subject (implicit or
|
|
58
|
+
# explicit) of the example group.
|
|
59
|
+
#
|
|
60
|
+
# == Examples
|
|
61
|
+
#
|
|
62
|
+
# describe Person do
|
|
63
|
+
# it { should_not be_eligible_to_vote }
|
|
64
|
+
# end
|
|
65
|
+
def should_not(matcher=nil, message=nil)
|
|
66
|
+
self == subject ? self.__should_not_for_example_group__(matcher) : subject.should_not(matcher,message)
|
|
67
|
+
end
|
|
68
|
+
rescue LoadError
|
|
69
|
+
end
|
|
65
70
|
end
|
|
66
71
|
|
|
67
72
|
module ClassMethods
|
|
@@ -85,23 +90,45 @@ module RSpec
|
|
|
85
90
|
# The attribute can be a +Symbol+ or a +String+. Given a +String+
|
|
86
91
|
# with dots, the result is as though you concatenated that +String+
|
|
87
92
|
# onto the subject in an expression.
|
|
88
|
-
#
|
|
89
|
-
# describe Person
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
+
#
|
|
94
|
+
# describe Person do
|
|
95
|
+
# subject do
|
|
96
|
+
# Person.new.tap do |person|
|
|
97
|
+
# person.phone_numbers << "555-1212"
|
|
98
|
+
# end
|
|
93
99
|
# end
|
|
94
100
|
#
|
|
95
101
|
# its("phone_numbers.first") { should == "555-1212" }
|
|
96
102
|
# end
|
|
103
|
+
#
|
|
104
|
+
# When the subject is a +Hash+, you can refer to the Hash keys by
|
|
105
|
+
# specifying a +Symbol+ or +String+ in an array.
|
|
106
|
+
#
|
|
107
|
+
# describe "a configuration Hash" do
|
|
108
|
+
# subject do
|
|
109
|
+
# { :max_users => 3,
|
|
110
|
+
# 'admin' => :all_permissions }
|
|
111
|
+
# end
|
|
112
|
+
#
|
|
113
|
+
# its([:max_users]) { should == 3 }
|
|
114
|
+
# its(['admin']) { should == :all_permissions }
|
|
115
|
+
#
|
|
116
|
+
# # You can still access to its regular methods this way:
|
|
117
|
+
# its(:keys) { should include(:max_users) }
|
|
118
|
+
# its(:count) { should == 2 }
|
|
119
|
+
# end
|
|
97
120
|
def its(attribute, &block)
|
|
98
121
|
describe(attribute) do
|
|
99
122
|
example do
|
|
100
123
|
self.class.class_eval do
|
|
101
124
|
define_method(:subject) do
|
|
102
|
-
attribute.
|
|
103
|
-
|
|
104
|
-
|
|
125
|
+
@_subject ||= if attribute.is_a?(Array)
|
|
126
|
+
super()[*attribute]
|
|
127
|
+
else
|
|
128
|
+
attribute.to_s.split('.').inject(super()) do |target, method|
|
|
129
|
+
target.send(method)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
105
132
|
end
|
|
106
133
|
end
|
|
107
134
|
instance_eval(&block)
|
|
@@ -127,7 +154,7 @@ module RSpec
|
|
|
127
154
|
|
|
128
155
|
attr_reader :explicit_subject_block # :nodoc:
|
|
129
156
|
|
|
130
|
-
|
|
157
|
+
private
|
|
131
158
|
|
|
132
159
|
def explicit_subject
|
|
133
160
|
group = self
|
data/lib/rspec/core/version.rb
CHANGED
data/lib/rspec/core/world.rb
CHANGED
|
@@ -2,7 +2,31 @@ module RSpec
|
|
|
2
2
|
module Core
|
|
3
3
|
class World
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
module Describable
|
|
6
|
+
PROC_HEX_NUMBER = /0x[0-9a-f]+@/
|
|
7
|
+
PROJECT_DIR = File.expand_path('.')
|
|
8
|
+
|
|
9
|
+
def description
|
|
10
|
+
reject { |k, v| RSpec::Core::Configuration::CONDITIONAL_FILTERS[k] == v }.inspect.gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)','')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def empty_without_conditional_filters?
|
|
14
|
+
reject { |k, v| RSpec::Core::Configuration::CONDITIONAL_FILTERS[k] == v }.empty?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def reject
|
|
18
|
+
super rescue {}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def empty?
|
|
22
|
+
super rescue false
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
include RSpec::Core::Hooks
|
|
27
|
+
|
|
28
|
+
attr_reader :example_groups, :filtered_examples, :wants_to_quit
|
|
29
|
+
attr_writer :wants_to_quit
|
|
6
30
|
|
|
7
31
|
def initialize(configuration=RSpec.configuration)
|
|
8
32
|
@configuration = configuration
|
|
@@ -17,12 +41,21 @@ module RSpec
|
|
|
17
41
|
}
|
|
18
42
|
end
|
|
19
43
|
|
|
44
|
+
def reset
|
|
45
|
+
example_groups.clear
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def register(example_group)
|
|
49
|
+
example_groups << example_group
|
|
50
|
+
example_group
|
|
51
|
+
end
|
|
52
|
+
|
|
20
53
|
def inclusion_filter
|
|
21
|
-
@configuration.
|
|
54
|
+
@configuration.inclusion_filter.extend(Describable)
|
|
22
55
|
end
|
|
23
56
|
|
|
24
57
|
def exclusion_filter
|
|
25
|
-
@configuration.exclusion_filter
|
|
58
|
+
@configuration.exclusion_filter.extend(Describable)
|
|
26
59
|
end
|
|
27
60
|
|
|
28
61
|
def configure_group(group)
|
|
@@ -38,51 +71,76 @@ module RSpec
|
|
|
38
71
|
end
|
|
39
72
|
|
|
40
73
|
def apply_inclusion_filters(examples, conditions={})
|
|
41
|
-
examples.select(&
|
|
74
|
+
examples.select(&apply?(:any?, conditions))
|
|
42
75
|
end
|
|
43
76
|
|
|
44
77
|
alias_method :find, :apply_inclusion_filters
|
|
45
78
|
|
|
46
79
|
def apply_exclusion_filters(examples, conditions={})
|
|
47
|
-
examples.reject(&
|
|
80
|
+
examples.reject(&apply?(:any?, conditions))
|
|
48
81
|
end
|
|
49
82
|
|
|
50
83
|
def preceding_declaration_line(filter_line)
|
|
51
|
-
declaration_line_numbers.inject(nil) do |highest_prior_declaration_line, line|
|
|
84
|
+
declaration_line_numbers.sort.inject(nil) do |highest_prior_declaration_line, line|
|
|
52
85
|
line <= filter_line ? line : highest_prior_declaration_line
|
|
53
86
|
end
|
|
54
87
|
end
|
|
55
88
|
|
|
56
|
-
def
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
89
|
+
def reporter
|
|
90
|
+
@configuration.reporter
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def announce_filters
|
|
94
|
+
filter_announcements = []
|
|
95
|
+
|
|
96
|
+
if @configuration.run_all_when_everything_filtered? && example_count.zero?
|
|
97
|
+
reporter.message( "No examples matched #{inclusion_filter.description}. Running all.")
|
|
98
|
+
filtered_examples.clear
|
|
99
|
+
@configuration.clear_inclusion_filter
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
announce_inclusion_filter filter_announcements
|
|
103
|
+
announce_exclusion_filter filter_announcements
|
|
104
|
+
|
|
105
|
+
if example_count.zero?
|
|
106
|
+
example_groups.clear
|
|
107
|
+
if filter_announcements.empty?
|
|
108
|
+
reporter.message("No examples found.")
|
|
109
|
+
elsif inclusion_filter
|
|
110
|
+
message = "No examples matched #{inclusion_filter.description}."
|
|
111
|
+
if @configuration.run_all_when_everything_filtered?
|
|
112
|
+
message << " Running all."
|
|
113
|
+
end
|
|
114
|
+
reporter.message(message)
|
|
115
|
+
elsif exclusion_filter
|
|
116
|
+
reporter.message(
|
|
117
|
+
"No examples were matched. Perhaps #{exclusion_filter.description} is excluding everything?")
|
|
64
118
|
end
|
|
119
|
+
elsif !filter_announcements.empty?
|
|
120
|
+
reporter.message("Run filtered #{filter_announcements.join(', ')}")
|
|
65
121
|
end
|
|
66
122
|
end
|
|
67
|
-
|
|
68
|
-
def
|
|
69
|
-
if
|
|
70
|
-
|
|
71
|
-
"No examples were matched. Perhaps #{exclusion_filter.inspect} is excluding everything?")
|
|
72
|
-
example_groups.clear
|
|
123
|
+
|
|
124
|
+
def announce_inclusion_filter(announcements)
|
|
125
|
+
if inclusion_filter
|
|
126
|
+
announcements << "including #{inclusion_filter.description}"
|
|
73
127
|
end
|
|
74
128
|
end
|
|
75
129
|
|
|
76
|
-
|
|
130
|
+
def announce_exclusion_filter(announcements)
|
|
131
|
+
unless exclusion_filter.empty_without_conditional_filters?
|
|
132
|
+
announcements << "excluding #{exclusion_filter.description}"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
77
135
|
|
|
78
|
-
def find_hook(hook, scope, group)
|
|
79
|
-
@configuration.find_hook(hook, scope, group)
|
|
136
|
+
def find_hook(hook, scope, group, example = nil)
|
|
137
|
+
@configuration.find_hook(hook, scope, group, example)
|
|
80
138
|
end
|
|
81
139
|
|
|
82
140
|
private
|
|
83
141
|
|
|
84
|
-
def
|
|
85
|
-
lambda {|example| example.metadata.
|
|
142
|
+
def apply?(predicate, conditions)
|
|
143
|
+
lambda {|example| example.metadata.apply?(predicate, conditions)}
|
|
86
144
|
end
|
|
87
145
|
|
|
88
146
|
def declaration_line_numbers
|
data/lib/rspec/core.rb
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
require 'rspec/core/extensions'
|
|
2
2
|
require 'rspec/core/load_path'
|
|
3
3
|
require 'rspec/core/deprecation'
|
|
4
|
+
require 'rspec/core/backward_compatibility'
|
|
4
5
|
require 'rspec/core/reporter'
|
|
5
|
-
require 'rspec/core/formatters'
|
|
6
6
|
|
|
7
|
+
require 'rspec/core/metadata_hash_builder'
|
|
7
8
|
require 'rspec/core/hooks'
|
|
8
9
|
require 'rspec/core/subject'
|
|
9
10
|
require 'rspec/core/let'
|
|
10
11
|
require 'rspec/core/metadata'
|
|
11
12
|
require 'rspec/core/pending'
|
|
12
13
|
|
|
13
|
-
require 'rspec/core/around_proxy'
|
|
14
14
|
require 'rspec/core/world'
|
|
15
15
|
require 'rspec/core/configuration'
|
|
16
16
|
require 'rspec/core/command_line_configuration'
|
|
@@ -20,59 +20,75 @@ require 'rspec/core/command_line'
|
|
|
20
20
|
require 'rspec/core/drb_command_line'
|
|
21
21
|
require 'rspec/core/runner'
|
|
22
22
|
require 'rspec/core/example'
|
|
23
|
+
require 'rspec/core/shared_context'
|
|
23
24
|
require 'rspec/core/shared_example_group'
|
|
24
25
|
require 'rspec/core/example_group'
|
|
25
26
|
require 'rspec/core/version'
|
|
26
27
|
require 'rspec/core/errors'
|
|
27
28
|
|
|
28
29
|
module RSpec
|
|
29
|
-
|
|
30
|
+
autoload :Matchers, 'rspec/matchers'
|
|
31
|
+
|
|
32
|
+
SharedContext = Core::SharedContext
|
|
30
33
|
|
|
34
|
+
module Core
|
|
31
35
|
def self.install_directory
|
|
32
36
|
@install_directory ||= File.expand_path(File.dirname(__FILE__))
|
|
33
37
|
end
|
|
38
|
+
end
|
|
34
39
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
RSpec.configuration
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def self.configure
|
|
41
|
-
RSpec.deprecate('RSpec::Core.configure', 'RSpec.configure', '2.0.0')
|
|
42
|
-
yield RSpec.configuration if block_given?
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def self.world
|
|
46
|
-
RSpec.deprecate('RSpec::Core.world', 'RSpec.world', '2.0.0')
|
|
47
|
-
RSpec.world
|
|
48
|
-
end
|
|
49
|
-
|
|
40
|
+
def self.wants_to_quit
|
|
41
|
+
world.wants_to_quit
|
|
50
42
|
end
|
|
51
43
|
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
def self.wants_to_quit=(maybe)
|
|
45
|
+
world.wants_to_quit=(maybe)
|
|
54
46
|
end
|
|
55
47
|
|
|
56
48
|
def self.world
|
|
57
49
|
@world ||= RSpec::Core::World.new
|
|
58
50
|
end
|
|
59
51
|
|
|
52
|
+
# Used internally to ensure examples get reloaded between multiple runs in
|
|
53
|
+
# the same process.
|
|
54
|
+
def self.reset
|
|
55
|
+
world.reset
|
|
56
|
+
configuration.reset
|
|
57
|
+
end
|
|
58
|
+
|
|
60
59
|
def self.configuration
|
|
61
60
|
@configuration ||= RSpec::Core::Configuration.new
|
|
62
61
|
end
|
|
63
62
|
|
|
64
63
|
def self.configure
|
|
64
|
+
warn_about_deprecated_configure if RSpec.world.example_groups.any?
|
|
65
65
|
yield configuration if block_given?
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
def self.clear_remaining_example_groups
|
|
69
69
|
world.example_groups.clear
|
|
70
70
|
end
|
|
71
|
-
end
|
|
72
71
|
|
|
73
|
-
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def self.warn_about_deprecated_configure
|
|
75
|
+
warn <<-NOTICE
|
|
76
|
+
|
|
77
|
+
*****************************************************************
|
|
78
|
+
DEPRECATION WARNING: you are using deprecated behaviour that will
|
|
79
|
+
be removed from RSpec 3.
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
You have set some configuration options after an example group has
|
|
82
|
+
already been defined. In RSpec 3, this will not be allowed. All
|
|
83
|
+
configuration should happen before the first example group is
|
|
84
|
+
defined. The configuration is happening at:
|
|
77
85
|
|
|
86
|
+
#{caller[1]}
|
|
87
|
+
*****************************************************************
|
|
88
|
+
|
|
89
|
+
NOTICE
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
require 'rspec/core/backward_compatibility'
|
|
78
94
|
require 'rspec/monkey'
|