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
@@ -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
|