rspec 0.5.3 → 0.5.4
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/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
@@ -3,50 +3,39 @@ require File.dirname(__FILE__) + '/../../spec'
|
|
3
3
|
module Spec
|
4
4
|
module Runner
|
5
5
|
class ContextRunner
|
6
|
+
attr_reader :standalone
|
6
7
|
|
7
|
-
def
|
8
|
-
context_runner = ContextRunner.new(args, true)
|
9
|
-
context_runner.add_context context
|
10
|
-
context_runner.run
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize(args, standalone=false, err=$stderr)
|
14
|
-
options = OptionParser.parse(args, standalone, err)
|
8
|
+
def initialize(reporter, standalone, dry_run, single_spec=nil)
|
15
9
|
@contexts = []
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@
|
19
|
-
@
|
20
|
-
@listener = SimpleTextReporter.new(@out, options.verbose) unless @doc
|
10
|
+
@reporter = reporter
|
11
|
+
@standalone = standalone
|
12
|
+
@dry_run = dry_run
|
13
|
+
@single_spec = single_spec
|
21
14
|
end
|
22
15
|
|
23
16
|
def add_context(context)
|
17
|
+
return if !@single_spec.nil? unless context.matches?@single_spec
|
18
|
+
context.isolate @single_spec if context.matches?@single_spec
|
24
19
|
@contexts << context
|
25
|
-
self
|
26
20
|
end
|
27
21
|
|
28
|
-
def run
|
29
|
-
|
30
|
-
run_docs if @doc
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def run_specs
|
36
|
-
@listener.start
|
22
|
+
def run(exit_when_done=false)
|
23
|
+
@reporter.start number_of_specs
|
37
24
|
@contexts.each do |context|
|
38
|
-
context.run(@
|
25
|
+
context.run(@reporter, @dry_run)
|
26
|
+
end
|
27
|
+
@reporter.end
|
28
|
+
failure_count = @reporter.dump
|
29
|
+
if(exit_when_done)
|
30
|
+
exit_code = (failure_count == 0) ? 0 : 1
|
31
|
+
exit!(exit_code)
|
39
32
|
end
|
40
|
-
@listener.end
|
41
|
-
@listener.dump
|
42
33
|
end
|
43
34
|
|
44
|
-
def
|
45
|
-
@contexts.
|
46
|
-
context.run_docs(@listener)
|
47
|
-
end
|
35
|
+
def number_of_specs
|
36
|
+
@contexts.inject(0) {|sum, context| sum + context.number_of_specs}
|
48
37
|
end
|
49
|
-
|
38
|
+
|
50
39
|
end
|
51
40
|
end
|
52
41
|
end
|
@@ -5,14 +5,14 @@ module Spec
|
|
5
5
|
@spec = spec
|
6
6
|
end
|
7
7
|
|
8
|
-
def mock(name)
|
9
|
-
mock = Api::Mock.new(name)
|
8
|
+
def mock(name, options={})
|
9
|
+
mock = Api::Mock.new(name, options)
|
10
10
|
@spec.add_mock(mock)
|
11
11
|
mock
|
12
12
|
end
|
13
13
|
|
14
14
|
def duck_type(*args)
|
15
|
-
return Api::
|
15
|
+
return Api::DuckTypeArgConstraint.new(*args)
|
16
16
|
end
|
17
17
|
|
18
18
|
def violated(message="")
|
@@ -1,5 +1,14 @@
|
|
1
1
|
module Kernel
|
2
2
|
def context(name, &block)
|
3
|
-
Spec::Runner::Context.new(name, &block)
|
3
|
+
context = Spec::Runner::Context.new(name, &block)
|
4
|
+
runner = context_runner
|
5
|
+
runner.add_context(context)
|
6
|
+
runner.run if runner.standalone
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def context_runner
|
12
|
+
$context_runner || ::Spec::Runner::OptionParser.create_context_runner(ARGV.dup, true, STDERR, STDOUT)
|
4
13
|
end
|
5
14
|
end
|
@@ -1,34 +1,50 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
require 'optparse'
|
3
|
+
|
3
4
|
module Spec
|
4
5
|
module Runner
|
5
6
|
class OptionParser
|
6
7
|
|
7
|
-
def self.
|
8
|
+
def self.create_context_runner(args, standalone, err, out=STDOUT)
|
9
|
+
options = parse(args, standalone, err, out)
|
10
|
+
|
11
|
+
formatter = options.formatter_type.new(options.out, options.dry_run)
|
12
|
+
reporter = Reporter.new(formatter, options.backtrace_tweaker)
|
13
|
+
ContextRunner.new(reporter, standalone, options.dry_run, options.spec_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.parse(args, standalone, err, out)
|
8
17
|
options = OpenStruct.new
|
9
18
|
options.out = out
|
10
|
-
options.
|
11
|
-
options.
|
19
|
+
options.formatter_type = ProgressBarFormatter
|
20
|
+
options.backtrace_tweaker = QuietBacktraceTweaker.new
|
21
|
+
options.spec_name = nil
|
12
22
|
|
13
23
|
opts = ::OptionParser.new do |opts|
|
14
24
|
opts.banner = "Usage: spec [options] (FILE|DIRECTORY)+"
|
15
25
|
opts.separator ""
|
16
26
|
|
17
|
-
opts.on("-
|
18
|
-
options.
|
19
|
-
options.out = outfile unless outfile.nil? or outfile == "stringio"
|
20
|
-
exit if outfile.nil?
|
27
|
+
opts.on("-b", "--backtrace", "Output full backtrace") do
|
28
|
+
options.backtrace_tweaker = NoisyBacktraceTweaker.new
|
21
29
|
end
|
22
|
-
|
23
|
-
opts.on("-
|
24
|
-
options.
|
30
|
+
|
31
|
+
opts.on("-f", "--format FORMAT", "Output format (specdoc|s|rdoc|r)") do |format|
|
32
|
+
options.formatter_type = SpecdocFormatter if format == 'specdoc'
|
33
|
+
options.formatter_type = SpecdocFormatter if format == 's'
|
34
|
+
options.formatter_type = RdocFormatter if format == 'rdoc'
|
35
|
+
options.formatter_type = RdocFormatter if format == 'r'
|
36
|
+
options.dry_run = true if format == 'rdoc'
|
25
37
|
end
|
26
38
|
|
27
|
-
opts.on("-d", "--
|
28
|
-
options.
|
39
|
+
opts.on("-d", "--dry-run", "Don't execute specs") do
|
40
|
+
options.dry_run = true
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on("-s", "--spec SPECIFICATION_NAME", "Execute a single specification") do |spec_name|
|
44
|
+
options.spec_name = spec_name
|
29
45
|
end
|
30
46
|
|
31
|
-
opts.on("--version", "Show version") do
|
47
|
+
opts.on("-v", "--version", "Show version") do
|
32
48
|
out.puts ::Spec::VERSION::DESCRIPTION
|
33
49
|
exit if out == $stdout
|
34
50
|
end
|
@@ -37,13 +53,15 @@ module Spec
|
|
37
53
|
out.puts opts
|
38
54
|
exit if out == $stdout
|
39
55
|
end
|
40
|
-
|
56
|
+
|
41
57
|
end
|
42
58
|
opts.parse!(args)
|
59
|
+
|
43
60
|
if args.empty?
|
44
61
|
err.puts opts unless standalone
|
45
62
|
exit if err == $stderr unless standalone
|
46
63
|
end
|
64
|
+
|
47
65
|
options
|
48
66
|
end
|
49
67
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Spec
|
2
|
+
module Runner
|
3
|
+
class ProgressBarFormatter < BaseTextFormatter
|
4
|
+
def add_context(name, first)
|
5
|
+
@output << "\n" if first
|
6
|
+
end
|
7
|
+
|
8
|
+
def spec_failed(name, counter)
|
9
|
+
@output << 'F'
|
10
|
+
end
|
11
|
+
|
12
|
+
def spec_passed(name)
|
13
|
+
@output << '.'
|
14
|
+
end
|
15
|
+
|
16
|
+
def start_dump
|
17
|
+
@output << "\n"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,17 +1,27 @@
|
|
1
1
|
module Spec
|
2
2
|
module Runner
|
3
|
-
class
|
4
|
-
def initialize(output=
|
5
|
-
|
3
|
+
class RdocFormatter < BaseTextFormatter
|
4
|
+
def initialize(output, dry_run=false)
|
5
|
+
super(output, true) # always dry
|
6
6
|
end
|
7
7
|
|
8
|
-
def add_context(name)
|
8
|
+
def add_context(name, first)
|
9
9
|
@output << "# #{name}\n"
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
12
|
+
def spec_passed(name)
|
13
13
|
@output << "# * #{name}\n"
|
14
14
|
end
|
15
|
+
|
16
|
+
def spec_failed(name, counter)
|
17
|
+
@output << "# * #{name} [#{counter} - FAILED]\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
def dump_failure(counter, failure)
|
21
|
+
end
|
22
|
+
|
23
|
+
def start_dump
|
24
|
+
end
|
15
25
|
end
|
16
26
|
end
|
17
27
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Spec
|
2
|
+
module Runner
|
3
|
+
class Reporter
|
4
|
+
# TODO: remove this attr_reader!!
|
5
|
+
attr_reader :formatter
|
6
|
+
|
7
|
+
def initialize(formatter, backtrace_tweaker)
|
8
|
+
@formatter = formatter
|
9
|
+
@context_names = []
|
10
|
+
@failures = []
|
11
|
+
@spec_names = []
|
12
|
+
@backtrace_tweaker = backtrace_tweaker
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_context(name)
|
16
|
+
#TODO - @context_names.empty? tells the formatter whether this is the first context or not - that's a little slippery
|
17
|
+
@formatter.add_context(name, @context_names.empty?)
|
18
|
+
@context_names << name
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_spec(name, error=nil, failure_location=nil)
|
22
|
+
if error.nil?
|
23
|
+
spec_passed(name)
|
24
|
+
else
|
25
|
+
@backtrace_tweaker.tweak_backtrace(error, failure_location)
|
26
|
+
spec_failed(name, Failure.new(@context_names.last, name, error))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def start(number_of_specs=0)
|
31
|
+
@start_time = Time.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def end
|
35
|
+
@end_time = Time.new
|
36
|
+
end
|
37
|
+
|
38
|
+
# Dumps the summary and returns the total number of failures
|
39
|
+
def dump
|
40
|
+
@formatter.start_dump
|
41
|
+
dump_failures
|
42
|
+
@formatter.dump_summary(duration, @context_names.length, @spec_names.length, @failures.length)
|
43
|
+
@failures.length
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def dump_failures
|
49
|
+
return if @failures.empty?
|
50
|
+
@failures.inject(1) do |index, failure|
|
51
|
+
@formatter.dump_failure(index, failure)
|
52
|
+
index + 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def duration
|
57
|
+
return @end_time - @start_time unless (@end_time.nil? or @start_time.nil?)
|
58
|
+
return "0.0"
|
59
|
+
end
|
60
|
+
|
61
|
+
def spec_passed(name)
|
62
|
+
@spec_names << name
|
63
|
+
@formatter.spec_passed(name)
|
64
|
+
end
|
65
|
+
|
66
|
+
def spec_failed(name, failure)
|
67
|
+
@spec_names << name
|
68
|
+
@failures << failure
|
69
|
+
@formatter.spec_failed(name, @failures.length)
|
70
|
+
end
|
71
|
+
|
72
|
+
class Failure
|
73
|
+
def initialize(context_name, spec_name, error)
|
74
|
+
@context_name = context_name
|
75
|
+
@spec_name = spec_name
|
76
|
+
@error = error
|
77
|
+
end
|
78
|
+
|
79
|
+
def header
|
80
|
+
"#{class_name} in '#{@context_name} #{@spec_name}'"
|
81
|
+
end
|
82
|
+
|
83
|
+
def message
|
84
|
+
@error.message
|
85
|
+
end
|
86
|
+
|
87
|
+
def backtrace
|
88
|
+
@error.backtrace.join("\n") unless @error.backtrace.nil?
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def class_name
|
94
|
+
@error.class.name.split('::').last
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Spec
|
2
|
+
module Runner
|
3
|
+
class SpecdocFormatter < BaseTextFormatter
|
4
|
+
def add_context(name, first)
|
5
|
+
@output << "\n#{name}\n"
|
6
|
+
end
|
7
|
+
|
8
|
+
def spec_failed(name, counter)
|
9
|
+
@output << "- #{name} (FAILED - #{counter})\n"
|
10
|
+
end
|
11
|
+
|
12
|
+
def spec_passed(name)
|
13
|
+
@output << "- #{name}\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
def start_dump
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -6,37 +6,57 @@ module Spec
|
|
6
6
|
@name = name
|
7
7
|
@block = block
|
8
8
|
@mocks = []
|
9
|
-
@errors = []
|
10
9
|
end
|
11
10
|
|
12
|
-
def run(reporter=nil, setup_block=nil, teardown_block=nil)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
execution_context.
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
def run(reporter=nil, setup_block=nil, teardown_block=nil, dry_run=false)
|
12
|
+
if dry_run
|
13
|
+
reporter.add_spec(@name)
|
14
|
+
else
|
15
|
+
execution_context = ::Spec::Runner::ExecutionContext.new(self)
|
16
|
+
errors = []
|
17
|
+
begin
|
18
|
+
execution_context.instance_exec(&setup_block) unless setup_block.nil?
|
19
|
+
setup_ok = true
|
20
|
+
execution_context.instance_exec(&@block)
|
21
|
+
spec_ok = true
|
22
|
+
rescue => e
|
23
|
+
errors << e
|
24
|
+
end
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
mock
|
26
|
+
begin
|
27
|
+
execution_context.instance_exec(&teardown_block) unless teardown_block.nil?
|
28
|
+
teardown_ok = true
|
29
|
+
@mocks.each do |mock|
|
30
|
+
mock.__verify
|
31
|
+
end
|
32
|
+
rescue => e
|
33
|
+
errors << e
|
25
34
|
end
|
26
|
-
rescue => e
|
27
|
-
@errors << e
|
28
|
-
end
|
29
35
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
def run_docs(reporter)
|
34
|
-
reporter.add_spec(@name)
|
36
|
+
reporter.add_spec(@name, first_error(errors), failure_location(setup_ok, spec_ok, teardown_ok)) unless reporter.nil?
|
37
|
+
end
|
35
38
|
end
|
36
|
-
|
39
|
+
|
37
40
|
def add_mock(mock)
|
38
41
|
@mocks << mock
|
39
42
|
end
|
43
|
+
|
44
|
+
def matches? name
|
45
|
+
name == @name
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def first_error errors
|
51
|
+
errors[0]
|
52
|
+
end
|
53
|
+
|
54
|
+
def failure_location(setup_ok, spec_ok, teardown_ok)
|
55
|
+
return 'setup' unless setup_ok
|
56
|
+
return @name unless spec_ok
|
57
|
+
return 'teardown' unless teardown_ok
|
58
|
+
end
|
59
|
+
|
40
60
|
end
|
41
61
|
end
|
42
62
|
end
|