nullstyle-test-spec 0.4.1

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