ember-data-factory-guy 0.1.3 → 0.2.0
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/Gruntfile.js +1 -0
- data/README.md +45 -26
- data/bower.json +1 -1
- data/dist/ember-data-factory-guy.js +247 -124
- data/dist/ember-data-factory-guy.min.js +1 -1
- data/ember-data-factory-guy.gemspec +1 -1
- data/package.json +2 -7
- data/src/factory_guy.js +56 -24
- data/src/factory_guy_test_mixin.js +26 -7
- data/src/model_definition.js +41 -16
- data/src/sequence.js +2 -3
- data/src/store.js +123 -74
- data/tests/active_model_adapter_factory_test.js +9 -2
- data/tests/factory_guy_test.js +28 -1
- data/tests/fixture_adapter_factory_test.js +15 -15
- data/tests/rest_adapter_factory_test.js +35 -1
- data/vendor/assets/javascripts/ember_data_factory_guy.js +247 -124
- metadata +2 -2
| @@ -65,7 +65,7 @@ test("supports hasMany associations", function() { | |
| 65 65 | 
             
              var user = store.makeFixture('user', {projects: [p1.id, p2.id]})
         | 
| 66 66 |  | 
| 67 67 | 
             
              equal(user.get('projects.length'), 2);
         | 
| 68 | 
            -
            })
         | 
| 68 | 
            +
            });
         | 
| 69 69 |  | 
| 70 70 |  | 
| 71 71 | 
             
            test("when hasMany associations assigned, belongTo parent is assigned", function() {
         | 
| @@ -73,7 +73,14 @@ test("when hasMany associations assigned, belongTo parent is assigned", function | |
| 73 73 | 
             
              var user = store.makeFixture('user', {projects: [p1.id]})
         | 
| 74 74 |  | 
| 75 75 | 
             
              deepEqual(p1.get('user').toJSON(), user.toJSON());
         | 
| 76 | 
            -
            })
         | 
| 76 | 
            +
            });
         | 
| 77 | 
            +
             | 
| 78 | 
            +
            test("when belongTo parent is assigned, parent adds to hasMany records", function() {
         | 
| 79 | 
            +
              var user = store.makeFixture('user');
         | 
| 80 | 
            +
              var project = store.makeFixture('project', {user: user});
         | 
| 81 | 
            +
             | 
| 82 | 
            +
              equal(user.get('projects.length'), 1);
         | 
| 83 | 
            +
            });
         | 
| 77 84 |  | 
| 78 85 |  | 
| 79 86 | 
             
            module('DS.Store#makeList with ActiveModelAdapter', {
         | 
    
        data/tests/factory_guy_test.js
    CHANGED
    
    | @@ -17,6 +17,8 @@ module('FactoryGuy', { | |
| 17 17 |  | 
| 18 18 |  | 
| 19 19 | 
             
            test("Using sequences in definitions", function() {
         | 
| 20 | 
            +
              delete FactoryGuy.modelDefinitions['person']
         | 
| 21 | 
            +
             | 
| 20 22 | 
             
              FactoryGuy.define('person', {
         | 
| 21 23 | 
             
                sequences: {
         | 
| 22 24 | 
             
                  personName: function(num) {
         | 
| @@ -50,6 +52,31 @@ test("Using sequences in definitions", function() { | |
| 50 52 | 
             
                MissingSequenceError,
         | 
| 51 53 | 
             
                "throws error when sequence name not found"
         | 
| 52 54 | 
             
              )
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            });
         | 
| 57 | 
            +
             | 
| 58 | 
            +
             | 
| 59 | 
            +
            test("Referring to other attributes in attribute definition", function() {
         | 
| 60 | 
            +
              delete FactoryGuy.modelDefinitions['person']
         | 
| 61 | 
            +
             | 
| 62 | 
            +
              FactoryGuy.define('person', {
         | 
| 63 | 
            +
                default: {
         | 
| 64 | 
            +
                  name: 'Bob',
         | 
| 65 | 
            +
                  type: 'normal'
         | 
| 66 | 
            +
                },
         | 
| 67 | 
            +
                funny_person: {
         | 
| 68 | 
            +
                  type: function(fixture) { return 'funny ' + fixture.name }
         | 
| 69 | 
            +
                },
         | 
| 70 | 
            +
                missing_person: {
         | 
| 71 | 
            +
                  type: function(fixture) { return 'level ' + fixture.brain_size }
         | 
| 72 | 
            +
                }
         | 
| 73 | 
            +
              });
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              var json = FactoryGuy.build('funny_person');
         | 
| 76 | 
            +
              deepEqual(json, {id: 1, name: 'Bob', type: 'funny Bob'}, 'works when attribute exists');
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              var json = FactoryGuy.build('missing_person');
         | 
| 79 | 
            +
              deepEqual(json, {id: 2, name: 'Bob', type: 'level undefined'}, 'still works when attribute does not exists');
         | 
| 53 80 | 
             
            });
         | 
| 54 81 |  | 
| 55 82 |  | 
| @@ -91,4 +118,4 @@ test("#buildList creates list of fixtures", function() { | |
| 91 118 | 
             
              var userList = FactoryGuy.buildList('user', 2);
         | 
| 92 119 | 
             
              deepEqual(userList[0], {id: 1, name: 'User1'});
         | 
| 93 120 | 
             
              deepEqual(userList[1], {id: 2, name: 'User1'});
         | 
| 94 | 
            -
            });
         | 
| 121 | 
            +
            });
         | 
| @@ -69,7 +69,7 @@ module('DS.Store with DS.FixtureAdapter', { | |
| 69 69 | 
             
            });
         | 
| 70 70 |  | 
| 71 71 |  | 
| 72 | 
            -
            test("#makeFixture builds and pushes fixture into the  | 
| 72 | 
            +
            test("#makeFixture builds and pushes fixture into the models FIXTURE array", function() {
         | 
| 73 73 | 
             
              var json = store.makeFixture('user');
         | 
| 74 74 | 
             
              equal(User.FIXTURES.length, 1);
         | 
| 75 75 | 
             
              equal(User.FIXTURES[0], json);
         | 
| @@ -92,17 +92,17 @@ asyncTest("#makeFixture sets hasMany associations on fixtures", function() { | |
| 92 92 | 
             
              })
         | 
| 93 93 | 
             
            })
         | 
| 94 94 |  | 
| 95 | 
            -
             | 
| 96 | 
            -
             | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 95 | 
            +
            asyncTest("#createRecord adds belongsTo associations to hasMany array", function() {
         | 
| 96 | 
            +
              var user = store.makeFixture('user');
         | 
| 97 | 
            +
             | 
| 98 | 
            +
              store.find('user', user.id).then(function(user) {
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                var projectJson = {title:'project', user: user};
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                store.createRecord('project', projectJson).save()
         | 
| 103 | 
            +
                  .then( function() {
         | 
| 104 | 
            +
                    equal(user.get('projects.length'), 1);
         | 
| 105 | 
            +
                    start();
         | 
| 106 | 
            +
                  });
         | 
| 107 | 
            +
              })
         | 
| 108 | 
            +
            })
         | 
| @@ -72,4 +72,38 @@ test("when hasMany associations assigned, belongTo parent is assigned", function | |
| 72 72 | 
             
              var user = store.makeFixture('user', {projects: [p1.id]})
         | 
| 73 73 |  | 
| 74 74 | 
             
              deepEqual(p1.get('user').toJSON(), user.toJSON());
         | 
| 75 | 
            -
            });
         | 
| 75 | 
            +
            });
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            test("when belongTo parent is assigned, parent adds to hasMany records", function() {
         | 
| 78 | 
            +
              var user = store.makeFixture('user');
         | 
| 79 | 
            +
              var project = store.makeFixture('project', {user: user});
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              equal(user.get('projects.length'), 1);
         | 
| 82 | 
            +
            });
         | 
| 83 | 
            +
             | 
| 84 | 
            +
             | 
| 85 | 
            +
            module('DS.Store#makeList with ActiveModelAdapter', {
         | 
| 86 | 
            +
              setup: function() {
         | 
| 87 | 
            +
                testHelper = TestHelper.setup(DS.RESTAdapter);
         | 
| 88 | 
            +
                store = testHelper.getStore();
         | 
| 89 | 
            +
              },
         | 
| 90 | 
            +
              teardown: function() {
         | 
| 91 | 
            +
                Em.run(function() { testHelper.teardown(); });
         | 
| 92 | 
            +
              }
         | 
| 93 | 
            +
            });
         | 
| 94 | 
            +
             | 
| 95 | 
            +
             | 
| 96 | 
            +
            test("creates list of DS.Model instances", function() {
         | 
| 97 | 
            +
              var users = store.makeList('user', 2);
         | 
| 98 | 
            +
              equal(users.length, 2);
         | 
| 99 | 
            +
              equal(users[0] instanceof DS.Model, true);
         | 
| 100 | 
            +
            });
         | 
| 101 | 
            +
             | 
| 102 | 
            +
             | 
| 103 | 
            +
            test("creates records in the store", function() {
         | 
| 104 | 
            +
              var users = store.makeList('user', 2);
         | 
| 105 | 
            +
             | 
| 106 | 
            +
              var storeUsers = store.all('user').get('content');
         | 
| 107 | 
            +
              deepEqual(storeUsers[0].toJSON(), users[0].toJSON());
         | 
| 108 | 
            +
              deepEqual(storeUsers[1].toJSON(), users[1].toJSON());
         | 
| 109 | 
            +
            });
         | 
| @@ -1,6 +1,5 @@ | |
| 1 1 | 
             
            Sequence = function (fn) {
         | 
| 2 2 | 
             
              var index = 1;
         | 
| 3 | 
            -
              var fn = fn;
         | 
| 4 3 |  | 
| 5 4 | 
             
              this.next = function () {
         | 
| 6 5 | 
             
                return fn.call(this, index++);
         | 
| @@ -9,12 +8,19 @@ Sequence = function (fn) { | |
| 9 8 | 
             
              this.reset = function () {
         | 
| 10 9 | 
             
                index = 1;
         | 
| 11 10 | 
             
              }
         | 
| 12 | 
            -
            }
         | 
| 11 | 
            +
            };
         | 
| 13 12 |  | 
| 14 13 | 
             
            function MissingSequenceError(message) {
         | 
| 15 14 | 
             
              this.toString = function() { return message }
         | 
| 16 | 
            -
            }
         | 
| 15 | 
            +
            };
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            /**
         | 
| 18 | 
            +
             A ModelDefinition encapsulates a model's definition
         | 
| 17 19 |  | 
| 20 | 
            +
             @param model
         | 
| 21 | 
            +
             @param config
         | 
| 22 | 
            +
             @constructor
         | 
| 23 | 
            +
             */
         | 
| 18 24 | 
             
            ModelDefinition = function (model, config) {
         | 
| 19 25 | 
             
              var sequences = {};
         | 
| 20 26 | 
             
              var defaultAttributes = {};
         | 
| @@ -23,36 +29,50 @@ ModelDefinition = function (model, config) { | |
| 23 29 | 
             
              this.model = model;
         | 
| 24 30 |  | 
| 25 31 | 
             
              /**
         | 
| 26 | 
            -
               @param name model name like 'user' or named type like 'admin'
         | 
| 27 | 
            -
               @ | 
| 28 | 
            -
             | 
| 32 | 
            +
               @param {String} name model name like 'user' or named type like 'admin'
         | 
| 33 | 
            +
               @returns {Boolean} true if name is this definitions model or this definition
         | 
| 34 | 
            +
               contains a named model with that name
         | 
| 29 35 | 
             
               */
         | 
| 30 36 | 
             
              this.matchesName = function (name) {
         | 
| 31 37 | 
             
                return model == name || namedModels[name];
         | 
| 32 38 | 
             
              }
         | 
| 33 39 |  | 
| 40 | 
            +
              // TODO
         | 
| 34 41 | 
             
              this.merge = function (config) {
         | 
| 35 42 | 
             
              }
         | 
| 36 43 |  | 
| 37 44 | 
             
              /**
         | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 45 | 
            +
               Call the next method on the named sequence function
         | 
| 46 | 
            +
             | 
| 47 | 
            +
               @param {String} sequenceName
         | 
| 48 | 
            +
               @returns {String} output of sequence function
         | 
| 40 49 | 
             
               */
         | 
| 41 50 | 
             
              this.generate = function (sequenceName) {
         | 
| 42 | 
            -
                 | 
| 43 | 
            -
             | 
| 51 | 
            +
                var sequence = sequences[sequenceName];
         | 
| 52 | 
            +
                if (!sequence) {
         | 
| 53 | 
            +
                  throw new MissingSequenceError("Can not find that sequence named [" + sequenceName + "] in '" + model + "' definition")
         | 
| 44 54 | 
             
                }
         | 
| 45 | 
            -
                return  | 
| 55 | 
            +
                return sequence.next();
         | 
| 46 56 | 
             
              }
         | 
| 47 57 |  | 
| 58 | 
            +
              /**
         | 
| 59 | 
            +
               Build a fixture by name
         | 
| 60 | 
            +
             | 
| 61 | 
            +
               @param {String} name fixture name
         | 
| 62 | 
            +
               @param {Object} opts attributes to override
         | 
| 63 | 
            +
               @returns {Object} json
         | 
| 64 | 
            +
               */
         | 
| 48 65 | 
             
              this.build = function (name, opts) {
         | 
| 49 66 | 
             
                var modelAttributes = namedModels[name] || {};
         | 
| 67 | 
            +
                // merge default, modelAttributes and opts to get the rough fixture
         | 
| 50 68 | 
             
                var fixture = $.extend({}, defaultAttributes, modelAttributes, opts);
         | 
| 51 | 
            -
                 | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 69 | 
            +
                // convert attributes that are functions to strings
         | 
| 70 | 
            +
                for (attribute in fixture) {
         | 
| 71 | 
            +
                  if (typeof fixture[attribute] == 'function') {
         | 
| 72 | 
            +
                    fixture[attribute] = fixture[attribute].call(this, fixture);
         | 
| 54 73 | 
             
                  }
         | 
| 55 74 | 
             
                }
         | 
| 75 | 
            +
                // set the id, unless it was already set in opts
         | 
| 56 76 | 
             
                if (!fixture.id) {
         | 
| 57 77 | 
             
                  fixture.id = modelId++;
         | 
| 58 78 | 
             
                }
         | 
| @@ -60,12 +80,12 @@ ModelDefinition = function (model, config) { | |
| 60 80 | 
             
              }
         | 
| 61 81 |  | 
| 62 82 | 
             
              /**
         | 
| 63 | 
            -
             | 
| 83 | 
            +
               Build a list of fixtures
         | 
| 64 84 |  | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 85 | 
            +
               @param name model name or named model type
         | 
| 86 | 
            +
               @param number of fixtures to build
         | 
| 87 | 
            +
               @param opts attribute options
         | 
| 88 | 
            +
               @returns array of fixtures
         | 
| 69 89 | 
             
               */
         | 
| 70 90 | 
             
              this.buildList = function (name, number, opts) {
         | 
| 71 91 | 
             
                var arr = [];
         | 
| @@ -75,8 +95,12 @@ ModelDefinition = function (model, config) { | |
| 75 95 | 
             
                return arr;
         | 
| 76 96 | 
             
              }
         | 
| 77 97 |  | 
| 98 | 
            +
              // Set the modelId back to 1, and reset the sequences
         | 
| 78 99 | 
             
              this.reset = function () {
         | 
| 79 100 | 
             
                modelId = 1;
         | 
| 101 | 
            +
                for (name in sequences) {
         | 
| 102 | 
            +
                  sequences[name].reset();
         | 
| 103 | 
            +
                }
         | 
| 80 104 | 
             
              }
         | 
| 81 105 |  | 
| 82 106 | 
             
              var parseDefault = function (object) {
         | 
| @@ -144,12 +168,12 @@ FactoryGuy = { | |
| 144 168 |  | 
| 145 169 | 
             
               ```
         | 
| 146 170 |  | 
| 147 | 
            -
               For the Person model, you can define fixtures like 'dude' or | 
| 148 | 
            -
               and get default values.
         | 
| 171 | 
            +
               For the Person model, you can define named fixtures like 'dude' or
         | 
| 172 | 
            +
               just use 'person' and get default values.
         | 
| 149 173 |  | 
| 150 174 | 
             
               And to get those fixtures you would call them this way:
         | 
| 151 175 |  | 
| 152 | 
            -
               FactoryGuy.build(' | 
| 176 | 
            +
               FactoryGuy.build('dude') or FactoryGuy.build('person')
         | 
| 153 177 |  | 
| 154 178 | 
             
               @param model the model to define
         | 
| 155 179 | 
             
               @param config your model definition object
         | 
| @@ -162,18 +186,41 @@ FactoryGuy = { | |
| 162 186 | 
             
                }
         | 
| 163 187 | 
             
              },
         | 
| 164 188 |  | 
| 189 | 
            +
              /**
         | 
| 190 | 
            +
               Used in model definitions to declare use of a sequence. For example:
         | 
| 191 | 
            +
             | 
| 192 | 
            +
               ```
         | 
| 193 | 
            +
             | 
| 194 | 
            +
               FactoryGuy.define('person', {
         | 
| 195 | 
            +
                 sequences: {
         | 
| 196 | 
            +
                   personName: function(num) {
         | 
| 197 | 
            +
                     return 'person #' + num;
         | 
| 198 | 
            +
                   }
         | 
| 199 | 
            +
                 },
         | 
| 200 | 
            +
                 default: {
         | 
| 201 | 
            +
                   name: FactoryGuy.generate('personName')
         | 
| 202 | 
            +
                 }
         | 
| 203 | 
            +
               });
         | 
| 204 | 
            +
             | 
| 205 | 
            +
               ```
         | 
| 206 | 
            +
             | 
| 207 | 
            +
               @param   {String} sequenceName
         | 
| 208 | 
            +
               @returns {Function} wrapper function that is called by the model
         | 
| 209 | 
            +
                        definition containing the sequence
         | 
| 210 | 
            +
               */
         | 
| 165 211 | 
             
              generate: function (sequenceName) {
         | 
| 166 212 | 
             
                return function () {
         | 
| 167 213 | 
             
                  return this.generate(sequenceName);
         | 
| 168 214 | 
             
                }
         | 
| 169 215 | 
             
              },
         | 
| 170 216 |  | 
| 171 | 
            -
             | 
| 172 217 | 
             
              /**
         | 
| 218 | 
            +
                Given a name like 'person' or 'dude' determine what model this name
         | 
| 219 | 
            +
                refers to. In this case it's 'person' for each one.
         | 
| 173 220 |  | 
| 174 | 
            -
               @param name fixture name could be model name like ' | 
| 175 | 
            -
             | 
| 176 | 
            -
               @returns model associated with fixture name
         | 
| 221 | 
            +
               @param {String} name a fixture name could be model name like 'person'
         | 
| 222 | 
            +
                      or a named person in model definition like 'dude'
         | 
| 223 | 
            +
               @returns {String} model name associated with fixture name
         | 
| 177 224 | 
             
               */
         | 
| 178 225 | 
             
              lookupModelForName: function (name) {
         | 
| 179 226 | 
             
                for (model in this.modelDefinitions) {
         | 
| @@ -186,9 +233,9 @@ FactoryGuy = { | |
| 186 233 |  | 
| 187 234 | 
             
              /**
         | 
| 188 235 |  | 
| 189 | 
            -
               @param name fixture name could be model name like ' | 
| 190 | 
            -
             | 
| 191 | 
            -
               @returns definition associated with model
         | 
| 236 | 
            +
               @param {String} name a fixture name could be model name like 'person'
         | 
| 237 | 
            +
                      or a named person in model definition like 'dude'
         | 
| 238 | 
            +
               @returns {ModelDefinition} definition associated with model
         | 
| 192 239 | 
             
               */
         | 
| 193 240 | 
             
              lookupDefinitionForName: function (name) {
         | 
| 194 241 | 
             
                for (model in this.modelDefinitions) {
         | 
| @@ -206,9 +253,9 @@ FactoryGuy = { | |
| 206 253 | 
             
               FactoryGuy.build('user') for User model
         | 
| 207 254 | 
             
               FactoryGuy.build('bob') for User model with bob attributes
         | 
| 208 255 |  | 
| 209 | 
            -
               @param name fixture name
         | 
| 210 | 
            -
               @param opts options that will override default fixture values
         | 
| 211 | 
            -
               @returns { | 
| 256 | 
            +
               @param {String} name fixture name
         | 
| 257 | 
            +
               @param {Object} opts options that will override default fixture values
         | 
| 258 | 
            +
               @returns {Object} json fixture
         | 
| 212 259 | 
             
               */
         | 
| 213 260 | 
             
              build: function (name, opts) {
         | 
| 214 261 | 
             
                var definition = this.lookupDefinitionForName(name);
         | 
| @@ -224,10 +271,10 @@ FactoryGuy = { | |
| 224 271 | 
             
               FactoryGuy.buildList('user', 2) for 2 User models
         | 
| 225 272 | 
             
               FactoryGuy.build('bob', 2) for 2 User model with bob attributes
         | 
| 226 273 |  | 
| 227 | 
            -
               @param name fixture name
         | 
| 228 | 
            -
               @param number number of fixtures to create
         | 
| 229 | 
            -
               @param opts options that will override default fixture values
         | 
| 230 | 
            -
               @returns list of fixtures
         | 
| 274 | 
            +
               @param {String} name fixture name
         | 
| 275 | 
            +
               @param {Number} number number of fixtures to create
         | 
| 276 | 
            +
               @param {Object} opts options that will override default fixture values
         | 
| 277 | 
            +
               @returns {Array} list of fixtures
         | 
| 231 278 | 
             
               */
         | 
| 232 279 | 
             
              buildList: function (name, number, opts) {
         | 
| 233 280 | 
             
                var definition = this.lookupDefinitionForName(name);
         | 
| @@ -238,9 +285,11 @@ FactoryGuy = { | |
| 238 285 | 
             
              },
         | 
| 239 286 |  | 
| 240 287 | 
             
              /**
         | 
| 288 | 
            +
               TODO: This is kind of problematic right now .. needs work
         | 
| 289 | 
            +
             | 
| 241 290 | 
             
               Clear model instances from FIXTURES array, and from store cache.
         | 
| 242 291 | 
             
               Reset the id sequence for the models back to zero.
         | 
| 243 | 
            -
             | 
| 292 | 
            +
              */
         | 
| 244 293 | 
             
              resetModels: function (store) {
         | 
| 245 294 | 
             
                var typeMaps = store.typeMaps;
         | 
| 246 295 | 
             
                for (model in this.modelDefinitions) {
         | 
| @@ -259,9 +308,6 @@ FactoryGuy = { | |
| 259 308 | 
             
            //        store.unloadAll(typeMaps[model].type);
         | 
| 260 309 | 
             
            //      }
         | 
| 261 310 | 
             
            //    }
         | 
| 262 | 
            -
             | 
| 263 | 
            -
            //    for (model in this.modelDefinitions) {
         | 
| 264 | 
            -
            //      this.modelDefinitions[model].reset();
         | 
| 265 311 | 
             
                }
         | 
| 266 312 | 
             
              },
         | 
| 267 313 |  | 
| @@ -269,9 +315,9 @@ FactoryGuy = { | |
| 269 315 | 
             
               Push fixture to model's FIXTURES array.
         | 
| 270 316 | 
             
               Used when store's adapter is a DS.FixtureAdapter.
         | 
| 271 317 |  | 
| 272 | 
            -
               @param  | 
| 273 | 
            -
               @param fixture the fixture to add
         | 
| 274 | 
            -
               @returns json fixture data
         | 
| 318 | 
            +
               @param {DS.Model} modelClass
         | 
| 319 | 
            +
               @param {Object} fixture the fixture to add
         | 
| 320 | 
            +
               @returns {Object} json fixture data
         | 
| 275 321 | 
             
               */
         | 
| 276 322 | 
             
              pushFixture: function (modelClass, fixture) {
         | 
| 277 323 | 
             
                if (!modelClass['FIXTURES']) {
         | 
| @@ -279,22 +325,34 @@ FactoryGuy = { | |
| 279 325 | 
             
                }
         | 
| 280 326 | 
             
                modelClass['FIXTURES'].push(fixture);
         | 
| 281 327 | 
             
                return fixture;
         | 
| 328 | 
            +
              },
         | 
| 329 | 
            +
             | 
| 330 | 
            +
              /**
         | 
| 331 | 
            +
               Clears all model definitions
         | 
| 332 | 
            +
              */
         | 
| 333 | 
            +
              clear: function (opts) {
         | 
| 334 | 
            +
                if (!opts) {
         | 
| 335 | 
            +
                  this.modelDefinitions = {};
         | 
| 336 | 
            +
                  return;
         | 
| 337 | 
            +
                }
         | 
| 282 338 | 
             
              }
         | 
| 283 339 | 
             
            }
         | 
| 284 340 | 
             
            DS.Store.reopen({
         | 
| 285 | 
            -
             | 
| 286 | 
            -
             | 
| 341 | 
            +
              /**
         | 
| 342 | 
            +
               @returns {Boolean} true if store's adapter is DS.FixtureAdapter
         | 
| 343 | 
            +
               */
         | 
| 344 | 
            +
              usingFixtureAdapter: function () {
         | 
| 287 345 | 
             
                var adapter = this.adapterFor('application');
         | 
| 288 | 
            -
                return adapter instanceof DS.FixtureAdapter
         | 
| 346 | 
            +
                return adapter instanceof DS.FixtureAdapter;
         | 
| 289 347 | 
             
              },
         | 
| 290 348 |  | 
| 291 349 | 
             
              /**
         | 
| 292 | 
            -
             | 
| 293 | 
            -
             | 
| 350 | 
            +
               Make new fixture and save to store. If the store is using FixtureAdapter,
         | 
| 351 | 
            +
               will push to FIXTURE array, otherwise will use push method on adapter.
         | 
| 294 352 |  | 
| 295 | 
            -
             | 
| 296 | 
            -
             | 
| 297 | 
            -
             | 
| 353 | 
            +
               @param {String} name name of fixture
         | 
| 354 | 
            +
               @param {Object} options fixture options
         | 
| 355 | 
            +
               @returns {Object|DS.Model} json or record depending on the adapter type
         | 
| 298 356 | 
             
               */
         | 
| 299 357 | 
             
              makeFixture: function (name, options) {
         | 
| 300 358 | 
             
                var modelName = FactoryGuy.lookupModelForName(name);
         | 
| @@ -307,7 +365,7 @@ DS.Store.reopen({ | |
| 307 365 | 
             
                } else {
         | 
| 308 366 | 
             
                  var self = this;
         | 
| 309 367 | 
             
                  var model;
         | 
| 310 | 
            -
                  Em.run(  | 
| 368 | 
            +
                  Em.run(function () {
         | 
| 311 369 | 
             
                    model = self.push(modelName, fixture);
         | 
| 312 370 | 
             
                    self.setBelongsToRESTAdapter(modelType, modelName, model);
         | 
| 313 371 | 
             
                  });
         | 
| @@ -316,13 +374,13 @@ DS.Store.reopen({ | |
| 316 374 | 
             
              },
         | 
| 317 375 |  | 
| 318 376 | 
             
              /**
         | 
| 319 | 
            -
             | 
| 377 | 
            +
               Make a list of Fixtures
         | 
| 320 378 |  | 
| 321 | 
            -
             | 
| 322 | 
            -
             | 
| 323 | 
            -
             | 
| 324 | 
            -
             | 
| 325 | 
            -
             | 
| 379 | 
            +
               @param {String} name name of fixture
         | 
| 380 | 
            +
               @param {Number} number number to create
         | 
| 381 | 
            +
               @param {Object} options fixture options
         | 
| 382 | 
            +
               @returns {Array} list of json fixtures or records depending on the adapter type
         | 
| 383 | 
            +
               */
         | 
| 326 384 | 
             
              makeList: function (name, number, options) {
         | 
| 327 385 | 
             
                var arr = [];
         | 
| 328 386 | 
             
                for (var i = 0; i < number; i++) {
         | 
| @@ -332,16 +390,16 @@ DS.Store.reopen({ | |
| 332 390 | 
             
              },
         | 
| 333 391 |  | 
| 334 392 | 
             
              /**
         | 
| 335 | 
            -
             | 
| 336 | 
            -
             | 
| 393 | 
            +
               Set the belongsTo association for FixtureAdapter,
         | 
| 394 | 
            +
               with models that have a hasMany association.
         | 
| 337 395 |  | 
| 338 | 
            -
             | 
| 339 | 
            -
             | 
| 340 | 
            -
             | 
| 396 | 
            +
               For example if a user hasMany projects, then set the user.id
         | 
| 397 | 
            +
               on each project that the user hasMany of, so that the project
         | 
| 398 | 
            +
               now has the belongsTo user association setup.
         | 
| 341 399 |  | 
| 342 | 
            -
             | 
| 343 | 
            -
             | 
| 344 | 
            -
             | 
| 400 | 
            +
               @param {String} modelType model type like App.User
         | 
| 401 | 
            +
               @param {String} modelName model name like 'user'
         | 
| 402 | 
            +
               @param {Object} parentFixture parent to assign as belongTo
         | 
| 345 403 | 
             
               */
         | 
| 346 404 | 
             
              setBelongsToFixturesAdapter: function (modelType, modelName, parentFixture) {
         | 
| 347 405 | 
             
                var store = this;
         | 
| @@ -351,7 +409,7 @@ DS.Store.reopen({ | |
| 351 409 | 
             
                  relationShips.hasMany.forEach(function (relationship) {
         | 
| 352 410 | 
             
                    var hasManyModel = store.modelFor(Em.String.singularize(relationship));
         | 
| 353 411 | 
             
                    if (parentFixture[relationship]) {
         | 
| 354 | 
            -
                      parentFixture[relationship].forEach(function(id) {
         | 
| 412 | 
            +
                      parentFixture[relationship].forEach(function (id) {
         | 
| 355 413 | 
             
                        var hasManyfixtures = adapter.fixturesForType(hasManyModel);
         | 
| 356 414 | 
             
                        var fixture = adapter.findFixtureById(hasManyfixtures, id);
         | 
| 357 415 | 
             
                        fixture[modelName] = parentFixture.id;
         | 
| @@ -362,38 +420,59 @@ DS.Store.reopen({ | |
| 362 420 | 
             
              },
         | 
| 363 421 |  | 
| 364 422 | 
             
              /**
         | 
| 365 | 
            -
             | 
| 366 | 
            -
             | 
| 423 | 
            +
               For the REST type models:
         | 
| 424 | 
            +
             | 
| 425 | 
            +
               Set the belongsTo association with a hasMany association
         | 
| 367 426 |  | 
| 368 | 
            -
             | 
| 369 | 
            -
                on each project that the user hasMany of, so that the project
         | 
| 370 | 
            -
                now has the belongsTo user association setup
         | 
| 427 | 
            +
               Set this model in the parent hasMany array this model belongsTo
         | 
| 371 428 |  | 
| 372 | 
            -
             | 
| 373 | 
            -
             | 
| 374 | 
            -
             | 
| 429 | 
            +
               For example if a user hasMany projects, then set the user
         | 
| 430 | 
            +
               on each project that the user hasMany of, so that the project
         | 
| 431 | 
            +
               now has the belongsTo user association setup
         | 
| 432 | 
            +
             | 
| 433 | 
            +
               @param {DS.Model} modelType model type like 'User'
         | 
| 434 | 
            +
               @param {String} modelName model name like 'user'
         | 
| 435 | 
            +
               @param {DS.Model} model
         | 
| 375 436 | 
             
               */
         | 
| 376 | 
            -
              setBelongsToRESTAdapter: function (modelType, modelName,  | 
| 377 | 
            -
                var  | 
| 437 | 
            +
              setBelongsToRESTAdapter: function (modelType, modelName, model) {
         | 
| 438 | 
            +
                var self = this;
         | 
| 439 | 
            +
                Ember.get(modelType, 'relationshipsByName').forEach(function (name, relationship) {
         | 
| 440 | 
            +
                  if (relationship.kind == 'hasMany') {
         | 
| 441 | 
            +
                    var children = model.get(name) || [];
         | 
| 442 | 
            +
                    children.forEach(function (child) {
         | 
| 443 | 
            +
                      child.set(modelName, model)
         | 
| 444 | 
            +
                    })
         | 
| 445 | 
            +
                  }
         | 
| 378 446 |  | 
| 379 | 
            -
             | 
| 380 | 
            -
             | 
| 381 | 
            -
                     | 
| 382 | 
            -
             | 
| 383 | 
            -
                       | 
| 384 | 
            -
                        child.set(modelName, parent)
         | 
| 385 | 
            -
                      })
         | 
| 447 | 
            +
                  if (relationship.kind == 'belongsTo') {
         | 
| 448 | 
            +
                    var belongsToRecord = model.get(name);
         | 
| 449 | 
            +
                    if (belongsToRecord) {
         | 
| 450 | 
            +
                      var hasManyName = self.findHasManyRelationshipName(belongsToRecord, model)
         | 
| 451 | 
            +
                      belongsToRecord.get(hasManyName).addObject(model);
         | 
| 386 452 | 
             
                    }
         | 
| 387 | 
            -
                  } | 
| 388 | 
            -
                }
         | 
| 453 | 
            +
                  }
         | 
| 454 | 
            +
                })
         | 
| 455 | 
            +
              },
         | 
| 456 | 
            +
             | 
| 457 | 
            +
              findHasManyRelationshipName: function (belongToModel, childModel) {
         | 
| 458 | 
            +
                var relationshipName;
         | 
| 459 | 
            +
                Ember.get(belongToModel.constructor, 'relationshipsByName').forEach(
         | 
| 460 | 
            +
                  function (name, relationship) {
         | 
| 461 | 
            +
                    if (relationship.kind == 'hasMany' &&
         | 
| 462 | 
            +
                      relationship.type == childModel.constructor) {
         | 
| 463 | 
            +
                      relationshipName = relationship.key;
         | 
| 464 | 
            +
                    }
         | 
| 465 | 
            +
                  }
         | 
| 466 | 
            +
                )
         | 
| 467 | 
            +
                return relationshipName;
         | 
| 389 468 | 
             
              },
         | 
| 390 469 |  | 
| 391 470 | 
             
              /**
         | 
| 392 | 
            -
             | 
| 393 | 
            -
             | 
| 471 | 
            +
               Adding a pushPayload for FixtureAdapter, but using the original with
         | 
| 472 | 
            +
               other adapters that support pushPayload.
         | 
| 394 473 |  | 
| 395 | 
            -
             | 
| 396 | 
            -
             | 
| 474 | 
            +
               @param {String} type
         | 
| 475 | 
            +
               @param {Object} payload
         | 
| 397 476 | 
             
               */
         | 
| 398 477 | 
             
              pushPayload: function (type, payload) {
         | 
| 399 478 | 
             
                if (this.usingFixtureAdapter()) {
         | 
| @@ -409,38 +488,63 @@ DS.Store.reopen({ | |
| 409 488 | 
             
            DS.FixtureAdapter.reopen({
         | 
| 410 489 |  | 
| 411 490 | 
             
              /**
         | 
| 412 | 
            -
             | 
| 413 | 
            -
             | 
| 414 | 
            -
             | 
| 415 | 
            -
             | 
| 416 | 
            -
             | 
| 417 | 
            -
             | 
| 418 | 
            -
             | 
| 419 | 
            -
             | 
| 420 | 
            -
             | 
| 421 | 
            -
             | 
| 422 | 
            -
             | 
| 491 | 
            +
               Overriding createRecord to add the record created to the
         | 
| 492 | 
            +
               hashMany records for all of the records that this record belongsTo.
         | 
| 493 | 
            +
             | 
| 494 | 
            +
               For example:
         | 
| 495 | 
            +
             | 
| 496 | 
            +
               If models are defined like so:
         | 
| 497 | 
            +
             | 
| 498 | 
            +
               User = DS.Model.extend({
         | 
| 499 | 
            +
                   projects: DS.hasMany('project')
         | 
| 500 | 
            +
                 })
         | 
| 501 | 
            +
             | 
| 502 | 
            +
               Project = DS.Model.extend({
         | 
| 503 | 
            +
                   user: DS.belongsTo('user')
         | 
| 504 | 
            +
                 })
         | 
| 505 | 
            +
             | 
| 506 | 
            +
               and you create a project record with a user defined:
         | 
| 507 | 
            +
                store.createRecord('project', {user: user})
         | 
| 508 | 
            +
             | 
| 509 | 
            +
               this method will take the new project created and add it to the user's 'projects'
         | 
| 510 | 
            +
               hasMany array.
         | 
| 511 | 
            +
             | 
| 512 | 
            +
               And a full code example:
         | 
| 513 | 
            +
             | 
| 514 | 
            +
               var userJson = store.makeFixture('user');
         | 
| 515 | 
            +
             | 
| 516 | 
            +
               store.find('user', userJson.id).then(function(user) {
         | 
| 517 | 
            +
                   store.createRecord('project', {user: user}).save()
         | 
| 518 | 
            +
                     .then( function(project) {
         | 
| 519 | 
            +
                       // user.get('projects.length') == 1;
         | 
| 520 | 
            +
                   })
         | 
| 521 | 
            +
                 })
         | 
| 522 | 
            +
             | 
| 523 | 
            +
               @method createRecord
         | 
| 524 | 
            +
               @param {DS.Store} store
         | 
| 525 | 
            +
               @param {subclass of DS.Model} type
         | 
| 526 | 
            +
               @param {DS.Model} record
         | 
| 527 | 
            +
               @return {Promise} promise
         | 
| 528 | 
            +
               */
         | 
| 529 | 
            +
              createRecord: function (store, type, record) {
         | 
| 423 530 | 
             
                var promise = this._super(store, type, record);
         | 
| 424 531 |  | 
| 425 | 
            -
             | 
| 426 | 
            -
             | 
| 427 | 
            -
             | 
| 428 | 
            -
             | 
| 429 | 
            -
             | 
| 430 | 
            -
             | 
| 431 | 
            -
             | 
| 432 | 
            -
             | 
| 433 | 
            -
             | 
| 434 | 
            -
             | 
| 435 | 
            -
             | 
| 436 | 
            -
             | 
| 437 | 
            -
             | 
| 532 | 
            +
                promise.then(function () {
         | 
| 533 | 
            +
                  var relationShips = Ember.get(type, 'relationshipNames');
         | 
| 534 | 
            +
                  if (relationShips.belongsTo) {
         | 
| 535 | 
            +
                    relationShips.belongsTo.forEach(function (relationship) {
         | 
| 536 | 
            +
                      var belongsToRecord = record.get(relationship);
         | 
| 537 | 
            +
                      if (belongsToRecord) {
         | 
| 538 | 
            +
                        var hasManyName = store.findHasManyRelationshipName(belongsToRecord, record);
         | 
| 539 | 
            +
                        belongsToRecord.get(hasManyName).addObject(record);
         | 
| 540 | 
            +
                      }
         | 
| 541 | 
            +
                    })
         | 
| 542 | 
            +
                  }
         | 
| 543 | 
            +
                });
         | 
| 544 | 
            +
             | 
| 438 545 | 
             
                return promise;
         | 
| 439 546 | 
             
              }
         | 
| 440 | 
            -
             | 
| 441 547 | 
             
            })
         | 
| 442 | 
            -
             | 
| 443 | 
            -
             | 
| 444 548 | 
             
            FactoryGuyTestMixin = Em.Mixin.create({
         | 
| 445 549 |  | 
| 446 550 | 
             
              // Pass in the app root, which typically is App.
         | 
| @@ -454,6 +558,13 @@ FactoryGuyTestMixin = Em.Mixin.create({ | |
| 454 558 | 
             
                this.getStore().adapterFor('application').simulateRemoteResponse = false;
         | 
| 455 559 | 
             
              },
         | 
| 456 560 |  | 
| 561 | 
            +
              /**
         | 
| 562 | 
            +
                Proxy to store's find method
         | 
| 563 | 
            +
             | 
| 564 | 
            +
               @param {String or subclass of DS.Model} type
         | 
| 565 | 
            +
               @param {Object|String|Integer|null} id
         | 
| 566 | 
            +
               @return {Promise} promise
         | 
| 567 | 
            +
               */
         | 
| 457 568 | 
             
              find: function(type, id) {
         | 
| 458 569 | 
             
                return this.getStore().find(type, id);
         | 
| 459 570 | 
             
              },
         | 
| @@ -474,6 +585,13 @@ FactoryGuyTestMixin = Em.Mixin.create({ | |
| 474 585 | 
             
                return this.getStore().push(type, hash);
         | 
| 475 586 | 
             
              },
         | 
| 476 587 |  | 
| 588 | 
            +
              /**
         | 
| 589 | 
            +
                Using mockjax to stub an http request.
         | 
| 590 | 
            +
             | 
| 591 | 
            +
                @param {String} url request url
         | 
| 592 | 
            +
                @param {Object} json response
         | 
| 593 | 
            +
                @param {Object} options ajax request options
         | 
| 594 | 
            +
               */
         | 
| 477 595 | 
             
              stubEndpointForHttpRequest: function (url, json, options) {
         | 
| 478 596 | 
             
                options = options || {};
         | 
| 479 597 | 
             
                var request = {
         | 
| @@ -492,21 +610,27 @@ FactoryGuyTestMixin = Em.Mixin.create({ | |
| 492 610 | 
             
              },
         | 
| 493 611 |  | 
| 494 612 | 
             
              /**
         | 
| 495 | 
            -
             | 
| 496 | 
            -
             | 
| 497 | 
            -
             | 
| 498 | 
            -
             | 
| 613 | 
            +
                Handling ajax POST ( create record ) for a model
         | 
| 614 | 
            +
             | 
| 615 | 
            +
                @param {String} name of the fixture ( or model ) to create
         | 
| 616 | 
            +
                @param {Object} opts fixture options
         | 
| 499 617 | 
             
               */
         | 
| 500 618 | 
             
              handleCreate: function (name, opts) {
         | 
| 501 619 | 
             
                var model = FactoryGuy.lookupModelForName(name);
         | 
| 502 620 | 
             
                this.stubEndpointForHttpRequest(
         | 
| 503 621 | 
             
                  "/" + Em.String.pluralize(model),
         | 
| 504 | 
            -
                  this. | 
| 622 | 
            +
                  this.buildAjaxCreateResponse(name, opts),
         | 
| 505 623 | 
             
                  {type: 'POST'}
         | 
| 506 624 | 
             
                )
         | 
| 507 625 | 
             
              },
         | 
| 508 626 |  | 
| 509 | 
            -
               | 
| 627 | 
            +
              /**
         | 
| 628 | 
            +
                Build the json used for creating record
         | 
| 629 | 
            +
             | 
| 630 | 
            +
                @param {String} name of the fixture ( or model ) to create
         | 
| 631 | 
            +
                @param {Object} opts fixture options
         | 
| 632 | 
            +
            ¬  */
         | 
| 633 | 
            +
              buildAjaxCreateResponse: function (name, opts) {
         | 
| 510 634 | 
             
                var fixture = FactoryGuy.build(name, opts);
         | 
| 511 635 | 
             
                var model = FactoryGuy.lookupModelForName(name);
         | 
| 512 636 | 
             
                var hash = {};
         | 
| @@ -529,5 +653,4 @@ FactoryGuyTestMixin = Em.Mixin.create({ | |
| 529 653 | 
             
              teardown: function () {
         | 
| 530 654 | 
             
                FactoryGuy.resetModels(this.getStore());
         | 
| 531 655 | 
             
              }
         | 
| 532 | 
            -
             | 
| 533 656 | 
             
            })
         |