ember-data-factory-guy 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|