rspec 0.5.3 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +57 -32
- data/EXAMPLES.rd +0 -0
- data/Rakefile +22 -21
- data/bin/spec +9 -11
- data/doc/README +1 -3
- data/doc/plugin/syntax.rb +27 -5
- data/doc/src/core_team.page +22 -0
- data/doc/src/default.css +11 -11
- data/doc/src/default.template +0 -1
- data/doc/src/documentation/index.page +183 -8
- data/doc/src/documentation/meta.info +7 -7
- data/doc/src/documentation/mocks.page +168 -109
- data/doc/src/documentation/underscores.page +20 -0
- data/doc/src/examples.page +2 -1
- data/doc/src/images/David_and_Aslak.jpg +0 -0
- data/doc/src/images/Whats_That_Dude.jpg +0 -0
- data/doc/src/index.page +70 -3
- data/doc/src/meta.info +18 -11
- data/doc/src/tools/index.page +40 -134
- data/doc/src/tools/meta.info +9 -3
- data/doc/src/tools/rails.page +3 -1
- data/doc/src/tools/rake.page +20 -3
- data/doc/src/tools/rcov.page +19 -0
- data/doc/src/tools/spec.page +99 -0
- data/doc/src/tools/test2rspec.page +2 -4
- data/doc/src/tutorials/index.page +52 -0
- data/doc/src/tutorials/meta.info +31 -0
- data/doc/src/tutorials/notes.txt +252 -0
- data/doc/src/tutorials/stack.rb +11 -0
- data/doc/src/tutorials/stack_01.page +224 -0
- data/doc/src/tutorials/stack_02.page +180 -0
- data/doc/src/tutorials/stack_03.page +291 -0
- data/doc/src/tutorials/stack_04.page +203 -0
- data/doc/src/tutorials/stack_04.page.orig +123 -0
- data/doc/src/tutorials/stack_05.page +90 -0
- data/doc/src/tutorials/stack_05.page.orig +124 -0
- data/doc/src/tutorials/stack_06.page +359 -0
- data/doc/src/tutorials/stack_06.page.orig +359 -0
- data/doc/src/tutorials/stack_spec.rb +41 -0
- data/examples/airport_spec.rb +4 -4
- data/examples/{spec_framework_spec.rb → bdd_framework_spec.rb} +6 -7
- data/examples/mocking_spec.rb +0 -5
- data/examples/stack_spec.rb +6 -7
- data/examples/sugar_spec.rb +14 -0
- data/lib/spec/api.rb +5 -2
- data/lib/spec/api/helper/should_base.rb +17 -22
- data/lib/spec/api/helper/should_helper.rb +4 -3
- data/lib/spec/api/helper/should_negator.rb +3 -2
- data/lib/spec/api/mocks/argument_expectation.rb +104 -0
- data/lib/spec/api/{mock.rb → mocks/message_expectation.rb} +47 -96
- data/lib/spec/api/mocks/mock.rb +63 -0
- data/lib/spec/api/mocks/order_group.rb +21 -0
- data/lib/spec/api/sugar.rb +47 -0
- data/lib/spec/rake/rcov_verify.rb +45 -0
- data/lib/spec/rake/spectask.rb +41 -56
- data/lib/spec/runner.rb +4 -1
- data/lib/spec/runner/backtrace_tweaker.rb +24 -3
- data/lib/spec/runner/base_text_formatter.rb +28 -0
- data/lib/spec/runner/context.rb +21 -18
- data/lib/spec/runner/context_runner.rb +20 -31
- data/lib/spec/runner/execution_context.rb +3 -3
- data/lib/spec/runner/kernel_ext.rb +10 -1
- data/lib/spec/runner/option_parser.rb +32 -14
- data/lib/spec/runner/progress_bar_formatter.rb +21 -0
- data/lib/spec/runner/rdoc_formatter.rb +15 -5
- data/lib/spec/runner/reporter.rb +100 -0
- data/lib/spec/runner/specdoc_formatter.rb +20 -0
- data/lib/spec/runner/specification.rb +42 -22
- data/lib/spec/version.rb +1 -1
- data/test/rcov/rcov_testtask.rb +1 -0
- data/test/spec/api/duck_type_test.rb +4 -4
- data/test/spec/api/helper/raising_test.rb +37 -17
- data/test/spec/api/{mock_arg_constraints_test.rb → mocks/mock_arg_constraints_test.rb} +10 -4
- data/test/spec/api/mocks/mock_ordering_test.rb +62 -0
- data/test/spec/api/{mock_test.rb → mocks/mock_test.rb} +30 -7
- data/test/spec/api/mocks/null_object_test.rb +31 -0
- data/test/spec/api/sugar_test.rb +71 -0
- data/test/spec/runner/backtrace_tweaker_test.rb +52 -4
- data/test/spec/runner/context_runner_test.rb +41 -21
- data/test/spec/runner/context_test.rb +60 -32
- data/test/spec/runner/execution_context_test.rb +4 -3
- data/test/spec/runner/failure_dump_test.rb +92 -0
- data/test/spec/runner/kernel_ext_test.rb +1 -2
- data/test/spec/runner/option_parser_test.rb +48 -28
- data/test/spec/runner/progress_bar_formatter_test.rb +48 -0
- data/test/spec/runner/rdoc_formatter_test.rb +31 -4
- data/test/spec/runner/reporter_test.rb +103 -0
- data/test/spec/runner/specdoc_formatter_test.rb +50 -0
- data/test/spec/runner/specification_test.rb +49 -11
- data/test/test_helper.rb +1 -4
- metadata +46 -15
- data/doc/src/community.page +0 -7
- data/doc/src/documentation/api.page +0 -185
- data/doc/src/why_rspec.page +0 -7
- data/examples/empty_stack_spec.rb +0 -22
- data/examples/team_spec.rb +0 -30
- data/lib/spec/api/duck_type.rb +0 -16
- data/lib/spec/runner/simple_text_reporter.rb +0 -88
- data/test/rcov/rcov_verify.rb +0 -28
- data/test/spec/runner/simple_text_reporter_test.rb +0 -123
@@ -0,0 +1,63 @@
|
|
1
|
+
module Spec
|
2
|
+
module Api
|
3
|
+
class Mock
|
4
|
+
# Remove all methods so they can be mocked too
|
5
|
+
(public_instance_methods - ['__id__', '__send__', 'nil?']).each do |m|
|
6
|
+
undef_method m
|
7
|
+
end
|
8
|
+
|
9
|
+
# Creates a new mock with a +name+ (that will be used in error messages only)
|
10
|
+
# Options:
|
11
|
+
# * <tt>:null_object</tt> - if true, the mock object acts as a forgiving null object allowing any message to be sent to it.
|
12
|
+
def initialize(name, options={})
|
13
|
+
@name = name
|
14
|
+
@options = DEFAULT_OPTIONS.dup.merge(options)
|
15
|
+
@expectations = []
|
16
|
+
@expectation_ordering = OrderGroup.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def should
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def receive(sym, &block)
|
24
|
+
expected_from = caller(1)[0]
|
25
|
+
expectation = MessageExpectation.new(@name, @expectation_ordering, expected_from, sym, block_given? ? block : nil)
|
26
|
+
@expectations << expectation
|
27
|
+
expectation
|
28
|
+
end
|
29
|
+
|
30
|
+
def __verify #:nodoc:
|
31
|
+
@expectations.each do |expectation|
|
32
|
+
expectation.verify_messages_received
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def method_missing(sym, *args, &block)
|
37
|
+
if expectation = find_matching_expectation(sym, *args)
|
38
|
+
expectation.verify_message(args, block)
|
39
|
+
else
|
40
|
+
begin
|
41
|
+
# act as null object if method is missing and we ignore them. return value too!
|
42
|
+
@options[:null_object] ? self : super(sym, *args, &block)
|
43
|
+
rescue NoMethodError
|
44
|
+
arg_message = args.collect{|arg| "<#{arg}:#{arg.class.name}>"}.join(", ")
|
45
|
+
Kernel::raise Spec::Api::MockExpectationError, "Mock '#{@name}' received unexpected message '#{sym}' with [#{arg_message}]"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
DEFAULT_OPTIONS = {
|
53
|
+
:null_object => false
|
54
|
+
}
|
55
|
+
|
56
|
+
def find_matching_expectation(sym, *args)
|
57
|
+
expectation = @expectations.find {|expectation| expectation.matches(sym, args)}
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Spec
|
2
|
+
module Api
|
3
|
+
class OrderGroup
|
4
|
+
def initialize
|
5
|
+
@ordering = Array.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def register(expectation)
|
9
|
+
@ordering << expectation
|
10
|
+
end
|
11
|
+
|
12
|
+
def ready_for?(expectation)
|
13
|
+
return @ordering.first == expectation
|
14
|
+
end
|
15
|
+
|
16
|
+
def consume(expectation)
|
17
|
+
@ordering.shift
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Spec
|
2
|
+
module Api
|
3
|
+
# This module adds syntactic sugar that allows usage of should_* instead of should.*
|
4
|
+
module Sugar
|
5
|
+
alias_method :__orig_method_missing, :method_missing
|
6
|
+
def method_missing(sym, *args, &block)
|
7
|
+
if __is_sweetened? sym
|
8
|
+
object = self
|
9
|
+
calls = sym.to_s.split("_")
|
10
|
+
while calls.length > 1
|
11
|
+
call = calls.shift
|
12
|
+
object = object.__send__(call)
|
13
|
+
break if call == "be"
|
14
|
+
end
|
15
|
+
return object.__send__(calls.join("_"), *args, &block)
|
16
|
+
end
|
17
|
+
__orig_method_missing(sym, *args, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def __is_sweetened? sym
|
21
|
+
return true if sym.to_s =~ /^should_/
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module MessageExpectationSugar
|
26
|
+
def __is_sweetened? sym
|
27
|
+
return true if sym.to_s =~ /^and_|^at_|^any_|^once_/
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Object #:nodoc:
|
34
|
+
include Spec::Api::Sugar
|
35
|
+
end
|
36
|
+
|
37
|
+
class Spec::Api::Mock #:nodoc:
|
38
|
+
#NOTE: this resolves a bug caused by a conflict between Sugar#method_missing and Mock#method_missing, specifically
|
39
|
+
# when the mock is set null_object=>true. It would be nice to get rid of this.
|
40
|
+
def should_receive(sym, &block)
|
41
|
+
return receive(sym, &block)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Spec::Api::MessageExpectation #:nodoc:
|
46
|
+
include Spec::Api::MessageExpectationSugar
|
47
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module RCov
|
2
|
+
# A task that can verify that the RCov coverage doesn't
|
3
|
+
# drop below a certain threshold.
|
4
|
+
class VerifyTask < Rake::TaskLib
|
5
|
+
# Name of the task. Defaults to :rcov_verify
|
6
|
+
attr_accessor :name
|
7
|
+
|
8
|
+
# Path to the index.html file generated by RCov, which
|
9
|
+
# is the file containing the total coverage.
|
10
|
+
# Defaults to 'coverage/index.html'
|
11
|
+
attr_accessor :index_html
|
12
|
+
|
13
|
+
# Whether or not to output details
|
14
|
+
attr_accessor :verbose
|
15
|
+
|
16
|
+
# The threshold value (in percent) for coverage. If the
|
17
|
+
# actual coverage is below this value, the task will raise an
|
18
|
+
# exception
|
19
|
+
attr_accessor :threshold
|
20
|
+
|
21
|
+
def initialize(name=:rcov_verify)
|
22
|
+
@name = name
|
23
|
+
@index_html = 'coverage/index.html'
|
24
|
+
@verbose = false
|
25
|
+
yield self if block_given?
|
26
|
+
raise "Threshold must be set" if @threshold.nil?
|
27
|
+
define
|
28
|
+
end
|
29
|
+
|
30
|
+
def define
|
31
|
+
desc "Verify that rcov coverage is at least #{threshold}%"
|
32
|
+
task @name do
|
33
|
+
total_coverage = nil
|
34
|
+
File.open(index_html).each_line do |line|
|
35
|
+
if line =~ /<tt>(\d+\.\d+)%<\/tt> <\/td>/
|
36
|
+
total_coverage = eval($1)
|
37
|
+
break
|
38
|
+
end
|
39
|
+
end
|
40
|
+
puts "Coverage: #{total_coverage}% (threshold: #{threshold}%)" if verbose
|
41
|
+
raise "Coverage must be at least #{threshold}% but was #{total_coverage}%" if total_coverage < threshold
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/spec/rake/spectask.rb
CHANGED
@@ -9,33 +9,15 @@ require File.dirname(__FILE__) + '/../../spec'
|
|
9
9
|
module Spec
|
10
10
|
module Rake
|
11
11
|
|
12
|
-
#
|
12
|
+
# A task that runs a set of RSpec contexts.
|
13
13
|
#
|
14
14
|
# Example:
|
15
15
|
#
|
16
16
|
# Rake::SpecTask.new do |t|
|
17
17
|
# t.libs << "spec"
|
18
18
|
# t.spec_files = FileList['spec/**/*_spec.rb']
|
19
|
-
# t.verbose = true
|
20
19
|
# end
|
21
20
|
#
|
22
|
-
# If rake is invoked with a "SPEC=filename" command line option,
|
23
|
-
# then the list of spec files will be overridden to include only the
|
24
|
-
# filename specified on the command line. This provides an easy way
|
25
|
-
# to run just one spec.
|
26
|
-
#
|
27
|
-
# If rake is invoked with a "SPECOPTS=options" command line option,
|
28
|
-
# then the given options are passed to the spec process after a
|
29
|
-
# '--'. This allows Test::Unit options to be passed to the spec
|
30
|
-
# suite.
|
31
|
-
#
|
32
|
-
# Examples:
|
33
|
-
#
|
34
|
-
# rake spec # run specs normally
|
35
|
-
# rake spec SPEC=just_one_file.rb # run just one spec file.
|
36
|
-
# rake spec SPECOPTS="-v" # run in verbose mode
|
37
|
-
# rake spec SPECOPTS="--runner=fox" # use the fox spec runner
|
38
|
-
#
|
39
21
|
class SpecTask < ::Rake::TaskLib
|
40
22
|
|
41
23
|
# Name of spec task. (default is :spec)
|
@@ -45,8 +27,8 @@ module Rake
|
|
45
27
|
# specs. (default is 'lib')
|
46
28
|
attr_accessor :libs
|
47
29
|
|
48
|
-
#
|
49
|
-
attr_accessor :
|
30
|
+
# Options poassed to spec
|
31
|
+
attr_accessor :spec_opts
|
50
32
|
|
51
33
|
# Test options passed to the spec suite. An explicit
|
52
34
|
# SPECOPTS=opts on the command line will override this. (default
|
@@ -60,15 +42,14 @@ module Rake
|
|
60
42
|
# Glob pattern to match spec files. (default is 'spec/spec*.rb')
|
61
43
|
attr_accessor :pattern
|
62
44
|
|
63
|
-
#
|
64
|
-
#
|
65
|
-
|
66
|
-
# * :specrb -- Ruby provided spec loading script.
|
67
|
-
# * :direct -- Load specs using command line loader.
|
68
|
-
#
|
69
|
-
attr_accessor :loader
|
45
|
+
# Whether or not to use rcov (default is false)
|
46
|
+
# See http://eigenclass.org/hiki.rb?rcov
|
47
|
+
attr_accessor :rcov
|
70
48
|
|
71
|
-
#
|
49
|
+
# Where output is written. Default is STDOUT.
|
50
|
+
attr_accessor :out
|
51
|
+
|
52
|
+
# Array of commandline options to pass to ruby (or rcov) when running specs.
|
72
53
|
attr_accessor :ruby_opts
|
73
54
|
|
74
55
|
# Explicitly define the list of spec files to be included in a
|
@@ -86,10 +67,11 @@ module Rake
|
|
86
67
|
@pattern = nil
|
87
68
|
@options = nil
|
88
69
|
@spec_files = nil
|
89
|
-
@
|
70
|
+
@spec_opts = []
|
90
71
|
@warning = false
|
91
|
-
@
|
72
|
+
@rcov = false
|
92
73
|
@ruby_opts = []
|
74
|
+
@out = nil
|
93
75
|
yield self if block_given?
|
94
76
|
@pattern = 'spec/**/*_spec.rb' if @pattern.nil? && @spec_files.nil?
|
95
77
|
define
|
@@ -100,30 +82,24 @@ module Rake
|
|
100
82
|
lib_path = @libs.join(File::PATH_SEPARATOR)
|
101
83
|
desc "Run specs" + (@name==:spec ? "" : " for #{@name}")
|
102
84
|
task @name do
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
@
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
" #{option_list}"
|
118
|
-
end
|
85
|
+
spec = File.dirname(__FILE__) + '/../../../bin/spec'
|
86
|
+
file_prefix = @rcov ? " -- " : ""
|
87
|
+
interpreter = @rcov ? "rcov" : "ruby"
|
88
|
+
redirect = @out.nil? ? "" : " > #{@out}"
|
89
|
+
|
90
|
+
@ruby_opts.unshift( "-I#{lib_path}" )
|
91
|
+
@ruby_opts.unshift( "-w" ) if @warning
|
92
|
+
@ruby_opts.unshift( '--exclude "lib\/spec\/.*"' ) if @rcov
|
93
|
+
run interpreter, @ruby_opts.join(" ") +
|
94
|
+
" \"#{spec}\" " +
|
95
|
+
" #{@spec_opts.join(' ')} " +
|
96
|
+
file_prefix +
|
97
|
+
file_list.collect { |fn| "\"#{fn}\"" }.join(' ') +
|
98
|
+
redirect
|
119
99
|
end
|
120
100
|
self
|
121
101
|
end
|
122
102
|
|
123
|
-
def option_list # :nodoc:
|
124
|
-
ENV['SPECOPTS'] || @options || ""
|
125
|
-
end
|
126
|
-
|
127
103
|
def file_list # :nodoc:
|
128
104
|
if ENV['SPEC']
|
129
105
|
FileList[ ENV['SPEC'] ]
|
@@ -135,11 +111,6 @@ module Rake
|
|
135
111
|
end
|
136
112
|
end
|
137
113
|
|
138
|
-
def rake_loader # :nodoc:
|
139
|
-
find_file('rake/rake_test_loader') or
|
140
|
-
fail "unable to find rake test loader"
|
141
|
-
end
|
142
|
-
|
143
114
|
def find_file(fn) # :nodoc:
|
144
115
|
$LOAD_PATH.each do |path|
|
145
116
|
file_path = File.join(path, "#{fn}.rb")
|
@@ -147,6 +118,20 @@ module Rake
|
|
147
118
|
end
|
148
119
|
nil
|
149
120
|
end
|
121
|
+
|
122
|
+
def run(interpreter, *args, &block)
|
123
|
+
if Hash === args.last
|
124
|
+
options = args.pop
|
125
|
+
else
|
126
|
+
options = {}
|
127
|
+
end
|
128
|
+
if args.length > 1 then
|
129
|
+
sh(*([interpreter] + args + [options]), &block)
|
130
|
+
else
|
131
|
+
sh("#{interpreter} #{args}", options, &block)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
150
135
|
end
|
151
136
|
end
|
152
137
|
end
|
data/lib/spec/runner.rb
CHANGED
@@ -5,5 +5,8 @@ require 'spec/runner/execution_context'
|
|
5
5
|
require 'spec/runner/context_runner'
|
6
6
|
require 'spec/runner/option_parser'
|
7
7
|
require 'spec/runner/backtrace_tweaker'
|
8
|
+
require 'spec/runner/reporter'
|
9
|
+
require 'spec/runner/base_text_formatter'
|
10
|
+
require 'spec/runner/progress_bar_formatter'
|
8
11
|
require 'spec/runner/rdoc_formatter'
|
9
|
-
require 'spec/runner/
|
12
|
+
require 'spec/runner/specdoc_formatter'
|
@@ -1,11 +1,32 @@
|
|
1
1
|
module Spec
|
2
2
|
module Runner
|
3
3
|
class BacktraceTweaker
|
4
|
-
def
|
4
|
+
def tweak_instance_exec_line line, spec_name
|
5
|
+
line = line.split(':in')[0] + ":in `#{spec_name}'" if line.include?('__instance_exec')
|
6
|
+
line
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
# Tweaks raised Exceptions to mask noisy (unneeded) parts of the backtrace
|
11
|
+
class NoisyBacktraceTweaker < BacktraceTweaker
|
12
|
+
def tweak_backtrace(error, spec_name)
|
13
|
+
return if error.backtrace.nil?
|
14
|
+
error.backtrace.collect! do |line|
|
15
|
+
tweak_instance_exec_line line, spec_name
|
16
|
+
end
|
17
|
+
error.backtrace.compact!
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Tweaks raised Exceptions to mask noisy (unneeded) parts of the backtrace
|
22
|
+
class QuietBacktraceTweaker < BacktraceTweaker
|
23
|
+
def tweak_backtrace(error, spec_name)
|
5
24
|
return if error.backtrace.nil?
|
6
25
|
error.backtrace.collect! do |line|
|
7
|
-
line = line
|
8
|
-
line = nil if line =~ /\/lib\/spec\/api
|
26
|
+
line = tweak_instance_exec_line line, spec_name
|
27
|
+
line = nil if line =~ /\/lib\/spec\/api\//
|
28
|
+
line = nil if line =~ /\/lib\/spec\/runner\//
|
29
|
+
line = nil if line =~ /bin\/spec:/
|
9
30
|
line
|
10
31
|
end
|
11
32
|
error.backtrace.compact!
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Spec
|
2
|
+
module Runner
|
3
|
+
class BaseTextFormatter
|
4
|
+
def initialize(output, dry_run=false)
|
5
|
+
@dry_run = dry_run
|
6
|
+
@output = output
|
7
|
+
end
|
8
|
+
|
9
|
+
def dump_failure(counter, failure)
|
10
|
+
@output << "\n"
|
11
|
+
@output << counter.to_s << ")\n"
|
12
|
+
@output << "#{failure.header}\n"
|
13
|
+
@output << "#{failure.message}\n"
|
14
|
+
@output << "#{failure.backtrace}\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
def dump_summary(duration, context_count, spec_count, failure_count)
|
18
|
+
return if @dry_run
|
19
|
+
@output << "\n"
|
20
|
+
@output << "Finished in " << (duration).to_s << " seconds\n\n"
|
21
|
+
@output << "#{context_count} context#{'s' unless context_count == 1}, "
|
22
|
+
@output << "#{spec_count} specification#{'s' unless spec_count == 1}, "
|
23
|
+
@output << "#{failure_count} failure#{'s' unless failure_count == 1}"
|
24
|
+
@output << "\n"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/spec/runner/context.rb
CHANGED
@@ -1,33 +1,18 @@
|
|
1
1
|
module Spec
|
2
2
|
module Runner
|
3
3
|
class Context
|
4
|
-
@@context_runner = nil
|
5
|
-
|
6
|
-
def self.context_runner= runner
|
7
|
-
@@context_runner = runner
|
8
|
-
end
|
9
|
-
|
10
4
|
def initialize(name, &context_block)
|
11
5
|
@setup_block = nil
|
12
6
|
@teardown_block = nil
|
13
7
|
@specifications = []
|
14
8
|
@name = name
|
15
9
|
instance_exec(&context_block)
|
16
|
-
ContextRunner.standalone(self) if @@context_runner.nil?
|
17
|
-
@@context_runner.add_context(self) unless @@context_runner.nil?
|
18
10
|
end
|
19
11
|
|
20
|
-
def run(reporter)
|
21
|
-
reporter.add_context(@name)
|
22
|
-
@specifications.each do |specification|
|
23
|
-
specification.run(reporter, @setup_block, @teardown_block)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def run_docs(reporter)
|
12
|
+
def run(reporter, dry_run=false)
|
28
13
|
reporter.add_context(@name)
|
29
14
|
@specifications.each do |specification|
|
30
|
-
specification.
|
15
|
+
specification.run(reporter, @setup_block, @teardown_block, dry_run)
|
31
16
|
end
|
32
17
|
end
|
33
18
|
|
@@ -42,6 +27,24 @@ module Spec
|
|
42
27
|
def specify(spec_name, &block)
|
43
28
|
@specifications << Specification.new(spec_name, &block)
|
44
29
|
end
|
30
|
+
|
31
|
+
def number_of_specs
|
32
|
+
@specifications.length
|
33
|
+
end
|
34
|
+
|
35
|
+
def matches? name
|
36
|
+
return false unless name =~ /^#{@name} /
|
37
|
+
@specifications.each do |spec|
|
38
|
+
return true if spec.matches? name[(@name.length + 1)..-1]
|
39
|
+
end
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
|
43
|
+
def isolate name
|
44
|
+
@specifications.reject! do |spec|
|
45
|
+
!spec.matches? name[(@name.length + 1)..-1]
|
46
|
+
end
|
47
|
+
end
|
45
48
|
end
|
46
49
|
end
|
47
|
-
end
|
50
|
+
end
|