shoulda-context 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ # Stolen straight from ActiveSupport
2
+
3
+ class Proc #:nodoc:
4
+ def bind(object)
5
+ block, time = self, Time.now
6
+ (class << object; self end).class_eval do
7
+ method_name = "__bind_#{time.to_i}_#{time.usec}"
8
+ define_method(method_name, &block)
9
+ method = instance_method(method_name)
10
+ remove_method(method_name)
11
+ method
12
+ end.bind(object)
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ Dir[File.join(File.dirname(__FILE__), 'tasks', '*.rake')].each do |f|
2
+ load f
3
+ end
@@ -0,0 +1,29 @@
1
+ namespace :shoulda do
2
+ desc "List the names of the test methods in a specification like format"
3
+ task :list do
4
+ $LOAD_PATH.unshift("test")
5
+
6
+ require 'test/unit'
7
+ require 'rubygems'
8
+ require 'active_support'
9
+
10
+ # bug in test unit. Set to true to stop from running.
11
+ Test::Unit.run = true
12
+
13
+ test_files = Dir.glob(File.join('test', '**', '*_test.rb'))
14
+ test_files.each do |file|
15
+ load file
16
+ klass = File.basename(file, '.rb').classify
17
+ unless Object.const_defined?(klass.to_s)
18
+ puts "Skipping #{klass} because it doesn't map to a Class"
19
+ next
20
+ end
21
+ klass = klass.constantize
22
+
23
+ puts klass.name.gsub('Test', '')
24
+
25
+ test_methods = klass.instance_methods.grep(/^test/).map {|s| s.gsub(/^test: /, '')}.sort
26
+ test_methods.each {|m| puts " " + m }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ namespace :shoulda do
2
+ # From http://blog.internautdesign.com/2007/11/2/a-yaml_to_shoulda-rake-task
3
+ # David.Lowenfels@gmail.com
4
+ desc "Converts a YAML file (FILE=./path/to/yaml) into a Shoulda skeleton"
5
+ task :from_yaml do
6
+ require 'yaml'
7
+
8
+ def yaml_to_context(hash, indent = 0)
9
+ indent1 = ' ' * indent
10
+ indent2 = ' ' * (indent + 1)
11
+ hash.each_pair do |context, shoulds|
12
+ puts indent1 + "context \"#{context}\" do"
13
+ puts
14
+ shoulds.each do |should|
15
+ yaml_to_context( should, indent + 1 ) and next if should.is_a?( Hash )
16
+ puts indent2 + "should_eventually \"" + should.gsub(/^should +/,'') + "\" do"
17
+ puts indent2 + "end"
18
+ puts
19
+ end
20
+ puts indent1 + "end"
21
+ end
22
+ end
23
+
24
+ puts("Please pass in a FILE argument.") and exit unless ENV['FILE']
25
+
26
+ yaml_to_context( YAML.load_file( ENV['FILE'] ) )
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ module Shoulda
2
+ module Context
3
+ VERSION = '1.0.0.beta1'.freeze
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ if RAILS_ENV == 'test'
2
+ require 'shoulda-context'
3
+ Shoulda.autoload_macros RAILS_ROOT, File.join("vendor", "{plugins,gems}", "*")
4
+ end
@@ -0,0 +1,6 @@
1
+ module CustomMacro
2
+ def custom_macro
3
+ end
4
+ end
5
+ Test::Unit::TestCase.extend(CustomMacro)
6
+
@@ -0,0 +1,6 @@
1
+ module GemMacro
2
+ def gem_macro
3
+ end
4
+ end
5
+ Test::Unit::TestCase.extend(GemMacro)
6
+
@@ -0,0 +1,6 @@
1
+ module PluginMacro
2
+ def plugin_macro
3
+ end
4
+ end
5
+ Test::Unit::TestCase.extend(PluginMacro)
6
+
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+
3
+ class AutoloadMacroTest < Test::Unit::TestCase # :nodoc:
4
+ context "The macro auto-loader" do
5
+ should "load macros from the plugins" do
6
+ assert self.class.respond_to?('plugin_macro')
7
+ end
8
+
9
+ should "load macros from the gems" do
10
+ assert self.class.respond_to?('gem_macro')
11
+ end
12
+
13
+ should "load custom macros from ROOT/test/shoulda_macros" do
14
+ assert self.class.respond_to?('custom_macro')
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,368 @@
1
+ require 'test_helper'
2
+
3
+ class ContextTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ def self.context_macro(&blk)
6
+ context "with a subcontext made by a macro" do
7
+ setup { @context_macro = :foo }
8
+
9
+ merge_block &blk
10
+ end
11
+ end
12
+
13
+ # def self.context_macro(&blk)
14
+ # context "with a subcontext made by a macro" do
15
+ # setup { @context_macro = :foo }
16
+ # yield # <- this doesn't work.
17
+ # end
18
+ # end
19
+
20
+ context "context with setup block" do
21
+ setup do
22
+ @blah = "blah"
23
+ end
24
+
25
+ should "run the setup block" do
26
+ assert_equal "blah", @blah
27
+ end
28
+
29
+ should "have name set right" do
30
+ assert_match(/^test: context with setup block/, self.to_s)
31
+ end
32
+
33
+ context "and a subcontext" do
34
+ setup do
35
+ @blah = "#{@blah} twice"
36
+ end
37
+
38
+ should "be named correctly" do
39
+ assert_match(/^test: context with setup block and a subcontext should be named correctly/, self.to_s)
40
+ end
41
+
42
+ should "run the setup blocks in order" do
43
+ assert_equal @blah, "blah twice"
44
+ end
45
+ end
46
+
47
+ context_macro do
48
+ should "have name set right" do
49
+ assert_match(/^test: context with setup block with a subcontext made by a macro should have name set right/, self.to_s)
50
+ end
51
+
52
+ should "run the setup block of that context macro" do
53
+ assert_equal :foo, @context_macro
54
+ end
55
+
56
+ should "run the setup block of the main context" do
57
+ assert_equal "blah", @blah
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ context "another context with setup block" do
64
+ setup do
65
+ @blah = "foo"
66
+ end
67
+
68
+ should "have @blah == 'foo'" do
69
+ assert_equal "foo", @blah
70
+ end
71
+
72
+ should "have name set right" do
73
+ assert_match(/^test: another context with setup block/, self.to_s)
74
+ end
75
+ end
76
+
77
+ context "context with method definition" do
78
+ setup do
79
+ def hello; "hi"; end
80
+ end
81
+
82
+ should "be able to read that method" do
83
+ assert_equal "hi", hello
84
+ end
85
+
86
+ should "have name set right" do
87
+ assert_match(/^test: context with method definition/, self.to_s)
88
+ end
89
+ end
90
+
91
+ context "another context" do
92
+ should "not define @blah" do
93
+ assert_nil @blah
94
+ end
95
+ end
96
+
97
+ context "context with multiple setups and/or teardowns" do
98
+
99
+ cleanup_count = 0
100
+
101
+ 2.times do |i|
102
+ setup { cleanup_count += 1 }
103
+ teardown { cleanup_count -= 1 }
104
+ end
105
+
106
+ 2.times do |i|
107
+ should "call all setups and all teardowns (check ##{i + 1})" do
108
+ assert_equal 2, cleanup_count
109
+ end
110
+ end
111
+
112
+ context "subcontexts" do
113
+
114
+ 2.times do |i|
115
+ setup { cleanup_count += 1 }
116
+ teardown { cleanup_count -= 1 }
117
+ end
118
+
119
+ 2.times do |i|
120
+ should "also call all setups and all teardowns in parent and subcontext (check ##{i + 1})" do
121
+ assert_equal 4, cleanup_count
122
+ end
123
+ end
124
+
125
+ end
126
+
127
+ end
128
+
129
+ should_eventually "pass, since it's unimplemented" do
130
+ flunk "what?"
131
+ end
132
+
133
+ should_eventually "not require a block when using should_eventually"
134
+ should "pass without a block, as that causes it to piggyback to should_eventually"
135
+
136
+ context "context for testing should piggybacking" do
137
+ should "call should_eventually as we are not passing a block"
138
+ end
139
+
140
+ context "context" do
141
+ context "with nested subcontexts" do
142
+ should_eventually "only print this statement once for a should_eventually"
143
+ end
144
+ end
145
+
146
+ class ::SomeModel; end
147
+
148
+ context "given a test named after a class" do
149
+ setup do
150
+ self.class.stubs(:name).returns("SomeModelTest")
151
+ end
152
+
153
+ should "determine the described type" do
154
+ assert_equal SomeModel, self.class.described_type
155
+ end
156
+
157
+ should "return a new instance of the described type as the subject if none exists" do
158
+ assert_kind_of SomeModel, subject
159
+ end
160
+
161
+ context "with an explicit subject block" do
162
+ setup { @expected = SomeModel.new }
163
+ subject { @expected }
164
+ should "return the result of the block as the subject" do
165
+ assert_equal @expected, subject
166
+ end
167
+
168
+ context "nested context block without a subject block" do
169
+ should "return the result of the parent context's subject block" do
170
+ assert_equal @expected, subject
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ end
177
+
178
+ class ::Some
179
+ class NestedModel; end
180
+ end
181
+
182
+
183
+ class Some::NestedModelTest < Test::Unit::TestCase
184
+ should "determine the described type for a nested model" do
185
+ assert_equal Some::NestedModel, self.class.described_type
186
+ end
187
+ end
188
+
189
+ class ShouldMatcherTest < Test::Unit::TestCase
190
+ class FakeMatcher
191
+ attr_reader :subject
192
+ attr_accessor :fail
193
+
194
+ def description
195
+ "do something"
196
+ end
197
+
198
+ def matches?(subject)
199
+ @subject = subject
200
+ !@fail
201
+ end
202
+
203
+ def failure_message
204
+ "a failure message"
205
+ end
206
+
207
+ def negative_failure_message
208
+ "not a failure message"
209
+ end
210
+ end
211
+
212
+ def run_test
213
+ @test_suite.run(@test_result) { |event, name |}
214
+ end
215
+
216
+ def setup
217
+ @matcher = FakeMatcher.new
218
+ @test_result = Test::Unit::TestResult.new
219
+ class << @test_result
220
+ def failure_messages
221
+ @failures.map { |failure| failure.message }
222
+ end
223
+ end
224
+ end
225
+
226
+ def create_test_suite(&definition)
227
+ test_class = Class.new(Test::Unit::TestCase, &definition)
228
+ test_class.suite
229
+ end
230
+
231
+ def assert_failed_with(message, test_result)
232
+ assert_equal 1, test_result.failure_count
233
+ assert_equal [message], test_result.failure_messages
234
+ end
235
+
236
+ def assert_passed(test_result)
237
+ assert_equal 0, test_result.failure_count
238
+ end
239
+
240
+ def assert_test_named(expected_name, test_suite)
241
+ name = test_suite.tests.map { |test| test.method_name }.first
242
+ assert name.include?(expected_name), "Expected #{name} to include #{expected_name}"
243
+ end
244
+
245
+ def self.should_use_positive_matcher
246
+ should "generate a test using the matcher's description" do
247
+ assert_test_named "should #{@matcher.description}", @test_suite
248
+ end
249
+
250
+ should "pass with a passing matcher" do
251
+ @matcher.fail = false
252
+ run_test
253
+ assert_passed @test_result
254
+ end
255
+
256
+ should "fail with a failing matcher" do
257
+ @matcher.fail = true
258
+ run_test
259
+ assert_failed_with @matcher.failure_message, @test_result
260
+ end
261
+
262
+ should "provide the subject" do
263
+ @matcher.fail = false
264
+ run_test
265
+ assert_equal 'a subject', @matcher.subject
266
+ end
267
+ end
268
+
269
+ def self.should_use_negative_matcher
270
+ should "generate a test using the matcher's description" do
271
+ assert_test_named "should not #{@matcher.description}", @test_suite
272
+ end
273
+
274
+ should "pass with a failing matcher" do
275
+ @matcher.fail = true
276
+ run_test
277
+ assert_passed @test_result
278
+ end
279
+
280
+ should "fail with a passing matcher" do
281
+ @matcher.fail = false
282
+ run_test
283
+ assert_failed_with @matcher.negative_failure_message, @test_result
284
+ end
285
+
286
+ should "provide the subject" do
287
+ @matcher.fail = false
288
+ run_test
289
+ assert_equal 'a subject', @matcher.subject
290
+ end
291
+ end
292
+
293
+ context "a should block with a matcher" do
294
+ setup do
295
+ matcher = @matcher
296
+ @test_suite = create_test_suite do
297
+ subject { 'a subject' }
298
+ should matcher
299
+ end
300
+ end
301
+
302
+ should_use_positive_matcher
303
+ end
304
+
305
+ context "a should block with a matcher within a context" do
306
+ setup do
307
+ matcher = @matcher
308
+ @test_suite = create_test_suite do
309
+ context "in context" do
310
+ subject { 'a subject' }
311
+ should matcher
312
+ end
313
+ end
314
+ end
315
+
316
+ should_use_positive_matcher
317
+ end
318
+
319
+ context "a should_not block with a matcher" do
320
+ setup do
321
+ matcher = @matcher
322
+ @test_suite = create_test_suite do
323
+ subject { 'a subject' }
324
+ should_not matcher
325
+ end
326
+ end
327
+
328
+ should_use_negative_matcher
329
+ end
330
+
331
+ context "a should_not block with a matcher within a context" do
332
+ setup do
333
+ matcher = @matcher
334
+ @test_suite = create_test_suite do
335
+ context "in context" do
336
+ subject { 'a subject' }
337
+ should_not matcher
338
+ end
339
+ end
340
+ end
341
+
342
+ should_use_negative_matcher
343
+ end
344
+ end
345
+
346
+ class Subject; end
347
+
348
+ class SubjectTest < Test::Unit::TestCase
349
+
350
+ def setup
351
+ @expected = Subject.new
352
+ end
353
+
354
+ subject { @expected }
355
+
356
+ should "return a specified subject" do
357
+ assert_equal @expected, subject
358
+ end
359
+ end
360
+
361
+ class SubjectLazinessTest < Test::Unit::TestCase
362
+ subject { Subject.new }
363
+
364
+ should "only build the subject once" do
365
+ assert_equal subject, subject
366
+ end
367
+ end
368
+