rspec 0.5.6 → 0.5.7

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 (40) hide show
  1. data/CHANGES +8 -0
  2. data/Rakefile +11 -11
  3. data/bin/spec +4 -1
  4. data/doc/src/documentation/index.page +37 -37
  5. data/doc/src/documentation/mocks.page +34 -34
  6. data/doc/src/documentation/underscores.page +5 -4
  7. data/doc/src/index.page +2 -2
  8. data/doc/src/tools/rails.page +11 -0
  9. data/doc/src/tools/spec.page +18 -3
  10. data/doc/src/tutorials/notes.txt +17 -6
  11. data/doc/src/tutorials/stack_04.page.orig +2 -2
  12. data/doc/src/tutorials/stack_05.page.orig +5 -5
  13. data/doc/src/tutorials/stack_06.page +7 -7
  14. data/doc/src/tutorials/stack_06.page.orig +7 -7
  15. data/examples/custom_formatter.rb +21 -0
  16. data/examples/mocking_spec.rb +1 -1
  17. data/examples/stack_spec.rb +21 -21
  18. data/lib/spec/runner/base_text_formatter.rb +42 -0
  19. data/lib/spec/runner/context_runner.rb +1 -1
  20. data/lib/spec/runner/kernel_ext.rb +1 -1
  21. data/lib/spec/runner/option_parser.rb +23 -7
  22. data/lib/spec/runner/progress_bar_formatter.rb +1 -1
  23. data/lib/spec/runner/rdoc_formatter.rb +0 -10
  24. data/lib/spec/runner/reporter.rb +3 -4
  25. data/lib/spec/runner/specdoc_formatter.rb +0 -3
  26. data/lib/spec/runner/specification.rb +3 -7
  27. data/lib/spec/tool/test_unit_translator.rb +20 -20
  28. data/lib/spec/version.rb +1 -1
  29. data/test/spec/api/mocks/mock_ordering_test.rb +28 -0
  30. data/test/spec/runner/context_test.rb +4 -4
  31. data/test/spec/runner/failure_dump_test.rb +7 -7
  32. data/test/spec/runner/option_parser_test.rb +22 -1
  33. data/test/spec/runner/progress_bar_formatter_test.rb +6 -0
  34. data/test/spec/runner/rdoc_formatter_test.rb +1 -1
  35. data/test/spec/runner/reporter_test.rb +9 -8
  36. data/test/spec/runner/specdoc_formatter_test.rb +5 -0
  37. data/test/spec/runner/specification_test.rb +8 -8
  38. data/test/spec/tool/command_line_test.rb +4 -4
  39. data/test/spec/tool/test_unit_api_spec.rb +25 -25
  40. metadata +5 -4
@@ -20,7 +20,7 @@ module Spec
20
20
  end
21
21
 
22
22
  def run(exit_when_done)
23
- @reporter.start number_of_specs
23
+ @reporter.start(number_of_specs)
24
24
  @contexts.each do |context|
25
25
  context.run(@reporter, @dry_run)
26
26
  end
@@ -9,6 +9,6 @@ module Kernel
9
9
  private
10
10
 
11
11
  def context_runner
12
- $context_runner || ::Spec::Runner::OptionParser.create_context_runner(ARGV.dup, true, STDERR, STDOUT)
12
+ $context_runner ||= ::Spec::Runner::OptionParser.create_context_runner(ARGV.dup, true, STDERR, STDOUT)
13
13
  end
14
14
  end
@@ -21,19 +21,35 @@ module Spec
21
21
  options.spec_name = nil
22
22
 
23
23
  opts = ::OptionParser.new do |opts|
24
- opts.banner = "Usage: spec [options] (FILE|DIRECTORY)+"
24
+ opts.banner = "Usage: spec [options] (FILE|DIRECTORY|GLOB)+"
25
25
  opts.separator ""
26
26
 
27
27
  opts.on("-b", "--backtrace", "Output full backtrace") do
28
28
  options.backtrace_tweaker = NoisyBacktraceTweaker.new
29
29
  end
30
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'
31
+ opts.on("-r", "--require FILE", "Require FILE before running specs",
32
+ "Useful for loading custom formatters or other extensions") do |req|
33
+ require req
34
+ end
35
+
36
+ opts.on("-f", "--format FORMAT", "Builtin formats: specdoc|s|rdoc|r",
37
+ "You can also specify a custom formatter class") do |format|
38
+ case format
39
+ when 'specdoc', 's'
40
+ options.formatter_type = SpecdocFormatter
41
+ when 'rdoc', 'r'
42
+ options.formatter_type = RdocFormatter
43
+ options.dry_run = true
44
+ else
45
+ begin
46
+ options.formatter_type = eval(format)
47
+ rescue NameError
48
+ err.puts "Couldn't find formatter class #{format}"
49
+ err.puts "Make sure the --require option is specified *before* --format"
50
+ exit if out == $stdout
51
+ end
52
+ end
37
53
  end
38
54
 
39
55
  opts.on("-d", "--dry-run", "Don't execute specs") do
@@ -1,6 +1,6 @@
1
1
  module Spec
2
2
  module Runner
3
- class ProgressBarFormatter < BaseTextFormatter
3
+ class ProgressBarFormatter < BaseTextFormatter
4
4
  def add_context(name, first)
5
5
  @output << "\n" if first
6
6
  end
@@ -1,10 +1,6 @@
1
1
  module Spec
2
2
  module Runner
3
3
  class RdocFormatter < BaseTextFormatter
4
- def initialize(output, dry_run=false)
5
- super(output, true) # always dry
6
- end
7
-
8
4
  def add_context(name, first)
9
5
  @output << "# #{name}\n"
10
6
  end
@@ -16,12 +12,6 @@ module Spec
16
12
  def spec_failed(name, counter)
17
13
  @output << "# * #{name} [#{counter} - FAILED]\n"
18
14
  end
19
-
20
- def dump_failure(counter, failure)
21
- end
22
-
23
- def start_dump
24
- end
25
15
  end
26
16
  end
27
17
  end
@@ -1,8 +1,6 @@
1
1
  module Spec
2
2
  module Runner
3
3
  class Reporter
4
- # TODO: remove this attr_reader!!
5
- attr_reader :formatter
6
4
 
7
5
  def initialize(formatter, backtrace_tweaker)
8
6
  @formatter = formatter
@@ -18,7 +16,7 @@ module Spec
18
16
  @context_names << name
19
17
  end
20
18
 
21
- def add_spec(name, error=nil, failure_location=nil)
19
+ def spec_finished(name, error=nil, failure_location=nil)
22
20
  if error.nil?
23
21
  spec_passed(name)
24
22
  else
@@ -27,8 +25,9 @@ module Spec
27
25
  end
28
26
  end
29
27
 
30
- def start(number_of_specs=0)
28
+ def start(number_of_specs)
31
29
  @start_time = Time.new
30
+ @formatter.start(number_of_specs)
32
31
  end
33
32
 
34
33
  def end
@@ -12,9 +12,6 @@ module Spec
12
12
  def spec_passed(name)
13
13
  @output << "- #{name}\n"
14
14
  end
15
-
16
- def start_dump
17
- end
18
15
  end
19
16
  end
20
17
  end
@@ -10,7 +10,7 @@ module Spec
10
10
 
11
11
  def run(reporter=nil, setup_block=nil, teardown_block=nil, dry_run=false)
12
12
  if dry_run
13
- reporter.add_spec(@name)
13
+ reporter.spec_finished(@name)
14
14
  else
15
15
  execution_context = ::Spec::Runner::ExecutionContext.new(self)
16
16
  errors = []
@@ -33,7 +33,7 @@ module Spec
33
33
  errors << e
34
34
  end
35
35
 
36
- reporter.add_spec(@name, first_error(errors), failure_location(setup_ok, spec_ok, teardown_ok)) unless reporter.nil?
36
+ reporter.spec_finished(@name, errors.first, failure_location(setup_ok, spec_ok, teardown_ok)) unless reporter.nil?
37
37
  end
38
38
  end
39
39
 
@@ -41,16 +41,12 @@ module Spec
41
41
  @mocks << mock
42
42
  end
43
43
 
44
- def matches_matcher? matcher
44
+ def matches_matcher?(matcher)
45
45
  matcher.matches? @name
46
46
  end
47
47
 
48
48
  private
49
49
 
50
- def first_error errors
51
- errors[0]
52
- end
53
-
54
50
  def failure_location(setup_ok, spec_ok, teardown_ok)
55
51
  return 'setup' unless setup_ok
56
52
  return @name unless spec_ok
@@ -3,27 +3,27 @@ module Spec
3
3
  # Translates Test::Unit tests to RSpec specs.
4
4
  class TestUnitTranslator
5
5
  ONE_ARG_TRANSLATIONS = {
6
- "assert" => "should.not.be nil",
7
- "assert_nil" => "should.be nil",
8
- "assert_not_nil" => "should.not.be nil"
6
+ "assert" => "should_not_be nil",
7
+ "assert_nil" => "should_be nil",
8
+ "assert_not_nil" => "should_not_be nil"
9
9
 
10
10
  }
11
11
  TWO_ARG_TRANSLATIONS = {
12
- "assert_equal" => "should.equal",
13
- "assert_instance_of" => "should.be.instance.of",
14
- "assert_kind_of" => "should.be.kind.of",
15
- "assert_match" => "should.match",
16
- "assert_no_match" => "should.not.match",
17
- "assert_not_equal" => "should.not.equal",
18
- "assert_not_same" => "should.not.be",
19
- "assert_same" => "should.be"
12
+ "assert_equal" => "should_equal",
13
+ "assert_instance_of" => "should_be_instance_of",
14
+ "assert_kind_of" => "should_be_kind_of",
15
+ "assert_match" => "should_match",
16
+ "assert_no_match" => "should_not_match",
17
+ "assert_not_equal" => "should_not_equal",
18
+ "assert_not_same" => "should_not_be",
19
+ "assert_same" => "should_be"
20
20
  }
21
21
  RAISE_TRANSLATIONS = {
22
- "assert_nothing_raised" => "should.not.raise",
23
- "assert_nothing_thrown" => "should.not.throw",
24
- "assert_raise" => "should.raise",
25
- "assert_raises" => "should.raise",
26
- "assert_throws" => "should.throw",
22
+ "assert_nothing_raised" => "should_not_raise",
23
+ "assert_nothing_thrown" => "should_not_throw",
24
+ "assert_raise" => "should_raise",
25
+ "assert_raises" => "should_raise",
26
+ "assert_throws" => "should_throw",
27
27
  }
28
28
 
29
29
  def translate(test_unit_file)
@@ -71,7 +71,7 @@ module Spec
71
71
 
72
72
  elsif assertion == "assert_respond_to"
73
73
  actual, method, message = args.split(",").collect{|arg| arg.strip}
74
- line = "#{spaces}#{actual}.should.respond.to #{method}\n"
74
+ line = "#{spaces}#{actual}.should_respond_to #{method}\n"
75
75
 
76
76
  elsif translation = ONE_ARG_TRANSLATIONS[assertion]
77
77
  actual, message = args.split(",").collect{|arg| arg.strip}
@@ -87,15 +87,15 @@ module Spec
87
87
  end_replacement = "#{translation} #{expected}\n"
88
88
 
89
89
  elsif assertion == "assert_block" and suffix =~ /\{.*\}/
90
- line = "#{spaces}lambda #{suffix}.should.be true\n"
90
+ line = "#{spaces}lambda #{suffix}.should_be true\n"
91
91
 
92
92
  elsif assertion == "assert_block"
93
93
  line = "#{spaces}lambda do\n"
94
- end_replacement = "should.be true\n"
94
+ end_replacement = "should_be true\n"
95
95
 
96
96
  elsif assertion == "assert_in_delta"
97
97
  expected, actual, delta, message = args.split(",").collect{|arg| arg.strip}
98
- line = "#{spaces}#{actual}.should.be.close #{expected}, #{delta}\n"
98
+ line = "#{spaces}#{actual}.should_be_close #{expected}, #{delta}\n"
99
99
  end
100
100
  elsif end_replacement && line =~ /(\s+)end/
101
101
  spaces = $1
@@ -3,7 +3,7 @@ module Spec
3
3
  unless defined? MAJOR
4
4
  MAJOR = 0
5
5
  MINOR = 5
6
- TINY = 6
6
+ TINY = 7
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY].join('.')
9
9
  TAG = "REL_" + [MAJOR, MINOR, TINY].join('_')
@@ -25,6 +25,34 @@ module Spec
25
25
  end
26
26
  end
27
27
 
28
+ def FIXME_test_two_in_order_calls_with_block
29
+ @mock.should.receive(:doit).ordered do |a, b|
30
+ a.should_equal "a1"
31
+ a.should_equal "b1"
32
+ end
33
+ @mock.should.receive(:doit).ordered do |a, b|
34
+ a.should_equal "a2"
35
+ a.should_equal "b2"
36
+ end
37
+ @mock.doit "a1", "b1"
38
+ @mock.doit "b1", "b2"
39
+ @mock.__verify
40
+ end
41
+
42
+ def FIXME_test_two_out_of_order_calls_with_block
43
+ @mock.should.receive(:doit).ordered do |a, b|
44
+ a.should_equal "a1"
45
+ a.should_equal "b1"
46
+ end
47
+ @mock.should.receive(:doit).ordered do |a, b|
48
+ a.should_equal "a2"
49
+ a.should_equal "b2"
50
+ end
51
+ @mock.doit "b1", "b2"
52
+ @mock.doit "a1", "b1"
53
+ @mock.__verify
54
+ end
55
+
28
56
  def test_three_linear_calls
29
57
  @mock.should.receive(:one).ordered
30
58
  @mock.should.receive(:two).ordered
@@ -17,7 +17,7 @@ module Spec
17
17
 
18
18
  def test_should_run_spec
19
19
  @formatter.should.receive(:add_context).with :any_args
20
- @formatter.should.receive(:add_spec).with "test", :anything, :anything
20
+ @formatter.should.receive(:spec_finished).with "test", :anything, :anything
21
21
  $spec_ran = false
22
22
  @context.specify("test") {$spec_ran = true}
23
23
  @context.run(@formatter)
@@ -27,7 +27,7 @@ module Spec
27
27
 
28
28
  def test_should_run_spec_dry
29
29
  @formatter.should.receive(:add_context).with :any_args
30
- @formatter.should.receive(:add_spec).with "test"
30
+ @formatter.should.receive(:spec_finished).with "test"
31
31
  $spec_ran = false
32
32
  @context.specify("test") {$spec_ran = true}
33
33
  @context.run(@formatter, true)
@@ -37,7 +37,7 @@ module Spec
37
37
 
38
38
  def test_setup
39
39
  @formatter.should.receive(:add_context).with :any_args
40
- @formatter.should.receive(:add_spec).with :any_args
40
+ @formatter.should.receive(:spec_finished).with :any_args
41
41
  $setup_ran = false
42
42
  @context.setup {$setup_ran = true}
43
43
  @context.specify("test") {true}
@@ -48,7 +48,7 @@ module Spec
48
48
 
49
49
  def test_teardwown
50
50
  @formatter.should.receive(:add_context).with :any_args
51
- @formatter.should.receive(:add_spec).with :any_args
51
+ @formatter.should.receive(:spec_finished).with :any_args
52
52
  $teardwown_ran = false
53
53
  @context.teardown {$teardwown_ran = true}
54
54
  @context.specify("test") {true}
@@ -17,7 +17,7 @@ module Spec
17
17
  def test_spacing_between_sections
18
18
  error = Spec::Api::ExpectationNotMetError.new "message"
19
19
  set_backtrace error
20
- @reporter.add_spec "spec", error, "spec"
20
+ @reporter.spec_finished "spec", error, "spec"
21
21
  @reporter.dump
22
22
  assert_match(/\nF\n\n1\)\nExpectationNotMetError in 'context spec'\nmessage\n\/a\/b\/c\/d\/e.rb:34:in `spec'\n\nFinished in /, @io.string)
23
23
  end
@@ -25,7 +25,7 @@ module Spec
25
25
  def test_should_end_with_line_break
26
26
  error = Spec::Api::ExpectationNotMetError.new "message"
27
27
  set_backtrace error
28
- @reporter.add_spec "spec", error, "spec"
28
+ @reporter.spec_finished "spec", error, "spec"
29
29
  @reporter.dump
30
30
  assert_match(/\n\z/, @io.string)
31
31
  end
@@ -33,7 +33,7 @@ module Spec
33
33
  def test_should_include_informational_header
34
34
  error = Spec::Api::ExpectationNotMetError.new "message"
35
35
  set_backtrace error
36
- @reporter.add_spec "spec", error, "spec"
36
+ @reporter.spec_finished "spec", error, "spec"
37
37
  @reporter.dump
38
38
  assert_match(/^ExpectationNotMetError in 'context spec'/, @io.string)
39
39
  end
@@ -41,7 +41,7 @@ module Spec
41
41
  def test_should_include_context_and_spec_name_in_backtrace_if_error_in_spec
42
42
  error = RuntimeError.new "message"
43
43
  set_backtrace error
44
- @reporter.add_spec "spec", error, "spec"
44
+ @reporter.spec_finished "spec", error, "spec"
45
45
  @reporter.dump
46
46
  assert_match(/RuntimeError in 'context spec'/, @io.string)
47
47
  assert_match(/:in `spec'/, @io.string)
@@ -50,7 +50,7 @@ module Spec
50
50
  def test_should_include_context_and_setup_in_backtrace_if_error_in_setup
51
51
  error = RuntimeError.new
52
52
  set_backtrace error
53
- @reporter.add_spec "spec", error, "setup"
53
+ @reporter.spec_finished "spec", error, "setup"
54
54
  @reporter.dump
55
55
  assert_match(/RuntimeError in 'context spec'/, @io.string)
56
56
  assert_match(/in `setup'/, @io.string)
@@ -59,7 +59,7 @@ module Spec
59
59
  def test_should_include_context_and_teardown_in_backtrace_if_error_in_teardown
60
60
  error = RuntimeError.new
61
61
  set_backtrace error
62
- @reporter.add_spec "spec", error, "teardown"
62
+ @reporter.spec_finished "spec", error, "teardown"
63
63
  @reporter.dump
64
64
  assert_match(/RuntimeError in 'context spec'/, @io.string)
65
65
  assert_match(/in `teardown'/, @io.string)
@@ -82,7 +82,7 @@ module Spec
82
82
  def test_spacing_between_sections
83
83
  error = Spec::Api::ExpectationNotMetError.new "message"
84
84
  set_backtrace error
85
- @reporter.add_spec "spec", error, "spec"
85
+ @reporter.spec_finished "spec", error, "spec"
86
86
  @reporter.dump
87
87
  assert_match(/\ncontext\n- spec \(FAILED - 1\)\n\n1\)\nExpectationNotMetError in 'context spec'\nmessage\n\/a\/b\/c\/d\/e.rb:34:in `spec'\n\nFinished in /, @io.string)
88
88
  end
@@ -1,5 +1,10 @@
1
1
  require File.dirname(__FILE__) + '/../../test_helper'
2
2
 
3
+ module Custom
4
+ class Formatter
5
+ end
6
+ end
7
+
3
8
  module Spec
4
9
  module Runner
5
10
  class OptionParserTest < Test::Unit::TestCase
@@ -18,7 +23,7 @@ module Spec
18
23
  def test_should_print_help_to_stdout
19
24
  options = OptionParser.parse(["--help"], false, @err, @out)
20
25
  @out.rewind
21
- assert_match(/Usage: spec \[options\] \(FILE\|DIRECTORY\)\+/n, @out.read)
26
+ assert_match(/Usage: spec \[options\] \(FILE\|DIRECTORY\|GLOB\)\+/n, @out.read)
22
27
  end
23
28
 
24
29
  def test_verbose_should_be_false_by_default
@@ -60,6 +65,22 @@ module Spec
60
65
  options = OptionParser.parse(["--format","rdoc"], false, @err, @out)
61
66
  assert(options.dry_run)
62
67
  end
68
+
69
+ def test_should_eval_and_use_custom_formatter_when_none_of_the_builtins
70
+ options = OptionParser.parse(["--format","Custom::Formatter"], false, @err, @out)
71
+ assert_equal(Custom::Formatter, options.formatter_type)
72
+ end
73
+
74
+ def test_should_print_instructions_about_how_to_fix_bad_formatter
75
+ options = OptionParser.parse(["--format","Custom::BadFormatter"], false, @err, @out)
76
+ assert_match(/Couldn't find formatter class Custom::BadFormatter/n, @err.string)
77
+ end
78
+
79
+ def test_should_require_file_when_require_specified
80
+ assert_raise(LoadError) do
81
+ OptionParser.parse(["--require","whatever"], false, @err, @out)
82
+ end
83
+ end
63
84
 
64
85
  def test_should_print_usage_to_err_if_no_dir_specified
65
86
  options = OptionParser.parse([], false, @err, @out)
@@ -7,6 +7,11 @@ module Spec
7
7
  @io = StringIO.new
8
8
  @formatter = ProgressBarFormatter.new(@io)
9
9
  end
10
+
11
+ def test_should_push_nothing_on_start
12
+ @formatter.start(4)
13
+ assert_equal("", @io.string)
14
+ end
10
15
 
11
16
  def test_should_push_line_break_for_context
12
17
  @formatter.add_context("context", :ignored)
@@ -33,6 +38,7 @@ module Spec
33
38
  assert_equal("\n", @io.string)
34
39
  end
35
40
  end
41
+
36
42
  class ProgressBarFormatterDryRunTest < Test::Unit::TestCase
37
43
  def setup
38
44
  @io = StringIO.new
@@ -5,7 +5,7 @@ module Spec
5
5
 
6
6
  def setup
7
7
  @io = StringIO.new
8
- @formatter = RdocFormatter.new(@io)
8
+ @formatter = RdocFormatter.new(@io, true)
9
9
  end
10
10
 
11
11
  def test_should_push_out_context