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