ember-data-factory-guy 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 136ffab1eceb2a2640055a30a6699e816b9beb1a
4
- data.tar.gz: f4c9876488f66fa89253fa20d7ada97906268785
3
+ metadata.gz: 473a275179e818f802dbabd583b165881041075d
4
+ data.tar.gz: fa6ee1183d3633585c1a550720b3c4c26a7edc69
5
5
  SHA512:
6
- metadata.gz: b280fe560c1514aff86f6de6914472bbac12cbdf2aea24576783c49b9d4c992327fdb138eaa5f814671f29d5abcc1663d87ea43b5aacde5cabdb6c42c3ddf8af
7
- data.tar.gz: d17f2a63800fc6e5deefec052b195e052f6f1385c0f0aba73dc6d293e271a352f595d13ddd84f4fb3a835e025e2c320131a351a3742a41fe76f3f5c74c8888fd
6
+ metadata.gz: edf890374037db93120303bca6e74f023514526c4b6f53c73f94bf835ef0cf8f907d7bd5666cde33e35f875106c2b497a69e9b9de0140bfcd327a5482ab26cd8
7
+ data.tar.gz: 991e511cd9dcd2a451fb2dcea9cdbf82ba0a76b58f0a291cf8cc3d26e6ad5d53c2a9ca0ce54975f14a4da9090ff3f76cd59b94fd201318714f384a2fe2a68a7e
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Ember Data Factory Guy [![Build Status](https://secure.travis-ci.org/danielspaniel/ember-data-factory-guy.png?branch=master)](http://travis-ci.org/danielspaniel/ember-data-factory-guy)
1
+ # Ember Data Factory Guy
2
2
 
3
3
  ## Using as Gem
4
4
 
@@ -18,15 +18,17 @@ $ bundle install
18
18
 
19
19
  then:
20
20
 
21
- ```javascript
22
- // require the 'ember_data_factory_guy' javascript file in your test helper
21
+ require the 'ember_data_factory_guy' javascript file in your test helper
22
+
23
+ ```
23
24
  //= require ember_data_factory_guy
24
25
  ```
25
26
 
26
27
  ## Using as bower component
27
28
 
28
29
  Add as one of your dependencies in bower.json file:
29
- ```json
30
+
31
+ ```json
30
32
  "dependencies": {
31
33
  "foo-dependency": "latest",
32
34
  "other-foo-dependency": "latest",
@@ -36,18 +38,35 @@ Add as one of your dependencies in bower.json file:
36
38
 
37
39
  then:
38
40
  ```
39
- $ bower install
41
+ $ bower install
40
42
  ```
41
43
 
42
- ## How this works
44
+ ### How this works
45
+
46
+ - Using DS.RestAdapter / DS.ActiveModelAdapter
47
+ - Add record instances to the store
48
+ - Faster, since models can be accessed synchronously
49
+ - Using DS.FixtureAdapter
50
+ - Add fixtures to the store
51
+ - Slower, since models are accessed asynchronously
52
+
53
+
54
+ ##### DS.RestAdapter / DS.ActiveModelAdapter
55
+
56
+ The preferred way to use this project is to use the default adapter for your project,
57
+ which is usually going to be the RESTAdapter/ActiveModelAdapter.
58
+ *In other words, it is NOT recommended to use the DS.FixtureAdapter.*
43
59
 
44
- Add fixtures to the store using the:
60
+ When you call: store.makeFixture('user'), you create model in the store and this method
61
+ returns this model instance
45
62
 
46
- * DS.RestAdapter
47
- * DS.ActiveModelAdapter
48
- * DS.FixtureAdapter
63
+ *Since you are synchronously getting model instances, you can immediately start asking
64
+ for data from the model, and its associations, which is why it is faster to use
65
+ the REST/ActiveModel adapter than the FixtureAdapter*
49
66
 
50
- NOTE: The benefit of using FactoryGuy is that you can run your tests with the
67
+ ##### Using DS.FixtureAdapter
68
+
69
+ The benefit of using FactoryGuy is that you can run your tests with the
51
70
  default adapter that your application's store normally uses. In other words:
52
71
  You do not have to use the DS.FixtureAdapter. But if you do choose to use the Fixture adapter,
53
72
  which does not run any faster, and does not handle associations as elegantly
@@ -57,15 +76,18 @@ Error: Assertion Failed: You looked up the 'projects' relationship on '<User:emb
57
76
 
58
77
  If you do get these types of errors try requiring the factory_guy_has_many.js file
59
78
  ( located in dist dir and vendor dir ) AFTER you require ember-data,
60
- but BEFORE you require your models.
79
+ but BEFORE you require your models.
61
80
 
62
- Let's say you have a few models like these:
63
81
 
64
- ```javascript
82
+ ### Setup
83
+
84
+ In the following examples, assume the models look like this:
65
85
 
86
+ ```javascript
87
+ // standard models
66
88
  User = DS.Model.extend({
67
89
  name: DS.attr('string'),
68
- type: DS.attr('string'),
90
+ style: DS.attr('string'),
69
91
  projects: DS.hasMany('project'),
70
92
  hats: DS.hasMany('hat', {polymorphic: true})
71
93
  });
@@ -74,81 +96,65 @@ Let's say you have a few models like these:
74
96
  title: DS.attr('string'),
75
97
  user: DS.belongsTo('user')
76
98
  });
77
-
99
+
100
+ // polymorphic models
78
101
  Hat = DS.Model.extend({
79
102
  type: DS.attr('string'),
80
103
  user: DS.belongsTo('user')
81
104
  });
82
-
105
+
83
106
  BigHat = Hat.extend();
84
107
  SmallHat = Hat.extend();
85
-
86
108
  ```
87
109
 
88
110
 
89
- ### Defining a Fixture Factory for a Model
111
+ ### Defining Factories
112
+ - A factory has a name and a set of attributes.
113
+ - The name should match the model type name. So, for 'User' model, the name would be 'user'
114
+
115
+
116
+ ##### Standard models
90
117
 
91
118
  ```javascript
92
- ////////////////////////////////////////////
93
- // FactoryGuy definitions for models
94
119
 
95
120
  FactoryGuy.define('user', {
96
- // sequences to be used in attributes definition
97
- sequences: {
98
- userName: function(num) {
99
- return 'User' + num;
100
- }
101
- },
102
-
103
- // default 'user' attributes
121
+ // Put default 'user' attributes in the default section
104
122
  default: {
105
- type: 'normal',
106
- // use the 'userName' sequence for this attribute
107
- name: FactoryGuy.generate('userName')
123
+ style: 'normal',
124
+ name: 'Dude'
108
125
  },
109
- //
110
- // named 'user' type with custom attributes
111
- //
126
+ // Create a named 'user' with custom attributes
112
127
  admin: {
113
- type: 'superuser',
128
+ style: 'super',
114
129
  name: 'Admin'
115
130
  }
116
- //
117
- // using a function for an attribute that refers to other attributes
118
- //
119
- funny_user: {
120
- type: function(f) { return 'funny ' + f.name }
121
- }
122
131
  });
123
132
 
124
- FactoryGuy.define('project', {
133
+ ```
134
+
135
+
136
+ ##### Polymorphic models
137
+
138
+ It is better to define each polymorphic model in it's own typed definition:
139
+
140
+ ```
141
+ FactoryGuy.define('small_hat', {
125
142
  default: {
126
- title: 'Project'
127
- },
128
- //
129
- // declaring inline sequence
130
- //
131
- special_project: {
132
- title: FactoryGuy.generate(function(num) { return 'Project #' + num})
133
- },
134
- //
135
- // define built in belongTo models
136
- //
137
- project_with_user: {
138
- // user model with default attributes
139
- user: {}
140
- },
141
- project_with_dude: {
142
- // user model with custom attributes
143
- user: {name: 'Dude'}
144
- },
145
- project_with_admin: {
146
- // for named association, use the FactoryGuy.belongsTo helper method
147
- user: FactoryGuy.belongsTo('admin')
143
+ type: 'SmallHat'
148
144
  }
145
+ })
146
+
147
+ FactoryGuy.define('big_hat', {
148
+ default: {
149
+ type: 'BigHat'
150
+ }
151
+ })
149
152
 
150
- });
153
+ ```
151
154
 
155
+ rather than doing this:
156
+
157
+ ```
152
158
  FactoryGuy.define('hat', {
153
159
  default: {},
154
160
  small_hat: {
@@ -160,178 +166,341 @@ Let's say you have a few models like these:
160
166
  })
161
167
  ```
162
168
 
169
+ Since there are times that the latter can cause problems when
170
+ the store is looking up the correct model type name
171
+
172
+
173
+ ### Using Factories
174
+ - FactoryGuy.build
175
+ - Builds json
176
+ - store.makeFixture
177
+ - Loads model instance into the store
178
+ - Can override default attributes by passing in a hash
179
+ - Can add attributes with traits ( see traits section )
180
+
181
+ ```javascript
182
+
183
+ // returns json
184
+ var json = FactoryGuy.build('user');
185
+ json // => {id: 1, name: 'Dude', style: 'normal'}
186
+
187
+ // returns a User instance that is loaded into your application's store
188
+ var user = store.makeFixture('user');
189
+ user.toJSON() // => {id: 2, name: 'Dude', style: 'normal'}
190
+
191
+ var json = FactoryGuy.build('admin');
192
+ json // => {id: 3, name: 'Admin', style: 'super'}
193
+
194
+ var user = store.makeFixture('admin');
195
+ user.toJSON() // => {id: 4, name: 'Admin', style: 'super'}
196
+
197
+ ```
198
+
199
+ You can override the default attributes by passing in a hash
200
+
201
+ ```javascript
202
+
203
+ var json = FactoryGuy.build('user', {name: 'Fred'});
204
+ // json.name => 'Fred'
205
+
206
+ ```
207
+
163
208
 
164
- ### Building Json
209
+ ### Sequences
210
+
211
+ - For generating unique attribute values.
212
+ - Can be defined:
213
+ - In the model definition's sequences hash
214
+ - Inline on the attribute
215
+ - Values are generated by calling FactoryGuy.generate
216
+
217
+ ##### Declaring sequences in sequences hash
165
218
 
166
219
  ```javascript
167
- //////////////////////////////////////////////////////////////////
168
- //
169
- // building json with FactoryGuy.build
170
- //
171
220
 
172
- FactoryGuy.build('user') // {id: 1, name: 'User1', type: 'normal'}
173
- // note the sequence used in the name attribute
174
- FactoryGuy.build('user') // {id: 2, name: 'User2', type: 'normal'}
175
- FactoryGuy.build('user', {name: 'bob'}) // {id: 3, name: 'bob', type: 'normal'}
176
- FactoryGuy.build('admin') // {id: 4, name: 'Admin', type: 'superuser'}
177
- // note the type attribute was built from a function which depends on the name
178
- // and the name is still a generated attribute from a sequence function
179
- FactoryGuy.build('funny_user') // {id: 5, name: 'User3', type: 'funny User3'}
221
+ FactoryGuy.define('user', {
222
+ sequences: {
223
+ userName: function(num) {
224
+ return 'User' + num;
225
+ }
226
+ },
227
+
228
+ default: {
229
+ // use the 'userName' sequence for this attribute
230
+ name: FactoryGuy.generate('userName')
231
+ }
232
+ });
233
+
234
+ var json = FactoryGuy.build('user');
235
+ json.name // => 'User1'
236
+
237
+ var user = store.makeFixture('user');
238
+ user.get('name') // => 'User2'
239
+
240
+ ```
180
241
 
181
- // basic project
182
- FactoryGuy.build('project') // {id: 1, title: 'Project'}
242
+ ##### Declaring an inline sequence on attribute
183
243
 
184
- // note the inline sequence used in the title attribute
185
- FactoryGuy.build('special_project') // {id: 2, title: 'Project #1'}
244
+ ```javascript
245
+
246
+ FactoryGuy.define('project', {
247
+ special_project: {
248
+ title: FactoryGuy.generate(function(num) { return 'Project #' + num})
249
+ },
250
+ });
186
251
 
187
- // project with a user
188
- FactoryGuy.build('project_with_user') // {id: 3, title: 'Project', user: {id:6, name: 'User4', type: 'normal'}
189
- // project with user that has custom attributes
190
- FactoryGuy.build('project_with_dude') // {id: 4, title: 'Project', user: {id:7, name: 'Dude', type: 'normal'}
191
- // project with user that has a named user
192
- FactoryGuy.build('project_with_admin') // {id: 3, title: 'Project', user: {id:8, name: 'Admin', type: 'superuser'}
252
+ var json = FactoryGuy.build('special_project');
253
+ json.title // => 'Project 1'
193
254
 
194
- //////////////////////////////////////////////////////////////////
195
- //
196
- // building json with FactoryGuy.buildList
197
- //
255
+ var project = store.makeFixture('special_project');
256
+ project.get('title') // => 'Project 2'
198
257
 
199
- FactoryGuy.buildList('user', 2) // [ {id: 1, name: 'User1', type: 'normal'}, {id: 2, name: 'User2', type: 'normal'} ]
200
258
  ```
201
259
 
260
+ ### Inline Functions
261
+
262
+ - Declare a function for an attribute
263
+ - Can reference other attributes
264
+
265
+ ```javascript
266
+
267
+ FactoryGuy.define('user', {
268
+ // Assume that this definition includes the same sequences and default section
269
+ // from the user definition in: "Declaring sequences in sequences hash" section.
270
+
271
+ funny_user: {
272
+ style: function(f) { return 'funny ' + f.name }
273
+ }
274
+ });
275
+
276
+ var json = FactoryGuy.build('funny_user');
277
+ json.name = 'User1'
278
+ json.style = 'funny User1'
279
+
280
+ var user = store.makeFixture('funny_user');
281
+ user.get('name') // => 'User2'
282
+ user.get('style') // => 'funny User2'
202
283
 
203
- ###Adding records to store
284
+ ```
204
285
 
205
- #####DS.ActiveModelAdapter/DS.RestAdapter
286
+ *Note the style attribute was built from a function which depends on the name
287
+ and the name is a generated attribute from a sequence function*
206
288
 
207
- ###### The Basics
208
289
 
209
- store.makeFixture => creates model in the store and returns model instance
210
- *NOTE* since you are getting a model instances, you can synchronously
211
- start asking for data from the model, and its associations
290
+ ### Traits
212
291
 
292
+ - For grouping attributes together
293
+ - Can use one or more traits in a row
294
+ - The last trait included overrides any values in traits before it
295
+
213
296
  ```javascript
214
- var user = store.makeFixture('user'); // user.toJSON() = {id: 1, name: 'User1', type: 'normal'}
215
- // note that the user name is a sequence
216
- var user = store.makeFixture('user'); // user.toJSON() = {id: 2, name: 'User2', type: 'normal'}
217
- var user = store.makeFixture('funny_user'); // user.toJSON() = {id: 3, name: 'User3', type: 'funny User3'}
218
- var user = store.makeFixture('user', {name: 'bob'}); // user.toJSON() = {id: 4, name: 'bob', type: 'normal'}
219
- var user = store.makeFixture('admin'); // user.toJSON() = {id: 5, name: 'Admin', type: 'superuser'}
220
- var user = store.makeFixture('admin', {name: 'Fred'}); // user.toJSON() = {id: 6, name: 'Fred', type: 'superuser'}
297
+
298
+ FactoryGuy.define('user', {
299
+ traits: {
300
+ big: { name: 'Big Guy' }
301
+ friendly: { style: 'Friendly' }
302
+ }
303
+ });
304
+
305
+ var json = FactoryGuy.build('user', 'big', 'friendly');
306
+ json.name // => 'Big Guy'
307
+ json.style // => 'Friendly'
308
+
309
+ var user = store.makeFixture('user', 'big', 'friendly');
310
+ user.get('name') // => 'Big Guy'
311
+ user.get('style') // => 'Friendly'
312
+
221
313
  ```
222
314
 
223
- ###### Associations
315
+ You can still pass in a hash of options when using traits. This hash of
316
+ attributes will override any trait attributes or default attributes
317
+
318
+ ```javascript
224
319
 
225
- ``` javascript
226
- // setting models on the hasMany association
227
- var project = store.makeFixture('project');
228
- var user = store.makeFixture('user', {projects: [project]});
229
- // OR
230
- // setting a model on the belongsTo association
231
- var user = store.makeFixture('user');
232
- var project = store.makeFixture('project', {user: user});
320
+ var user = store.makeFixture('user', 'big', 'friendly', {name: 'Dave'});
321
+ user.get('name') // => 'Dave'
322
+ user.get('style') // => 'Friendly'
233
323
 
234
- // will get you the same results, since FactoryGuy makes sure the associations
235
- // are created in both directions
236
- // user.get('projects.length') == 1;
237
- // user.get('projects.firstObject.user') == user;
238
324
  ```
239
325
 
240
- ###### Polymorphic hasMany associations
241
326
 
327
+ ### Associations
328
+
329
+ - Can setup belongsTo or hasMany associations in factory definitions
330
+ - As inline attribute definition
331
+ - With traits
332
+ - Can setup belongsTo or hasMany associations manually
333
+ - The inverse association is being set up for you
334
+
335
+ ##### Setup belongsTo associations in Factory Definition
336
+
242
337
  ```javascript
243
- // setting polymorphic models on the (polymorphic) hasMany association
244
- var sh = store.makeFixture('big_hat');
245
- var bh = store.makeFixture('small_hat');
246
- var user = store.makeFixture('user', {hats: [sh, bh]})
247
- // user.get('hats.length') == 2;
248
- // (user.get('hats.firstObject') instanceof BigHat) == true
249
- // (user.get('hats.lastObject') instanceof SmallHat) == true
338
+ // Recall ( from above setup ) that there is a user belongsTo on the Project model
339
+ // Also, assume 'user' factory is same as from 'user' factory definition above in
340
+ // 'Defining Factories' section
341
+ FactoryGuy.define('project', {
250
342
 
251
- // OR
343
+ project_with_user: {
344
+ // create user model with default attributes
345
+ user: {}
346
+ },
347
+ project_with_dude: {
348
+ // create user model with custom attributes
349
+ user: {name: 'Bob'}
350
+ },
351
+ project_with_admin: {
352
+ // create a named user model with the FactoryGuy.belongsTo helper method
353
+ user: FactoryGuy.belongsTo('admin')
354
+ }
355
+ });
356
+
357
+ var json = FactoryGuy.build('project_with_user');
358
+ json.user // => {id:1, name: 'Dude', style: 'normal'}
252
359
 
253
- // setting belongTo association on polymorphic model
254
- var user = store.makeFixture('user');
255
- store.makeFixture('big_hat', {user: user});
256
- store.makeFixture('small_hat', {user: user});
360
+ var json = FactoryGuy.build('project_with_dude');
361
+ json.user // => {id:1, name: 'Dude', style: 'normal'}
257
362
 
258
- // will get you the same results, since FactoryGuy makes sure the associations
259
- // are created in both directions, even for polymorphic associations.
260
- // user.get('hats.length') == 2;
261
- // (user.get('hats.firstObject') instanceof BigHat) == true
262
- // (user.get('hats.lastObject') instanceof SmallHat) == true
363
+ var project = store.makeFixture('project_with_admin');
364
+ project.get('user.name') // => 'Admin'
365
+ project.get('user.style') // => 'super'
263
366
 
264
367
  ```
265
368
 
266
- ###### Create lists
369
+ *You could also accomplish the above with traits:*
267
370
 
268
371
  ```javascript
269
- var users = store.makeList('user', 3);
372
+
373
+ FactoryGuy.define('project', {
374
+ traits: {
375
+ with_user: { user: {} },
376
+ with_admin: { user: FactoryGuy.belongsTo('admin') }
377
+ }
378
+ });
379
+
380
+ var user = store.makeFixture('project', 'with_user');
381
+ project.get('user').toJSON() // => {id:1, name: 'Dude', style: 'normal'}
382
+
270
383
  ```
271
384
 
272
- #####DS.Fixture adapter
273
385
 
274
- store.makeFixture => creates model in the store and returns json
386
+ ##### Setup belongsTo associations manually
275
387
 
276
- Technically when you call store.makeFixture with a store using the DS.FixtureAdapter,
277
- the fixture is actually added to the models FIXTURE array. It just seems to be added
278
- to the store because when you call store.find to get that record, the adapter looks
279
- in that FIXTURE array to find it and then puts it in the store.
388
+ ```javascript
389
+ var user = store.makeFixture('user');
390
+ var project = store.makeFixture('project', {user: user});
391
+
392
+ project.get('user').toJSON() // => {id:1, name: 'Dude', style: 'normal'}
393
+ ```
394
+
395
+ *Note that though you are setting the 'user' belongsTo association on a project,
396
+ the reverse user hasMany 'projects' association is being setup for you on the user
397
+ ( for both manual and factory defined belongsTo associations ) as well*
280
398
 
281
399
  ```javascript
400
+ user.get('projects.length') // => 1
401
+ ```
282
402
 
283
- store.makeFixture('user'); // user.FIXTURES = [{id: 1, name: 'User1', type: 'normal'}]
284
- store.makeFixture('user', {name: 'bob'}); // user.FIXTURES = [{id: 2, name: 'bob', type: 'normal'}]
285
- store.makeFixture('admin'); // user.FIXTURES = [{id: 3, name: 'Admin', type: 'superuser'}]
286
- store.makeFixture('admin', {name: 'Fred'}); // user.FIXTURES = [{id: 4, name: 'Fred', type: 'superuser'}]
287
403
 
288
404
 
289
- // Use store.find to get the model instance ( Remember this is the Fixture adapter, if
290
- // you use the ActiveModelAdapter or RESTAdapter the record is returned so you don't
291
- // have to then go and find it )
292
- var userJson = store.makeFixture('user');
293
- store.find('user', userJson.id).then(function(user) {
294
- user.toJSON() ( pretty much equals ) userJson;
295
- });
405
+ ##### Setup hasMany associations in Factory Definition
296
406
 
297
- // and to setup associations ...
298
- var projectJson = store.makeFixture('project');
299
- var userJson = store.makeFixture('user', {projects: [projectJson.id]});
300
- // OR
301
- var userJson = store.makeFixture('user');
302
- var projectJson = store.makeFixture('project', {user: userJson.id});
407
+ ``` javascript
408
+ FactoryGuy.define('user', {
409
+ user_with_projects: { FactoryGuy.hasMany('project', 2) }
410
+ });
411
+
412
+ var user = store.makeFixture('user_with_projects');
413
+ user.get('projects.length') // => 2
414
+
415
+ ```
303
416
 
304
- // will give you the same result, but with fixture adapter all associations
305
- // are treated as async ( by factory_guy_has_many.js fix ), so it's
306
- // a bit clunky to get this associated data. When using DS.FixtureAdapter
307
- // in view specs though, this clunk is dealt with for you. But remember,
308
- // you don't have to use the Fixture adapter.
309
- store.find('user', 1).then(function(user) {
310
- user.toJSON() (pretty much equals) userJson;
311
- user.get('projects').then(function(projects) {
312
- projects.length == 1;
417
+ *You could also accomplish the above with traits:*
418
+
419
+ ```javascript
420
+
421
+ FactoryGuy.define('project', {
422
+ traits: {
423
+ with_projects: {
424
+ projects: FactoryGuy.hasMany('project', 2)
425
+ }
426
+ }
313
427
  });
314
- });
428
+
429
+ var user = store.makeFixture('user', 'with_projects');
430
+ user.get('projects.length') // => 2
431
+
432
+ ```
433
+
434
+ ##### Setup hasMany associations manually
315
435
 
316
- // and for lists
317
- store.makeList('user', 2, {projects: [project.id]});
436
+ ```javascript
437
+ var project1 = store.makeFixture('project');
438
+ var project2 = store.makeFixture('project');
439
+ var user = store.makeFixture('user', {projects: [project1,project2]});
440
+ user.get('projects.length') // => 2
441
+
442
+ // or
443
+ var projects = store.makeList('project', 2);
444
+ var user = store.makeFixture('user', {projects: projects});
445
+ user.get('projects.length') // => 2
446
+
447
+ ```
448
+
449
+ *Note that though you are setting the 'projects' hasMany association on a user,
450
+ the reverse 'user' belongsTo association is being setup for you on the project
451
+ ( for both manual and factory defined hasMany associations ) as well*
452
+
453
+ ```javascript
454
+ projects.get('firstObject.user') // => user
318
455
  ```
319
456
 
320
- ###Testing models, controllers, views
321
457
 
458
+ #### Building many models at once
322
459
 
323
- This section assumes you are testing the ( controllers and views ) in isolation.
460
+ - FactoryGuy.buildList
461
+ - Builds an array of one or more json objects
462
+ - store.makeList
463
+ - Loads one or more instances into store
324
464
 
325
- The code bundled in dist/ember-data-factory-guy.js includes a mixin named FactoryGuyTestMixin which
326
- can be used in your tests to make it easier to access the store and make fixtures.
465
+
466
+ ##### Building json array
327
467
 
328
468
  ```javascript
469
+ var json = FactoryGuy.buildList('user', 2)
470
+ json.length // => 2
471
+ json[0] // => {id: 1, name: 'User1', style: 'normal'}
472
+ json[1] // => {id: 2, name: 'User2', style: 'normal'}
329
473
 
330
- // Let's say you have a helper for your tests named TestHelper declared in a file.
474
+ ```
331
475
 
332
- TestHelper = Ember.Object.createWithMixins(FactoryGuyTestMixin);
476
+ ##### Building model instances
477
+
478
+ ```javascript
479
+ var users = store.makeList('user', 2)
480
+ users.get('length') // => 2
481
+ users[0].toJSON() // => {id: 3, name: 'User3', style: 'normal'}
482
+ users[1].toJSON() // => {id: 4, name: 'User4', style: 'normal'}
483
+
484
+ ```
485
+
486
+
487
+ ###Testing models, controllers, views
488
+
489
+ - Testing the models, controllers and views in isolation
490
+ - Use FactoryGuyTestMixin to help with testing
333
491
 
334
492
 
493
+ ##### Using FactoryGuyTestMixin
494
+
495
+ - Using FactoryGuyTestMixin helper methods:
496
+ - make
497
+ - teardown
498
+
499
+ ```javascript
500
+
501
+ // Create a helper class using FactoryGuyTestMixin.
502
+ TestHelper = Ember.Object.createWithMixins(FactoryGuyTestMixin);
503
+
335
504
  // Then in your tests you can use it like so:
336
505
 
337
506
  var testHelper, store;
@@ -350,16 +519,6 @@ module('User Model', {
350
519
  // to be even more concise in tests you could add this method to your tests
351
520
  var make = function(name, opts) { return testHelper.make(name, opts); }
352
521
 
353
-
354
- test("make a user using fixture adapter", function() {
355
- // useFixtureAdapter method is built into FactoryGuyTestMixin, and usually
356
- // this would be called in the setup function
357
- testHelper.useFixtureAdapter();
358
- var json = make('user');
359
- equal(User.FIXTURES.length, 1);
360
- equal(User.FIXTURES[0], json);
361
- });
362
-
363
522
  // assuming your default adapter is ActiveModelAdapter or RESTAdapter
364
523
  test("make a user using your applications default adapter", function() {
365
524
  var user = make('user');
@@ -373,6 +532,16 @@ test("make a user using your applications default adapter", function() {
373
532
 
374
533
  ###Integration Tests
375
534
 
535
+
536
+ ##### Using FactoryGuyTestMixin
537
+
538
+ - Uses mockjax
539
+ - Has helper methods
540
+ - handleFind
541
+ - handleCreate
542
+ - handleUpdate
543
+ - handleDelete
544
+
376
545
  Since it is recommended to use your normal adapter ( which is usually a subclass of RESTAdapter, )
377
546
  FactoryGuyTestMixin assumes you will want to use that adapter to do your integration tests.
378
547
 
@@ -453,3 +622,48 @@ test("Creates new project", function() {
453
622
  ```
454
623
 
455
624
 
625
+ ### Using DS.Fixture adapter
626
+
627
+ - Not recommended
628
+ - store.makeFixture ... creates model in the store and returns json
629
+
630
+ Technically when you call store.makeFixture with a store using the DS.FixtureAdapter,
631
+ the fixture is actually added to the models FIXTURE array. It just seems to be added
632
+ to the store because when you call store.find to get that record, the adapter looks
633
+ in that FIXTURE array to find it and then puts it in the store.
634
+
635
+ ```javascript
636
+
637
+
638
+ store.makeFixture('user'); // user.FIXTURES = [{id: 1, name: 'User1', style: 'normal'}]
639
+ store.makeFixture('user', {name: 'bob'}); // user.FIXTURES = [{id: 2, name: 'bob', style: 'normal'}]
640
+ store.makeFixture('admin'); // user.FIXTURES = [{id: 3, name: 'Admin', style: 'super'}]
641
+ store.makeFixture('admin', {name: 'Fred'}); // user.FIXTURES = [{id: 4, name: 'Fred', style: 'super'}]
642
+
643
+
644
+ // Use store.find to get the model instance ( Remember this is the Fixture adapter, if
645
+ // you use the ActiveModelAdapter or RESTAdapter the record is returned so you don't
646
+ // have to then go and find it )
647
+ var userJson = store.makeFixture('user');
648
+ store.find('user', userJson.id).then(function(user) {
649
+ user.toJSON() ( pretty much equals ) userJson;
650
+ });
651
+
652
+ // and to setup associations ...
653
+ var projectJson = store.makeFixture('project');
654
+ var userJson = store.makeFixture('user', {projects: [projectJson.id]});
655
+ // OR
656
+ var userJson = store.makeFixture('user');
657
+ var projectJson = store.makeFixture('project', {user: userJson.id});
658
+
659
+ // will give you the same result, but with fixture adapter all associations
660
+ // are treated as async ( by factory_guy_has_many.js fix ), so it's
661
+ // a bit clunky to get this associated data. When using DS.FixtureAdapter
662
+ // in view specs though, this clunk is dealt with for you. But remember,
663
+ // you DON'T have to use the Fixture adapter.
664
+ store.find('user', 1).then(function(user) {
665
+ user.toJSON() (pretty much equals) userJson;
666
+ user.get('projects').then(function(projects) {
667
+ projects.length == 1;
668
+ });
669
+ });
data/bower.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-data-factory-guy",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "authors": [
5
5
  "Daniel Sudol <dansudol@yahoo.com>",
6
6
  "Opak Alex <opak.alexandr@gmail.com>"
@@ -438,6 +438,7 @@ FactoryGuy = {
438
438
  }
439
439
  },
440
440
 
441
+
441
442
  /**
442
443
  Push fixture to model's FIXTURES array.
443
444
  Used when store's adapter is a DS.FixtureAdapter.
@@ -821,11 +822,13 @@ DS.FixtureAdapter.reopen({
821
822
  if (belongsToRecord && belongsToRecord.get('length') > 0) {
822
823
  var hasManyName = store.findRelationshipName(
823
824
  'hasMany',
824
- belongsToRecord.constructor,
825
+ belongsToRecord.get('firstObject').constructor,
825
826
  record
826
827
  );
827
828
  belongsToRecord.forEach(function (child){
828
- child.get(hasManyName).addObject(record)
829
+ Em.RSVP.resolve(child.get(hasManyName)).then( function(value) {
830
+ value.addObjects(record);
831
+ });
829
832
  });
830
833
  }
831
834
  });
@@ -1 +1 @@
1
- Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};function MissingSequenceError(message){this.toString=function(){return message}}ModelDefinition=function(model,config){var sequences={};var traits={};var defaultAttributes={};var namedModels={};var modelId=1;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.merge=function(config){};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts,traitArgs){var traitsObj={};traitArgs.forEach(function(trait){$.extend(traitsObj,traits[trait])});var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,traitsObj,opts);for(attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}if(!fixture.id){fixture.id=modelId++}return fixture};this.buildList=function(name,number,traits,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts,traits))}return arr};this.reset=function(){modelId=1;for(name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseTraits=function(object){if(!object){return}traits=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(Ember.typeOf(sequenceFn)!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseTraits(config.traits);delete config.traits;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},generate:function(nameOrFunction){var sortaRandomName=Math.floor((1+Math.random())*65536).toString(16)+Date.now();return function(){if(Em.typeOf(nameOrFunction)=="function"){return this.generate(sortaRandomName,nameOrFunction)}else{return this.generate(nameOrFunction)}}},belongsTo:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},hasMany:function(fixtureName,number,opts){return function(){return FactoryGuy.buildList(fixtureName,number,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];if(definition.matchesName(name)){return definition}}},build:function(){var args=Array.prototype.slice.call(arguments);var opts={};var name=args.shift();if(!name){throw new Error("Build needs a factory name to build")}if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.build(name,opts,traits)},buildList:function(){var args=Array.prototype.slice.call(arguments);var name=args.shift();var number=args.shift();if(!name||!number){throw new Error("buildList needs a name and a number ( at least ) to build with")}var opts={};if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.buildList(name,number,traits,opts)},resetModels:function(store){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){}}},pushFixture:function(modelClass,fixture){if(!modelClass["FIXTURES"]){modelClass["FIXTURES"]=[]}modelClass["FIXTURES"].push(fixture);return fixture},clear:function(opts){if(!opts){this.modelDefinitions={}}}};DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(name,options){var store=this;var modelName=FactoryGuy.lookupModelForFixtureName(name);var fixture=FactoryGuy.build(name,options);var modelType=store.modelFor(modelName);if(this.usingFixtureAdapter()){this.setAssociationsForFixtureAdapter(modelType,modelName,fixture);return FactoryGuy.pushFixture(modelType,fixture)}else{var store=this;var model;Em.run(function(){store.findEmbeddedBelongsToAssociationsForRESTAdapter(modelType,fixture);if(fixture.type){modelName=fixture.type.underscore();modelType=store.modelFor(modelName)}model=store.push(modelName,fixture);store.setAssociationsForRESTAdapter(modelType,modelName,model)});return model}},makeList:function(name,number,options){var arr=[];for(var i=0;i<number;i++){arr.push(this.makeFixture(name,options))}return arr},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"){if(fixture[relationship.key]){fixture[relationship.key].forEach(function(id){var hasManyfixtures=adapter.fixturesForType(relationship.type);var fixture=adapter.findFixtureById(hasManyfixtures,id);fixture[modelName]=fixture.id})}}if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(belongsToRecord){if(typeof belongsToRecord=="object"){FactoryGuy.pushFixture(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord.id}var hasManyName=self.findHasManyRelationshipNameForFixtureAdapter(relationship.type,relationship.parentType);var belongsToFixtures=adapter.fixturesForType(relationship.type);var belongsTofixture=adapter.findFixtureById(belongsToFixtures,fixture[relationship.key]);if(!belongsTofixture[hasManyName]){belongsTofixture[hasManyName]=[]}belongsTofixture[hasManyName].push(fixture.id)}}})},findEmbeddedBelongsToAssociationsForRESTAdapter:function(modelType,fixture){var store=this;Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(Ember.typeOf(belongsToRecord)=="object"){belongsToRecord=store.push(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord}}if(relationship.kind=="hasMany"){var hasManyRecords=fixture[relationship.key];if(Ember.typeOf(hasManyRecords)=="array"&&Ember.typeOf(hasManyRecords[0])=="object"){var records=Em.A();hasManyRecords.forEach(function(record){var record=store.push(relationship.type,record);records.push(record)});fixture[relationship.key]=records}}})},setAssociationsForRESTAdapter:function(modelType,modelName,model){var self=this;Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"){var children=model.get(name)||[];children.forEach(function(child){var belongsToName=self.findRelationshipName("belongsTo",child.constructor,model);var hasManyName=self.findRelationshipName("hasMany",child.constructor,model);var inverseName=relationship.options&&relationship.options.inverse;if(belongsToName){child.set(belongsToName||inverseName,model)}else if(hasManyName){relation=child.get(hasManyName||inverseName)||[];relation.pushObject(model)}})}if(relationship.kind=="belongsTo"){var belongsToRecord=model.get(name);if(belongsToRecord){var setAssociations=function(){var hasManyName=self.findRelationshipName("hasMany",belongsToRecord.constructor,model);if(hasManyName){belongsToRecord.get(hasManyName).addObject(model);return}var oneToOneName=self.findRelationshipName("belongsTo",belongsToRecord.constructor,model);if(oneToOneName&&!(belongsToRecord.constructor==model.constructor)){belongsToRecord.set(oneToOneName,model)}};if(belongsToRecord.then){belongsToRecord.then(function(record){belongsToRecord=record;setAssociations()})}else{setAssociations()}}}})},findRelationshipName:function(kind,belongToModelType,childModel){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind==kind&&childModel instanceof relationship.type){relationshipName=relationship.key}});return relationshipName},findHasManyRelationshipNameForFixtureAdapter:function(belongToModelType,childModelType){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"&&childModelType==relationship.type){relationshipName=relationship.key}});return relationshipName},pushPayload:function(type,payload){if(this.usingFixtureAdapter()){var model=this.modelFor(modelName);FactoryGuy.pushFixture(model,payload)}else{this._super(type,payload)}}});DS.FixtureAdapter.reopen({createRecord:function(store,type,record){var promise=this._super(store,type,record);promise.then(function(){Em.RSVP.Promise.resolve(Ember.get(type,"relationshipNames")).then(function(relationShips){if(relationShips.belongsTo){relationShips.belongsTo.forEach(function(relationship){Em.RSVP.Promise.resolve(record.get(relationship)).then(function(belongsToRecord){if(belongsToRecord){var hasManyName=store.findRelationshipName("hasMany",belongsToRecord.constructor,record);if(hasManyName){Ember.RSVP.resolve(belongsToRecord.get(hasManyName)).then(function(relationship){relationship.addObject(record)})}}})})}if(relationShips.hasMany){relationShips.hasMany.forEach(function(relationship){Em.RSVP.Promise.resolve(record.get(relationship)).then(function(belongsToRecord){if(belongsToRecord&&belongsToRecord.get("length")>0){var hasManyName=store.findRelationshipName("hasMany",belongsToRecord.constructor,record);belongsToRecord.forEach(function(child){child.get(hasManyName).addObject(record)})}})})}})});return promise}});FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var type=store.modelFor(type);var serializer=store.serializerFor(type.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(name,opts){return this.getStore().makeFixture(name,opts)},getStore:function(){return this.get("container").lookup("store:main")},pushPayload:function(type,hash){return this.getStore().pushPayload(type,hash)},pushRecord:function(type,hash){return this.getStore().push(type,hash)},stubEndpointForHttpRequest:function(url,json,options){options=options||{};var request={url:url,dataType:"json",responseText:json,type:options.type||"GET",status:options.status||200};if(options.data){request.data=options.data}$.mockjax(request)},buildAjaxHttpResponse:function(name,opts){var fixture=FactoryGuy.build(name,opts);var modelName=FactoryGuy.lookupModelForFixtureName(name);if(this.usingActiveModelSerializer(modelName)){this.toSnakeCase(fixture)}var hash={};hash[modelName]=fixture;return hash},toSnakeCase:function(fixture){for(key in fixture){if(key!=Em.String.decamelize(key)){var value=fixture[key];delete fixture[key];fixture[Em.String.decamelize(key)]=value}}},buildURL:function(type,id){return this.getStore().adapterFor("application").buildURL(type,id)},handleFind:function(name,opts,status){var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxHttpResponse(name,opts);var id=responseJson[modelName].id;var url=this.buildURL(modelName,id);this.stubEndpointForHttpRequest(url,responseJson,{type:"GET",status:status||200});return responseJson},handleCreate:function(name,opts,status){var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxHttpResponse(name,opts);var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson,{type:"POST",status:status||200});return responseJson},handleUpdate:function(type,id,status){this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"PUT",status:status||200})},handleDelete:function(type,id,status){this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"DELETE",status:status||200})},teardown:function(){FactoryGuy.resetModels(this.getStore())}});
1
+ Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};function MissingSequenceError(message){this.toString=function(){return message}}ModelDefinition=function(model,config){var sequences={};var traits={};var defaultAttributes={};var namedModels={};var modelId=1;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.merge=function(config){};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts,traitArgs){var traitsObj={};traitArgs.forEach(function(trait){$.extend(traitsObj,traits[trait])});var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,traitsObj,opts);for(attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}if(!fixture.id){fixture.id=modelId++}return fixture};this.buildList=function(name,number,traits,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts,traits))}return arr};this.reset=function(){modelId=1;for(name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseTraits=function(object){if(!object){return}traits=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(Ember.typeOf(sequenceFn)!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseTraits(config.traits);delete config.traits;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},generate:function(nameOrFunction){var sortaRandomName=Math.floor((1+Math.random())*65536).toString(16)+Date.now();return function(){if(Em.typeOf(nameOrFunction)=="function"){return this.generate(sortaRandomName,nameOrFunction)}else{return this.generate(nameOrFunction)}}},belongsTo:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},association:function(fixtureName,opts){console.log("DEPRECATION Warning: use FactoryGuy.belongsTo instead");return this.belongsTo(fixtureName,opts)},hasMany:function(fixtureName,number,opts){return function(){return FactoryGuy.buildList(fixtureName,number,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];if(definition.matchesName(name)){return definition}}},build:function(){var args=Array.prototype.slice.call(arguments);var opts={};var name=args.shift();if(!name){throw new Error("Build needs a factory name to build")}if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.build(name,opts,traits)},buildList:function(){var args=Array.prototype.slice.call(arguments);var name=args.shift();var number=args.shift();if(!name||!number){throw new Error("buildList needs a name and a number ( at least ) to build with")}var opts={};if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.buildList(name,number,traits,opts)},resetModels:function(store){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){}}},pushFixture:function(modelClass,fixture){if(!modelClass["FIXTURES"]){modelClass["FIXTURES"]=[]}modelClass["FIXTURES"].push(fixture);return fixture},clear:function(opts){if(!opts){this.modelDefinitions={}}}};DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(name,options){var store=this;var modelName=FactoryGuy.lookupModelForFixtureName(name);var fixture=FactoryGuy.build(name,options);var modelType=store.modelFor(modelName);if(this.usingFixtureAdapter()){this.setAssociationsForFixtureAdapter(modelType,modelName,fixture);return FactoryGuy.pushFixture(modelType,fixture)}else{var store=this;var model;Em.run(function(){store.findEmbeddedBelongsToAssociationsForRESTAdapter(modelType,fixture);if(fixture.type){modelName=fixture.type.underscore();modelType=store.modelFor(modelName)}model=store.push(modelName,fixture);store.setAssociationsForRESTAdapter(modelType,modelName,model)});return model}},makeList:function(name,number,options){var arr=[];for(var i=0;i<number;i++){arr.push(this.makeFixture(name,options))}return arr},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"){if(fixture[relationship.key]){fixture[relationship.key].forEach(function(id){var hasManyfixtures=adapter.fixturesForType(relationship.type);var fixture=adapter.findFixtureById(hasManyfixtures,id);fixture[modelName]=fixture.id})}}if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(belongsToRecord){if(typeof belongsToRecord=="object"){FactoryGuy.pushFixture(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord.id}var hasManyName=self.findHasManyRelationshipNameForFixtureAdapter(relationship.type,relationship.parentType);var belongsToFixtures=adapter.fixturesForType(relationship.type);var belongsTofixture=adapter.findFixtureById(belongsToFixtures,fixture[relationship.key]);if(!belongsTofixture[hasManyName]){belongsTofixture[hasManyName]=[]}belongsTofixture[hasManyName].push(fixture.id)}}})},findEmbeddedBelongsToAssociationsForRESTAdapter:function(modelType,fixture){var store=this;Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(Ember.typeOf(belongsToRecord)=="object"){belongsToRecord=store.push(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord}}if(relationship.kind=="hasMany"){var hasManyRecords=fixture[relationship.key];if(Ember.typeOf(hasManyRecords)=="array"&&Ember.typeOf(hasManyRecords[0])=="object"){var records=Em.A();hasManyRecords.forEach(function(record){var record=store.push(relationship.type,record);records.push(record)});fixture[relationship.key]=records}}})},setAssociationsForRESTAdapter:function(modelType,modelName,model){var self=this;Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"){var children=model.get(name)||[];children.forEach(function(child){var belongsToName=self.findRelationshipName("belongsTo",child.constructor,model);var hasManyName=self.findRelationshipName("hasMany",child.constructor,model);var inverseName=relationship.options&&relationship.options.inverse;if(belongsToName){child.set(belongsToName||inverseName,model)}else if(hasManyName){relation=child.get(hasManyName||inverseName)||[];relation.pushObject(model)}})}if(relationship.kind=="belongsTo"){var belongsToRecord=model.get(name);if(belongsToRecord){var setAssociations=function(){var hasManyName=self.findRelationshipName("hasMany",belongsToRecord.constructor,model);if(hasManyName){belongsToRecord.get(hasManyName).addObject(model);return}var oneToOneName=self.findRelationshipName("belongsTo",belongsToRecord.constructor,model);if(oneToOneName&&!(belongsToRecord.constructor==model.constructor)){belongsToRecord.set(oneToOneName,model)}};if(belongsToRecord.then){belongsToRecord.then(function(record){belongsToRecord=record;setAssociations()})}else{setAssociations()}}}})},findRelationshipName:function(kind,belongToModelType,childModel){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind==kind&&childModel instanceof relationship.type){relationshipName=relationship.key}});return relationshipName},findHasManyRelationshipNameForFixtureAdapter:function(belongToModelType,childModelType){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"&&childModelType==relationship.type){relationshipName=relationship.key}});return relationshipName},pushPayload:function(type,payload){if(this.usingFixtureAdapter()){var model=this.modelFor(modelName);FactoryGuy.pushFixture(model,payload)}else{this._super(type,payload)}}});DS.FixtureAdapter.reopen({createRecord:function(store,type,record){var promise=this._super(store,type,record);promise.then(function(){Em.RSVP.Promise.resolve(Ember.get(type,"relationshipNames")).then(function(relationShips){if(relationShips.belongsTo){relationShips.belongsTo.forEach(function(relationship){Em.RSVP.Promise.resolve(record.get(relationship)).then(function(belongsToRecord){if(belongsToRecord){var hasManyName=store.findRelationshipName("hasMany",belongsToRecord.constructor,record);if(hasManyName){Ember.RSVP.resolve(belongsToRecord.get(hasManyName)).then(function(relationship){relationship.addObject(record)})}}})})}if(relationShips.hasMany){relationShips.hasMany.forEach(function(relationship){Em.RSVP.Promise.resolve(record.get(relationship)).then(function(belongsToRecord){if(belongsToRecord&&belongsToRecord.get("length")>0){var hasManyName=store.findRelationshipName("hasMany",belongsToRecord.get("firstObject").constructor,record);belongsToRecord.forEach(function(child){Em.RSVP.resolve(child.get(hasManyName)).then(function(value){value.addObjects(record)})})}})})}})});return promise}});FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var type=store.modelFor(type);var serializer=store.serializerFor(type.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(name,opts){return this.getStore().makeFixture(name,opts)},getStore:function(){return this.get("container").lookup("store:main")},pushPayload:function(type,hash){return this.getStore().pushPayload(type,hash)},pushRecord:function(type,hash){return this.getStore().push(type,hash)},stubEndpointForHttpRequest:function(url,json,options){options=options||{};var request={url:url,dataType:"json",responseText:json,type:options.type||"GET",status:options.status||200};if(options.data){request.data=options.data}$.mockjax(request)},buildAjaxHttpResponse:function(name,opts){var fixture=FactoryGuy.build(name,opts);var modelName=FactoryGuy.lookupModelForFixtureName(name);if(this.usingActiveModelSerializer(modelName)){this.toSnakeCase(fixture)}var hash={};hash[modelName]=fixture;return hash},toSnakeCase:function(fixture){for(key in fixture){if(key!=Em.String.decamelize(key)){var value=fixture[key];delete fixture[key];fixture[Em.String.decamelize(key)]=value}}},buildURL:function(type,id){return this.getStore().adapterFor("application").buildURL(type,id)},handleFind:function(name,opts,status){var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxHttpResponse(name,opts);var id=responseJson[modelName].id;var url=this.buildURL(modelName,id);this.stubEndpointForHttpRequest(url,responseJson,{type:"GET",status:status||200});return responseJson},handleCreate:function(name,opts,status){var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxHttpResponse(name,opts);var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson,{type:"POST",status:status||200});return responseJson},handleUpdate:function(type,id,status){this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"PUT",status:status||200})},handleDelete:function(type,id,status){this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"DELETE",status:status||200})},teardown:function(){FactoryGuy.resetModels(this.getStore())}});
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |s|
3
3
  s.name = "ember-data-factory-guy"
4
- s.version = "0.6.1"
4
+ s.version = "0.6.2"
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ["Daniel Sudol", "Alex Opak"]
7
7
  s.email = ["dansudol@yahoo.com", "opak.alexandr@gmail.com"]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-data-factory-guy",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "authors": [
5
5
  "Daniel Sudol <dansudol@yahoo.com>",
6
6
  "Opak Alex <opak.alexandr@gmail.com>"
@@ -268,6 +268,7 @@ FactoryGuy = {
268
268
  }
269
269
  },
270
270
 
271
+
271
272
  /**
272
273
  Push fixture to model's FIXTURES array.
273
274
  Used when store's adapter is a DS.FixtureAdapter.
@@ -356,11 +356,13 @@ DS.FixtureAdapter.reopen({
356
356
  if (belongsToRecord && belongsToRecord.get('length') > 0) {
357
357
  var hasManyName = store.findRelationshipName(
358
358
  'hasMany',
359
- belongsToRecord.constructor,
359
+ belongsToRecord.get('firstObject').constructor,
360
360
  record
361
361
  );
362
362
  belongsToRecord.forEach(function (child){
363
- child.get(hasManyName).addObject(record)
363
+ Em.RSVP.resolve(child.get(hasManyName)).then( function(value) {
364
+ value.addObjects(record);
365
+ });
364
366
  });
365
367
  }
366
368
  });
@@ -6,7 +6,7 @@ module('FactoryGuy with ActiveModelAdapter', {
6
6
  store = testHelper.getStore();
7
7
  },
8
8
  teardown: function() {
9
- Em.run(function() { testHelper.teardown(); });
9
+ testHelper.teardown();
10
10
  }
11
11
  });
12
12
 
@@ -11,7 +11,9 @@ module('FactoryGuy', {
11
11
  store = testHelper.getStore();
12
12
  },
13
13
  teardown: function() {
14
- Em.run(function() { testHelper.teardown(); });
14
+ Em.run(function() {
15
+ testHelper.teardown();
16
+ });
15
17
  }
16
18
  });
17
19
 
@@ -173,14 +173,18 @@ asyncTest("#createRecord can work for one-to-none associations", function () {
173
173
  asyncTest("#createRecord adds hasMany association to records it hasMany of ", function () {
174
174
  var usersJson = store.makeList('user', 3);
175
175
 
176
- Em.RSVP.all([store.find('user', usersJson[0].id), store.find('user', usersJson[1].id), store.find('user', usersJson[2].id)]).then(function (users) {
176
+ var user1Promise = store.find('user', usersJson[0].id)
177
+ var user2Promise = store.find('user', usersJson[1].id)
178
+ var user3Promise = store.find('user', usersJson[2].id)
179
+ Em.RSVP.all([user1Promise, user2Promise, user3Promise]).then(function (users) {
177
180
 
178
181
  var propertyJson = {name: 'beach front property'};
179
182
 
180
- property = store.createRecord('property', propertyJson);
183
+ var property = store.createRecord('property', propertyJson);
181
184
  property.get('owners').then(function (owners) {
182
185
  owners.addObjects(users);
183
- }).then(function () {
186
+ return property.save();
187
+ }).then(function (property) {
184
188
  return property.get('owners');
185
189
  }).then(function (users) {
186
190
  equal(users.get('length'), usersJson.length);
@@ -285,6 +285,11 @@ FactoryGuy = {
285
285
  }
286
286
  },
287
287
 
288
+ association: function(fixtureName, opts) {
289
+ console.log('DEPRECATION Warning: use FactoryGuy.belongsTo instead')
290
+ return this.belongsTo(fixtureName, opts);
291
+ },
292
+
288
293
  /**
289
294
  Used in model definitions to define a hasMany association attribute.
290
295
  For example:
@@ -433,6 +438,7 @@ FactoryGuy = {
433
438
  }
434
439
  },
435
440
 
441
+
436
442
  /**
437
443
  Push fixture to model's FIXTURES array.
438
444
  Used when store's adapter is a DS.FixtureAdapter.
@@ -816,11 +822,13 @@ DS.FixtureAdapter.reopen({
816
822
  if (belongsToRecord && belongsToRecord.get('length') > 0) {
817
823
  var hasManyName = store.findRelationshipName(
818
824
  'hasMany',
819
- belongsToRecord.constructor,
825
+ belongsToRecord.get('firstObject').constructor,
820
826
  record
821
827
  );
822
828
  belongsToRecord.forEach(function (child){
823
- child.get(hasManyName).addObject(record)
829
+ Em.RSVP.resolve(child.get(hasManyName)).then( function(value) {
830
+ value.addObjects(record);
831
+ });
824
832
  });
825
833
  }
826
834
  });
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ember-data-factory-guy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Sudol
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-21 00:00:00.000000000 Z
12
+ date: 2014-09-04 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Easily create Fixtures for Ember Data
15
15
  email: