rspec 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/CHANGES +57 -32
  2. data/EXAMPLES.rd +0 -0
  3. data/Rakefile +22 -21
  4. data/bin/spec +9 -11
  5. data/doc/README +1 -3
  6. data/doc/plugin/syntax.rb +27 -5
  7. data/doc/src/core_team.page +22 -0
  8. data/doc/src/default.css +11 -11
  9. data/doc/src/default.template +0 -1
  10. data/doc/src/documentation/index.page +183 -8
  11. data/doc/src/documentation/meta.info +7 -7
  12. data/doc/src/documentation/mocks.page +168 -109
  13. data/doc/src/documentation/underscores.page +20 -0
  14. data/doc/src/examples.page +2 -1
  15. data/doc/src/images/David_and_Aslak.jpg +0 -0
  16. data/doc/src/images/Whats_That_Dude.jpg +0 -0
  17. data/doc/src/index.page +70 -3
  18. data/doc/src/meta.info +18 -11
  19. data/doc/src/tools/index.page +40 -134
  20. data/doc/src/tools/meta.info +9 -3
  21. data/doc/src/tools/rails.page +3 -1
  22. data/doc/src/tools/rake.page +20 -3
  23. data/doc/src/tools/rcov.page +19 -0
  24. data/doc/src/tools/spec.page +99 -0
  25. data/doc/src/tools/test2rspec.page +2 -4
  26. data/doc/src/tutorials/index.page +52 -0
  27. data/doc/src/tutorials/meta.info +31 -0
  28. data/doc/src/tutorials/notes.txt +252 -0
  29. data/doc/src/tutorials/stack.rb +11 -0
  30. data/doc/src/tutorials/stack_01.page +224 -0
  31. data/doc/src/tutorials/stack_02.page +180 -0
  32. data/doc/src/tutorials/stack_03.page +291 -0
  33. data/doc/src/tutorials/stack_04.page +203 -0
  34. data/doc/src/tutorials/stack_04.page.orig +123 -0
  35. data/doc/src/tutorials/stack_05.page +90 -0
  36. data/doc/src/tutorials/stack_05.page.orig +124 -0
  37. data/doc/src/tutorials/stack_06.page +359 -0
  38. data/doc/src/tutorials/stack_06.page.orig +359 -0
  39. data/doc/src/tutorials/stack_spec.rb +41 -0
  40. data/examples/airport_spec.rb +4 -4
  41. data/examples/{spec_framework_spec.rb → bdd_framework_spec.rb} +6 -7
  42. data/examples/mocking_spec.rb +0 -5
  43. data/examples/stack_spec.rb +6 -7
  44. data/examples/sugar_spec.rb +14 -0
  45. data/lib/spec/api.rb +5 -2
  46. data/lib/spec/api/helper/should_base.rb +17 -22
  47. data/lib/spec/api/helper/should_helper.rb +4 -3
  48. data/lib/spec/api/helper/should_negator.rb +3 -2
  49. data/lib/spec/api/mocks/argument_expectation.rb +104 -0
  50. data/lib/spec/api/{mock.rb → mocks/message_expectation.rb} +47 -96
  51. data/lib/spec/api/mocks/mock.rb +63 -0
  52. data/lib/spec/api/mocks/order_group.rb +21 -0
  53. data/lib/spec/api/sugar.rb +47 -0
  54. data/lib/spec/rake/rcov_verify.rb +45 -0
  55. data/lib/spec/rake/spectask.rb +41 -56
  56. data/lib/spec/runner.rb +4 -1
  57. data/lib/spec/runner/backtrace_tweaker.rb +24 -3
  58. data/lib/spec/runner/base_text_formatter.rb +28 -0
  59. data/lib/spec/runner/context.rb +21 -18
  60. data/lib/spec/runner/context_runner.rb +20 -31
  61. data/lib/spec/runner/execution_context.rb +3 -3
  62. data/lib/spec/runner/kernel_ext.rb +10 -1
  63. data/lib/spec/runner/option_parser.rb +32 -14
  64. data/lib/spec/runner/progress_bar_formatter.rb +21 -0
  65. data/lib/spec/runner/rdoc_formatter.rb +15 -5
  66. data/lib/spec/runner/reporter.rb +100 -0
  67. data/lib/spec/runner/specdoc_formatter.rb +20 -0
  68. data/lib/spec/runner/specification.rb +42 -22
  69. data/lib/spec/version.rb +1 -1
  70. data/test/rcov/rcov_testtask.rb +1 -0
  71. data/test/spec/api/duck_type_test.rb +4 -4
  72. data/test/spec/api/helper/raising_test.rb +37 -17
  73. data/test/spec/api/{mock_arg_constraints_test.rb → mocks/mock_arg_constraints_test.rb} +10 -4
  74. data/test/spec/api/mocks/mock_ordering_test.rb +62 -0
  75. data/test/spec/api/{mock_test.rb → mocks/mock_test.rb} +30 -7
  76. data/test/spec/api/mocks/null_object_test.rb +31 -0
  77. data/test/spec/api/sugar_test.rb +71 -0
  78. data/test/spec/runner/backtrace_tweaker_test.rb +52 -4
  79. data/test/spec/runner/context_runner_test.rb +41 -21
  80. data/test/spec/runner/context_test.rb +60 -32
  81. data/test/spec/runner/execution_context_test.rb +4 -3
  82. data/test/spec/runner/failure_dump_test.rb +92 -0
  83. data/test/spec/runner/kernel_ext_test.rb +1 -2
  84. data/test/spec/runner/option_parser_test.rb +48 -28
  85. data/test/spec/runner/progress_bar_formatter_test.rb +48 -0
  86. data/test/spec/runner/rdoc_formatter_test.rb +31 -4
  87. data/test/spec/runner/reporter_test.rb +103 -0
  88. data/test/spec/runner/specdoc_formatter_test.rb +50 -0
  89. data/test/spec/runner/specification_test.rb +49 -11
  90. data/test/test_helper.rb +1 -4
  91. metadata +46 -15
  92. data/doc/src/community.page +0 -7
  93. data/doc/src/documentation/api.page +0 -185
  94. data/doc/src/why_rspec.page +0 -7
  95. data/examples/empty_stack_spec.rb +0 -22
  96. data/examples/team_spec.rb +0 -30
  97. data/lib/spec/api/duck_type.rb +0 -16
  98. data/lib/spec/runner/simple_text_reporter.rb +0 -88
  99. data/test/rcov/rcov_verify.rb +0 -28
  100. 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 self.standalone(context, args=ARGV)
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
- @out = options.out
17
- @out = File.open(@out, 'w') if @out.is_a? String
18
- @doc = options.doc
19
- @listener = RDocFormatter.new(@out) if @doc
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
- run_specs unless @doc
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(@listener)
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 run_docs
45
- @contexts.each do |context|
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::DuckType.new(*args)
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.parse(args, standalone=false, err=$stderr, out=$stdout)
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.verbose = false
11
- options.doc = false
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("-o", "--of [FILE]", "Set the output file (defaults to STDOUT)") do |outfile|
18
- options.out = StringIO.new if outfile == "stringio"
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("-v", "--verbose", "Verbose output") do
24
- options.verbose = true
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", "--doc", "Output specdoc only") do
28
- options.doc = true
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 RDocFormatter
4
- def initialize(output=STDOUT)
5
- @output = output
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 add_spec(name)
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
- execution_context = ::Spec::Runner::ExecutionContext.new(self)
14
- begin
15
- execution_context.instance_exec(&setup_block) unless setup_block.nil?
16
- execution_context.instance_exec(&@block)
17
- rescue => e
18
- @errors << e
19
- end
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
- begin
22
- execution_context.instance_exec(&teardown_block) unless teardown_block.nil?
23
- @mocks.each do |mock|
24
- mock.__verify
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
- reporter.add_spec(@name, @errors) unless reporter.nil?
31
- end
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
@@ -3,7 +3,7 @@ module Spec
3
3
  unless defined? MAJOR
4
4
  MAJOR = 0
5
5
  MINOR = 5
6
- TINY = 3
6
+ TINY = 4
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY].join('.')
9
9