ember-data-factory-guy 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -69,7 +69,7 @@ FactoryGuyTestMixin = Em.Mixin.create({
69
69
  @param {Object} opts fixture options
70
70
  */
71
71
  handleCreate: function (name, opts) {
72
- var model = FactoryGuy.lookupModelForName(name);
72
+ var model = FactoryGuy.lookupModelForFixtureName(name);
73
73
  this.stubEndpointForHttpRequest(
74
74
  "/" + Em.String.pluralize(model),
75
75
  this.buildAjaxCreateResponse(name, opts),
@@ -85,7 +85,7 @@ FactoryGuyTestMixin = Em.Mixin.create({
85
85
  ¬ */
86
86
  buildAjaxCreateResponse: function (name, opts) {
87
87
  var fixture = FactoryGuy.build(name, opts);
88
- var model = FactoryGuy.lookupModelForName(name);
88
+ var model = FactoryGuy.lookupModelForFixtureName(name);
89
89
  var hash = {};
90
90
  hash[model] = fixture;
91
91
  return hash;
@@ -50,10 +50,15 @@ ModelDefinition = function (model, config) {
50
50
  var modelAttributes = namedModels[name] || {};
51
51
  // merge default, modelAttributes and opts to get the rough fixture
52
52
  var fixture = $.extend({}, defaultAttributes, modelAttributes, opts);
53
- // convert attributes that are functions to strings
53
+ // deal with attributes that are functions or objects
54
54
  for (attribute in fixture) {
55
- if (typeof fixture[attribute] == 'function') {
55
+ if (Ember.typeOf(fixture[attribute]) == 'function') {
56
+ // function might be a sequence of a named association
56
57
  fixture[attribute] = fixture[attribute].call(this, fixture);
58
+ } else if (Ember.typeOf(fixture[attribute]) == 'object') {
59
+ // if it's an object it's for a model association, so build the json
60
+ // for the association and replace the attribute with that json
61
+ fixture[attribute] = FactoryGuy.build(attribute, fixture[attribute])
57
62
  }
58
63
  }
59
64
  // set the id, unless it was already set in opts
data/src/store.js CHANGED
@@ -16,19 +16,25 @@ DS.Store.reopen({
16
16
  @returns {Object|DS.Model} json or record depending on the adapter type
17
17
  */
18
18
  makeFixture: function (name, options) {
19
- var modelName = FactoryGuy.lookupModelForName(name);
19
+ var modelName = FactoryGuy.lookupModelForFixtureName(name);
20
20
  var fixture = FactoryGuy.build(name, options);
21
21
  var modelType = this.modelFor(modelName);
22
22
 
23
23
  if (this.usingFixtureAdapter()) {
24
- this.setBelongsToFixturesAdapter(modelType, modelName, fixture);
24
+ this.setAssociationsForFixtureAdapter(modelType, modelName, fixture);
25
25
  return FactoryGuy.pushFixture(modelType, fixture);
26
26
  } else {
27
- var self = this;
27
+ var store = this;
28
28
  var model;
29
29
  Em.run(function () {
30
- model = self.push(modelName, fixture);
31
- self.setBelongsToRESTAdapter(modelType, modelName, model);
30
+ store.findEmbeddedBelongsToAssociationsForRESTAdapter(modelType, fixture);
31
+ if (fixture.type) {
32
+ // assuming its polymorphic if there is a type attribute
33
+ // is this too bold an assumption?
34
+ modelName = fixture.type
35
+ }
36
+ model = store.push(modelName, fixture);
37
+ store.setAssociationsForRESTAdapter(modelType, modelName, model);
32
38
  });
33
39
  return model;
34
40
  }
@@ -51,18 +57,32 @@ DS.Store.reopen({
51
57
  },
52
58
 
53
59
  /**
54
- Set the belongsTo association for FixtureAdapter,
55
- with models that have a hasMany association.
60
+ Set the hasMany and belongsTo associations for FixtureAdapter.
56
61
 
57
- For example if a user hasMany projects, then set the user.id
58
- on each project that the user hasMany of, so that the project
59
- now has the belongsTo user association setup.
62
+ For example, assuming a user hasMany projects, if you make a project,
63
+ then a user with that project in the users list of project, then this method
64
+ will go back and set the user.id on each project that the user hasMany of,
65
+ so that the project now has the belongsTo user association setup.
66
+ As in this scenario:
67
+
68
+ ```js
69
+ var projectJson = store.makeFixture('project');
70
+ var userJson = store.makeFixture('user', {projects: [projectJson.id]});
71
+ ```
72
+
73
+ Or if you make a project with a user, then set this project in
74
+ the users list of 'projects' it hasMany of. As in this scenario:
60
75
 
61
- @param {String} modelType model type like App.User
76
+ ```js
77
+ var userJson = store.makeFixture('user');
78
+ var projectJson = store.makeFixture('project', {user: userJson.id});
79
+ ```
80
+
81
+ @param {DS.Model} modelType model type like User
62
82
  @param {String} modelName model name like 'user'
63
- @param {Object} parentFixture parent to assign as belongTo
83
+ @param {Object} fixture to check for needed association assignments
64
84
  */
65
- setBelongsToFixturesAdapter: function(modelType, modelName, fixture) {
85
+ setAssociationsForFixtureAdapter: function(modelType, modelName, fixture) {
66
86
  var self = this;
67
87
  var adapter = this.adapterFor('application');
68
88
  Ember.get(modelType, 'relationshipsByName').forEach(function (name, relationship) {
@@ -79,7 +99,11 @@ DS.Store.reopen({
79
99
  if (relationship.kind == 'belongsTo') {
80
100
  var belongsToRecord = fixture[relationship.key];
81
101
  if (belongsToRecord) {
82
- var hasManyName = self.findHasManyRelationshipName2(relationship.type, relationship.parentType);
102
+ if (typeof belongsToRecord == 'object') {
103
+ FactoryGuy.pushFixture(relationship.type, belongsToRecord);
104
+ fixture[relationship.key] = belongsToRecord.id;
105
+ }
106
+ var hasManyName = self.findHasManyRelationshipName(relationship.type, relationship.parentType);
83
107
  var belongsToFixtures = adapter.fixturesForType(relationship.type);
84
108
  var belongsTofixture = adapter.findFixtureById(belongsToFixtures, fixture[relationship.key]);
85
109
  if (!belongsTofixture[hasManyName]) {
@@ -92,21 +116,56 @@ DS.Store.reopen({
92
116
  },
93
117
 
94
118
  /**
95
- For the REST type models:
119
+ Before pushing the fixture to the store, do some preprocessing.
96
120
 
97
- Set the belongsTo association with a hasMany association
121
+ If its a belongs to association, and the fixture has an object there,
122
+ then push that model to the store and set the id of that new model
123
+ as the attribute value in the fixture
124
+
125
+ If it's a hasMany association, and its polymorphic, then convert the
126
+ attribute value to a polymorphic style
127
+
128
+ @param modelType
129
+ @param fixture
130
+ */
131
+ findEmbeddedBelongsToAssociationsForRESTAdapter: function (modelType, fixture) {
132
+ var store = this;
133
+ Ember.get(modelType, 'relationshipsByName').forEach(function (name, relationship) {
134
+ if (relationship.kind == 'belongsTo') {
135
+ var belongsToRecord = fixture[relationship.key];
136
+ if (typeof belongsToRecord == 'object') {
137
+ belongsToRecord = store.push(relationship.type, belongsToRecord);
138
+ fixture[relationship.key] = belongsToRecord;
139
+ }
140
+ }
141
+ })
142
+ },
98
143
 
99
- Set this model in the parent hasMany array this model belongsTo
144
+ /**
145
+ For the REST type models:
100
146
 
101
147
  For example if a user hasMany projects, then set the user
102
148
  on each project that the user hasMany of, so that the project
103
- now has the belongsTo user association setup
149
+ now has the belongsTo user association setup. As in this scenario:
150
+
151
+ ```js
152
+ var project = store.makeFixture('project');
153
+ var user = store.makeFixture('user', {projects: [project]});
154
+ ```
155
+
156
+ Or if you make a user, then a project with that user, then set the project
157
+ in the users list of 'projects' it hasMany of. As in this scenario:
158
+
159
+ ```js
160
+ var user = store.makeFixture('user');
161
+ var project = store.makeFixture('project', {user: user});
162
+ ```
104
163
 
105
164
  @param {DS.Model} modelType model type like 'User'
106
165
  @param {String} modelName model name like 'user'
107
- @param {DS.Model} model
166
+ @param {DS.Model} model model to check for needed association assignments
108
167
  */
109
- setBelongsToRESTAdapter: function (modelType, modelName, model) {
168
+ setAssociationsForRESTAdapter: function (modelType, modelName, model) {
110
169
  var self = this;
111
170
  Ember.get(modelType, 'relationshipsByName').forEach(function (name, relationship) {
112
171
  if (relationship.kind == 'hasMany') {
@@ -119,31 +178,22 @@ DS.Store.reopen({
119
178
  if (relationship.kind == 'belongsTo') {
120
179
  var belongsToRecord = model.get(name);
121
180
  if (belongsToRecord) {
122
- var hasManyName = self.findHasManyRelationshipName(belongsToRecord, model)
181
+ var hasManyName = self.findHasManyRelationshipName(
182
+ belongsToRecord.constructor,
183
+ model.constructor
184
+ )
123
185
  belongsToRecord.get(hasManyName).addObject(model);
124
186
  }
125
187
  }
126
188
  })
127
189
  },
128
190
 
129
- findHasManyRelationshipName2: function (belongToModel, childModel) {
130
- var relationshipName;
131
- Ember.get(belongToModel, 'relationshipsByName').forEach(
132
- function (name, relationship) {
133
- if (relationship.kind == 'hasMany' &&
134
- relationship.type == childModel) {
135
- relationshipName = relationship.key;
136
- }
137
- }
138
- )
139
- return relationshipName;
140
- },
141
- findHasManyRelationshipName: function (belongToModel, childModel) {
191
+ findHasManyRelationshipName: function (belongToModelType, childModelType) {
142
192
  var relationshipName;
143
- Ember.get(belongToModel.constructor, 'relationshipsByName').forEach(
193
+ Ember.get(belongToModelType, 'relationshipsByName').forEach(
144
194
  function (name, relationship) {
145
195
  if (relationship.kind == 'hasMany' &&
146
- relationship.type == childModel.constructor) {
196
+ relationship.type == childModelType) {
147
197
  relationshipName = relationship.key;
148
198
  }
149
199
  }
@@ -219,7 +269,10 @@ DS.FixtureAdapter.reopen({
219
269
  relationShips.belongsTo.forEach(function (relationship) {
220
270
  var belongsToRecord = record.get(relationship);
221
271
  if (belongsToRecord) {
222
- var hasManyName = store.findHasManyRelationshipName(belongsToRecord, record);
272
+ var hasManyName = store.findHasManyRelationshipName(
273
+ belongsToRecord.constructor,
274
+ record.constructor
275
+ );
223
276
  belongsToRecord.get(hasManyName).addObject(record);
224
277
  }
225
278
  })
@@ -13,7 +13,7 @@ module('FactoryGuy with ActiveModelAdapter', {
13
13
 
14
14
  test("#resetModels clears the store of models, and resets the model definition", function() {
15
15
  var project = store.makeFixture('project');
16
- var user = store.makeFixture('user', {projects: [project.id]});
16
+ var user = store.makeFixture('user', {projects: [project]});
17
17
 
18
18
  for (model in FactoryGuy.modelDefinitions) {
19
19
  var definition = FactoryGuy.modelDefinitions[model];
@@ -62,19 +62,29 @@ asyncTest("creates record in the store", function() {
62
62
  test("supports hasMany associations", function() {
63
63
  var p1 = store.makeFixture('project');
64
64
  var p2 = store.makeFixture('project');
65
- var user = store.makeFixture('user', {projects: [p1.id, p2.id]})
65
+ var user = store.makeFixture('user', {projects: [p1, p2]})
66
66
 
67
67
  equal(user.get('projects.length'), 2);
68
68
  });
69
69
 
70
+ test("supports hasMany polymorphic associations", function() {
71
+ var sh = store.makeFixture('big_hat');
72
+ var bh = store.makeFixture('small_hat');
73
+ var user = store.makeFixture('user', {hats: [sh, bh]})
74
+ equal(user.get('hats.length'), 2);
75
+ ok(user.get('hats.firstObject') instanceof BigHat)
76
+ ok(user.get('hats.lastObject') instanceof SmallHat)
77
+ });
78
+
70
79
 
71
80
  test("when hasMany associations assigned, belongTo parent is assigned", function() {
72
81
  var p1 = store.makeFixture('project');
73
- var user = store.makeFixture('user', {projects: [p1.id]})
82
+ var user = store.makeFixture('user', {projects: [p1]})
74
83
 
75
84
  deepEqual(p1.get('user').toJSON(), user.toJSON());
76
85
  });
77
86
 
87
+
78
88
  test("when belongTo parent is assigned, parent adds to hasMany records", function() {
79
89
  var user = store.makeFixture('user');
80
90
  var project = store.makeFixture('project', {user: user});
@@ -83,6 +93,19 @@ test("when belongTo parent is assigned, parent adds to hasMany records", functio
83
93
  });
84
94
 
85
95
 
96
+ test("belongsTo associations defined as attributes in fixture", function() {
97
+ var project = store.makeFixture('project_with_user');
98
+ equal(project.get('user') instanceof User, true)
99
+ deepEqual(project.get('user').toJSON(),{name: 'User1'})
100
+
101
+ var project = store.makeFixture('project_with_dude');
102
+ deepEqual(project.get('user').toJSON(),{name: 'Dude'})
103
+
104
+ var project = store.makeFixture('project_with_admin');
105
+ deepEqual(project.get('user').toJSON(),{name: 'Admin'})
106
+ })
107
+
108
+
86
109
  module('DS.Store#makeList with ActiveModelAdapter', {
87
110
  setup: function() {
88
111
  testHelper = TestHelper.setup(DS.ActiveModelAdapter);
@@ -65,10 +65,10 @@ test("Referring to other attributes in attribute definition", function() {
65
65
  type: 'normal'
66
66
  },
67
67
  funny_person: {
68
- type: function(fixture) { return 'funny ' + fixture.name }
68
+ type: function(f) { return 'funny ' + f.name }
69
69
  },
70
70
  missing_person: {
71
- type: function(fixture) { return 'level ' + fixture.brain_size }
71
+ type: function(f) { return 'level ' + f.brain_size }
72
72
  }
73
73
  });
74
74
 
@@ -80,6 +80,18 @@ test("Referring to other attributes in attribute definition", function() {
80
80
  });
81
81
 
82
82
 
83
+ test("Using associations in attribute definition", function() {
84
+ var json = FactoryGuy.build('project_with_user');
85
+ deepEqual(json, {id: 1, title: 'Project', user: {id: 1, name: 'User1'}}, 'creates default user for "user" belongsTo attribute');
86
+
87
+ var json = FactoryGuy.build('project_with_dude');
88
+ deepEqual(json, {id: 2, title: 'Project', user: {id: 2, name: 'Dude'}}, 'creates user with optional attributes for "user" belongsTo attribute');
89
+
90
+ var json = FactoryGuy.build('project_with_admin');
91
+ deepEqual(json, {id: 3, title: 'Project', user: {id: 3, name: 'Admin'}}, 'creates named user for "user" belongsTo attribute');
92
+ });
93
+
94
+
83
95
  test("#build creates default json for model", function() {
84
96
  var json = FactoryGuy.build('user');
85
97
  deepEqual(json, {id: 1, name: 'User1'});
@@ -118,4 +130,18 @@ test("#buildList creates list of fixtures", function() {
118
130
  var userList = FactoryGuy.buildList('user', 2);
119
131
  deepEqual(userList[0], {id: 1, name: 'User1'});
120
132
  deepEqual(userList[1], {id: 2, name: 'User1'});
133
+ });
134
+
135
+
136
+ test("#lookupDefinitionForFixtureName", function() {
137
+ equal(!!FactoryGuy.lookupDefinitionForFixtureName('person'), true, 'finds definition if its the same as model name');
138
+ equal(!!FactoryGuy.lookupDefinitionForFixtureName('funny_person'), true, 'finds definition if its a named fixture');
139
+ equal(!!FactoryGuy.lookupDefinitionForFixtureName('fake'), false, "return nothing if can't find definition");
140
+ });
141
+
142
+
143
+ test("#lookupModelForFixtureName", function() {
144
+ equal(FactoryGuy.lookupModelForFixtureName('person'), 'person', "finds model if its the same as model name");
145
+ equal(FactoryGuy.lookupModelForFixtureName('funny_person'), 'person', "finds model if it's definition has this named fixture");
146
+ equal(FactoryGuy.lookupModelForFixtureName('fake'), undefined, "return nothing if can't find definition");
121
147
  });
@@ -106,6 +106,29 @@ asyncTest("#makeFixture adds record to hasMany association array for which it be
106
106
  })
107
107
  })
108
108
 
109
+ asyncTest("#makeFixture handles default belongsTo associations in fixture", function() {
110
+ var projectWithUser = store.makeFixture('project_with_user');
111
+ equal(User.FIXTURES.length, 1);
112
+
113
+ store.find('user', 1).then( function(user) {
114
+ user.get('projects').then( function(projects) {
115
+ equal(projects.get('length'), 1, "adds hasMany records");
116
+ equal(projects.get('firstObject.user.id'), 1, "sets belongsTo record");
117
+ start();
118
+ })
119
+ })
120
+ // TODO.. have to make belongsTo async for fixture adapter
121
+ // to get this to work
122
+ // store.find('project', projectWithUser.id).then( function(project) {
123
+ // console.log('a',project+'', project.id)
124
+ // console.log('b',project.get('user')+'', project.get('user').toJSON())
125
+ // project.get('user').then( function(user) {
126
+ // console.log('c',user.toJSON())
127
+ // })
128
+ // start();
129
+ // })
130
+ })
131
+
109
132
 
110
133
  asyncTest("#createRecord adds belongsTo association to records it hasMany of", function() {
111
134
  var user = store.makeFixture('user');
@@ -13,7 +13,7 @@ module('FactoryGuy with DS.RESTAdapter', {
13
13
 
14
14
  test("#resetModels clears the store of models, and resets the model definition", function() {
15
15
  var project = store.makeFixture('project');
16
- var user = store.makeFixture('user', {projects: [project.id]});
16
+ var user = store.makeFixture('user', {projects: [project]});
17
17
 
18
18
  for (model in FactoryGuy.modelDefinitions) {
19
19
  var definition = FactoryGuy.modelDefinitions[model];
@@ -61,19 +61,30 @@ asyncTest("creates records in the store", function() {
61
61
  test("supports hasMany associations", function() {
62
62
  var p1 = store.makeFixture('project');
63
63
  var p2 = store.makeFixture('project');
64
- var user = store.makeFixture('user', {projects: [p1.id, p2.id]})
64
+ var user = store.makeFixture('user', {projects: [p1, p2]})
65
65
 
66
66
  equal(user.get('projects.length'), 2);
67
67
  });
68
68
 
69
69
 
70
+ test("supports hasMany polymorphic associations", function() {
71
+ var sh = store.makeFixture('big_hat');
72
+ var bh = store.makeFixture('small_hat');
73
+ var user = store.makeFixture('user', {hats: [sh, bh]})
74
+ equal(user.get('hats.length'), 2);
75
+ ok(user.get('hats.firstObject') instanceof BigHat)
76
+ ok(user.get('hats.lastObject') instanceof SmallHat)
77
+ });
78
+
79
+
70
80
  test("when hasMany associations assigned, belongTo parent is assigned", function() {
71
81
  var p1 = store.makeFixture('project');
72
- var user = store.makeFixture('user', {projects: [p1.id]})
82
+ var user = store.makeFixture('user', {projects: [p1]})
73
83
 
74
84
  deepEqual(p1.get('user').toJSON(), user.toJSON());
75
85
  });
76
86
 
87
+
77
88
  test("when belongTo parent is assigned, parent adds to hasMany records", function() {
78
89
  var user = store.makeFixture('user');
79
90
  var project = store.makeFixture('project', {user: user});
@@ -82,7 +93,19 @@ test("when belongTo parent is assigned, parent adds to hasMany records", functio
82
93
  });
83
94
 
84
95
 
85
- module('DS.Store#makeList with ActiveModelAdapter', {
96
+ test("belongsTo associations defined as attributes in fixture", function() {
97
+ var project = store.makeFixture('project_with_user');
98
+ equal(project.get('user') instanceof User, true)
99
+ deepEqual(project.get('user').toJSON(),{name: 'User1'})
100
+
101
+ var project = store.makeFixture('project_with_dude');
102
+ deepEqual(project.get('user').toJSON(),{name: 'Dude'})
103
+
104
+ var project = store.makeFixture('project_with_admin');
105
+ deepEqual(project.get('user').toJSON(),{name: 'Admin'})
106
+ })
107
+
108
+ module('DS.Store#makeList with DS.RESTAdapter', {
86
109
  setup: function() {
87
110
  testHelper = TestHelper.setup(DS.RESTAdapter);
88
111
  store = testHelper.getStore();
data/tests/store_test.js CHANGED
@@ -1,6 +1,6 @@
1
1
  var container;
2
2
 
3
- module('DS.Store#usingFixtureAdapter', {
3
+ module('DS.Store', {
4
4
  setup: function() {
5
5
  container = new Ember.Container();
6
6
  },
@@ -0,0 +1,9 @@
1
+ FactoryGuy.define('hat', {
2
+ default: {},
3
+ small_hat: {
4
+ type: 'small_hat'
5
+ },
6
+ big_hat: {
7
+ type: 'big_hat'
8
+ }
9
+ })