ember-data-factory-guy 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ FactoryGuy.define('project', {
2
+ default: {title: 'Project'}
3
+ });
@@ -0,0 +1,10 @@
1
+ FactoryGuy.define('user', {
2
+ // default values for 'user' attributes
3
+ default: {
4
+ name: 'User1'
5
+ },
6
+ // named 'user' type with custom attributes
7
+ admin: {
8
+ name: 'Admin'
9
+ }
10
+ });
@@ -0,0 +1,4 @@
1
+ Project = DS.Model.extend({
2
+ title: DS.attr('string'),
3
+ user: DS.belongsTo('user')
4
+ })
@@ -0,0 +1,4 @@
1
+ User = DS.Model.extend({
2
+ name: DS.attr('string'),
3
+ projects: DS.hasMany('project')
4
+ })
@@ -0,0 +1,23 @@
1
+ TestHelper = Ember.Object.createWithMixins(FactoryGuyHelperMixin,{
2
+
3
+ /**
4
+ * Setup with type of adapter
5
+ *
6
+ * @param adapter DS.FixtureAdapter or DS.ActiveModelSerializer or whatever
7
+ */
8
+ setup: function(adapter) {
9
+ var container = new Ember.Container();
10
+ this.set('container', container);
11
+
12
+ container.register("model:user", User);
13
+ container.register("model:project", Project);
14
+ container.register("store:main", DS.Store.extend({adapter: adapter}));
15
+ container.register("serializer:-default", DS.RESTSerializer);
16
+ container.register('transform:string', DS.StringTransform);
17
+
18
+ if (adapter instanceof DS.FixtureAdapter) {
19
+ adapter.simulateRemoteResponse = false;
20
+ }
21
+ return this;
22
+ }
23
+ });
@@ -0,0 +1,22 @@
1
+ FactoryGuy.define('project', {
2
+ default: {title: 'Project'}
3
+ });
4
+ FactoryGuy.define('user', {
5
+ // default values for 'user' attributes
6
+ default: {
7
+ name: 'User1'
8
+ },
9
+ // named 'user' type with custom attributes
10
+ admin: {
11
+ name: 'Admin'
12
+ }
13
+ });
14
+ Project = DS.Model.extend({
15
+ title: DS.attr('string'),
16
+ user: DS.belongsTo('user')
17
+ })
18
+
19
+ User = DS.Model.extend({
20
+ name: DS.attr('string'),
21
+ projects: DS.hasMany('project')
22
+ })
@@ -0,0 +1,376 @@
1
+ FactoryGuy = Ember.Object.reopenClass({
2
+ fixtureStore: {},
3
+ fixtureLookup: {},
4
+ modelIds: {},
5
+
6
+ /**
7
+ ```javascript
8
+
9
+ User = DS.Model.extend({
10
+ name: DS.attr('string'),
11
+ })
12
+
13
+ FactoryGuy.define('user', {
14
+ default: {
15
+ name: "Fred"
16
+ },
17
+
18
+ bob: {
19
+ name: "Bob"
20
+ }
21
+ });
22
+
23
+ ```
24
+
25
+ For the User model, you can define fixtures like 'bob' or just use 'user'
26
+ and get default values.
27
+
28
+ And to get those fixtures you would call them this way:
29
+
30
+ FactoryGuy.build('user') or FactoryGuy.build('bob')
31
+
32
+ @param model the model to define
33
+ @param config your default and specific fixtures
34
+ */
35
+ define: function (model, config) {
36
+ var info = this.getModelInfo(model);
37
+ for (key in config) {
38
+ var value = config[key];
39
+ info[key] = value;
40
+ if (key != 'default') {
41
+ this.fixtureLookup[key] = model;
42
+ }
43
+ }
44
+ // setup id
45
+ this.modelIds[model] = 0;
46
+ },
47
+
48
+ /**
49
+
50
+ @param model
51
+ */
52
+ getModelInfo: function (model) {
53
+ if (!this.fixtureStore[model]) {
54
+ this.fixtureStore[model] = {};
55
+ }
56
+ return this.fixtureStore[model];
57
+ },
58
+
59
+ /**
60
+
61
+ @param name fixture name
62
+ @returns model associated with fixture name
63
+ */
64
+ lookupModelForName: function (name) {
65
+ var model = this.fixtureLookup[name];
66
+ if (!model) {
67
+ if (this.fixtureStore[name]) {
68
+ model = name;
69
+ }
70
+ }
71
+ return model;
72
+ },
73
+
74
+ /**
75
+ Generate next id for model
76
+ */
77
+ generateId: function (model) {
78
+ var lastId = this.modelIds[model] || 0;
79
+ this.modelIds[model] = lastId + 1;
80
+ return this.modelIds[model];
81
+ },
82
+
83
+ /**
84
+ Build fixtures for model or specific fixture name. For example:
85
+
86
+ FactoryGuy.build('user') for User model
87
+ FactoryGuy.build('bob') for User model with bob attributes
88
+
89
+ @param name fixture name
90
+ @param opts options that will override default fixture values
91
+ @returns {*}
92
+ */
93
+ build: function (name, opts) {
94
+ var model = this.lookupModelForName(name);
95
+ if (!model) {
96
+ throw new Error("can't find that factory named [" + name + "]");
97
+ }
98
+
99
+ var modelInfo = this.fixtureStore[model];
100
+ var modelAttributes = modelInfo[name] || {};
101
+ var defaultModelAttributes = modelInfo.default;
102
+ var fixture = $.extend({}, defaultModelAttributes, modelAttributes, opts);
103
+ fixture.id = this.generateId(model);
104
+ return fixture;
105
+ },
106
+
107
+ /**
108
+ Clear model instances from FIXTURES array, and from store cache.
109
+ Reset the id sequence for the models back to zero.
110
+ */
111
+ resetModels: function (store) {
112
+ var typeMaps = store.typeMaps;
113
+ if (store.usingFixtureAdapter()) {
114
+ for (typeKey in this.fixtureStore) {
115
+ var modelType = store.modelFor(typeKey);
116
+ modelType.FIXTURES = [];
117
+ store.unloadAll(modelType);
118
+ }
119
+ } else {
120
+ for (model in typeMaps) {
121
+ if (typeMaps[model].type.typeKey != 'user') {
122
+ // console.log(typeMaps[model].type.typeKey)
123
+ store.unloadAll(typeMaps[model].type);
124
+ }
125
+ }
126
+ }
127
+ this.modelIds = {}
128
+ },
129
+
130
+ /**
131
+ Push fixture to model's FIXTURES array.
132
+ Used when store's adapter is a DS.FixtureAdapter.
133
+
134
+ @param modelClass DS.Model type
135
+ @param fixture the fixture to add
136
+ */
137
+ pushFixture: function (modelClass, fixture) {
138
+ if (!modelClass['FIXTURES']) {
139
+ modelClass['FIXTURES'] = [];
140
+ }
141
+ modelClass['FIXTURES'].push(fixture);
142
+ return fixture;
143
+ }
144
+ })
145
+ DS.Store.reopen({
146
+
147
+ usingFixtureAdapter: function() {
148
+ var adapter = this.adapterFor('application');
149
+ return adapter instanceof DS.FixtureAdapter
150
+ },
151
+
152
+ /**
153
+ Make new fixture and save to store. If the store is using FixtureAdapter,
154
+ will push to FIXTURE array, otherwise will use push method on adapter.
155
+
156
+ @param name
157
+ @param options
158
+ @returns {*}
159
+ */
160
+ makeFixture: function (name, options) {
161
+ var modelName = FactoryGuy.lookupModelForName(name);
162
+ var fixture = FactoryGuy.build(name, options);
163
+ var modelType = this.modelFor(modelName);
164
+
165
+ if (this.usingFixtureAdapter()) {
166
+ this.setBelongsToFixturesAssociation(modelType, modelName, fixture);
167
+ return FactoryGuy.pushFixture(modelType, fixture);
168
+ } else {
169
+ var self = this;
170
+ var model;
171
+ Em.run( function() {
172
+ model = self.push(modelName, fixture);
173
+ self.setBelongsToRestAssociation(modelType, modelName, model);
174
+ });
175
+ return model;
176
+ }
177
+ },
178
+
179
+ /**
180
+ Trying to set the belongsTo association for FixtureAdapter,
181
+ with models that have a hasMany association.
182
+
183
+ For example if a client hasMany projects, then set the client.id
184
+ on each project that the client hasMany of, so that the project
185
+ now has the belongsTo client association setup.
186
+
187
+ @param name
188
+ @param model
189
+ */
190
+ setBelongsToFixturesAssociation: function (modelType, modelName, parentFixture) {
191
+ var store = this;
192
+ var adapter = this.adapterFor('application');
193
+ var relationShips = Ember.get(modelType, 'relationshipNames');
194
+ if (relationShips.hasMany) {
195
+ relationShips.hasMany.forEach(function (relationship) {
196
+ var hasManyModel = store.modelFor(Em.String.singularize(relationship));
197
+ if (parentFixture[relationship]) {
198
+ parentFixture[relationship].forEach(function(id) {
199
+ var hasManyfixtures = adapter.fixturesForType(hasManyModel);
200
+ var fixture = adapter.findFixtureById(hasManyfixtures, id);
201
+ fixture[modelName] = parentFixture.id;
202
+ })
203
+ }
204
+ })
205
+ }
206
+ },
207
+
208
+ /**
209
+ * Trying to set the belongsTo association for the rest type models
210
+ * with a hasMany association
211
+ *
212
+ * For example if a client hasMany projects, then set the client
213
+ * on each project that the client hasMany of, so that the project
214
+ * now has the belongsTo client association setup
215
+ *
216
+ * @param modelType
217
+ * @param modelName
218
+ * @param parent model to check for hasMany
219
+ */
220
+ setBelongsToRestAssociation: function (modelType, modelName, parent) {
221
+ var relationShips = Ember.get(modelType, 'relationshipNames');
222
+
223
+ if (relationShips.hasMany) {
224
+ relationShips.hasMany.forEach(function (name) {
225
+ var children = parent.get(name);
226
+ if (children.get('length') > 0) {
227
+ children.forEach(function(child) {
228
+ child.set(modelName, parent)
229
+ })
230
+ }
231
+ })
232
+ }
233
+ },
234
+
235
+ /**
236
+ Adding a pushPayload for FixtureAdapter, but using the original with
237
+ other adapters that support pushPayload.
238
+
239
+ @param type
240
+ @param payload
241
+ */
242
+ pushPayload: function (type, payload) {
243
+ if (this.usingFixtureAdapter()) {
244
+ var model = this.modelFor(modelName);
245
+ FactoryGuy.pushFixture(model, payload);
246
+ } else {
247
+ this._super(type, payload);
248
+ }
249
+ }
250
+ });
251
+
252
+
253
+ DS.FixtureAdapter.reopen({
254
+
255
+ /**
256
+ Overriding createRecord in FixtureAdapter to add the record
257
+ created to the hashMany records for all of the records that
258
+ this one belongsTo.
259
+
260
+ @method createRecord
261
+ @param {DS.Store} store
262
+ @param {subclass of DS.Model} type
263
+ @param {DS.Model} record
264
+ @return {Promise} promise
265
+ */
266
+ createRecord: function(store, type, record) {
267
+ var promise = this._super(store, type, record);
268
+
269
+ promise.then( function() {
270
+ var hasManyName = Ember.String.pluralize(type.typeKey);
271
+ var relationShips = Ember.get(type, 'relationshipNames');
272
+ if (relationShips.belongsTo) {
273
+ // console.log('record',record+'', type.typeKey, hasManyName);
274
+ // relationShips.belongsTo.forEach(function (relationship) {
275
+ // console.log(relationship, record.get(relationship)+'')
276
+ // var belongsToRecord = record.get(relationship);
277
+ // console.log(relationshipForType)
278
+ // belongsToRecord.get(hasManyName).addObject(record);
279
+ // })
280
+ }
281
+ })
282
+ return promise;
283
+ }
284
+
285
+ })
286
+
287
+
288
+ FactoryGuyHelperMixin = Em.Mixin.create({
289
+
290
+ setup: function(app) {
291
+ this.set('container', app.__container__);
292
+ return this;
293
+ },
294
+
295
+ useFixtureAdapter: function(app) {
296
+ app.ApplicationAdapter = DS.FixtureAdapter;
297
+ this.getStore().adapterFor('application').simulateRemoteResponse = false;
298
+ },
299
+
300
+ find: function(type, id) {
301
+ return this.getStore().find(type, id);
302
+ },
303
+
304
+ make: function(name, opts) {
305
+ return this.getStore().makeFixture(name, opts);
306
+ },
307
+
308
+ getStore: function () {
309
+ return this.get('container').lookup('store:main');
310
+ },
311
+
312
+ pushPayload: function(type, hash) {
313
+ return this.getStore().pushPayload(type, hash);
314
+ },
315
+
316
+ pushRecord: function(type, hash) {
317
+ return this.getStore().push(type, hash);
318
+ },
319
+
320
+ stubEndpointForHttpRequest: function (url, json, options) {
321
+ options = options || {};
322
+ var request = {
323
+ url: url,
324
+ dataType: 'json',
325
+ responseText: json,
326
+ type: options.type || 'GET',
327
+ status: options.status || 200
328
+ }
329
+
330
+ if (options.data) {
331
+ request.data = options.data
332
+ }
333
+
334
+ $.mockjax(request);
335
+ },
336
+
337
+ /**
338
+ * Handling ajax POST for a model
339
+ *
340
+ * @param name of the fixture ( or model ) to create
341
+ * @param opts fixture options
342
+ */
343
+ handleCreate: function (name, opts) {
344
+ var model = FactoryGuy.lookupModelForName(name);
345
+ this.stubEndpointForHttpRequest(
346
+ "/" + Em.String.pluralize(model),
347
+ this.buildAjaxResponse(name, opts),
348
+ {type: 'POST'}
349
+ )
350
+ },
351
+
352
+ buildAjaxResponse: function (name, opts) {
353
+ var fixture = FactoryGuy.build(name, opts);
354
+ var model = FactoryGuy.lookupModelForName(name);
355
+ var hash = {};
356
+ hash[model] = fixture;
357
+ return hash;
358
+ },
359
+
360
+ handleUpdate: function (root, id) {
361
+ this.stubEndpointForHttpRequest(
362
+ "/" + Em.String.pluralize(root) + "/" + id, '{}', {type: 'PUT'}
363
+ )
364
+ },
365
+
366
+ handleDelete: function (root, id) {
367
+ this.stubEndpointForHttpRequest(
368
+ "/" + Em.String.pluralize(root) + "/" + id, {}, {type: 'DELETE'}
369
+ )
370
+ },
371
+
372
+ teardown: function () {
373
+ FactoryGuy.resetModels(this.getStore());
374
+ }
375
+
376
+ })