dima-exe-factory_girl 1.1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,565 @@
1
+ require(File.join(File.dirname(__FILE__), 'test_helper'))
2
+
3
+ class FactoryTest < Test::Unit::TestCase
4
+
5
+ def self.should_instantiate_class
6
+
7
+ should "instantiate the build class" do
8
+ assert_kind_of @class, @instance
9
+ end
10
+
11
+ should "assign attributes on the instance" do
12
+ assert_equal @first_name, @instance.first_name
13
+ assert_equal @last_name, @instance.last_name
14
+ end
15
+
16
+ should "override attributes using the passed hash" do
17
+ @value = 'Davis'
18
+ @instance = @factory.build(:first_name => @value)
19
+ assert_equal @value, @instance.first_name
20
+ end
21
+
22
+ end
23
+
24
+ context "defining a factory" do
25
+
26
+ setup do
27
+ @name = :user
28
+ @factory = mock('factory')
29
+ @factory.stubs(:factory_name).returns(@name)
30
+ @options = { :class => 'magic' }
31
+ Factory.stubs(:new).returns(@factory)
32
+ end
33
+
34
+ should "create a new factory using the specified name and options" do
35
+ Factory.expects(:new).with(@name, @options).returns(@factory)
36
+ Factory.define(@name, @options) {|f| }
37
+ end
38
+
39
+ should "pass the factory do the block" do
40
+ yielded = nil
41
+ Factory.define(@name) do |y|
42
+ yielded = y
43
+ end
44
+ assert_equal @factory, yielded
45
+ end
46
+
47
+ should "add the factory to the list of factories" do
48
+ Factory.define(@name) {|f| }
49
+ assert_equal Factory.factories[@name],
50
+ @factory,
51
+ "Factories: #{Factory.factories.inspect}"
52
+ end
53
+
54
+ end
55
+
56
+ context "a factory" do
57
+
58
+ setup do
59
+ @name = :user
60
+ @class = User
61
+ @factory = Factory.new(@name)
62
+ end
63
+
64
+ should "have a factory name" do
65
+ assert_equal @name, @factory.factory_name
66
+ end
67
+
68
+ should "have a build class" do
69
+ assert_equal @class, @factory.build_class
70
+ end
71
+
72
+ should "not allow the same attribute to be added twice" do
73
+ assert_raise(Factory::AttributeDefinitionError) do
74
+ 2.times { @factory.add_attribute @name }
75
+ end
76
+ end
77
+
78
+ context "when adding an attribute with a value parameter" do
79
+
80
+ setup do
81
+ @attr = :name
82
+ @value = 'Elvis lives!'
83
+ @factory.add_attribute(@attr, @value)
84
+ end
85
+
86
+ should "include that value in the generated attributes hash" do
87
+ assert_equal @value, @factory.attributes_for[@attr]
88
+ end
89
+
90
+ end
91
+
92
+ should "not allow the same scope to be added twice" do
93
+ assert_raise(Factory::ScopeDefinitionError) do
94
+ 2.times { @factory.add_scope @name, { :a => "a" } }
95
+ end
96
+ end
97
+
98
+ context "when adding an scope with a value parameter" do
99
+
100
+ setup do
101
+ @scope = :scope
102
+ @attr = :name
103
+ @value = 'Elvis lives!'
104
+ @factory.add_scope(@scope, @attr => @value)
105
+ end
106
+
107
+ should "include that value in the generated scopes hash" do
108
+ assert_equal @value, @factory.scope_attributes_for(@scope)[@attr]
109
+ end
110
+
111
+ should "include a scope in the generated scope names" do
112
+ assert @factory.scope_names.include?(@scope)
113
+ end
114
+
115
+ end
116
+
117
+ context "when adding an attribute with a block" do
118
+
119
+ setup do
120
+ @attr = :name
121
+ @attrs = {}
122
+ @proxy = mock('attr-proxy')
123
+ Factory::AttributeProxy.stubs(:new).returns(@proxy)
124
+ end
125
+
126
+ should "not evaluate the block when the attribute is added" do
127
+ @factory.add_attribute(@attr) { flunk }
128
+ end
129
+
130
+ should "evaluate the block when attributes are generated" do
131
+ called = false
132
+ @factory.add_attribute(@attr) do
133
+ called = true
134
+ end
135
+ @factory.attributes_for
136
+ assert called
137
+ end
138
+
139
+ should "use the result of the block as the value of the attribute" do
140
+ value = "Watch out for snakes!"
141
+ @factory.add_attribute(@attr) { value }
142
+ assert_equal value, @factory.attributes_for[@attr]
143
+ end
144
+
145
+ should "build an attribute proxy" do
146
+ Factory::AttributeProxy.expects(:new).with(@factory, @attr, :attributes_for, @attrs)
147
+ @factory.add_attribute(@attr) {}
148
+ @factory.attributes_for
149
+ end
150
+
151
+ should "yield an attribute proxy to the block" do
152
+ yielded = nil
153
+ @factory.add_attribute(@attr) {|y| yielded = y }
154
+ @factory.attributes_for
155
+ assert_equal @proxy, yielded
156
+ end
157
+
158
+ context "when other attributes have previously been defined" do
159
+
160
+ setup do
161
+ @attr = :unimportant
162
+ @attrs = {
163
+ :one => 'whatever',
164
+ :another => 'soup'
165
+ }
166
+ @factory.add_attribute(:one, 'whatever')
167
+ @factory.add_attribute(:another) { 'soup' }
168
+ @factory.add_attribute(@attr) {}
169
+ end
170
+
171
+ should "provide previously set attributes" do
172
+ Factory::AttributeProxy.expects(:new).with(@factory, @attr, :attributes_for, @attrs)
173
+ @factory.attributes_for
174
+ end
175
+
176
+ end
177
+
178
+ end
179
+
180
+ context "when adding an association without a factory name" do
181
+
182
+ setup do
183
+ @factory = Factory.new(:post)
184
+ @name = :user
185
+ @factory.association(@name)
186
+ Post.any_instance.stubs(:user=)
187
+ Factory.stubs(:create)
188
+ end
189
+
190
+ should "add an attribute with the name of the association" do
191
+ assert @factory.attributes_for.key?(@name)
192
+ end
193
+
194
+ should "create a block that builds the association" do
195
+ Factory.expects(:create).with(@name, {})
196
+ @factory.build
197
+ end
198
+
199
+ end
200
+
201
+ context "when adding an association with a factory name" do
202
+
203
+ setup do
204
+ @factory = Factory.new(:post)
205
+ @name = :author
206
+ @factory_name = :user
207
+ @factory.association(@name, :factory => @factory_name)
208
+ Factory.stubs(:create)
209
+ end
210
+
211
+ should "add an attribute with the name of the association" do
212
+ assert @factory.attributes_for.key?(@name)
213
+ end
214
+
215
+ should "create a block that builds the association" do
216
+ Factory.expects(:create).with(@factory_name, {})
217
+ @factory.build
218
+ end
219
+
220
+ end
221
+
222
+ should "add an attribute using the method name when passed an undefined method" do
223
+ @attr = :first_name
224
+ @value = 'Sugar'
225
+ @factory.send(@attr, @value)
226
+ assert_equal @value, @factory.attributes_for[@attr]
227
+ end
228
+
229
+ should "allow attributes to be added with strings as names" do
230
+ @factory.add_attribute('name', 'value')
231
+ assert_equal 'value', @factory.attributes_for[:name]
232
+ end
233
+
234
+ context "when overriding generated attributes with a hash" do
235
+
236
+ setup do
237
+ @attr = :name
238
+ @value = 'The price is right!'
239
+ @hash = { @attr => @value }
240
+ end
241
+
242
+ should "return the overridden value in the generated attributes" do
243
+ @factory.add_attribute(@attr, 'The price is wrong, Bob!')
244
+ assert_equal @value, @factory.attributes_for(@hash)[@attr]
245
+ end
246
+
247
+ should "not call a lazy attribute block for an overridden attribute" do
248
+ @factory.add_attribute(@attr) { flunk }
249
+ @factory.attributes_for(@hash)
250
+ end
251
+
252
+ should "override a symbol parameter with a string parameter" do
253
+ @factory.add_attribute(@attr, 'The price is wrong, Bob!')
254
+ @hash = { @attr.to_s => @value }
255
+ assert_equal @value, @factory.attributes_for(@hash)[@attr]
256
+ end
257
+
258
+ end
259
+
260
+ context "overriding an attribute with an alias" do
261
+
262
+ setup do
263
+ @factory.add_attribute(:test, 'original')
264
+ Factory.alias(/(.*)_alias/, '\1')
265
+ @result = @factory.attributes_for(:test_alias => 'new')
266
+ end
267
+
268
+ should "use the passed in value for the alias" do
269
+ assert_equal 'new', @result[:test_alias]
270
+ end
271
+
272
+ should "discard the predefined value for the attribute" do
273
+ assert_nil @result[:test]
274
+ end
275
+
276
+ end
277
+
278
+ should "guess the build class from the factory name" do
279
+ assert_equal User, @factory.build_class
280
+ end
281
+
282
+ context "when defined with a custom class" do
283
+
284
+ setup do
285
+ @class = User
286
+ @factory = Factory.new(:author, :class => @class)
287
+ end
288
+
289
+ should "use the specified class as the build class" do
290
+ assert_equal @class, @factory.build_class
291
+ end
292
+
293
+ end
294
+
295
+ context "when defined with a class instead of a name" do
296
+
297
+ setup do
298
+ @class = ArgumentError
299
+ @name = :argument_error
300
+ @factory = Factory.new(@class)
301
+ end
302
+
303
+ should "guess the name from the class" do
304
+ assert_equal @name, @factory.factory_name
305
+ end
306
+
307
+ should "use the class as the build class" do
308
+ assert_equal @class, @factory.build_class
309
+ end
310
+
311
+ end
312
+ context "when defined with a custom class name" do
313
+
314
+ setup do
315
+ @class = ArgumentError
316
+ @factory = Factory.new(:author, :class => :argument_error)
317
+ end
318
+
319
+ should "use the specified class as the build class" do
320
+ assert_equal @class, @factory.build_class
321
+ end
322
+
323
+ end
324
+
325
+ context "with some attributes added" do
326
+
327
+ setup do
328
+ @first_name = 'Billy'
329
+ @last_name = 'Idol'
330
+ @email = 'test@something.com'
331
+
332
+ @factory.add_attribute(:first_name, @first_name)
333
+ @factory.add_attribute(:last_name, @last_name)
334
+ @factory.add_attribute(:email, @email)
335
+ end
336
+
337
+ context "when building an instance" do
338
+
339
+ setup do
340
+ @instance = @factory.build
341
+ end
342
+
343
+ should_instantiate_class
344
+
345
+ should "not save the instance" do
346
+ assert @instance.new_record?
347
+ end
348
+
349
+ end
350
+
351
+ context "when creating an instance" do
352
+
353
+ setup do
354
+ @instance = @factory.create
355
+ end
356
+
357
+ should_instantiate_class
358
+
359
+ should "save the instance" do
360
+ assert !@instance.new_record?
361
+ end
362
+
363
+ end
364
+
365
+ should "raise an error for invalid instances" do
366
+ assert_raise(ActiveRecord::RecordInvalid) do
367
+ @factory.create(:first_name => nil)
368
+ end
369
+ end
370
+
371
+ end
372
+
373
+ end
374
+
375
+ context "a factory with a name ending in s" do
376
+
377
+ setup do
378
+ @name = :business
379
+ @class = Business
380
+ @factory = Factory.new(@name)
381
+ end
382
+
383
+ should "have a factory name" do
384
+ assert_equal @name, @factory.factory_name
385
+ end
386
+
387
+ should "have a build class" do
388
+ assert_equal @class, @factory.build_class
389
+ end
390
+
391
+ end
392
+
393
+ context "a factory with a string for a name" do
394
+
395
+ setup do
396
+ @name = :user
397
+ @factory = Factory.new(@name.to_s) {}
398
+ end
399
+
400
+ should "convert the string to a symbol" do
401
+ assert_equal @name, @factory.factory_name
402
+ end
403
+
404
+ end
405
+
406
+ context "a factory defined with a string name" do
407
+
408
+ setup do
409
+ Factory.factories = {}
410
+ @name = :user
411
+ @factory = Factory.define(@name.to_s) {}
412
+ end
413
+
414
+ should "store the factory using a symbol" do
415
+ assert_equal @factory, Factory.factories[@name]
416
+ end
417
+
418
+ end
419
+
420
+ context "Factory class" do
421
+
422
+ setup do
423
+ @name = :user
424
+ @attrs = { :last_name => 'Override' }
425
+ @first_name = 'Johnny'
426
+ @last_name = 'Winter'
427
+ @class = User
428
+
429
+ Factory.define(@name) do |u|
430
+ u.first_name @first_name
431
+ u.last_name { @last_name }
432
+ u.email 'jwinter@guitar.org'
433
+ end
434
+
435
+ @factory = Factory.factories[@name]
436
+ end
437
+
438
+ [:build, :create, :attributes_for].each do |method|
439
+
440
+ should "delegate the #{method} method to the factory instance" do
441
+ @factory.expects(method).with(@attrs)
442
+ Factory.send(method, @name, @attrs)
443
+ end
444
+
445
+ should "raise an ArgumentError when #{method} is called with a nonexistant factory" do
446
+ assert_raise(ArgumentError) { Factory.send(method, :bogus) }
447
+ end
448
+
449
+ should "recognize either 'name' or :name for Factory.#{method}" do
450
+ assert_nothing_raised { Factory.send(method, @name.to_s) }
451
+ assert_nothing_raised { Factory.send(method, @name.to_sym) }
452
+ end
453
+
454
+ end
455
+
456
+ should "call the create method from the top-level Factory() method" do
457
+ @factory.expects(:create).with(@attrs)
458
+ Factory(@name, @attrs)
459
+ end
460
+
461
+ end
462
+
463
+ context "Create the factory with scopes" do
464
+ setup do
465
+ @name = :station
466
+ Factory.define(@name) do |s|
467
+ s.status 0
468
+ s.rotations 0
469
+ s.broadcast :tv
470
+ s.add_scope(:radio, :broadcast => :radio)
471
+ s.add_scope(:approved, :status => 1, :rotations => 1)
472
+ end
473
+ @factory = Factory.factories[@name]
474
+ end
475
+
476
+ should "delegate the scope_attributes_for method to the factory instance" do
477
+ attrs = {:a => "a" }
478
+ @factory.expects(:scope_attributes_for).with(:radio, attrs)
479
+ Factory.send(:scope_attributes_for, @name, :radio, attrs)
480
+ end
481
+
482
+ should "return scope attributes" do
483
+ Factory.send(:scope_attributes_for, @name, {})
484
+ end
485
+
486
+ should "raised a NoMethodError when called with a nonexistant factory" do
487
+ assert_raise(NoMethodError) { Factory.approved(:bogus) }
488
+ end
489
+
490
+ should "assign :approved scope" do
491
+ factory = Factory.approved(@name)
492
+ assert_equal 1, factory.status
493
+ assert_equal 1, factory.rotations
494
+ end
495
+
496
+ should "assign :radio scope" do
497
+ factory = Factory.radio(@name)
498
+ assert_equal :radio, factory.broadcast
499
+ end
500
+
501
+ should "assign :approved and :radio scope" do
502
+ factory = Factory.approved_radio(@name)
503
+ assert_equal :radio, factory.broadcast
504
+ assert_equal 1, factory.status
505
+ assert_equal 1, factory.rotations
506
+ end
507
+ end
508
+
509
+ def self.context_in_directory_with_files(*files)
510
+ context "in a directory with #{files.to_sentence}" do
511
+ setup do
512
+ @pwd = Dir.pwd
513
+ @tmp_dir = File.join(File.dirname(__FILE__), 'tmp')
514
+ FileUtils.mkdir_p @tmp_dir
515
+ Dir.chdir(@tmp_dir)
516
+
517
+ files.each do |file|
518
+ FileUtils.mkdir_p File.dirname(file)
519
+ FileUtils.touch file
520
+ Factory.stubs(:require).with(file)
521
+ end
522
+ end
523
+
524
+ teardown do
525
+ Dir.chdir(@pwd)
526
+ FileUtils.rm_rf(@tmp_dir)
527
+ end
528
+
529
+ yield
530
+ end
531
+ end
532
+
533
+ def self.should_require_definitions_from(file)
534
+ should "load definitions from #{file}" do
535
+ Factory.expects(:require).with(file)
536
+ Factory.find_definitions
537
+ end
538
+ end
539
+
540
+ context_in_directory_with_files 'factories.rb' do
541
+ should_require_definitions_from 'factories.rb'
542
+ end
543
+
544
+ %w(spec test).each do |dir|
545
+ context_in_directory_with_files File.join(dir, 'factories.rb') do
546
+ should_require_definitions_from "#{dir}/factories.rb"
547
+ end
548
+
549
+ context_in_directory_with_files File.join(dir, 'factories', 'post_factory.rb') do
550
+ should_require_definitions_from "#{dir}/factories/post_factory.rb"
551
+ end
552
+
553
+ context_in_directory_with_files File.join(dir, 'factories', 'post_factory.rb'), File.join(dir, 'factories', 'person_factory.rb') do
554
+ should_require_definitions_from "#{dir}/factories/post_factory.rb"
555
+ should_require_definitions_from "#{dir}/factories/person_factory.rb"
556
+ end
557
+
558
+ context_in_directory_with_files File.join(dir, 'factories.rb'), File.join(dir, 'factories', 'post_factory.rb'), File.join(dir, 'factories', 'person_factory.rb') do
559
+ should_require_definitions_from "#{dir}/factories.rb"
560
+ should_require_definitions_from "#{dir}/factories/post_factory.rb"
561
+ should_require_definitions_from "#{dir}/factories/person_factory.rb"
562
+ end
563
+ end
564
+
565
+ end
@@ -0,0 +1,147 @@
1
+ require(File.join(File.dirname(__FILE__), 'test_helper'))
2
+
3
+ class IntegrationTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Factory.define :user, :class => 'user' do |f|
7
+ f.first_name 'Jimi'
8
+ f.last_name 'Hendrix'
9
+ f.admin false
10
+ f.email {|a| "#{a.first_name}.#{a.last_name}@example.com".downcase }
11
+ end
12
+
13
+ Factory.define Post do |f|
14
+ f.name 'Test Post'
15
+ f.association :author, :factory => :user
16
+ end
17
+
18
+ Factory.define :admin, :class => User do |f|
19
+ f.first_name 'Ben'
20
+ f.last_name 'Stein'
21
+ f.admin true
22
+ f.email { Factory.next(:email) }
23
+ end
24
+
25
+ Factory.sequence :email do |n|
26
+ "somebody#{n}@example.com"
27
+ end
28
+ end
29
+
30
+ def teardown
31
+ Factory.factories.clear
32
+ end
33
+
34
+ context "a generated attributes hash" do
35
+
36
+ setup do
37
+ @attrs = Factory.attributes_for(:user, :first_name => 'Bill')
38
+ end
39
+
40
+ should "assign all attributes" do
41
+ assert_equal [:admin, :email, :first_name, :last_name],
42
+ @attrs.keys.sort {|a, b| a.to_s <=> b.to_s }
43
+ end
44
+
45
+ should "correctly assign lazy, dependent attributes" do
46
+ assert_equal "bill.hendrix@example.com", @attrs[:email]
47
+ end
48
+
49
+ should "override attrbutes" do
50
+ assert_equal 'Bill', @attrs[:first_name]
51
+ end
52
+
53
+ should "not assign associations" do
54
+ assert_nil Factory.attributes_for(:post)[:author]
55
+ end
56
+
57
+ end
58
+
59
+ context "a built instance" do
60
+
61
+ setup do
62
+ @instance = Factory.build(:post)
63
+ end
64
+
65
+ should "not be saved" do
66
+ assert @instance.new_record?
67
+ end
68
+
69
+ should "assign associations" do
70
+ assert_kind_of User, @instance.author
71
+ end
72
+
73
+ should "save associations" do
74
+ assert !@instance.author.new_record?
75
+ end
76
+
77
+ should "not assign both an association and its foreign key" do
78
+ assert_equal 1, Factory.build(:post, :author_id => 1).author_id
79
+ end
80
+
81
+ end
82
+
83
+ context "a created instance" do
84
+
85
+ setup do
86
+ @instance = Factory.create('post')
87
+ end
88
+
89
+ should "be saved" do
90
+ assert !@instance.new_record?
91
+ end
92
+
93
+ should "assign associations" do
94
+ assert_kind_of User, @instance.author
95
+ end
96
+
97
+ should "save associations" do
98
+ assert !@instance.author.new_record?
99
+ end
100
+
101
+ end
102
+
103
+ context "an instance generated by a factory with a custom class name" do
104
+
105
+ setup do
106
+ @instance = Factory.create(:admin)
107
+ end
108
+
109
+ should "use the correct class name" do
110
+ assert_kind_of User, @instance
111
+ end
112
+
113
+ should "use the correct factory definition" do
114
+ assert @instance.admin?
115
+ end
116
+
117
+ end
118
+
119
+ context "an attribute generated by a sequence" do
120
+
121
+ setup do
122
+ @email = Factory.attributes_for(:admin)[:email]
123
+ end
124
+
125
+ should "match the correct format" do
126
+ assert_match /^somebody\d+@example\.com$/, @email
127
+ end
128
+
129
+ context "after the attribute has already been generated once" do
130
+
131
+ setup do
132
+ @another_email = Factory.attributes_for(:admin)[:email]
133
+ end
134
+
135
+ should "match the correct format" do
136
+ assert_match /^somebody\d+@example\.com$/, @email
137
+ end
138
+
139
+ should "not be the same as the first generated value" do
140
+ assert_not_equal @email, @another_email
141
+ end
142
+
143
+ end
144
+
145
+ end
146
+
147
+ end