nullstyle-test-spec 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,148 @@
1
+ require 'test/unit/ui/console/testrunner'
2
+
3
+ module Test::Unit::UI # :nodoc:
4
+ module SpecDox # :nodoc:
5
+ class TestRunner < Test::Unit::UI::Console::TestRunner
6
+ protected
7
+ def setup_mediator
8
+ @mediator = create_mediator(@suite)
9
+ end
10
+
11
+ def add_fault(fault)
12
+ if fault.kind_of? Test::Spec::Disabled
13
+ @disabled += 1
14
+ output_no_nl " (disabled)"
15
+ elsif fault.kind_of? Test::Spec::Empty
16
+ @empty += 1
17
+ output_no_nl " (empty)"
18
+ else
19
+ @faults << fault
20
+ word = fault.class.name[/(.*::)?(.*)/, 2].upcase
21
+ output_no_nl " (#{word} - #{@faults.size})"
22
+ end
23
+ end
24
+
25
+ def started(result)
26
+ @result = result
27
+ @context = nil
28
+ @contexts = []
29
+ @disabled = 0
30
+ @empty = 0
31
+ indent 0
32
+ end
33
+
34
+ def finished(elapsed_time)
35
+ nl
36
+ output "Finished in #{elapsed_time} seconds."
37
+ @faults.each_with_index do |fault, index|
38
+ nl
39
+ output("%3d) %s" % [index + 1, fault.long_display])
40
+ end
41
+ nl
42
+ output_result
43
+ end
44
+
45
+ def output_result
46
+ if @disabled > 0
47
+ disabled = ", #{@disabled} disabled"
48
+ else
49
+ disabled = ""
50
+ end
51
+
52
+ if @empty > 0
53
+ empty = ", #{@empty} empty"
54
+ else
55
+ empty = ""
56
+ end
57
+
58
+ r = ("%d specifications#{disabled}#{empty} " +
59
+ "(%d requirements), %d failures") % [
60
+ @result.run_count, @result.assertion_count, @result.failure_count]
61
+ r << ", #{@result.error_count} errors" if @result.error_count > 0
62
+ output r
63
+ end
64
+
65
+ def test_started(name)
66
+ return if special_test? name
67
+
68
+ contextname, @specname = unmangle name
69
+ return if contextname.nil? || @specname.nil?
70
+
71
+ if @context != contextname
72
+ @context = contextname
73
+
74
+ @old_contexts = @contexts
75
+ @contexts = @context.split("\t")
76
+
77
+ common = 0
78
+ @contexts.zip(@old_contexts) { |a, b|
79
+ break if a != b
80
+ common += 1
81
+ }
82
+
83
+ nl if common == 0
84
+
85
+ @contexts[common..-1].each_with_index { |head, i|
86
+ indent common + i
87
+ output_heading head
88
+ }
89
+ end
90
+
91
+ @assertions = @result.assertion_count
92
+ @prevdisabled = @disabled
93
+ output_item @specname
94
+ end
95
+
96
+ def test_finished(name)
97
+ return if special_test? name
98
+
99
+ # Did any assertion run?
100
+ if @assertions == @result.assertion_count && @prevdisabled == @disabled
101
+ add_fault Test::Spec::Empty.new(@specname)
102
+ end
103
+
104
+ # Don't let empty contexts clutter up the output.
105
+ nl unless name =~ /\Adefault_test\(/
106
+ end
107
+
108
+ def output_no_nl(something, level=NORMAL)
109
+ @io.write(something) if (output?(level))
110
+ @io.flush
111
+ end
112
+
113
+ def output_item(item)
114
+ output_no_nl "#{@prefix}- #{item}"
115
+ end
116
+
117
+ def output_heading(heading)
118
+ output "#{@prefix}#{heading}"
119
+ end
120
+
121
+ def unmangle(name)
122
+ if name =~ /\Atest_spec \{(.*?)\} \d+ \[(.*)\]/
123
+ contextname = $1
124
+ specname = $2
125
+ elsif name =~ /test_(.*?)\((.*)\)$/
126
+ specname = $1
127
+ contextname = $2
128
+
129
+ contextname.gsub!(/^Test\B|\BTest$/, '')
130
+ specname.gsub!(/_/, ' ')
131
+ else
132
+ contextname = specname = nil
133
+ end
134
+
135
+ [contextname, specname]
136
+ end
137
+
138
+ def indent(depth)
139
+ @indent = depth
140
+ @prefix = " " * depth
141
+ end
142
+
143
+ def special_test?(name)
144
+ name =~ /\Atest_spec \{.*?\} (-1 BEFORE|AFTER) ALL\(/
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,25 @@
1
+ require 'test/spec/dox'
2
+
3
+ module Test::Unit::UI # :nodoc:
4
+ module RDox # :nodoc:
5
+ class TestRunner < Test::Unit::UI::SpecDox::TestRunner
6
+ def output_heading(heading)
7
+ output "#{@headprefix} #{heading}"
8
+ end
9
+
10
+ def output_item(item)
11
+ output_no_nl "* #{item}"
12
+ end
13
+
14
+ def finished(elapsed_time)
15
+ nl
16
+ output_result
17
+ end
18
+
19
+ def indent(depth)
20
+ @prefix = ""
21
+ @headprefix = "==" + "=" * depth
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,49 @@
1
+ # Code adapted from rs, written by Eero Saynatkari.
2
+ require 'fileutils'
3
+ require 'tmpdir'
4
+
5
+ class Test::Spec::Should
6
+ # Captures output from the IO given as
7
+ # the second argument (STDIN by default)
8
+ # and matches it against a String or
9
+ # Regexp given as the first argument.
10
+ def output(expected, to = STDOUT)
11
+ # Store the old stream
12
+ old_to = to.dup
13
+
14
+ # Obtain a filehandle to replace (works with Readline)
15
+ to.reopen File.open(File.join(Dir.tmpdir, "should_output_#{$$}"), "w+")
16
+
17
+ # Execute
18
+ @object.call
19
+
20
+ # Restore
21
+ out = to.dup
22
+ to.reopen old_to
23
+
24
+ # Grab the data
25
+ out.rewind
26
+ output = out.read
27
+
28
+ # Match up
29
+ case expected
30
+ when Regexp
31
+ output.should.match expected
32
+ else
33
+ output.should.equal expected
34
+ end # case expected
35
+
36
+ # Clean up
37
+ ensure
38
+ out.close
39
+
40
+ # STDIO redirection will break else
41
+ begin
42
+ to.seek 0, IO::SEEK_END
43
+ rescue Errno::ESPIPE
44
+ rescue Errno::EPIPE
45
+ end
46
+
47
+ FileUtils.rm_f out.path
48
+ end # output
49
+ end # Test::Spec::Should
@@ -0,0 +1,8 @@
1
+ # To load it externally, without activating Test::Unit.
2
+
3
+ module Test
4
+ module Spec
5
+ VERSION = "0.4"
6
+ end
7
+ end
8
+
@@ -0,0 +1,55 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "test-spec"
3
+ s.version = "0.4.1"
4
+ s.date = "2008-04-30"
5
+ s.summary = "a Behaviour Driven Development interface for Test::Unit"
6
+ s.email = "chneukirchen@gmail.com"
7
+ s.homepage = "http://test-spec.rubyforge.org"
8
+
9
+ s.description = <<EOF
10
+ test/spec layers an RSpec-inspired interface on top of Test::Unit, so
11
+ you can mix TDD and BDD (Behavior-Driven Development).
12
+
13
+ test/spec is a clean-room implementation that maps most kinds of
14
+ Test::Unit assertions to a `should'-like syntax.
15
+ EOF
16
+
17
+ s.has_rdoc = true
18
+ s.authors = ["Christian Neukirchen"]
19
+
20
+ s.files = [
21
+ "Manifest.txt",
22
+ "README",
23
+ "Rakefile",
24
+ "test-spec.gemspec",
25
+ "lib/test/spec.rb",
26
+ "lib/test/spec/dox.rb",
27
+ "lib/test/spec/rdox.rb",
28
+ "lib/test/spec/should-output.rb",
29
+ "lib/test/spec/version.rb",
30
+ "test/spec_dox.rb",
31
+ "test/spec_flexmock.rb",
32
+ "test/spec_mocha.rb",
33
+ "test/spec_nestedcontexts.rb",
34
+ "test/spec_new_style.rb",
35
+ "test/spec_should-output.rb",
36
+ "test/spec_testspec.rb",
37
+ "test/spec_testspec_order.rb",
38
+ "test/test_testunit.rb",
39
+ ]
40
+
41
+ s.test_files = [
42
+ "test/spec_dox.rb",
43
+ "test/spec_flexmock.rb",
44
+ "test/spec_mocha.rb",
45
+ "test/spec_nestedcontexts.rb",
46
+ "test/spec_new_style.rb",
47
+ "test/spec_should-output.rb",
48
+ "test/spec_testspec.rb",
49
+ "test/spec_testspec_order.rb",
50
+ "test/test_testunit.rb",
51
+ ]
52
+
53
+ s.rdoc_options = ["--main", "README"]
54
+ s.extra_rdoc_files = ["Manifest.txt", "README"]
55
+ end
@@ -0,0 +1,39 @@
1
+ require 'test/spec'
2
+
3
+ require 'test/spec/dox'
4
+
5
+ context "SpecDox" do
6
+ setup do
7
+ r = Test::Unit::UI::SpecDox::TestRunner.new(nil)
8
+ @unmangler = r.method(:unmangle)
9
+ end
10
+
11
+ specify "can unmangle Test::Unit names correctly" do
12
+ @unmangler["test_foo_bar(TestFoo)"].should.equal ["Foo", "foo bar"]
13
+ @unmangler["test_foo_bar(FooTest)"].should.equal ["Foo", "foo bar"]
14
+ @unmangler["test_he_he(Foo)"].should.equal ["Foo", "he he"]
15
+ @unmangler["test_heh(Foo)"].should.equal ["Foo", "heh"]
16
+
17
+ @unmangler["test_heh(Test::Unit::TC_Assertions)"].
18
+ should.equal ["Test::Unit::TC_Assertions", "heh"]
19
+
20
+ @unmangler["test_heh(Foo::Bar::Test)"].
21
+ should.equal ["Foo::Bar::Test", "heh"]
22
+ end
23
+
24
+ specify "can unmangle Test::Spec names correctly" do
25
+ @unmangler["test_spec {context} 007 [whee]()"].
26
+ should.equal ["context", "whee"]
27
+ @unmangler["test_spec {a bit longish context} 069 [and more text]()"].
28
+ should.equal ["a bit longish context", "and more text"]
29
+ @unmangler["test_spec {special chars !\"/&%$} 2 [special chars !\"/&%$]()"].
30
+ should.equal ["special chars !\"/&%$", "special chars !\"/&%$"]
31
+ @unmangler["test_spec {[]} 666666 [{}]()"].
32
+ should.equal ["[]", "{}"]
33
+ end
34
+
35
+ specify "has sensible fallbacks" do
36
+ @unmangler["weird"].should.equal [nil, nil]
37
+ end
38
+ end
39
+
@@ -0,0 +1,214 @@
1
+ # Adapted from flexmock (http://onestepback.org/software/flexmock).
2
+ #
3
+ # Copyright 2006 by Jim Weirich (jweirich@one.net).
4
+ # All rights reserved.
5
+
6
+ # Permission is granted for use, copying, modification, distribution,
7
+ # and distribution of modified versions of this work as long as the
8
+ # above copyright notice is included.
9
+
10
+
11
+ require 'test/spec'
12
+
13
+ begin
14
+ require 'flexmock'
15
+ rescue LoadError
16
+ context "flexmock" do
17
+ specify "can not be found. BAIL OUT!" do
18
+ end
19
+ end
20
+ else
21
+
22
+ context "flexmock" do
23
+ include FlexMock::TestCase
24
+
25
+ setup do
26
+ @mock = FlexMock.new
27
+ end
28
+
29
+ specify "should handle" do
30
+ args = nil
31
+ @mock.mock_handle(:hi) { |a, b| args = [a,b] }
32
+ @mock.hi(1,2)
33
+ args.should.equal [1,2]
34
+ end
35
+
36
+ specify "should handle without a block" do
37
+ lambda {
38
+ @mock.mock_handle(:blip)
39
+ @mock.blip
40
+ }.should.not.raise
41
+ end
42
+
43
+ specify "should handle with a block" do
44
+ called = false
45
+ @mock.mock_handle(:blip) { |block| block.call }
46
+ @mock.blip { called = true }
47
+ called.should.be true
48
+ end
49
+
50
+ specify "should have a return value" do
51
+ @mock.mock_handle(:blip) { 10 }
52
+ @mock.blip.should.equal 10
53
+ end
54
+
55
+ specify "should handle missing methods" do
56
+ ex = lambda {
57
+ @mock.not_defined
58
+ }.should.raise(NoMethodError)
59
+ ex.message.should.match(/not_defined/)
60
+ end
61
+
62
+ specify "should ignore missing methods" do
63
+ lambda {
64
+ @mock.mock_ignore_missing
65
+ @mock.blip
66
+ }.should.not.raise
67
+ end
68
+
69
+ specify "should count correctly" do
70
+ @mock.mock_handle(:blip, 3)
71
+ @mock.blip
72
+ @mock.blip
73
+ @mock.blip
74
+ lambda { @mock.mock_verify }.should.not.raise Test::Unit::AssertionFailedError
75
+ end
76
+
77
+ specify "should raise on bad counts" do
78
+ @mock.mock_handle(:blip, 3)
79
+ @mock.blip
80
+ @mock.blip
81
+ lambda { @mock.mock_verify }.should.raise Test::Unit::AssertionFailedError
82
+ end
83
+
84
+ specify "should handle undetermined counts" do
85
+ lambda {
86
+ FlexMock.use('fs') { |m|
87
+ m.mock_handle(:blip)
88
+ m.blip
89
+ m.blip
90
+ m.blip
91
+ }
92
+ }.should.not.raise Test::Unit::AssertionFailedError
93
+ end
94
+
95
+ specify "should handle zero counts" do
96
+ lambda {
97
+ FlexMock.use { |m|
98
+ m.mock_handle(:blip, 0)
99
+ m.blip
100
+ }
101
+ }.should.raise Test::Unit::AssertionFailedError
102
+ end
103
+
104
+ specify "should have file IO with use" do
105
+ file = FlexMock.use do |m|
106
+ filedata = ["line 1", "line 2"]
107
+ m.mock_handle(:gets, 3) { filedata.shift }
108
+ count_lines(m).should.equal 2
109
+ end
110
+ end
111
+
112
+ def count_lines(stream)
113
+ result = 0
114
+ while line = stream.gets
115
+ result += 1
116
+ end
117
+ result
118
+ end
119
+
120
+ specify "should have use" do
121
+ lambda {
122
+ FlexMock.use do |m|
123
+ m.mock_handle(:blip, 2)
124
+ m.blip
125
+ end
126
+ }.should.raise Test::Unit::AssertionFailedError
127
+ end
128
+
129
+ specify "should handle failures during use" do
130
+ ex = lambda {
131
+ FlexMock.use do |m|
132
+ m.mock_handle(:blip, 2)
133
+ xyz
134
+ end
135
+ }.should.raise NameError
136
+ ex.message.should.match(/undefined local variable or method/)
137
+ end
138
+
139
+ specify "should deal with sequential values" do
140
+ values = [1,4,9,16]
141
+ @mock.mock_handle(:get) { values.shift }
142
+ @mock.get.should.equal 1
143
+ @mock.get.should.equal 4
144
+ @mock.get.should.equal 9
145
+ @mock.get.should.equal 16
146
+ end
147
+
148
+ specify "respond_to? should return false for non handled methods" do
149
+ @mock.should.not.respond_to :blah
150
+ end
151
+
152
+ specify "respond_to? should return true for explicit methods" do
153
+ @mock.mock_handle(:xyz)
154
+ @mock.should.respond_to :xyz
155
+ end
156
+
157
+ specify "respond_to? should return true when ignoring_missing" do
158
+ @mock.mock_ignore_missing
159
+ @mock.should.respond_to :yada
160
+ end
161
+
162
+ specify "respond_to? should return true for missing_methods when should_ignore_missing" do
163
+ @mock.should_ignore_missing
164
+ @mock.should.respond_to :yada
165
+ end
166
+
167
+ specify "should raise error on unknown method proc" do
168
+ lambda {
169
+ @mock.method(:xyzzy)
170
+ }.should.raise NameError
171
+ end
172
+
173
+ specify "should return callable proc on method" do
174
+ got_it = false
175
+ @mock.mock_handle(:xyzzy) { got_it = true }
176
+ method_proc = @mock.method(:xyzzy)
177
+ method_proc.should.not.be.nil
178
+ method_proc.call
179
+ got_it.should.be true
180
+ end
181
+
182
+ specify "should return do nothing proc for missing methods" do
183
+ @mock.mock_ignore_missing
184
+ method_proc = @mock.method(:plugh)
185
+ method_proc.should.not.be.nil
186
+ lambda { method_proc.call }.should.not.raise
187
+ end
188
+ end
189
+
190
+
191
+ class TemperatureSampler
192
+ def initialize(sensor)
193
+ @sensor = sensor
194
+ end
195
+
196
+ def average_temp
197
+ total = (0...3).collect { @sensor.read_temperature }.inject { |i, s| i + s }
198
+ total / 3.0
199
+ end
200
+ end
201
+
202
+ context "flexmock" do
203
+ include FlexMock::TestCase
204
+
205
+ specify "works with test/spec" do
206
+ sensor = flexmock("temp")
207
+ sensor.should_receive(:read_temperature).times(3).and_return(10, 12, 14)
208
+
209
+ sampler = TemperatureSampler.new(sensor)
210
+ sampler.average_temp.should.equal 12
211
+ end
212
+ end
213
+
214
+ end # if not rescue LoadError