shoulda-context 1.0.0.beta1

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,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
+