ember-data-factory-guy 0.1.1 → 0.1.2
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.
- data/.gitignore +2 -1
- data/.travis.yml +7 -0
- data/Gruntfile.js +18 -3
- data/README.md +122 -16
- data/bower.json +6 -2
- data/dist/ember-data-factory-guy.js +264 -107
- data/dist/ember-data-factory-guy.min.js +1 -1
- data/dist/factory_guy_has_many.js +188 -0
- data/ember-data-factory-guy.gemspec +1 -1
- data/lib/ember-data-factory-guy.rb +0 -1
- data/package.json +4 -4
- data/src/factory_guy.js +114 -89
- data/src/{factory_guy_helper_mixin.js → factory_guy_test_mixin.js} +2 -1
- data/src/model_definition.js +98 -0
- data/src/sequence.js +16 -0
- data/src/store.js +40 -23
- data/tests/active_model_adapter_factory_test.js +45 -5
- data/tests/factory_guy_test.js +93 -0
- data/tests/fixture_adapter_factory_test.js +14 -40
- data/tests/index.html +1 -0
- data/tests/rest_adapter_factory_test.js +18 -4
- data/tests/support/factories/project_factory.js +3 -1
- data/tests/support/factories/user_factory.js +1 -1
- data/tests/support/libs/sinon.js +4287 -0
- data/tests/support/models/user.js +1 -1
- data/tests/support/test_helper.js +2 -2
- data/tests/test_setup.js +4291 -2
- data/vendor/assets/javascripts/ember_data_factory_guy.js +155 -113
- metadata +8 -3
@@ -0,0 +1,98 @@
|
|
1
|
+
ModelDefinition = function (model, config) {
|
2
|
+
var sequences = {};
|
3
|
+
var defaultAttributes = {};
|
4
|
+
var namedModels = {};
|
5
|
+
var modelId = 1;
|
6
|
+
this.model = model;
|
7
|
+
|
8
|
+
/**
|
9
|
+
@param name model name like 'user' or named type like 'admin'
|
10
|
+
@return boolean true if name is this definitions model or this definition
|
11
|
+
contains a named model with that name
|
12
|
+
*/
|
13
|
+
this.matchesName = function (name) {
|
14
|
+
return model == name || namedModels[name];
|
15
|
+
}
|
16
|
+
|
17
|
+
this.merge = function (config) {
|
18
|
+
}
|
19
|
+
|
20
|
+
/**
|
21
|
+
@param sequenceName
|
22
|
+
@returns output of sequence function
|
23
|
+
*/
|
24
|
+
this.generate = function (sequenceName) {
|
25
|
+
if (!sequences[sequenceName]) {
|
26
|
+
throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+ model+"' definition")
|
27
|
+
}
|
28
|
+
return sequences[sequenceName].next();
|
29
|
+
}
|
30
|
+
|
31
|
+
this.build = function (name, opts) {
|
32
|
+
var modelAttributes = namedModels[name] || {};
|
33
|
+
var fixture = $.extend({}, defaultAttributes, modelAttributes, opts);
|
34
|
+
for (attr in fixture) {
|
35
|
+
if (typeof fixture[attr] == 'function') {
|
36
|
+
fixture[attr] = fixture[attr].call(this)
|
37
|
+
}
|
38
|
+
}
|
39
|
+
if (!fixture.id) {
|
40
|
+
fixture.id = modelId++;
|
41
|
+
}
|
42
|
+
return fixture;
|
43
|
+
}
|
44
|
+
|
45
|
+
/**
|
46
|
+
Build a list of fixtures
|
47
|
+
|
48
|
+
@param name model name or named model type
|
49
|
+
@param number of fixtures to build
|
50
|
+
@param opts attribute options
|
51
|
+
@returns array of fixtures
|
52
|
+
*/
|
53
|
+
this.buildList = function (name, number, opts) {
|
54
|
+
var arr = [];
|
55
|
+
for (var i = 0; i < number; i++) {
|
56
|
+
arr.push(this.build(name, opts))
|
57
|
+
}
|
58
|
+
return arr;
|
59
|
+
}
|
60
|
+
|
61
|
+
this.reset = function () {
|
62
|
+
modelId = 1;
|
63
|
+
}
|
64
|
+
|
65
|
+
var parseDefault = function (object) {
|
66
|
+
if (!object) {
|
67
|
+
return
|
68
|
+
}
|
69
|
+
defaultAttributes = object;
|
70
|
+
}
|
71
|
+
|
72
|
+
var parseSequences = function (object) {
|
73
|
+
if (!object) {
|
74
|
+
return
|
75
|
+
}
|
76
|
+
for (sequenceName in object) {
|
77
|
+
var sequenceFn = object[sequenceName];
|
78
|
+
if (typeof sequenceFn != 'function') {
|
79
|
+
throw new Error('Problem with [' + sequenceName + '] sequence definition. Sequences must be functions')
|
80
|
+
}
|
81
|
+
object[sequenceName] = new Sequence(sequenceFn);
|
82
|
+
}
|
83
|
+
sequences = object;
|
84
|
+
}
|
85
|
+
|
86
|
+
var parseConfig = function (config) {
|
87
|
+
parseSequences(config.sequences);
|
88
|
+
delete config.sequences;
|
89
|
+
|
90
|
+
parseDefault(config.default);
|
91
|
+
delete config.default;
|
92
|
+
|
93
|
+
namedModels = config;
|
94
|
+
}
|
95
|
+
|
96
|
+
// initialize
|
97
|
+
parseConfig(config);
|
98
|
+
}
|
data/src/sequence.js
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Sequence = function (fn) {
|
2
|
+
var index = 1;
|
3
|
+
var fn = fn;
|
4
|
+
|
5
|
+
this.next = function () {
|
6
|
+
return fn.call(this, index++);
|
7
|
+
}
|
8
|
+
|
9
|
+
this.reset = function () {
|
10
|
+
index = 1;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
function MissingSequenceError(message) {
|
15
|
+
this.toString = function() { return message }
|
16
|
+
}
|
data/src/store.js
CHANGED
@@ -9,9 +9,9 @@ DS.Store.reopen({
|
|
9
9
|
Make new fixture and save to store. If the store is using FixtureAdapter,
|
10
10
|
will push to FIXTURE array, otherwise will use push method on adapter.
|
11
11
|
|
12
|
-
@param name
|
13
|
-
@param options
|
14
|
-
@returns
|
12
|
+
@param name name of fixture
|
13
|
+
@param options fixture options
|
14
|
+
@returns json or record
|
15
15
|
*/
|
16
16
|
makeFixture: function (name, options) {
|
17
17
|
var modelName = FactoryGuy.lookupModelForName(name);
|
@@ -19,31 +19,48 @@ DS.Store.reopen({
|
|
19
19
|
var modelType = this.modelFor(modelName);
|
20
20
|
|
21
21
|
if (this.usingFixtureAdapter()) {
|
22
|
-
this.
|
22
|
+
this.setBelongsToFixturesAdapter(modelType, modelName, fixture);
|
23
23
|
return FactoryGuy.pushFixture(modelType, fixture);
|
24
24
|
} else {
|
25
25
|
var self = this;
|
26
26
|
var model;
|
27
27
|
Em.run( function() {
|
28
28
|
model = self.push(modelName, fixture);
|
29
|
-
self.
|
29
|
+
self.setBelongsToRESTAdapter(modelType, modelName, model);
|
30
30
|
});
|
31
31
|
return model;
|
32
32
|
}
|
33
33
|
},
|
34
34
|
|
35
35
|
/**
|
36
|
-
|
36
|
+
Make a list of Fixtures
|
37
|
+
|
38
|
+
@param name name of fixture
|
39
|
+
@param number number of fixtures
|
40
|
+
@param options fixture options
|
41
|
+
@returns list of json fixtures or records depending on the adapter type
|
42
|
+
*/
|
43
|
+
makeList: function (name, number, options) {
|
44
|
+
var arr = [];
|
45
|
+
for (var i = 0; i < number; i++) {
|
46
|
+
arr.push(this.makeFixture(name, options))
|
47
|
+
}
|
48
|
+
return arr;
|
49
|
+
},
|
50
|
+
|
51
|
+
/**
|
52
|
+
Set the belongsTo association for FixtureAdapter,
|
37
53
|
with models that have a hasMany association.
|
38
54
|
|
39
|
-
For example if a
|
40
|
-
on each project that the
|
41
|
-
now has the belongsTo
|
55
|
+
For example if a user hasMany projects, then set the user.id
|
56
|
+
on each project that the user hasMany of, so that the project
|
57
|
+
now has the belongsTo user association setup.
|
42
58
|
|
43
|
-
@param
|
44
|
-
@param model
|
59
|
+
@param modelType model type like App.User
|
60
|
+
@param modelName model name like 'user'
|
61
|
+
@param parentFixture parent to assign as belongTo
|
45
62
|
*/
|
46
|
-
|
63
|
+
setBelongsToFixturesAdapter: function (modelType, modelName, parentFixture) {
|
47
64
|
var store = this;
|
48
65
|
var adapter = this.adapterFor('application');
|
49
66
|
var relationShips = Ember.get(modelType, 'relationshipNames');
|
@@ -62,18 +79,18 @@ DS.Store.reopen({
|
|
62
79
|
},
|
63
80
|
|
64
81
|
/**
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
82
|
+
Set the belongsTo association for the REST type models
|
83
|
+
with a hasMany association
|
84
|
+
|
85
|
+
For example if a user hasMany projects, then set the user
|
86
|
+
on each project that the user hasMany of, so that the project
|
87
|
+
now has the belongsTo user association setup
|
88
|
+
|
89
|
+
@param modelType model type like 'App.User'
|
90
|
+
@param modelName model name like 'user'
|
91
|
+
@param parent model to check for hasMany
|
75
92
|
*/
|
76
|
-
|
93
|
+
setBelongsToRESTAdapter: function (modelType, modelName, parent) {
|
77
94
|
var relationShips = Ember.get(modelType, 'relationshipNames');
|
78
95
|
|
79
96
|
if (relationShips.hasMany) {
|
@@ -1,5 +1,4 @@
|
|
1
|
-
var testHelper;
|
2
|
-
var store;
|
1
|
+
var testHelper, store;
|
3
2
|
|
4
3
|
module('FactoryGuy with ActiveModelAdapter', {
|
5
4
|
setup: function() {
|
@@ -12,16 +11,25 @@ module('FactoryGuy with ActiveModelAdapter', {
|
|
12
11
|
});
|
13
12
|
|
14
13
|
|
15
|
-
test("#resetModels clears the store of models, and resets the model
|
14
|
+
test("#resetModels clears the store of models, and resets the model definition", function() {
|
16
15
|
var project = store.makeFixture('project');
|
17
16
|
var user = store.makeFixture('user', {projects: [project.id]});
|
18
17
|
|
18
|
+
for (model in FactoryGuy.modelDefinitions) {
|
19
|
+
var definition = FactoryGuy.modelDefinitions[model];
|
20
|
+
sinon.spy(definition, 'reset');
|
21
|
+
}
|
22
|
+
|
19
23
|
FactoryGuy.resetModels(store);
|
20
24
|
|
21
25
|
equal(store.all('user').get('content.length'),0)
|
22
26
|
equal(store.all('project').get('content.length'),0)
|
23
27
|
|
24
|
-
|
28
|
+
for (model in FactoryGuy.modelDefinitions) {
|
29
|
+
var definition = FactoryGuy.modelDefinitions[model];
|
30
|
+
ok(definition.reset.calledOnce);
|
31
|
+
definition.reset.restore();
|
32
|
+
}
|
25
33
|
});
|
26
34
|
|
27
35
|
|
@@ -36,7 +44,13 @@ module('DS.Store#makeFixture with ActiveModelAdapter', {
|
|
36
44
|
});
|
37
45
|
|
38
46
|
|
39
|
-
|
47
|
+
test("creates DS.Model instance", function() {
|
48
|
+
var user = store.makeFixture('user');
|
49
|
+
equal(user instanceof DS.Model, true);
|
50
|
+
});
|
51
|
+
|
52
|
+
|
53
|
+
asyncTest("creates record in the store", function() {
|
40
54
|
var user = store.makeFixture('user');
|
41
55
|
|
42
56
|
store.find('user', user.id).then ( function(store_user) {
|
@@ -61,3 +75,29 @@ test("when hasMany associations assigned, belongTo parent is assigned", function
|
|
61
75
|
deepEqual(p1.get('user').toJSON(), user.toJSON());
|
62
76
|
})
|
63
77
|
|
78
|
+
|
79
|
+
module('DS.Store#makeList with ActiveModelAdapter', {
|
80
|
+
setup: function() {
|
81
|
+
testHelper = TestHelper.setup(DS.ActiveModelAdapter);
|
82
|
+
store = testHelper.getStore();
|
83
|
+
},
|
84
|
+
teardown: function() {
|
85
|
+
Em.run(function() { testHelper.teardown(); });
|
86
|
+
}
|
87
|
+
});
|
88
|
+
|
89
|
+
|
90
|
+
test("creates list of DS.Model instances", function() {
|
91
|
+
var users = store.makeList('user', 2);
|
92
|
+
equal(users.length, 2);
|
93
|
+
equal(users[0] instanceof DS.Model, true);
|
94
|
+
});
|
95
|
+
|
96
|
+
|
97
|
+
test("creates records in the store", function() {
|
98
|
+
var users = store.makeList('user', 2);
|
99
|
+
|
100
|
+
var storeUsers = store.all('user').get('content');
|
101
|
+
deepEqual(storeUsers[0].toJSON(), users[0].toJSON());
|
102
|
+
deepEqual(storeUsers[1].toJSON(), users[1].toJSON());
|
103
|
+
});
|
data/tests/factory_guy_test.js
CHANGED
@@ -0,0 +1,93 @@
|
|
1
|
+
Person = DS.Model.extend({
|
2
|
+
type: DS.attr('string'),
|
3
|
+
name: DS.attr('string')
|
4
|
+
})
|
5
|
+
|
6
|
+
var testHelper, store;
|
7
|
+
|
8
|
+
module('FactoryGuy', {
|
9
|
+
setup: function() {
|
10
|
+
testHelper = TestHelper.setup(DS.FixtureAdapter);
|
11
|
+
store = testHelper.getStore();
|
12
|
+
},
|
13
|
+
teardown: function() {
|
14
|
+
Em.run(function() { testHelper.teardown(); });
|
15
|
+
}
|
16
|
+
});
|
17
|
+
|
18
|
+
|
19
|
+
test("Using sequences in definitions", function() {
|
20
|
+
FactoryGuy.define('person', {
|
21
|
+
sequences: {
|
22
|
+
personName: function(num) {
|
23
|
+
return 'person #' + num;
|
24
|
+
},
|
25
|
+
personType: function(num) {
|
26
|
+
return 'person type #' + num;
|
27
|
+
}
|
28
|
+
},
|
29
|
+
default: {
|
30
|
+
type: 'normal',
|
31
|
+
name: FactoryGuy.generate('personName')
|
32
|
+
},
|
33
|
+
dude: {
|
34
|
+
type: FactoryGuy.generate('personType')
|
35
|
+
},
|
36
|
+
bro: {
|
37
|
+
type: FactoryGuy.generate('broType')
|
38
|
+
}
|
39
|
+
});
|
40
|
+
|
41
|
+
var json = FactoryGuy.build('person');
|
42
|
+
deepEqual(json, {id: 1, name: 'person #1', type: 'normal'}, 'in default attributes');
|
43
|
+
|
44
|
+
var json = FactoryGuy.build('dude');
|
45
|
+
deepEqual(json, {id: 2, name: 'person #2', type: 'person type #1'}, 'in named attributes');
|
46
|
+
|
47
|
+
throws( function() {
|
48
|
+
FactoryGuy.build('bro')
|
49
|
+
}, MissingSequenceError,
|
50
|
+
"throws error when sequence name not found"
|
51
|
+
)
|
52
|
+
});
|
53
|
+
|
54
|
+
|
55
|
+
test("#build creates default json for model", function() {
|
56
|
+
var json = FactoryGuy.build('user');
|
57
|
+
deepEqual(json, {id: 1, name: 'User1'});
|
58
|
+
});
|
59
|
+
|
60
|
+
|
61
|
+
test("#build can override default model attributes", function() {
|
62
|
+
var json = FactoryGuy.build('user',{name: 'bob'});
|
63
|
+
deepEqual(json, {id: 1, name: 'bob'});
|
64
|
+
});
|
65
|
+
|
66
|
+
|
67
|
+
test("#build can have named model definition with custom attributes", function() {
|
68
|
+
var json = FactoryGuy.build('admin')
|
69
|
+
deepEqual(json, {id: 1, name: 'Admin'});
|
70
|
+
});
|
71
|
+
|
72
|
+
|
73
|
+
test("#build can override named model attributes", function() {
|
74
|
+
var json = FactoryGuy.build('admin', {name: 'AdminGuy'})
|
75
|
+
deepEqual(json, {id: 1, name: 'AdminGuy'});
|
76
|
+
});
|
77
|
+
|
78
|
+
|
79
|
+
test("#build similar model type ids are created sequentially", function() {
|
80
|
+
var user1 = FactoryGuy.build('user');
|
81
|
+
var user2 = FactoryGuy.build('user');
|
82
|
+
var project = FactoryGuy.build('project');
|
83
|
+
equal(user1.id, 1);
|
84
|
+
equal(user2.id, 2);
|
85
|
+
equal(project.id, 1);
|
86
|
+
});
|
87
|
+
|
88
|
+
|
89
|
+
test("#buildList creates list of fixtures", function() {
|
90
|
+
var userList = FactoryGuy.buildList('user', 2);
|
91
|
+
deepEqual(userList[0], {id: 1, name: 'User1'});
|
92
|
+
deepEqual(userList[1], {id: 2, name: 'User1'});
|
93
|
+
});
|
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
var store;
|
1
|
+
var testHelper, store;
|
3
2
|
|
4
3
|
module('FactoryGuy with DS.FixtureAdapter', {
|
5
4
|
setup: function() {
|
@@ -12,40 +11,6 @@ module('FactoryGuy with DS.FixtureAdapter', {
|
|
12
11
|
});
|
13
12
|
|
14
13
|
|
15
|
-
test("#build creates default json for model", function() {
|
16
|
-
var json = FactoryGuy.build('user');
|
17
|
-
deepEqual(json, {id: 1, name: 'User1'});
|
18
|
-
});
|
19
|
-
|
20
|
-
|
21
|
-
test("#build can override default model attributes", function() {
|
22
|
-
var json = FactoryGuy.build('user',{name: 'bob'});
|
23
|
-
deepEqual(json, {id: 1, name: 'bob'});
|
24
|
-
});
|
25
|
-
|
26
|
-
|
27
|
-
test("#build can have named model definition with custom attributes", function() {
|
28
|
-
var json = FactoryGuy.build('admin')
|
29
|
-
deepEqual(json, {id: 1, name: 'Admin'});
|
30
|
-
});
|
31
|
-
|
32
|
-
|
33
|
-
test("#build can override named model attributes", function() {
|
34
|
-
var json = FactoryGuy.build('admin', {name: 'AdminGuy'})
|
35
|
-
deepEqual(json, {id: 1, name: 'AdminGuy'});
|
36
|
-
});
|
37
|
-
|
38
|
-
|
39
|
-
test("#build similar model type ids are created sequentially", function() {
|
40
|
-
var user1 = FactoryGuy.build('user');
|
41
|
-
var user2 = FactoryGuy.build('user');
|
42
|
-
var project = FactoryGuy.build('project');
|
43
|
-
equal(user1.id, 1);
|
44
|
-
equal(user2.id, 2);
|
45
|
-
equal(project.id, 1);
|
46
|
-
});
|
47
|
-
|
48
|
-
|
49
14
|
test("#pushFixture adds fixture to Fixture array on model", function() {
|
50
15
|
var fixtureJson = FactoryGuy.build('user');
|
51
16
|
FactoryGuy.pushFixture(User, fixtureJson);
|
@@ -68,19 +33,28 @@ asyncTest("can change fixture attributes after creation", function() {
|
|
68
33
|
});
|
69
34
|
|
70
35
|
|
71
|
-
test("#resetModels clears the store of models, clears the FIXTURES arrays for each model and resets the model
|
36
|
+
test("#resetModels clears the store of models, clears the FIXTURES arrays for each model and resets the model definition", function() {
|
72
37
|
var project = store.makeFixture('project');
|
73
38
|
var user = store.makeFixture('user', {projects: [project.id]});
|
74
39
|
|
40
|
+
for (model in FactoryGuy.modelDefinitions) {
|
41
|
+
var definition = FactoryGuy.modelDefinitions[model];
|
42
|
+
sinon.spy(definition, 'reset');
|
43
|
+
}
|
44
|
+
|
75
45
|
FactoryGuy.resetModels(store);
|
76
46
|
|
77
47
|
equal(User.FIXTURES.length, 0);
|
78
48
|
equal(Project.FIXTURES.length, 0);
|
79
49
|
|
80
|
-
equal(store.all('user').get('content.length'),0)
|
81
|
-
equal(store.all('project').get('content.length'),0)
|
50
|
+
equal(store.all('user').get('content.length'), 0)
|
51
|
+
equal(store.all('project').get('content.length'), 0)
|
82
52
|
|
83
|
-
|
53
|
+
for (model in FactoryGuy.modelDefinitions) {
|
54
|
+
var definition = FactoryGuy.modelDefinitions[model];
|
55
|
+
ok(definition.reset.calledOnce);
|
56
|
+
definition.reset.restore();
|
57
|
+
}
|
84
58
|
});
|
85
59
|
|
86
60
|
|