ember-data-source 1.0.0.beta.17 → 1.0.0.beta.18

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a4cbe6e34b3710f44c426d595269512863abb00a
4
- data.tar.gz: b3595f0c5de106855d354e759509672fc81812c3
3
+ metadata.gz: b32dd86fbff2e256742b7b4ebacb316277789299
4
+ data.tar.gz: 73a46ff21a0f525605b75e13662fd70a35407af9
5
5
  SHA512:
6
- metadata.gz: efb0302f60c03a809795ba70421e54f7232bf2fcb3bef2fc70a443f54d80f6f38799694b47b0bf26115bee92cd90cbf5580a72ad1d5e784287b7d79ece2eab26
7
- data.tar.gz: 1b39bf6ef22af8ae28ed6eb3ee64837af33a1e470ee17578eb98f556cc053de140900144c14f4f4e2e1fb65c5d09eb0499f1d2c5b105f065f835ddaddd9dd79c
6
+ metadata.gz: 7aa46ee56438cea72946c5b8207204012f09d8fca14c7f87257b6033389d85faf0e966cf64b5f907d07811c1a7b0446c44726c3cf5c74d63811ce5135d2a74d9
7
+ data.tar.gz: 89c5ff22c8a73186a45fa3c3f0679b2a22542d3b68d74d35fd391cfba549b6ac5abf491249efe3957afb62f0541c49bbd0bbd68893122bd21dd678b74b785acc
@@ -8,6 +8,8 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/syste
8
8
 
9
9
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/active-model-serializer.js should pass jshint\', function() { \n ok(true, \'lib/system/active-model-serializer.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/lib/system/active-model-serializer.jshint.js");
10
10
 
11
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/active-model-adapter-serializer-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/active-model-adapter-serializer-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/tests/integration/active-model-adapter-serializer-test.jshint.js");
12
+
11
13
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/active-model-adapter-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/active-model-adapter-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/tests/integration/active-model-adapter-test.jshint.js");
12
14
 
13
15
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/active-model-serializer-namespaced-modelname-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/active-model-serializer-namespaced-modelname-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/tests/integration/active-model-serializer-namespaced-modelname-test.jshint.js");
@@ -16,11 +18,13 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/int
16
18
 
17
19
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/adapter\');\ntest(\'tests/unit/adapter/path-for-type-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/adapter/path-for-type-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/tests/unit/adapter/path-for-type-test.jshint.js");
18
20
 
19
- eval("(function() {var env, store, adapter, SuperUser;\nvar passedUrl, passedVerb, passedHash;\nmodule(\"integration/active_model_adapter - AMS Adapter\", {\n setup: function() {\n SuperUser = DS.Model.extend();\n\n env = setupStore({\n superUser: SuperUser,\n adapter: DS.ActiveModelAdapter\n });\n\n store = env.store;\n adapter = env.adapter;\n\n passedUrl = passedVerb = passedHash = null;\n }\n});\n\ntest(\'buildURL - decamelizes names\', function() {\n equal(adapter.buildURL(\'superUser\', 1), \"/super_users/1\");\n});\n\ntest(\'ajaxError - returns invalid error if 422 response\', function() {\n var error = new DS.InvalidError({ name: \"can\'t be blank\" });\n\n var jqXHR = {\n status: 422,\n responseText: JSON.stringify({ errors: { name: \"can\'t be blank\" } })\n };\n\n equal(adapter.ajaxError(jqXHR), error.toString());\n});\n\ntest(\'ajaxError - accepts any kind of json on 422\', function() {\n var error = new DS.InvalidError({ name: \"can\'t be blank\" });\n\n var jqXHR = {\n status: 422,\n responseText: JSON.stringify({ name: \"can\'t be blank\" })\n };\n\n equal(adapter.ajaxError(jqXHR), error.toString());\n});\n\ntest(\'ajaxError - returns ajax response if not 422 response\', function() {\n var jqXHR = {\n status: 500,\n responseText: \"Something went wrong\"\n };\n\n equal(adapter.ajaxError(jqXHR), jqXHR);\n});\n})();//# sourceURL=activemodel-adapter/integration/active-model-adapter-test.js");
21
+ eval("(function() {var env, store, adapter, User;\nvar originalAjax;\n\nmodule(\"integration/active_model_adapter_serializer - AMS Adapter and Serializer\", {\n setup: function() {\n originalAjax = Ember.$.ajax;\n\n User = DS.Model.extend({\n firstName: DS.attr()\n });\n\n env = setupStore({\n user: User,\n adapter: DS.ActiveModelAdapter\n });\n\n store = env.store;\n adapter = env.adapter;\n\n env.registry.register(\'serializer:application\', DS.ActiveModelSerializer);\n },\n\n teardown: function() {\n Ember.$.ajax = originalAjax;\n }\n});\n\ntest(\'errors are camelCased and are expected under the `errors` property of the payload\', function() {\n var jqXHR = {\n status: 422,\n responseText: JSON.stringify({\n errors: {\n first_name: [\"firstName error\"]\n }\n })\n };\n\n Ember.$.ajax = function(hash) {\n hash.error(jqXHR);\n };\n\n var user;\n Ember.run(function() {\n user = store.push(\'user\', { id: 1 });\n });\n\n Ember.run(function() {\n user.save().then(null, function() {\n var errors = user.get(\'errors\');\n ok(errors.has(\'firstName\'), \"there are errors for the firstName attribute\");\n deepEqual(errors.errorsFor(\'firstName\').getEach(\'message\'), [\'firstName error\']);\n });\n });\n});\n})();//# sourceURL=activemodel-adapter/integration/active-model-adapter-serializer-test.js");
22
+
23
+ eval("(function() {var env, store, adapter, SuperUser;\nvar passedUrl, passedVerb, passedHash;\nmodule(\"integration/active_model_adapter - AMS Adapter\", {\n setup: function() {\n SuperUser = DS.Model.extend();\n\n env = setupStore({\n superUser: SuperUser,\n adapter: DS.ActiveModelAdapter\n });\n\n store = env.store;\n adapter = env.adapter;\n\n passedUrl = passedVerb = passedHash = null;\n }\n});\n\ntest(\'buildURL - decamelizes names\', function() {\n equal(adapter.buildURL(\'superUser\', 1), \"/super_users/1\");\n});\n\ntest(\'ajaxError - returns invalid error if 422 response\', function() {\n\n var jqXHR = {\n status: 422,\n responseText: JSON.stringify({ name: \"can\'t be blank\" })\n };\n\n equal(adapter.ajaxError(jqXHR).errors.name, \"can\'t be blank\");\n});\n\ntest(\'ajaxError - returns ajax response if not 422 response\', function() {\n var jqXHR = {\n status: 500,\n responseText: \"Something went wrong\"\n };\n\n equal(adapter.ajaxError(jqXHR), jqXHR);\n});\n})();//# sourceURL=activemodel-adapter/integration/active-model-adapter-test.js");
20
24
 
21
- eval("(function() {var SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, MediocreVillain, env;\nvar run = Ember.run;\n\nmodule(\"integration/active_model - AMS-namespaced-model-names\", {\n setup: function() {\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n YellowMinion = EvilMinion.extend();\n DoomsdayDevice = DS.Model.extend({\n name: DS.attr(\'string\'),\n evilMinion: DS.belongsTo(\'evilMinion\', { polymorphic: true })\n });\n MediocreVillain = DS.Model.extend({\n name: DS.attr(\'string\'),\n evilMinions: DS.hasMany(\'evilMinion\', { polymorphic: true })\n });\n env = setupStore({\n superVillain: SuperVillain,\n evilMinion: EvilMinion,\n \'evilMinions/yellowMinion\': YellowMinion,\n doomsdayDevice: DoomsdayDevice,\n mediocreVillain: MediocreVillain\n });\n env.store.modelFor(\'superVillain\');\n env.store.modelFor(\'evilMinion\');\n env.store.modelFor(\'evilMinions/yellowMinion\');\n env.store.modelFor(\'doomsdayDevice\');\n env.store.modelFor(\'mediocreVillain\');\n env.registry.register(\'serializer:application\', DS.ActiveModelSerializer);\n env.registry.register(\'serializer:-active-model\', DS.ActiveModelSerializer);\n env.registry.register(\'adapter:-active-model\', DS.ActiveModelAdapter);\n env.amsSerializer = env.container.lookup(\"serializer:-active-model\");\n env.amsAdapter = env.container.lookup(\"adapter:-active-model\");\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"serialize polymorphic\", function() {\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(\'evilMinions/yellowMinion\', { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.amsSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json, {\n name: \"DeathRay\",\n evil_minion_type: \"EvilMinions::YellowMinion\",\n evil_minion_id: \"124\"\n });\n});\n\ntest(\"serialize polymorphic when type key is not camelized\", function() {\n YellowMinion.typeKey = \'evil-minions/yellow-minion\';\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(YellowMinion, { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.amsSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json[\"evil_minion_type\"], \"EvilMinions::YellowMinion\");\n});\n\ntest(\"extractPolymorphic hasMany\", function() {\n var json_hash = {\n mediocre_villain: { id: 1, name: \"Dr Horrible\", evil_minions: [{ type: \"EvilMinions::YellowMinion\", id: 12 }] },\n evil_minions: [{ id: 12, name: \"Alex\", doomsday_device_ids: [1] }]\n };\n var json;\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json_hash);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"Dr Horrible\",\n \"evilMinions\": [{\n type: \"evilMinions/yellowMinion\",\n id: 12\n }]\n });\n});\n\ntest(\"extractPolymorphic\", function() {\n var json_hash = {\n doomsday_device: { id: 1, name: \"DeathRay\", evil_minion: { type: \"EvilMinions::YellowMinion\", id: 12 } },\n evil_minions: [{ id: 12, name: \"Alex\", doomsday_device_ids: [1] }]\n };\n var json;\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, DoomsdayDevice, json_hash);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"DeathRay\",\n \"evilMinion\": {\n type: \"evilMinions/yellowMinion\",\n id: 12\n }\n });\n});\n})();//# sourceURL=activemodel-adapter/integration/active-model-serializer-namespaced-modelname-test.js");
25
+ eval("(function() {var SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, MediocreVillain, env;\nvar run = Ember.run;\n\nmodule(\"integration/active_model - AMS-namespaced-model-names\", {\n setup: function() {\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n YellowMinion = EvilMinion.extend();\n DoomsdayDevice = DS.Model.extend({\n name: DS.attr(\'string\'),\n evilMinion: DS.belongsTo(\'evilMinion\', { polymorphic: true })\n });\n MediocreVillain = DS.Model.extend({\n name: DS.attr(\'string\'),\n evilMinions: DS.hasMany(\'evilMinion\', { polymorphic: true })\n });\n env = setupStore({\n superVillain: SuperVillain,\n evilMinion: EvilMinion,\n \'evilMinions/yellowMinion\': YellowMinion,\n doomsdayDevice: DoomsdayDevice,\n mediocreVillain: MediocreVillain\n });\n env.store.modelFor(\'superVillain\');\n env.store.modelFor(\'evilMinion\');\n env.store.modelFor(\'evilMinions/yellowMinion\');\n env.store.modelFor(\'doomsdayDevice\');\n env.store.modelFor(\'mediocreVillain\');\n env.registry.register(\'serializer:application\', DS.ActiveModelSerializer);\n env.registry.register(\'serializer:-active-model\', DS.ActiveModelSerializer);\n env.registry.register(\'adapter:-active-model\', DS.ActiveModelAdapter);\n env.amsSerializer = env.container.lookup(\"serializer:-active-model\");\n env.amsAdapter = env.container.lookup(\"adapter:-active-model\");\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"serialize polymorphic\", function() {\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(\'evilMinions/yellowMinion\', { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.amsSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json, {\n name: \"DeathRay\",\n evil_minion_type: \"EvilMinions::YellowMinion\",\n evil_minion_id: \"124\"\n });\n});\n\ntest(\"serialize polymorphic when type key is not camelized\", function() {\n YellowMinion.modelName = \'evil-minions/yellow-minion\';\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(YellowMinion, { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.amsSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json[\"evil_minion_type\"], \"EvilMinions::YellowMinion\");\n});\n\ntest(\"extractPolymorphic hasMany\", function() {\n var json_hash = {\n mediocre_villain: { id: 1, name: \"Dr Horrible\", evil_minions: [{ type: \"EvilMinions::YellowMinion\", id: 12 }] },\n evil_minions: [{ id: 12, name: \"Alex\", doomsday_device_ids: [1] }]\n };\n var json;\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json_hash);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"Dr Horrible\",\n \"evilMinions\": [{\n type: \"evil-minions/yellow-minion\",\n id: 12\n }]\n });\n});\n\ntest(\"extractPolymorphic\", function() {\n var json_hash = {\n doomsday_device: { id: 1, name: \"DeathRay\", evil_minion: { type: \"EvilMinions::YellowMinion\", id: 12 } },\n evil_minions: [{ id: 12, name: \"Alex\", doomsday_device_ids: [1] }]\n };\n var json;\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, DoomsdayDevice, json_hash);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"DeathRay\",\n \"evilMinion\": {\n type: \"evil-minions/yellow-minion\",\n id: 12\n }\n });\n});\n})();//# sourceURL=activemodel-adapter/integration/active-model-serializer-namespaced-modelname-test.js");
22
26
 
23
- eval("(function() {var get = Ember.get;\nvar HomePlanet, league, SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, MediocreVillain, env;\nvar run = Ember.run;\n\nmodule(\"integration/active_model - ActiveModelSerializer\", {\n setup: function() {\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n homePlanet: DS.belongsTo(\"homePlanet\"),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n HomePlanet = DS.Model.extend({\n name: DS.attr(\'string\'),\n superVillains: DS.hasMany(\'superVillain\', { async: true })\n });\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n YellowMinion = EvilMinion.extend();\n DoomsdayDevice = DS.Model.extend({\n name: DS.attr(\'string\'),\n evilMinion: DS.belongsTo(\'evilMinion\', { polymorphic: true })\n });\n MediocreVillain = DS.Model.extend({\n name: DS.attr(\'string\'),\n evilMinions: DS.hasMany(\'evilMinion\', { polymorphic: true })\n });\n env = setupStore({\n superVillain: SuperVillain,\n homePlanet: HomePlanet,\n evilMinion: EvilMinion,\n yellowMinion: YellowMinion,\n doomsdayDevice: DoomsdayDevice,\n mediocreVillain: MediocreVillain\n });\n env.store.modelFor(\'superVillain\');\n env.store.modelFor(\'homePlanet\');\n env.store.modelFor(\'evilMinion\');\n env.store.modelFor(\'yellowMinion\');\n env.store.modelFor(\'doomsdayDevice\');\n env.store.modelFor(\'mediocreVillain\');\n env.registry.register(\'serializer:application\', DS.ActiveModelSerializer);\n env.registry.register(\'serializer:-active-model\', DS.ActiveModelSerializer);\n env.registry.register(\'adapter:-active-model\', DS.ActiveModelAdapter);\n env.amsSerializer = env.container.lookup(\"serializer:-active-model\");\n env.amsAdapter = env.container.lookup(\"adapter:-active-model\");\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"serialize\", function() {\n var tom;\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n tom = env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", homePlanet: league });\n });\n\n var json = env.amsSerializer.serialize(tom._createSnapshot());\n\n deepEqual(json, {\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: get(league, \"id\")\n });\n});\n\ntest(\"serializeIntoHash\", function() {\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Umber\", id: \"123\" });\n });\n var json = {};\n\n env.amsSerializer.serializeIntoHash(json, HomePlanet, league._createSnapshot());\n\n deepEqual(json, {\n home_planet: {\n name: \"Umber\"\n }\n });\n});\n\ntest(\"serializeIntoHash with decamelized types\", function() {\n HomePlanet.typeKey = \'home-planet\';\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Umber\", id: \"123\" });\n });\n var json = {};\n\n env.amsSerializer.serializeIntoHash(json, HomePlanet, league._createSnapshot());\n\n deepEqual(json, {\n home_planet: {\n name: \"Umber\"\n }\n });\n});\n\n\ntest(\"normalize\", function() {\n SuperVillain.reopen({\n yellowMinion: DS.belongsTo(\'yellowMinion\')\n });\n\n var superVillain_hash = { first_name: \"Tom\", last_name: \"Dale\", home_planet_id: \"123\", evil_minion_ids: [1,2] };\n\n var json = env.amsSerializer.normalize(SuperVillain, superVillain_hash, \"superVillain\");\n\n deepEqual(json, {\n firstName: \"Tom\",\n lastName: \"Dale\",\n homePlanet: \"123\",\n evilMinions: [1,2]\n });\n});\n\ntest(\"normalize links\", function() {\n var home_planet = {\n id: \"1\",\n name: \"Umber\",\n links: { super_villains: \"/api/super_villians/1\" }\n };\n\n\n var json = env.amsSerializer.normalize(HomePlanet, home_planet, \"homePlanet\");\n\n equal(json.links.superVillains, \"/api/super_villians/1\", \"normalize links\");\n});\n\ntest(\"extractSingle\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n\n var json_hash = {\n home_planet: { id: \"1\", name: \"Umber\", super_villain_ids: [1] },\n super_villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: \"1\"\n }]\n };\n\n var json;\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, {\n \"id\": \"1\",\n \"name\": \"Umber\",\n \"superVillains\": [1]\n });\n\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"extractArray\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n var array;\n\n var json_hash = {\n home_planets: [{ id: \"1\", name: \"Umber\", super_villain_ids: [1] }],\n super_villains: [{ id: \"1\", first_name: \"Tom\", last_name: \"Dale\", home_planet_id: \"1\" }]\n };\n\n run(function() {\n array = env.amsSerializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(array, [{\n \"id\": \"1\",\n \"name\": \"Umber\",\n \"superVillains\": [1]\n }]);\n\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"serialize polymorphic\", function() {\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(YellowMinion, { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.amsSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json, {\n name: \"DeathRay\",\n evil_minion_type: \"YellowMinion\",\n evil_minion_id: \"124\"\n });\n});\n\ntest(\"serialize polymorphic when type key is not camelized\", function() {\n YellowMinion.typeKey = \'yellow-minion\';\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(YellowMinion, { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.amsSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json[\"evil_minion_type\"], \"YellowMinion\");\n});\n\ntest(\"serialize polymorphic when associated object is null\", function() {\n var ray, json;\n run(function() {\n ray = env.store.createRecord(DoomsdayDevice, { name: \"DeathRay\" });\n json = env.amsSerializer.serialize(ray._createSnapshot());\n });\n\n deepEqual(json[\"evil_minion_type\"], null);\n});\n\ntest(\"extractPolymorphic hasMany\", function() {\n env.registry.register(\'adapter:yellowMinion\', DS.ActiveModelAdapter);\n MediocreVillain.toString = function() { return \"MediocreVillain\"; };\n YellowMinion.toString = function() { return \"YellowMinion\"; };\n\n var json_hash = {\n mediocre_villain: { id: 1, name: \"Dr Horrible\", evil_minions: [{ type: \"yellow_minion\", id: 12 }] },\n evil_minions: [{ id: 12, name: \"Alex\", doomsday_device_ids: [1] }]\n };\n var json;\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json_hash);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"Dr Horrible\",\n \"evilMinions\": [{\n type: \"yellowMinion\",\n id: 12\n }]\n });\n});\n\ntest(\"extractPolymorphic\", function() {\n env.registry.register(\'adapter:yellowMinion\', DS.ActiveModelAdapter);\n EvilMinion.toString = function() { return \"EvilMinion\"; };\n YellowMinion.toString = function() { return \"YellowMinion\"; };\n\n var json_hash = {\n doomsday_device: { id: 1, name: \"DeathRay\", evil_minion: { type: \"yellow_minion\", id: 12 } },\n evil_minions: [{ id: 12, name: \"Alex\", doomsday_device_ids: [1] }]\n };\n var json;\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, DoomsdayDevice, json_hash);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"DeathRay\",\n \"evilMinion\": {\n type: \"yellowMinion\",\n id: 12\n }\n });\n});\n\ntest(\"extractPolymorphic when the related data is not specified\", function() {\n var json = {\n doomsday_device: { id: 1, name: \"DeathRay\" },\n evil_minions: [{ id: 12, name: \"Alex\", doomsday_device_ids: [1] }]\n };\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, DoomsdayDevice, json);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"DeathRay\",\n \"evilMinion\": undefined\n });\n});\n\ntest(\"extractPolymorphic hasMany when the related data is not specified\", function() {\n var json = {\n mediocre_villain: { id: 1, name: \"Dr Horrible\" }\n };\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"Dr Horrible\",\n \"evilMinions\": undefined\n });\n});\n\ntest(\"extractPolymorphic does not break hasMany relationships\", function() {\n var json = {\n mediocre_villain: { id: 1, name: \"Dr. Evil\", evil_minions: [] }\n };\n\n run(function () {\n json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"Dr. Evil\",\n \"evilMinions\": []\n });\n});\n\ntest(\"extractErrors camelizes keys\", function() {\n var payload = {\n errors: {\n first_name: [\"firstName not evil enough\"]\n }\n };\n\n run(function() {\n payload = env.amsSerializer.extractErrors(env.store, SuperVillain, payload);\n });\n\n deepEqual(payload, {\n firstName: [\"firstName not evil enough\"]\n });\n});\n})();//# sourceURL=activemodel-adapter/integration/active-model-serializer-test.js");
27
+ eval("(function() {var get = Ember.get;\nvar HomePlanet, league, SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, MediocreVillain, env;\nvar run = Ember.run;\n\nmodule(\"integration/active_model - ActiveModelSerializer\", {\n setup: function() {\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n homePlanet: DS.belongsTo(\"homePlanet\"),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n HomePlanet = DS.Model.extend({\n name: DS.attr(\'string\'),\n superVillains: DS.hasMany(\'superVillain\', { async: true })\n });\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n YellowMinion = EvilMinion.extend();\n DoomsdayDevice = DS.Model.extend({\n name: DS.attr(\'string\'),\n evilMinion: DS.belongsTo(\'evilMinion\', { polymorphic: true })\n });\n MediocreVillain = DS.Model.extend({\n name: DS.attr(\'string\'),\n evilMinions: DS.hasMany(\'evilMinion\', { polymorphic: true })\n });\n env = setupStore({\n superVillain: SuperVillain,\n homePlanet: HomePlanet,\n evilMinion: EvilMinion,\n yellowMinion: YellowMinion,\n doomsdayDevice: DoomsdayDevice,\n mediocreVillain: MediocreVillain\n });\n env.store.modelFor(\'superVillain\');\n env.store.modelFor(\'homePlanet\');\n env.store.modelFor(\'evilMinion\');\n env.store.modelFor(\'yellowMinion\');\n env.store.modelFor(\'doomsdayDevice\');\n env.store.modelFor(\'mediocreVillain\');\n env.registry.register(\'serializer:application\', DS.ActiveModelSerializer);\n env.registry.register(\'serializer:-active-model\', DS.ActiveModelSerializer);\n env.registry.register(\'adapter:-active-model\', DS.ActiveModelAdapter);\n env.amsSerializer = env.container.lookup(\"serializer:-active-model\");\n env.amsAdapter = env.container.lookup(\"adapter:-active-model\");\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"serialize\", function() {\n var tom;\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n tom = env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", homePlanet: league });\n });\n\n var json = env.amsSerializer.serialize(tom._createSnapshot());\n\n deepEqual(json, {\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: get(league, \"id\")\n });\n});\n\ntest(\"serializeIntoHash\", function() {\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Umber\", id: \"123\" });\n });\n var json = {};\n\n env.amsSerializer.serializeIntoHash(json, HomePlanet, league._createSnapshot());\n\n deepEqual(json, {\n home_planet: {\n name: \"Umber\"\n }\n });\n});\n\ntest(\"serializeIntoHash with decamelized types\", function() {\n HomePlanet.modelName = \'home-planet\';\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Umber\", id: \"123\" });\n });\n var json = {};\n\n env.amsSerializer.serializeIntoHash(json, HomePlanet, league._createSnapshot());\n\n deepEqual(json, {\n home_planet: {\n name: \"Umber\"\n }\n });\n});\n\n\ntest(\"normalize\", function() {\n SuperVillain.reopen({\n yellowMinion: DS.belongsTo(\'yellowMinion\')\n });\n\n var superVillain_hash = { first_name: \"Tom\", last_name: \"Dale\", home_planet_id: \"123\", evil_minion_ids: [1,2] };\n\n var json = env.amsSerializer.normalize(SuperVillain, superVillain_hash, \"superVillain\");\n\n deepEqual(json, {\n firstName: \"Tom\",\n lastName: \"Dale\",\n homePlanet: \"123\",\n evilMinions: [1,2]\n });\n});\n\ntest(\"normalize links\", function() {\n var home_planet = {\n id: \"1\",\n name: \"Umber\",\n links: { super_villains: \"/api/super_villians/1\" }\n };\n\n\n var json = env.amsSerializer.normalize(HomePlanet, home_planet, \"homePlanet\");\n\n equal(json.links.superVillains, \"/api/super_villians/1\", \"normalize links\");\n});\n\ntest(\"extractSingle\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n\n var json_hash = {\n home_planet: { id: \"1\", name: \"Umber\", super_villain_ids: [1] },\n super_villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: \"1\"\n }]\n };\n\n var json;\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, {\n \"id\": \"1\",\n \"name\": \"Umber\",\n \"superVillains\": [1]\n });\n\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"extractArray\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n var array;\n\n var json_hash = {\n home_planets: [{ id: \"1\", name: \"Umber\", super_villain_ids: [1] }],\n super_villains: [{ id: \"1\", first_name: \"Tom\", last_name: \"Dale\", home_planet_id: \"1\" }]\n };\n\n run(function() {\n array = env.amsSerializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(array, [{\n \"id\": \"1\",\n \"name\": \"Umber\",\n \"superVillains\": [1]\n }]);\n\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"serialize polymorphic\", function() {\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(YellowMinion, { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.amsSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json, {\n name: \"DeathRay\",\n evil_minion_type: \"YellowMinion\",\n evil_minion_id: \"124\"\n });\n});\n\ntest(\"serialize polymorphic when type key is not camelized\", function() {\n YellowMinion.modelName = \'yellow-minion\';\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(YellowMinion, { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.amsSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json[\"evil_minion_type\"], \"YellowMinion\");\n});\n\ntest(\"serialize polymorphic when associated object is null\", function() {\n var ray, json;\n run(function() {\n ray = env.store.createRecord(DoomsdayDevice, { name: \"DeathRay\" });\n json = env.amsSerializer.serialize(ray._createSnapshot());\n });\n\n deepEqual(json[\"evil_minion_type\"], null);\n});\n\ntest(\"extractPolymorphic hasMany\", function() {\n env.registry.register(\'adapter:yellowMinion\', DS.ActiveModelAdapter);\n MediocreVillain.toString = function() { return \"MediocreVillain\"; };\n YellowMinion.toString = function() { return \"YellowMinion\"; };\n\n var json_hash = {\n mediocre_villain: { id: 1, name: \"Dr Horrible\", evil_minions: [{ type: \"yellow_minion\", id: 12 }] },\n evil_minions: [{ id: 12, name: \"Alex\", doomsday_device_ids: [1] }]\n };\n var json;\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json_hash);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"Dr Horrible\",\n \"evilMinions\": [{\n type: \"yellow-minion\",\n id: 12\n }]\n });\n});\n\ntest(\"extractPolymorphic\", function() {\n env.registry.register(\'adapter:yellowMinion\', DS.ActiveModelAdapter);\n EvilMinion.toString = function() { return \"EvilMinion\"; };\n YellowMinion.toString = function() { return \"YellowMinion\"; };\n\n var json_hash = {\n doomsday_device: { id: 1, name: \"DeathRay\", evil_minion: { type: \"yellow_minion\", id: 12 } },\n evil_minions: [{ id: 12, name: \"Alex\", doomsday_device_ids: [1] }]\n };\n var json;\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, DoomsdayDevice, json_hash);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"DeathRay\",\n \"evilMinion\": {\n type: \"yellow-minion\",\n id: 12\n }\n });\n});\n\ntest(\"extractPolymorphic when the related data is not specified\", function() {\n var json = {\n doomsday_device: { id: 1, name: \"DeathRay\" },\n evil_minions: [{ id: 12, name: \"Alex\", doomsday_device_ids: [1] }]\n };\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, DoomsdayDevice, json);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"DeathRay\",\n \"evilMinion\": undefined\n });\n});\n\ntest(\"extractPolymorphic hasMany when the related data is not specified\", function() {\n var json = {\n mediocre_villain: { id: 1, name: \"Dr Horrible\" }\n };\n\n run(function() {\n json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"Dr Horrible\",\n \"evilMinions\": undefined\n });\n});\n\ntest(\"extractPolymorphic does not break hasMany relationships\", function() {\n var json = {\n mediocre_villain: { id: 1, name: \"Dr. Evil\", evil_minions: [] }\n };\n\n run(function () {\n json = env.amsSerializer.extractSingle(env.store, MediocreVillain, json);\n });\n\n deepEqual(json, {\n \"id\": 1,\n \"name\": \"Dr. Evil\",\n \"evilMinions\": []\n });\n});\n\ntest(\"extractErrors camelizes keys\", function() {\n var payload = {\n errors: {\n first_name: [\"firstName not evil enough\"]\n }\n };\n\n run(function() {\n payload = env.amsSerializer.extractErrors(env.store, SuperVillain, payload);\n });\n\n deepEqual(payload, {\n firstName: [\"firstName not evil enough\"]\n });\n});\n})();//# sourceURL=activemodel-adapter/integration/active-model-serializer-test.js");
24
28
 
25
29
  eval("(function() {var env, adapter;\nmodule(\"unit/adapter/path_for_type - DS.ActiveModelAdapter#pathForType\", {\n setup: function() {\n env = setupStore({\n adapter: DS.ActiveModelAdapter\n });\n\n adapter = env.adapter;\n }\n});\n\ntest(\'pathForType - works with camelized types\', function() {\n equal(adapter.pathForType(\'superUser\'), \"super_users\");\n});\n\ntest(\'pathForType - works with dasherized types\', function() {\n equal(adapter.pathForType(\'super-user\'), \"super_users\");\n});\n\ntest(\'pathForType - works with underscored types\', function() {\n equal(adapter.pathForType(\'super_user\'), \"super_users\");\n});\n})();//# sourceURL=activemodel-adapter/unit/adapter/path-for-type-test.js");
26
30
 
@@ -86,6 +90,8 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/syste
86
90
 
87
91
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/model\');\ntest(\'lib/system/model/states.js should pass jshint\', function() { \n ok(true, \'lib/system/model/states.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/model/states.jshint.js");
88
92
 
93
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/normalize-model-name.js should pass jshint\', function() { \n ok(true, \'lib/system/normalize-model-name.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/normalize-model-name.jshint.js");
94
+
89
95
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/ordered-set.js should pass jshint\', function() { \n ok(true, \'lib/system/ordered-set.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/ordered-set.jshint.js");
90
96
 
91
97
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/promise-proxies.js should pass jshint\', function() { \n ok(true, \'lib/system/promise-proxies.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/promise-proxies.jshint.js");
@@ -166,6 +172,10 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/int
166
172
 
167
173
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/application-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/application-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/application-test.jshint.js");
168
174
 
175
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/backwards-compat\');\ntest(\'tests/integration/backwards-compat/deprecate-type-key-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/backwards-compat/deprecate-type-key-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/backwards-compat/deprecate-type-key-test.jshint.js");
176
+
177
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/backwards-compat\');\ntest(\'tests/integration/backwards-compat/non-dasherized-lookups.js should pass jshint\', function() { \n ok(true, \'tests/integration/backwards-compat/non-dasherized-lookups.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/backwards-compat/non-dasherized-lookups.jshint.js");
178
+
169
179
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/client-id-generation-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/client-id-generation-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/client-id-generation-test.jshint.js");
170
180
 
171
181
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/debug-adapter-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/debug-adapter-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/debug-adapter-test.jshint.js");
@@ -250,6 +260,8 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/uni
250
260
 
251
261
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model\');\ntest(\'tests/unit/model/rollback-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/rollback-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/rollback-test.jshint.js");
252
262
 
263
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/normalize-type-key-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/normalize-type-key-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/normalize-type-key-test.jshint.js");
264
+
253
265
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/promise-proxies-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/promise-proxies-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/promise-proxies-test.jshint.js");
254
266
 
255
267
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/record-array-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/record-array-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/record-array-test.jshint.js");
@@ -280,7 +292,7 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/uni
280
292
 
281
293
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/transform\');\ntest(\'tests/unit/transform/string-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/transform/string-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/transform/string-test.jshint.js");
282
294
 
283
- eval("(function() {var env, store, adapter, Post, Comment, SuperUser;\nvar passedUrl;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter\", {\n setup: function() {\n Post = DS.Model.extend({\n name: DS.attr(\"string\")\n });\n\n Post.toString = function() {\n return \"Post\";\n };\n\n Comment = DS.Model.extend({\n name: DS.attr(\"string\")\n });\n\n SuperUser = DS.Model.extend();\n\n env = setupStore({\n post: Post,\n comment: Comment,\n superUser: SuperUser,\n adapter: DS.RESTAdapter\n });\n\n store = env.store;\n adapter = env.adapter;\n\n passedUrl = null;\n }\n});\n\nfunction ajaxResponse(value) {\n adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n\n return run(Ember.RSVP, \'resolve\', value);\n };\n}\n\n\ntest(\'buildURL - with host and namespace\', function() {\n run(function() {\n adapter.setProperties({\n host: \'http://example.com\',\n namespace: \'api/v1\'\n });\n });\n\n ajaxResponse({ posts: [{ id: 1 }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"http://example.com/api/v1/posts/1\");\n }));\n});\n\ntest(\'buildURL - with relative paths in links\', function() {\n run(function() {\n adapter.setProperties({\n host: \'http://example.com\',\n namespace: \'api/v1\'\n });\n });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n ajaxResponse({ posts: [{ id: 1, links: { comments: \'comments\' } }] });\n\n run(store, \'find\', \'post\', \'1\').then(async(function(post) {\n ajaxResponse({ comments: [{ id: 1 }] });\n return post.get(\'comments\');\n })).then(async(function (comments) {\n equal(passedUrl, \"http://example.com/api/v1/posts/1/comments\");\n }));\n});\n\ntest(\'buildURL - with absolute paths in links\', function() {\n run(function() {\n adapter.setProperties({\n host: \'http://example.com\',\n namespace: \'api/v1\'\n });\n });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n ajaxResponse({ posts: [{ id: 1, links: { comments: \'/api/v1/posts/1/comments\' } }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n ajaxResponse({ comments: [{ id: 1 }] });\n return post.get(\'comments\');\n })).then(async(function (comments) {\n equal(passedUrl, \"http://example.com/api/v1/posts/1/comments\");\n }));\n});\n\n\ntest(\'buildURL - with absolute paths in links and protocol relative host\', function() {\n run(function() {\n adapter.setProperties({\n host: \'//example.com\',\n namespace: \'api/v1\'\n });\n });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n ajaxResponse({ posts: [{ id: 1, links: { comments: \'/api/v1/posts/1/comments\' } }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n ajaxResponse({ comments: [{ id: 1 }] });\n return post.get(\'comments\');\n })).then(async(function (comments) {\n equal(passedUrl, \"//example.com/api/v1/posts/1/comments\");\n }));\n});\n\ntest(\'buildURL - with full URLs in links\', function() {\n adapter.setProperties({\n host: \'http://example.com\',\n namespace: \'api/v1\'\n });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n ajaxResponse({\n posts: [\n { id: 1,\n links: { comments: \'http://example.com/api/v1/posts/1/comments\' }\n }\n ]\n });\n\n run(function() {\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({ comments: [{ id: 1 }] });\n return post.get(\'comments\');\n })).then(async(function (comments) {\n equal(passedUrl, \"http://example.com/api/v1/posts/1/comments\");\n }));\n });\n});\n\ntest(\'buildURL - with camelized names\', function() {\n adapter.setProperties({\n pathForType: function(type) {\n var decamelized = Ember.String.decamelize(type);\n return Ember.String.pluralize(decamelized);\n }\n });\n\n ajaxResponse({ superUsers: [{ id: 1 }] });\n\n run(function() {\n store.find(\'superUser\', 1).then(async(function(post) {\n equal(passedUrl, \"/super_users/1\");\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes a record from find\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n adapter.buildURL = function(type, id, snapshot) {\n return \"/posts/\" + snapshot.belongsTo(\'post\', { id: true }) + \'/comments/\' + snapshot.id;\n };\n\n ajaxResponse({ comments: [{ id: 1 }] });\n\n var post;\n run(function() {\n post = store.push(\'post\', { id: 2 });\n });\n\n run(function() {\n store.find(\'comment\', 1, { post: post }).then(async(function(post) {\n equal(passedUrl, \"/posts/2/comments/1\");\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes the records from findMany\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n adapter.buildURL = function(type, ids, snapshots) {\n if (Ember.isArray(snapshots)) {\n return \"/posts/\" + snapshots.get(\'firstObject\').belongsTo(\'post\', { id: true }) + \'/comments/\';\n }\n return \"\";\n };\n adapter.coalesceFindRequests = true;\n\n ajaxResponse({ comments: [{ id: 1 }, { id: 2 }, { id: 3 }] });\n var post;\n\n run(function() {\n post = store.push(\'post\', { id: 2, comments: [1,2,3] });\n post.get(\'comments\').then(async(function(post) {\n equal(passedUrl, \"/posts/2/comments/\");\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes a record from create\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n adapter.buildURL = function(type, id, snapshot) {\n return \"/posts/\" + snapshot.belongsTo(\'post\', { id: true }) + \'/comments/\';\n };\n\n ajaxResponse({ comments: [{ id: 1 }] });\n\n run(function() {\n var post = store.push(\'post\', { id: 2 });\n var comment = store.createRecord(\'comment\');\n comment.set(\'post\', post);\n comment.save().then(async(function(post) {\n equal(passedUrl, \"/posts/2/comments/\");\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes a record from create to query a resolved async belongsTo relationship\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\', { async: true }) });\n\n ajaxResponse({ posts: [{ id: 2 }] });\n\n run(function() {\n store.find(\'post\', 2).then(async(function(post) {\n equal(post.get(\'id\'), 2);\n\n adapter.buildURL = function(type, id, snapshot) {\n return \"/posts/\" + snapshot.belongsTo(\'post\', { id: true }) + \'/comments/\';\n };\n\n ajaxResponse({ comments: [{ id: 1 }] });\n\n var comment = store.createRecord(\'comment\');\n comment.set(\'post\', post);\n comment.save().then(async(function(post) {\n equal(passedUrl, \"/posts/2/comments/\");\n }));\n\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes a record from update\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n adapter.buildURL = function(type, id, snapshot) {\n return \"/posts/\" + snapshot.belongsTo(\'post\', { id: true }) + \'/comments/\' + snapshot.id;\n };\n\n ajaxResponse({ comments: [{ id: 1 }] });\n\n var post, comment;\n run(function() {\n post = store.push(\'post\', { id: 2 });\n comment = store.push(\'comment\', { id: 1 });\n comment.set(\'post\', post);\n });\n run(function() {\n comment.save().then(async(function(post) {\n equal(passedUrl, \"/posts/2/comments/1\");\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes a record from delete\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n adapter.buildURL = function(type, id, snapshot) {\n return \'posts/\' + snapshot.belongsTo(\'post\', { id: true }) + \'/comments/\' + snapshot.id;\n };\n\n ajaxResponse({ comments: [{ id: 1 }] });\n\n var post, comment;\n run(function() {\n post = store.push(\'post\', { id: 2 });\n comment = store.push(\'comment\', { id: 1 });\n\n comment.set(\'post\', post);\n comment.deleteRecord();\n });\n run(function() {\n comment.save().then(async(function(post) {\n equal(passedUrl, \"posts/2/comments/1\");\n }));\n });\n});\n\ntest(\'buildURL - with absolute namespace\', function() {\n run(function() {\n adapter.setProperties({\n namespace: \'/api/v1\'\n });\n });\n\n ajaxResponse({ posts: [{ id: 1 }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/api/v1/posts/1\");\n }));\n});\n})();//# sourceURL=ember-data/integration/adapter/build-url-mixin-test.js");
295
+ eval("(function() {var env, store, adapter, Post, Comment, SuperUser;\nvar passedUrl;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter\", {\n setup: function() {\n Post = DS.Model.extend({\n name: DS.attr(\"string\")\n });\n\n Post.toString = function() {\n return \"Post\";\n };\n\n Comment = DS.Model.extend({\n name: DS.attr(\"string\")\n });\n\n SuperUser = DS.Model.extend();\n\n env = setupStore({\n post: Post,\n comment: Comment,\n superUser: SuperUser,\n adapter: DS.RESTAdapter\n });\n\n store = env.store;\n adapter = env.adapter;\n\n passedUrl = null;\n }\n});\n\nfunction ajaxResponse(value) {\n adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n\n return run(Ember.RSVP, \'resolve\', value);\n };\n}\n\n\ntest(\'buildURL - with host and namespace\', function() {\n run(function() {\n adapter.setProperties({\n host: \'http://example.com\',\n namespace: \'api/v1\'\n });\n });\n\n ajaxResponse({ posts: [{ id: 1 }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"http://example.com/api/v1/posts/1\");\n }));\n});\n\ntest(\'buildURL - with relative paths in links\', function() {\n run(function() {\n adapter.setProperties({\n host: \'http://example.com\',\n namespace: \'api/v1\'\n });\n });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n ajaxResponse({ posts: [{ id: 1, links: { comments: \'comments\' } }] });\n\n run(store, \'find\', \'post\', \'1\').then(async(function(post) {\n ajaxResponse({ comments: [{ id: 1 }] });\n return post.get(\'comments\');\n })).then(async(function (comments) {\n equal(passedUrl, \"http://example.com/api/v1/posts/1/comments\");\n }));\n});\n\ntest(\'buildURL - with absolute paths in links\', function() {\n run(function() {\n adapter.setProperties({\n host: \'http://example.com\',\n namespace: \'api/v1\'\n });\n });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n ajaxResponse({ posts: [{ id: 1, links: { comments: \'/api/v1/posts/1/comments\' } }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n ajaxResponse({ comments: [{ id: 1 }] });\n return post.get(\'comments\');\n })).then(async(function (comments) {\n equal(passedUrl, \"http://example.com/api/v1/posts/1/comments\");\n }));\n});\n\n\ntest(\'buildURL - with absolute paths in links and protocol relative host\', function() {\n run(function() {\n adapter.setProperties({\n host: \'//example.com\',\n namespace: \'api/v1\'\n });\n });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n ajaxResponse({ posts: [{ id: 1, links: { comments: \'/api/v1/posts/1/comments\' } }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n ajaxResponse({ comments: [{ id: 1 }] });\n return post.get(\'comments\');\n })).then(async(function (comments) {\n equal(passedUrl, \"//example.com/api/v1/posts/1/comments\");\n }));\n});\n\ntest(\'buildURL - with full URLs in links\', function() {\n adapter.setProperties({\n host: \'http://example.com\',\n namespace: \'api/v1\'\n });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n ajaxResponse({\n posts: [\n { id: 1,\n links: { comments: \'http://example.com/api/v1/posts/1/comments\' }\n }\n ]\n });\n\n run(function() {\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({ comments: [{ id: 1 }] });\n return post.get(\'comments\');\n })).then(async(function (comments) {\n equal(passedUrl, \"http://example.com/api/v1/posts/1/comments\");\n }));\n });\n});\n\ntest(\'buildURL - with camelized names\', function() {\n adapter.setProperties({\n pathForType: function(type) {\n var decamelized = Ember.String.decamelize(type);\n return Ember.String.underscore(Ember.String.pluralize(decamelized));\n }\n });\n\n ajaxResponse({ superUsers: [{ id: 1 }] });\n\n run(function() {\n store.find(\'superUser\', 1).then(async(function(post) {\n equal(passedUrl, \"/super_users/1\");\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes a record from find\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n adapter.buildURL = function(type, id, snapshot) {\n return \"/posts/\" + snapshot.belongsTo(\'post\', { id: true }) + \'/comments/\' + snapshot.id;\n };\n\n ajaxResponse({ comments: [{ id: 1 }] });\n\n var post;\n run(function() {\n post = store.push(\'post\', { id: 2 });\n });\n\n run(function() {\n store.find(\'comment\', 1, { post: post }).then(async(function(post) {\n equal(passedUrl, \"/posts/2/comments/1\");\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes the records from findMany\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n adapter.buildURL = function(type, ids, snapshots) {\n if (Ember.isArray(snapshots)) {\n return \"/posts/\" + snapshots.get(\'firstObject\').belongsTo(\'post\', { id: true }) + \'/comments/\';\n }\n return \"\";\n };\n adapter.coalesceFindRequests = true;\n\n ajaxResponse({ comments: [{ id: 1 }, { id: 2 }, { id: 3 }] });\n var post;\n\n run(function() {\n post = store.push(\'post\', { id: 2, comments: [1,2,3] });\n post.get(\'comments\').then(async(function(post) {\n equal(passedUrl, \"/posts/2/comments/\");\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes a record from create\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n adapter.buildURL = function(type, id, snapshot) {\n return \"/posts/\" + snapshot.belongsTo(\'post\', { id: true }) + \'/comments/\';\n };\n\n ajaxResponse({ comments: [{ id: 1 }] });\n\n run(function() {\n var post = store.push(\'post\', { id: 2 });\n var comment = store.createRecord(\'comment\');\n comment.set(\'post\', post);\n comment.save().then(async(function(post) {\n equal(passedUrl, \"/posts/2/comments/\");\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes a record from create to query a resolved async belongsTo relationship\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\', { async: true }) });\n\n ajaxResponse({ posts: [{ id: 2 }] });\n\n run(function() {\n store.find(\'post\', 2).then(async(function(post) {\n equal(post.get(\'id\'), 2);\n\n adapter.buildURL = function(type, id, snapshot) {\n return \"/posts/\" + snapshot.belongsTo(\'post\', { id: true }) + \'/comments/\';\n };\n\n ajaxResponse({ comments: [{ id: 1 }] });\n\n var comment = store.createRecord(\'comment\');\n comment.set(\'post\', post);\n comment.save().then(async(function(post) {\n equal(passedUrl, \"/posts/2/comments/\");\n }));\n\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes a record from update\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n adapter.buildURL = function(type, id, snapshot) {\n return \"/posts/\" + snapshot.belongsTo(\'post\', { id: true }) + \'/comments/\' + snapshot.id;\n };\n\n ajaxResponse({ comments: [{ id: 1 }] });\n\n var post, comment;\n run(function() {\n post = store.push(\'post\', { id: 2 });\n comment = store.push(\'comment\', { id: 1 });\n comment.set(\'post\', post);\n });\n run(function() {\n comment.save().then(async(function(post) {\n equal(passedUrl, \"/posts/2/comments/1\");\n }));\n });\n});\n\ntest(\'buildURL - buildURL takes a record from delete\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n adapter.buildURL = function(type, id, snapshot) {\n return \'posts/\' + snapshot.belongsTo(\'post\', { id: true }) + \'/comments/\' + snapshot.id;\n };\n\n ajaxResponse({ comments: [{ id: 1 }] });\n\n var post, comment;\n run(function() {\n post = store.push(\'post\', { id: 2 });\n comment = store.push(\'comment\', { id: 1 });\n\n comment.set(\'post\', post);\n comment.deleteRecord();\n });\n run(function() {\n comment.save().then(async(function(post) {\n equal(passedUrl, \"posts/2/comments/1\");\n }));\n });\n});\n\ntest(\'buildURL - with absolute namespace\', function() {\n run(function() {\n adapter.setProperties({\n namespace: \'/api/v1\'\n });\n });\n\n ajaxResponse({ posts: [{ id: 1 }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/api/v1/posts/1\");\n }));\n});\n})();//# sourceURL=ember-data/integration/adapter/build-url-mixin-test.js");
284
296
 
285
297
  eval("(function() {var get = Ember.get;\nvar Person, store, allRecords;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/find_all - Finding All Records of a Type\", {\n setup: function() {\n Person = DS.Model.extend({\n updatedAt: DS.attr(\'string\'),\n name: DS.attr(\'string\'),\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\')\n });\n\n allRecords = null;\n },\n\n teardown: function() {\n run(function() {\n if (allRecords) { allRecords.destroy(); }\n store.destroy();\n });\n }\n});\n\ntest(\"When all records for a type are requested, the store should call the adapter\'s `findAll` method.\", function() {\n expect(5);\n\n store = createStore({ adapter: DS.Adapter.extend({\n findAll: function(store, type, since) {\n // this will get called twice\n ok(true, \"the adapter\'s findAll method should be invoked\");\n\n return Ember.RSVP.resolve([{ id: 1, name: \"Braaaahm Dale\" }]);\n }\n })\n });\n\n var allRecords;\n\n run(function() {\n store.find(Person).then(function(all) {\n allRecords = all;\n equal(get(all, \'length\'), 1, \"the record array\'s length is 1 after a record is loaded into it\");\n equal(all.objectAt(0).get(\'name\'), \"Braaaahm Dale\", \"the first item in the record array is Braaaahm Dale\");\n });\n });\n\n run(function() {\n store.find(Person).then(function(all) {\n // Only one record array per type should ever be created (identity map)\n strictEqual(allRecords, all, \"the same record array is returned every time all records of a type are requested\");\n });\n });\n});\n\ntest(\"When all records for a type are requested, a rejection should reject the promise\", function() {\n expect(5);\n\n var count = 0;\n store = createStore({\n adapter: DS.Adapter.extend({\n findAll: function(store, type, since) {\n // this will get called twice\n ok(true, \"the adapter\'s findAll method should be invoked\");\n\n if (count++ === 0) {\n return Ember.RSVP.reject();\n } else {\n return Ember.RSVP.resolve([{ id: 1, name: \"Braaaahm Dale\" }]);\n }\n }\n })\n });\n\n var allRecords;\n\n run(function() {\n store.find(Person).then(null, function() {\n ok(true, \"The rejection should get here\");\n return store.find(Person);\n }).then(function(all) {\n allRecords = all;\n equal(get(all, \'length\'), 1, \"the record array\'s length is 1 after a record is loaded into it\");\n equal(all.objectAt(0).get(\'name\'), \"Braaaahm Dale\", \"the first item in the record array is Braaaahm Dale\");\n });\n });\n});\n\ntest(\"When all records for a type are requested, records that are already loaded should be returned immediately.\", function() {\n expect(3);\n store = createStore({ adapter: DS.Adapter.extend() });\n\n run(function() {\n // Load a record from the server\n store.push(Person, { id: 1, name: \"Jeremy Ashkenas\" });\n // Create a new, unsaved record in the store\n store.createRecord(Person, { name: \"Alex MacCaw\" });\n });\n\n allRecords = store.all(Person);\n\n equal(get(allRecords, \'length\'), 2, \"the record array\'s length is 2\");\n equal(allRecords.objectAt(0).get(\'name\'), \"Jeremy Ashkenas\", \"the first item in the record array is Jeremy Ashkenas\");\n equal(allRecords.objectAt(1).get(\'name\'), \"Alex MacCaw\", \"the second item in the record array is Alex MacCaw\");\n});\n\ntest(\"When all records for a type are requested, records that are created on the client should be added to the record array.\", function() {\n expect(3);\n\n store = createStore({ adapter: DS.Adapter.extend() });\n\n allRecords = store.all(Person);\n\n equal(get(allRecords, \'length\'), 0, \"precond - the record array\'s length is zero before any records are loaded\");\n\n run(function() {\n store.createRecord(Person, { name: \"Carsten Nielsen\" });\n });\n\n equal(get(allRecords, \'length\'), 1, \"the record array\'s length is 1\");\n equal(allRecords.objectAt(0).get(\'name\'), \"Carsten Nielsen\", \"the first item in the record array is Carsten Nielsen\");\n});\n})();//# sourceURL=ember-data/integration/adapter/find-all-test.js");
286
298
 
@@ -292,7 +304,7 @@ eval("(function() {var get = Ember.get;\nvar Person, env, store, adapter;\nvar r
292
304
 
293
305
  eval("(function() {var get = Ember.get;\nvar set = Ember.set;\nvar attr = DS.attr;\nvar Person, env, store;\nvar run = Ember.run;\n\nvar all = Ember.RSVP.all;\nvar hash = Ember.RSVP.hash;\n\nfunction assertClean(promise) {\n return promise.then(async(function(record) {\n equal(record.get(\'isDirty\'), false, \"The record is now clean\");\n return record;\n }));\n}\n\n\nmodule(\"integration/adapter/record_persistence - Persisting Records\", {\n setup: function() {\n Person = DS.Model.extend({\n updatedAt: attr(\'string\'),\n name: attr(\'string\'),\n firstName: attr(\'string\'),\n lastName: attr(\'string\')\n });\n Person.toString = function() { return \"Person\"; };\n\n env = setupStore({ person: Person });\n store = env.store;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"When a store is committed, the adapter\'s `commit` method should be called with records that have been changed.\", function() {\n expect(2);\n\n env.adapter.updateRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n equal(snapshot.record, tom, \"the record is correct\");\n\n return run(Ember.RSVP, \'resolve\');\n };\n\n run(function() {\n env.store.push(\'person\', { id: 1, name: \"Braaaahm Dale\" });\n });\n\n var tom;\n\n env.store.find(\'person\', 1).then(async(function(person) {\n tom = person;\n set(tom, \"name\", \"Tom Dale\");\n tom.save();\n }));\n});\n\ntest(\"When a store is committed, the adapter\'s `commit` method should be called with records that have been created.\", function() {\n expect(2);\n var tom;\n\n env.adapter.createRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n equal(snapshot.record, tom, \"the record is correct\");\n\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\" });\n };\n\n run(function() {\n tom = env.store.createRecord(\'person\', { name: \"Tom Dale\" });\n tom.save();\n });\n});\n\ntest(\"After a created record has been assigned an ID, finding a record by that ID returns the original record.\", function() {\n expect(1);\n var tom;\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\" });\n };\n\n run(function() {\n tom = env.store.createRecord(\'person\', { name: \"Tom Dale\" });\n tom.save();\n });\n\n asyncEqual(tom, env.store.find(\'person\', 1), \"the retrieved record is the same as the created record\");\n});\n\ntest(\"when a store is committed, the adapter\'s `commit` method should be called with records that have been deleted.\", function() {\n env.adapter.deleteRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n equal(snapshot.record, tom, \"the record is correct\");\n\n return run(Ember.RSVP, \'resolve\');\n };\n\n var tom;\n\n run(function() {\n env.store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n env.store.find(\'person\', 1).then(async(function(person) {\n tom = person;\n tom.deleteRecord();\n return tom.save();\n })).then(async(function(tom) {\n equal(get(tom, \'isDeleted\'), true, \"record is marked as deleted\");\n }));\n});\n\ntest(\"An adapter can notify the store that records were updated by calling `didSaveRecords`.\", function() {\n expect(6);\n\n var tom, yehuda;\n\n env.adapter.updateRecord = function(store, type, snapshot) {\n return Ember.RSVP.resolve();\n };\n\n run(function() {\n env.store.push(\'person\', { id: 1 });\n env.store.push(\'person\', { id: 2 });\n });\n\n all([env.store.find(\'person\', 1), env.store.find(\'person\', 2)])\n .then(async(function(array) {\n tom = array[0];\n yehuda = array[1];\n\n tom.set(\'name\', \"Michael Phelps\");\n yehuda.set(\'name\', \"Usain Bolt\");\n\n ok(tom.get(\'isDirty\'), \"tom is dirty\");\n ok(yehuda.get(\'isDirty\'), \"yehuda is dirty\");\n\n assertClean(tom.save()).then(async(function(record) {\n equal(record, tom, \"The record is correct\");\n }));\n\n assertClean(yehuda.save()).then(async(function(record) {\n equal(record, yehuda, \"The record is correct\");\n }));\n }));\n});\n\ntest(\"An adapter can notify the store that records were updated and provide new data by calling `didSaveRecords`.\", function() {\n env.adapter.updateRecord = function(store, type, snapshot) {\n if (snapshot.id === \"1\") {\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\", updatedAt: \"now\" });\n } else if (snapshot.id === \"2\") {\n return Ember.RSVP.resolve({ id: 2, name: \"Yehuda Katz\", updatedAt: \"now!\" });\n }\n };\n\n run(function() {\n env.store.push(\'person\', { id: 1, name: \"Braaaahm Dale\" });\n env.store.push(\'person\', { id: 2, name: \"Gentile Katz\" });\n });\n\n hash({ tom: env.store.find(\'person\', 1), yehuda: env.store.find(\'person\', 2) }).then(async(function(people) {\n people.tom.set(\'name\', \"Draaaaaahm Dale\");\n people.yehuda.set(\'name\', \"Goy Katz\");\n\n return hash({ tom: people.tom.save(), yehuda: people.yehuda.save() });\n })).then(async(function(people) {\n equal(people.tom.get(\'name\'), \"Tom Dale\", \"name attribute should reflect value of hash passed to didSaveRecords\");\n equal(people.tom.get(\'updatedAt\'), \"now\", \"updatedAt attribute should reflect value of hash passed to didSaveRecords\");\n equal(people.yehuda.get(\'name\'), \"Yehuda Katz\", \"name attribute should reflect value of hash passed to didSaveRecords\");\n equal(people.yehuda.get(\'updatedAt\'), \"now!\", \"updatedAt attribute should reflect value of hash passed to didSaveRecords\");\n }));\n});\n\ntest(\"An adapter can notify the store that a record was updated by calling `didSaveRecord`.\", function() {\n env.adapter.updateRecord = function(store, type, snapshot) {\n return Ember.RSVP.resolve();\n };\n\n run(function() {\n store.push(\'person\', { id: 1 });\n store.push(\'person\', { id: 2 });\n });\n\n hash({ tom: store.find(\'person\', 1), yehuda: store.find(\'person\', 2) }).then(async(function(people) {\n people.tom.set(\'name\', \"Tom Dale\");\n people.yehuda.set(\'name\', \"Yehuda Katz\");\n\n ok(people.tom.get(\'isDirty\'), \"tom is dirty\");\n ok(people.yehuda.get(\'isDirty\'), \"yehuda is dirty\");\n\n assertClean(people.tom.save());\n assertClean(people.yehuda.save());\n }));\n\n});\n\ntest(\"An adapter can notify the store that a record was updated and provide new data by calling `didSaveRecord`.\", function() {\n env.adapter.updateRecord = function(store, type, snapshot) {\n switch (snapshot.id) {\n case \"1\":\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\", updatedAt: \"now\" });\n case \"2\":\n return Ember.RSVP.resolve({ id: 2, name: \"Yehuda Katz\", updatedAt: \"now!\" });\n }\n };\n\n run(function() {\n env.store.push(\'person\', { id: 1, name: \"Braaaahm Dale\" });\n env.store.push(\'person\', { id: 2, name: \"Gentile Katz\" });\n });\n\n hash({ tom: store.find(\'person\', 1), yehuda: store.find(\'person\', 2) }).then(async(function(people) {\n people.tom.set(\'name\', \"Draaaaaahm Dale\");\n people.yehuda.set(\'name\', \"Goy Katz\");\n\n return hash({ tom: people.tom.save(), yehuda: people.yehuda.save() });\n })).then(async(function(people) {\n equal(people.tom.get(\'name\'), \"Tom Dale\", \"name attribute should reflect value of hash passed to didSaveRecords\");\n equal(people.tom.get(\'updatedAt\'), \"now\", \"updatedAt attribute should reflect value of hash passed to didSaveRecords\");\n equal(people.yehuda.get(\'name\'), \"Yehuda Katz\", \"name attribute should reflect value of hash passed to didSaveRecords\");\n equal(people.yehuda.get(\'updatedAt\'), \"now!\", \"updatedAt attribute should reflect value of hash passed to didSaveRecords\");\n }));\n\n});\n\ntest(\"An adapter can notify the store that records were deleted by calling `didSaveRecords`.\", function() {\n env.adapter.deleteRecord = function(store, type, snapshot) {\n return Ember.RSVP.resolve();\n };\n\n run(function() {\n env.store.push(\'person\', { id: 1, name: \"Braaaahm Dale\" });\n env.store.push(\'person\', { id: 2, name: \"Gentile Katz\" });\n });\n\n hash({ tom: store.find(\'person\', 1), yehuda: store.find(\'person\', 2) }).then(async(function(people) {\n people.tom.deleteRecord();\n people.yehuda.deleteRecord();\n\n assertClean(people.tom.save());\n assertClean(people.yehuda.save());\n }));\n});\n})();//# sourceURL=ember-data/integration/adapter/record-persistence-test.js");
294
306
 
295
- eval("(function() {var env, store, adapter, Post, Comment, SuperUser;\nvar passedUrl, passedVerb, passedHash;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/rest_adapter - REST Adapter\", {\n setup: function() {\n Post = DS.Model.extend({\n name: DS.attr(\"string\")\n });\n\n Post.toString = function() {\n return \"Post\";\n };\n\n Comment = DS.Model.extend({\n name: DS.attr(\"string\")\n });\n\n SuperUser = DS.Model.extend();\n\n env = setupStore({\n post: Post,\n comment: Comment,\n superUser: SuperUser,\n adapter: DS.RESTAdapter\n });\n\n store = env.store;\n adapter = env.adapter;\n\n passedUrl = passedVerb = passedHash = null;\n }\n});\n\nfunction ajaxResponse(value) {\n adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n passedVerb = verb;\n passedHash = hash;\n\n return run(Ember.RSVP, \'resolve\', value);\n };\n}\n\ntest(\"find - basic payload\", function() {\n ajaxResponse({ posts: [{ id: 1, name: \"Rails is omakase\" }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n }));\n});\n\n\ntest(\"find - passes buildURL a requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/\" + requestType + \"/post/\" + id;\n };\n\n ajaxResponse({ posts: [{ id: 1, name: \"Rails is omakase\" }] });\n\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/find/post/1\");\n }));\n});\n\ntest(\"find - basic payload (with legacy singular name)\", function() {\n ajaxResponse({ post: { id: 1, name: \"Rails is omakase\" } });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n }));\n});\n\ntest(\"find - payload with sideloaded records of the same type\", function() {\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ]\n });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n\n var post2 = store.getById(\'post\', 2);\n equal(post2.get(\'id\'), \"2\");\n equal(post2.get(\'name\'), \"The Parley Letter\");\n }));\n});\n\ntest(\"find - payload with sideloaded records of a different type\", function() {\n ajaxResponse({\n posts: [{ id: 1, name: \"Rails is omakase\" }],\n comments: [{ id: 1, name: \"FIRST\" }]\n });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n\n var comment = store.getById(\'comment\', 1);\n equal(comment.get(\'id\'), \"1\");\n equal(comment.get(\'name\'), \"FIRST\");\n }));\n});\n\n\ntest(\"find - payload with an serializer-specified primary key\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\'\n }));\n\n ajaxResponse({ posts: [{ \"_ID_\": 1, name: \"Rails is omakase\" }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n }));\n});\n\ntest(\"find - payload with a serializer-specified attribute mapping\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n attrs: {\n \'name\': \'_NAME_\',\n \'createdAt\': { key: \'_CREATED_AT_\', someOtherOption: \'option\' }\n }\n }));\n\n Post.reopen({\n createdAt: DS.attr(\"number\")\n });\n\n ajaxResponse({ posts: [{ id: 1, _NAME_: \"Rails is omakase\", _CREATED_AT_: 2013 }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n equal(post.get(\'createdAt\'), 2013);\n }));\n});\n\ntest(\"create - an empty payload is a basic success if an id was specified\", function() {\n ajaxResponse();\n var post;\n\n run(function() {\n post = store.createRecord(\'post\', { id: \"some-uuid\", name: \"The Parley Letter\" });\n post.save().then(async(function(post) {\n equal(passedUrl, \"/posts\");\n equal(passedVerb, \"POST\");\n deepEqual(passedHash.data, { post: { id: \"some-uuid\", name: \"The Parley Letter\" } });\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"The Parley Letter\", \"the post was updated\");\n }));\n });\n});\n\ntest(\"create - passes buildURL the requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/post/\" + requestType;\n };\n\n ajaxResponse();\n var post;\n\n run(function() {\n post = store.createRecord(\'post\', { id: \"some-uuid\", name: \"The Parley Letter\" });\n post.save().then(async(function(post) {\n equal(passedUrl, \"/post/createRecord\");\n }));\n });\n});\n\ntest(\"create - a payload with a new ID and data applies the updates\", function() {\n ajaxResponse({ posts: [{ id: \"1\", name: \"Dat Parley Letter\" }] });\n run(function() {\n var post = store.createRecord(\'post\', { name: \"The Parley Letter\" });\n\n post.save().then(async(function(post) {\n equal(passedUrl, \"/posts\");\n equal(passedVerb, \"POST\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'id\'), \"1\", \"the post has the updated ID\");\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n }));\n });\n});\n\ntest(\"create - a payload with a new ID and data applies the updates (with legacy singular name)\", function() {\n var post;\n ajaxResponse({ post: { id: \"1\", name: \"Dat Parley Letter\" } });\n run(function() {\n post = store.createRecord(\'post\', { name: \"The Parley Letter\" });\n });\n\n run(post, \'save\').then(async(function(post) {\n equal(passedUrl, \"/posts\");\n equal(passedVerb, \"POST\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'id\'), \"1\", \"the post has the updated ID\");\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n }));\n});\n\ntest(\"create - findMany doesn\'t overwrite owner\", function() {\n ajaxResponse({ comment: { id: \"1\", name: \"Dat Parley Letter\", post: 1 } });\n var comment;\n\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [] });\n });\n var post = store.getById(\'post\', 1);\n\n run(function() {\n comment = store.createRecord(\'comment\', { name: \"The Parley Letter\" });\n });\n post.get(\'comments\').pushObject(comment);\n\n equal(comment.get(\'post\'), post, \"the post has been set correctly\");\n\n run(function() {\n comment.save().then(async(function(comment) {\n equal(comment.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(comment.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n equal(comment.get(\'post\'), post, \"the post is still set\");\n }));\n });\n});\n\ntest(\"create - a serializer\'s primary key and attributes are consulted when building the payload\", function() {\n var post;\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_id_\',\n\n attrs: {\n name: \'_name_\'\n }\n }));\n\n ajaxResponse();\n\n run(function() {\n post = store.createRecord(\'post\', { id: \"some-uuid\", name: \"The Parley Letter\" });\n });\n\n run(post, \'save\').then(async(function(post) {\n deepEqual(passedHash.data, { post: { _id_: \'some-uuid\', \'_name_\': \"The Parley Letter\" } });\n }));\n});\n\ntest(\"create - a serializer\'s attributes are consulted when building the payload if no id is pre-defined\", function() {\n var post;\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primarykey: \'_id_\',\n\n attrs: {\n name: \'_name_\'\n }\n }));\n\n ajaxResponse();\n\n run(function() {\n post = store.createRecord(\'post\', { name: \"The Parley Letter\" });\n\n post.save().then(async(function(post) {\n deepEqual(passedHash.data, { post: { \'_name_\': \"The Parley Letter\" } });\n }));\n });\n});\n\ntest(\"create - a serializer\'s attribute mapping takes precdence over keyForAttribute when building the payload\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n attrs: {\n name: \'given_name\'\n },\n\n keyForAttribute: function(attr) {\n return attr.toUpperCase();\n }\n }));\n\n ajaxResponse();\n\n run(function() {\n var post = store.createRecord(\'post\', { id: \"some-uuid\", name: \"The Parley Letter\" });\n\n post.save().then(async(function(post) {\n deepEqual(passedHash.data, { post: { \'given_name\': \"The Parley Letter\", id: \"some-uuid\" } });\n }));\n });\n});\n\ntest(\"create - a serializer\'s attribute mapping takes precedence over keyForRelationship (belongsTo) when building the payload\", function() {\n env.registry.register(\'serializer:comment\', DS.RESTSerializer.extend({\n attrs: {\n post: \'article\'\n },\n\n keyForRelationship: function(attr, kind) {\n return attr.toUpperCase();\n }\n }));\n\n ajaxResponse();\n\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n var post = store.createRecord(\'post\', { id: \"a-post-id\", name: \"The Parley Letter\" });\n var comment = store.createRecord(\'comment\', { id: \"some-uuid\", name: \"Letters are fun\", post: post });\n\n comment.save().then(async(function(post) {\n deepEqual(passedHash.data, { comment: { article: \"a-post-id\", id: \"some-uuid\", name: \"Letters are fun\" } });\n }));\n });\n});\n\ntest(\"create - a serializer\'s attribute mapping takes precedence over keyForRelationship (hasMany) when building the payload\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n attrs: {\n comments: \'opinions\'\n },\n\n keyForRelationship: function(attr, kind) {\n return attr.toUpperCase();\n }\n }));\n\n ajaxResponse();\n\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n\n run(function() {\n var comment = store.createRecord(\'comment\', { id: \"a-comment-id\", name: \"First!\" });\n var post = store.createRecord(\'post\', { id: \"some-uuid\", name: \"The Parley Letter\" });\n post.get(\'comments\').pushObject(comment);\n\n post.save().then(async(function(post) {\n deepEqual(passedHash.data, { post: { opinions: [\"a-comment-id\"], id: \"some-uuid\", name: \"The Parley Letter\" } });\n }));\n });\n});\n\ntest(\"create - a record on the many side of a hasMany relationship should update relationships when data is sideloaded\", function() {\n expect(3);\n\n ajaxResponse({\n posts: [{\n id: \"1\",\n name: \"Rails is omakase\",\n comments: [1,2]\n }],\n comments: [{\n id: \"2\",\n name: \"Another Comment\",\n post: 1\n },\n {\n id: \"1\",\n name: \"Dat Parley Letter\",\n post: 1\n }]\n // My API is returning a comment:{} as well as a comments:[{...},...]\n //, comment: {\n // id: \"2\",\n // name: \"Another Comment\",\n // post: 1\n // }\n });\n\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1] });\n store.push(\'comment\', { id: 1, name: \"Dat Parlay Letter\", post: 1 });\n });\n\n var post = store.getById(\'post\', 1);\n var commentCount = post.get(\'comments.length\');\n equal(commentCount, 1, \"the post starts life with a comment\");\n\n run(function() {\n var comment = store.createRecord(\'comment\', { name: \"Another Comment\", post: post });\n\n comment.save().then(async(function(comment) {\n equal(comment.get(\'post\'), post, \"the comment is related to the post\");\n }));\n\n post.reload().then(async(function(post) {\n equal(post.get(\'comments.length\'), 2, \"Post comment count has been updated\");\n }));\n });\n});\n\ntest(\"create - sideloaded belongsTo relationships are both marked as loaded\", function () {\n expect(4);\n var post;\n\n Post.reopen({ comment: DS.belongsTo(\'comment\') });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n post = store.createRecord(\'post\', { name: \"man\" });\n });\n\n ajaxResponse({\n posts: [{ id: 1, comment: 1, name: \"marked\" }],\n comments: [{ id: 1, post: 1, name: \"Comcast is a bargain\" }]\n });\n\n run(function() {\n post.save().then(async(function(record) {\n equal(store.getById(\'post\', 1).get(\'comment.isLoaded\'), true, \"post\'s comment isLoaded (via store)\");\n equal(store.getById(\'comment\', 1).get(\'post.isLoaded\'), true, \"comment\'s post isLoaded (via store)\");\n equal(record.get(\'comment.isLoaded\'), true, \"post\'s comment isLoaded (via record)\");\n equal(record.get(\'comment.post.isLoaded\'), true, \"post\'s comment\'s post isLoaded (via record)\");\n }));\n });\n});\n\ntest(\"create - response can contain relationships the client doesn\'t yet know about\", function() {\n expect(3); // while records.length is 2, we are getting 4 assertions\n\n ajaxResponse({\n posts: [{\n id: \"1\",\n name: \"Rails is omakase\",\n comments: [2]\n }],\n comments: [{\n id: \"2\",\n name: \"Another Comment\",\n post: 1\n }]\n });\n\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n var post;\n run(function() {\n post = store.createRecord(\'post\', { name: \"Rails is omakase\" });\n });\n\n run(function() {\n post.save().then(async(function(post) {\n equal(post.get(\'comments.firstObject.post\'), post, \"the comments are related to the correct post model\");\n equal(store.typeMapFor(Post).records.length, 1, \"There should only be one post record in the store\");\n\n var postRecords = store.typeMapFor(Post).records;\n for (var i = 0; i < postRecords.length; i++) {\n equal(post, postRecords[i], \"The object in the identity map is the same\");\n }\n }));\n });\n});\n\ntest(\"create - relationships are not duplicated\", function() {\n var post, comment;\n\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n post = store.createRecord(\'post\', { name: \"Tomtomhuda\" });\n comment = store.createRecord(\'comment\', { id: 2, name: \"Comment title\" });\n });\n\n ajaxResponse({ post: [{ id: 1, name: \"Rails is omakase\", comments: [] }] });\n\n run(post, \'save\').then(async(function(post) {\n equal(post.get(\'comments.length\'), 0, \"post has 0 comments\");\n post.get(\'comments\').pushObject(comment);\n equal(post.get(\'comments.length\'), 1, \"post has 1 comment\");\n\n ajaxResponse({\n post: [{ id: 1, name: \"Rails is omakase\", comments: [2] }],\n comments: [{ id: 2, name: \"Comment title\" }]\n });\n\n return post.save();\n })).then(async(function(post) {\n equal(post.get(\'comments.length\'), 1, \"post has 1 comment\");\n }));\n});\n\ntest(\"update - an empty payload is a basic success\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse();\n\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"PUT\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"The Parley Letter\", \"the post was updated\");\n }));\n});\n\ntest(\"update - passes the requestType to buildURL\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/posts/\" + id + \"/\" + requestType;\n };\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse();\n\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1/updateRecord\");\n }));\n});\n\ntest(\"update - a payload with updates applies the updates\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({ posts: [{ id: 1, name: \"Dat Parley Letter\" }] });\n\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"PUT\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n }));\n});\n\ntest(\"update - a payload with updates applies the updates (with legacy singular name)\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({ post: { id: 1, name: \"Dat Parley Letter\" } });\n\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"PUT\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n }));\n});\n\ntest(\"update - a payload with sideloaded updates pushes the updates\", function() {\n var post;\n ajaxResponse({\n posts: [{ id: 1, name: \"Dat Parley Letter\" }],\n comments: [{ id: 1, name: \"FIRST\" }]\n });\n run(function() {\n post = store.createRecord(\'post\', { name: \"The Parley Letter\" });\n post.save().then(async(function(post) {\n equal(passedUrl, \"/posts\");\n equal(passedVerb, \"POST\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'id\'), \"1\", \"the post has the updated ID\");\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n\n var comment = store.getById(\'comment\', 1);\n equal(comment.get(\'name\'), \"FIRST\", \"The comment was sideloaded\");\n }));\n });\n});\n\ntest(\"update - a payload with sideloaded updates pushes the updates\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n posts: [{ id: 1, name: \"Dat Parley Letter\" }],\n comments: [{ id: 1, name: \"FIRST\" }]\n });\n\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"PUT\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n\n var comment = store.getById(\'comment\', 1);\n equal(comment.get(\'name\'), \"FIRST\", \"The comment was sideloaded\");\n }));\n});\n\ntest(\"update - a serializer\'s primary key and attributes are consulted when building the payload\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_id_\',\n\n attrs: {\n name: \'_name_\'\n }\n }));\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n ajaxResponse();\n\n store.find(\'post\', 1).then(async(function(post) {\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n deepEqual(passedHash.data, { post: { \'_name_\': \"The Parley Letter\" } });\n }));\n});\n\ntest(\"update - hasMany relationships faithfully reflect simultaneous adds and removes\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Not everyone uses Rails\", comments: [1] });\n store.push(\'comment\', { id: 1, name: \"Rails is omakase\" });\n store.push(\'comment\', { id: 2, name: \"Yes. Yes it is.\" });\n });\n\n ajaxResponse({\n posts: { id: 1, name: \"Not everyone uses Rails\", comments: [2] }\n });\n\n store.find(\'comment\', 2).then(async(function() {\n return store.find(\'post\', 1);\n })).then(async(function(post) {\n var newComment = store.getById(\'comment\', 2);\n var comments = post.get(\'comments\');\n\n // Replace the comment with a new one\n comments.popObject();\n comments.pushObject(newComment);\n\n return post.save();\n })).then(async(function(post) {\n equal(post.get(\'comments.length\'), 1, \"the post has the correct number of comments\");\n equal(post.get(\'comments.firstObject.name\'), \"Yes. Yes it is.\", \"the post has the correct comment\");\n }));\n});\n\ntest(\"delete - an empty payload is a basic success\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse();\n\n post.deleteRecord();\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"DELETE\");\n equal(passedHash, undefined);\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'isDeleted\'), true, \"the post is now deleted\");\n }));\n});\n\ntest(\"delete - passes the requestType to buildURL\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/posts/\" + id + \"/\" + requestType;\n };\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse();\n\n post.deleteRecord();\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1/deleteRecord\");\n }));\n});\n\ntest(\"delete - a payload with sideloaded updates pushes the updates\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({ comments: [{ id: 1, name: \"FIRST\" }] });\n\n post.deleteRecord();\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"DELETE\");\n equal(passedHash, undefined);\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'isDeleted\'), true, \"the post is now deleted\");\n\n var comment = store.getById(\'comment\', 1);\n equal(comment.get(\'name\'), \"FIRST\", \"The comment was sideloaded\");\n }));\n});\n\ntest(\"delete - a payload with sidloaded updates pushes the updates when the original record is omitted\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({ posts: [{ id: 2, name: \"The Parley Letter\" }] });\n\n post.deleteRecord();\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"DELETE\");\n equal(passedHash, undefined);\n\n equal(post.get(\'isDirty\'), false, \"the original post isn\'t dirty anymore\");\n equal(post.get(\'isDeleted\'), true, \"the original post is now deleted\");\n\n var newPost = store.getById(\'post\', 2);\n equal(newPost.get(\'name\'), \"The Parley Letter\", \"The new post was added to the store\");\n }));\n});\n\ntest(\"delete - deleting a newly created record should not throw an error\", function() {\n var post;\n run(function() {\n post = store.createRecord(\'post\');\n });\n\n run(function() {\n post.deleteRecord();\n post.save().then(async(function(post) {\n equal(passedUrl, null, \"There is no ajax call to delete a record that has never been saved.\");\n equal(passedVerb, null, \"There is no ajax call to delete a record that has never been saved.\");\n equal(passedHash, null, \"There is no ajax call to delete a record that has never been saved.\");\n\n equal(post.get(\'isDeleted\'), true, \"the post is now deleted\");\n equal(post.get(\'isError\'), false, \"the post is not an error\");\n }));\n });\n});\n\ntest(\"findAll - returning an array populates the array\", function() {\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ]\n });\n\n store.findAll(\'post\').then(async(function(posts) {\n equal(passedUrl, \"/posts\");\n equal(passedVerb, \"GET\");\n equal(passedHash.data, undefined);\n\n var post1 = store.getById(\'post\', 1);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(\n post1.getProperties(\'id\', \'name\'),\n { id: \"1\", name: \"Rails is omakase\" },\n \"Post 1 is loaded\"\n );\n\n deepEqual(\n post2.getProperties(\'id\', \'name\'),\n { id: \"2\", name: \"The Parley Letter\" },\n \"Post 2 is loaded\"\n );\n\n equal(posts.get(\'length\'), 2, \"The posts are in the array\");\n equal(posts.get(\'isLoaded\'), true, \"The RecordArray is loaded\");\n deepEqual(\n posts.toArray(),\n [post1, post2],\n \"The correct records are in the array\"\n );\n }));\n});\n\n\ntest(\"findAll - passes buildURL the requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/\" + requestType + \"/posts\";\n };\n\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ]\n });\n\n store.findAll(\'post\').then(async(function(posts) {\n equal(passedUrl, \"/findAll/posts\");\n }));\n});\n\ntest(\"findAll - returning sideloaded data loads the data\", function() {\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ],\n comments: [{ id: 1, name: \"FIRST\" }] });\n\n store.findAll(\'post\').then(async(function(posts) {\n var comment = store.getById(\'comment\', 1);\n\n deepEqual(comment.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n }));\n});\n\ntest(\"findAll - data is normalized through custom serializers\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n ajaxResponse({\n posts: [\n { _ID_: 1, _NAME_: \"Rails is omakase\" },\n { _ID_: 2, _NAME_: \"The Parley Letter\" }\n ]\n });\n\n store.findAll(\'post\').then(async(function(posts) {\n var post1 = store.getById(\'post\', 1);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(\n post1.getProperties(\'id\', \'name\'),\n { id: \"1\", name: \"Rails is omakase\" },\n \"Post 1 is loaded\"\n );\n deepEqual(\n post2.getProperties(\'id\', \'name\'),\n { id: \"2\", name: \"The Parley Letter\" },\n \"Post 2 is loaded\"\n );\n\n equal(posts.get(\'length\'), 2, \"The posts are in the array\");\n equal(posts.get(\'isLoaded\'), true, \"The RecordArray is loaded\");\n deepEqual(\n posts.toArray(),\n [post1, post2],\n \"The correct records are in the array\"\n );\n }));\n});\n\ntest(\"findAll - since token is passed to the adapter\", function() {\n ajaxResponse({\n meta: { since: \'later\' },\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ]\n });\n\n store.setMetadataFor(\'post\', { since: \'now\' });\n\n store.findAll(\'post\').then(async(function(posts) {\n equal(passedUrl, \'/posts\');\n equal(passedVerb, \'GET\');\n equal(store.typeMapFor(Post).metadata.since, \'later\');\n deepEqual(passedHash.data, { since: \'now\' });\n }));\n});\n\ntest(\"metadata is accessible\", function() {\n ajaxResponse({\n meta: { offset: 5 },\n posts: [{ id: 1, name: \"Rails is very expensive sushi\" }]\n });\n\n store.findAll(\'post\').then(async(function(posts) {\n equal(\n store.metadataFor(\'post\').offset,\n 5,\n \"Metadata can be accessed with metadataFor.\"\n );\n }));\n});\n\ntest(\"findQuery - if `sortQueryParams` option is not provided, query params are sorted alphabetically\", function() {\n adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n passedVerb = verb;\n passedHash = hash;\n\n deepEqual(Object.keys(hash.data), [\"in\", \"order\", \"params\", \"wrong\"], \'query params are received in alphabetical order\');\n\n return run(Ember.RSVP, \'resolve\', { posts: [{ id: 1, name: \"Rails is very expensive sushi\" }] });\n };\n\n store.findQuery(\'post\', { \"params\": 1, \"in\": 2, \"wrong\": 3, \"order\": 4 }).then(async(function() {\n // Noop\n }));\n});\n\ntest(\"findQuery - passes buildURL the requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/\" + requestType + \"/posts\";\n };\n\n adapter.ajax = function(url, verb, hash) {\n equal(url, \'/findQuery/posts\');\n\n return run(Ember.RSVP, \'resolve\', { posts: [{ id: 1, name: \"Rails is very expensive sushi\" }] });\n };\n\n store.findQuery(\'post\', { \"params\": 1, \"in\": 2, \"wrong\": 3, \"order\": 4 }).then(async(function() {\n // NOOP\n }));\n});\n\ntest(\"findQuery - if `sortQueryParams` is falsey, query params are not sorted at all\", function() {\n adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n passedVerb = verb;\n passedHash = hash;\n\n deepEqual(Object.keys(hash.data), [\"params\", \"in\", \"wrong\", \"order\"], \'query params are received in their original order\');\n\n return run(Ember.RSVP, \'resolve\', { posts: [{ id: 1, name: \"Rails is very expensive sushi\" }] });\n };\n\n adapter.sortQueryParams = null;\n\n store.findQuery(\'post\', { \"params\": 1, \"in\": 2, \"wrong\": 3, \"order\": 4 }).then(async(function() {\n // Noop\n }));\n});\n\ntest(\"findQuery - if `sortQueryParams` is a custom function, query params passed through that function\", function() {\n adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n passedVerb = verb;\n passedHash = hash;\n\n deepEqual(Object.keys(hash.data), [\"wrong\", \"params\", \"order\", \"in\"], \'query params are received in reverse alphabetical order\');\n\n return run(Ember.RSVP, \'resolve\', { posts: [{ id: 1, name: \"Rails is very expensive sushi\" }] });\n };\n\n adapter.sortQueryParams = function(obj) {\n var sortedKeys = Object.keys(obj).sort().reverse();\n var len = sortedKeys.length;\n var newQueryParams = {};\n\n for (var i = 0; i < len; i++) {\n newQueryParams[sortedKeys[i]] = obj[sortedKeys[i]];\n }\n return newQueryParams;\n };\n\n store.findQuery(\'post\', { \"params\": 1, \"in\": 2, \"wrong\": 3, \"order\": 4 }).then(async(function() {\n // Noop\n }));\n});\n\ntest(\"findQuery - payload \'meta\' is accessible on the record array\", function() {\n ajaxResponse({\n meta: { offset: 5 },\n posts: [{ id: 1, name: \"Rails is very expensive sushi\" }]\n });\n\n store.findQuery(\'post\', { page: 2 }).then(async(function(posts) {\n equal(\n posts.get(\'meta.offset\'),\n 5,\n \"Reponse metadata can be accessed with recordArray.meta\"\n );\n }));\n});\n\ntest(\"findQuery - each record array can have it\'s own meta object\", function() {\n ajaxResponse({\n meta: { offset: 5 },\n posts: [{ id: 1, name: \"Rails is very expensive sushi\" }]\n });\n\n store.findQuery(\'post\', { page: 2 }).then(async(function(posts) {\n equal(\n posts.get(\'meta.offset\'),\n 5,\n \"Reponse metadata can be accessed with recordArray.meta\"\n );\n ajaxResponse({\n meta: { offset: 1 },\n posts: [{ id: 1, name: \"Rails is very expensive sushi\" }]\n });\n store.findQuery(\'post\', { page: 1 }).then(async(function(newPosts) {\n equal(newPosts.get(\'meta.offset\'), 1, \'new array has correct metadata\');\n equal(posts.get(\'meta.offset\'), 5, \'metadata on the old array hasnt been clobbered\');\n }));\n }));\n});\n\n\ntest(\"findQuery - returning an array populates the array\", function() {\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }]\n });\n\n store.findQuery(\'post\', { page: 1 }).then(async(function(posts) {\n equal(passedUrl, \'/posts\');\n equal(passedVerb, \'GET\');\n deepEqual(passedHash.data, { page: 1 });\n\n var post1 = store.getById(\'post\', 1);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(\n post1.getProperties(\'id\', \'name\'),\n { id: \"1\", name: \"Rails is omakase\" },\n \"Post 1 is loaded\"\n );\n deepEqual(\n post2.getProperties(\'id\', \'name\'),\n { id: \"2\", name: \"The Parley Letter\" },\n \"Post 2 is loaded\"\n );\n\n equal(posts.get(\'length\'), 2, \"The posts are in the array\");\n equal(posts.get(\'isLoaded\'), true, \"The RecordArray is loaded\");\n deepEqual(\n posts.toArray(),\n [post1, post2],\n \"The correct records are in the array\"\n );\n }));\n});\n\ntest(\"findQuery - returning sideloaded data loads the data\", function() {\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ],\n comments: [{ id: 1, name: \"FIRST\" }]\n });\n\n store.findQuery(\'post\', { page: 1 }).then(async(function(posts) {\n var comment = store.getById(\'comment\', 1);\n\n deepEqual(comment.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n }));\n});\n\ntest(\"findQuery - data is normalized through custom serializers\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n ajaxResponse({\n posts: [{ _ID_: 1, _NAME_: \"Rails is omakase\" },\n { _ID_: 2, _NAME_: \"The Parley Letter\" }]\n });\n\n store.findQuery(\'post\', { page: 1 }).then(async(function(posts) {\n var post1 = store.getById(\'post\', 1);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(\n post1.getProperties(\'id\', \'name\'),\n { id: \"1\", name: \"Rails is omakase\" },\n \"Post 1 is loaded\"\n );\n\n deepEqual(\n post2.getProperties(\'id\', \'name\'),\n { id: \"2\", name: \"The Parley Letter\" },\n \"Post 2 is loaded\"\n );\n\n equal(posts.get(\'length\'), 2, \"The posts are in the array\");\n equal(posts.get(\'isLoaded\'), true, \"The RecordArray is loaded\");\n deepEqual(\n posts.toArray(),\n [post1, post2],\n \"The correct records are in the array\"\n );\n }));\n});\n\ntest(\"findMany - findMany uses a correct URL to access the records\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n var post = store.getById(\'post\', 1);\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n run(post, \'get\', \'comments\').then(async(function(comments) {\n equal(passedUrl, \"/comments\");\n deepEqual(passedHash, { data: { ids: [\"1\", \"2\", \"3\"] } });\n }));\n});\n\ntest(\"findMany - passes buildURL the requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/\" + requestType + \"/\" + type;\n };\n\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n var post = store.getById(\'post\', 1);\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n run(post, \'get\', \'comments\').then(async(function(comments) {\n equal(passedUrl, \"/findMany/comment\");\n }));\n});\n\ntest(\"findMany - findMany does not coalesce by default\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n var post = store.getById(\'post\', 1);\n //It\'s still ok to return this even without coalescing because RESTSerializer supports sideloading\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n run(post, \'get\', \'comments\').then(async(function(comments) {\n equal(passedUrl, \"/comments/3\");\n equal(passedHash, null);\n }));\n});\n\ntest(\"findMany - returning an array populates the array\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n\n deepEqual(comment1.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n deepEqual(comment2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"Rails is unagi\" });\n deepEqual(comment3.getProperties(\'id\', \'name\'), { id: \"3\", name: \"What is omakase?\" });\n\n deepEqual(\n comments.toArray(),\n [comment1, comment2, comment3],\n \"The correct records are in the array\"\n );\n }));\n});\n\ntest(\"findMany - returning sideloaded data loads the data\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" },\n { id: 4, name: \"Unrelated comment\" }\n ],\n posts: [{ id: 2, name: \"The Parley Letter\" }]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n var comment4 = store.getById(\'comment\', 4);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(\n comments.toArray(),\n [comment1, comment2, comment3],\n \"The correct records are in the array\"\n );\n\n deepEqual(comment4.getProperties(\'id\', \'name\'), { id: \"4\", name: \"Unrelated comment\" });\n deepEqual(post2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"The Parley Letter\" });\n }));\n});\n\ntest(\"findMany - a custom serializer is used if present\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n env.registry.register(\'serializer:comment\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n adapter.coalesceFindRequests = true;\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n comments: [\n { _ID_: 1, _NAME_: \"FIRST\" },\n { _ID_: 2, _NAME_: \"Rails is unagi\" },\n { _ID_: 3, _NAME_: \"What is omakase?\" }]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n\n deepEqual(comment1.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n deepEqual(comment2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"Rails is unagi\" });\n deepEqual(comment3.getProperties(\'id\', \'name\'), { id: \"3\", name: \"What is omakase?\" });\n\n deepEqual(comments.toArray(), [comment1, comment2, comment3], \"The correct records are in the array\");\n }));\n});\n\ntest(\"findHasMany - returning an array populates the array\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n run(function() {\n store.push(\n \'post\',\n {\n id: 1,\n name: \"Rails is omakase\",\n links: { comments: \'/posts/1/comments\' }\n }\n );\n });\n\n run(store, \'find\', \'post\', \'1\').then(async(function(post) {\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n equal(passedUrl, \'/posts/1/comments\');\n equal(passedVerb, \'GET\');\n equal(passedHash, undefined);\n\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n\n deepEqual(comment1.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n deepEqual(comment2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"Rails is unagi\" });\n deepEqual(comment3.getProperties(\'id\', \'name\'), { id: \"3\", name: \"What is omakase?\" });\n\n deepEqual(comments.toArray(), [comment1, comment2, comment3], \"The correct records are in the array\");\n }));\n});\n\ntest(\"findHasMany - passes buildURL the requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n equal(requestType, \'findHasMany\');\n };\n\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n run(function() {\n store.push(\n \'post\',\n {\n id: 1,\n name: \"Rails is omakase\",\n links: { comments: \'/posts/1/comments\' }\n }\n );\n });\n\n run(store, \'find\', \'post\', \'1\').then(async(function(post) {\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n // NOOP\n }));\n});\n\n\n\ntest(\"findMany - returning sideloaded data loads the data\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n run(function() {\n store.push(\n \'post\',\n {\n id: 1,\n name: \"Rails is omakase\",\n links: { comments: \'/posts/1/comments\' }\n }\n );\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ],\n posts: [{ id: 2, name: \"The Parley Letter\" }]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(comments.toArray(), [comment1, comment2, comment3], \"The correct records are in the array\");\n\n deepEqual(post2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"The Parley Letter\" });\n }));\n});\n\ntest(\"findMany - a custom serializer is used if present\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n env.registry.register(\'serializer:comment\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n run(function() {\n store.push(\n \'post\',\n {\n id: 1,\n name: \"Rails is omakase\",\n links: { comments: \'/posts/1/comments\' }\n }\n );\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n comments: [\n { _ID_: 1, _NAME_: \"FIRST\" },\n { _ID_: 2, _NAME_: \"Rails is unagi\" },\n { _ID_: 3, _NAME_: \"What is omakase?\" }\n ]\n });\n return post.get(\'comments\');\n })).then(async(function(comments) {\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n\n deepEqual(comment1.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n deepEqual(comment2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"Rails is unagi\" });\n deepEqual(comment3.getProperties(\'id\', \'name\'), { id: \"3\", name: \"What is omakase?\" });\n\n deepEqual(comments.toArray(), [comment1, comment2, comment3], \"The correct records are in the array\");\n }));\n});\n\ntest(\'findBelongsTo - passes buildURL the requestType\', function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n equal(requestType, \'findBelongsTo\');\n };\n\n Comment.reopen({ post: DS.belongsTo(\'post\', { async: true }) });\n\n run(function() {\n store.push(\'comment\', {\n id: 1, name: \"FIRST\",\n links: { post: \'/posts/1\' }\n });\n });\n\n run(store, \'find\', \'comment\', 1).then(async(function(comment) {\n ajaxResponse({ post: { id: 1, name: \'Rails is omakase\' } });\n return comment.get(\'post\');\n })).then(async(function(post) {\n // NOOP\n }));\n});\n\ntest(\'coalesceFindRequests warns if the expected records are not returned in the coalesced request\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n adapter.coalesceFindRequests = true;\n\n ajaxResponse({ comments: [{ id: 1 }] });\n var post;\n\n warns(function() {\n run(function() {\n post = store.push(\'post\', { id: 2, comments: [1,2,3] });\n post.get(\'comments\');\n });\n }, /expected to find records with the following ids in the adapter response but they were missing: \\[2,3\\]/);\n});\n\ntest(\'groupRecordsForFindMany groups records based on their url\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n adapter.buildURL = function(type, id, snapshot) {\n if (id === \'1\') {\n return \'/comments/1\';\n } else {\n return \'/other_comments/\' + id;\n }\n };\n\n adapter.find = function(store, type, id, snapshot) {\n equal(id, \'1\');\n return Ember.RSVP.resolve({ comments: { id: 1 } });\n };\n\n adapter.findMany = function(store, type, ids, snapshots) {\n deepEqual(ids, [\'2\', \'3\']);\n return Ember.RSVP.resolve({ comments: [{ id: 2 }, { id: 3 }] });\n };\n\n var post;\n run(function() {\n post = store.push(\'post\', { id: 2, comments: [1,2,3] });\n });\n\n run(function() {\n post.get(\'comments\');\n });\n});\n\ntest(\'groupRecordsForFindMany groups records correctly when singular URLs are encoded as query params\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n adapter.buildURL = function(type, id, snapshot) {\n if (id === \'1\') {\n return \'/comments?id=1\';\n } else {\n return \'/other_comments?id=\' + id;\n }\n };\n\n adapter.find = function(store, type, id, snapshot) {\n equal(id, \'1\');\n return Ember.RSVP.resolve({ comments: { id: 1 } });\n };\n\n adapter.findMany = function(store, type, ids, snapshots) {\n deepEqual(ids, [\'2\', \'3\']);\n return Ember.RSVP.resolve({ comments: [{ id: 2 }, { id: 3 }] });\n };\n var post;\n\n run(function() {\n post = store.push(\'post\', { id: 2, comments: [1,2,3] });\n });\n\n run(function() {\n post.get(\'comments\');\n });\n});\n\ntest(\'normalizeKey - to set up _ids and _id\', function() {\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n keyForAttribute: function(attr) {\n return Ember.String.underscore(attr);\n },\n\n keyForBelongsTo: function(belongsTo) {\n },\n\n keyForRelationship: function(rel, kind) {\n if (kind === \'belongsTo\') {\n var underscored = Ember.String.underscore(rel);\n return underscored + \'_id\';\n } else {\n var singular = Ember.String.singularize(rel);\n return Ember.String.underscore(singular) + \'_ids\';\n }\n }\n }));\n\n env.registry.register(\'model:post\', DS.Model.extend({\n name: DS.attr(),\n authorName: DS.attr(),\n author: DS.belongsTo(\'user\'),\n comments: DS.hasMany(\'comment\')\n }));\n\n env.registry.register(\'model:user\', DS.Model.extend({\n createdAt: DS.attr(),\n name: DS.attr()\n }));\n\n env.registry.register(\'model:comment\', DS.Model.extend({\n body: DS.attr()\n }));\n\n ajaxResponse({\n posts: [{\n id: \"1\",\n name: \"Rails is omakase\",\n author_name: \"@d2h\",\n author_id: \"1\",\n comment_ids: [\"1\", \"2\"]\n }],\n\n users: [{\n id: \"1\",\n name: \"D2H\"\n }],\n\n comments: [{\n id: \"1\",\n body: \"Rails is unagi\"\n }, {\n id: \"2\",\n body: \"What is omakase?\"\n }]\n });\n\n run(function() {\n store.find(\'post\', 1).then(async(function(post) {\n equal(post.get(\'authorName\'), \"@d2h\");\n equal(post.get(\'author.name\'), \"D2H\");\n deepEqual(post.get(\'comments\').mapBy(\'body\'), [\"Rails is unagi\", \"What is omakase?\"]);\n }));\n });\n});\n\ntest(\'groupRecordsForFindMany splits up calls for large ids\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n expect(2);\n\n function repeatChar(character, n) {\n return new Array(n+1).join(character);\n }\n\n var a2000 = repeatChar(\'a\', 2000);\n var b2000 = repeatChar(\'b\', 2000);\n var post;\n run(function() {\n post = store.push(\'post\', { id: 1, comments: [a2000, b2000] });\n });\n\n adapter.coalesceFindRequests = true;\n\n adapter.find = function(store, type, id, snapshot) {\n if (id === a2000 || id === b2000) {\n ok(true, \"Found \" + id);\n }\n\n return Ember.RSVP.resolve({ comments: { id: id } });\n };\n\n adapter.findMany = function(store, type, ids, snapshots) {\n ok(false, \"findMany should not be called - we expect 2 calls to find for a2000 and b2000\");\n return Ember.RSVP.reject();\n };\n\n run(function() {\n post.get(\'comments\');\n });\n});\n\ntest(\'groupRecordsForFindMany groups calls for small ids\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n expect(1);\n\n function repeatChar(character, n) {\n return new Array(n+1).join(character);\n }\n\n var a100 = repeatChar(\'a\', 100);\n var b100 = repeatChar(\'b\', 100);\n var post;\n\n run(function() {\n post = store.push(\'post\', { id: 1, comments: [a100, b100] });\n });\n\n adapter.coalesceFindRequests = true;\n\n adapter.find = function(store, type, id, snapshot) {\n ok(false, \"find should not be called - we expect 1 call to findMany for a100 and b100\");\n return Ember.RSVP.reject();\n };\n\n adapter.findMany = function(store, type, ids, snapshots) {\n deepEqual(ids, [a100, b100]);\n return Ember.RSVP.resolve({ comments: [{ id: a100 }, { id: b100 }] });\n };\n\n run(function() {\n post.get(\'comments\');\n });\n});\n\n\ntest(\"calls adapter.ajaxSuccess with the jqXHR and json\", function() {\n expect(2);\n var originalAjax = Ember.$.ajax;\n var jqXHR = {};\n var data = {\n post: {\n id: \"1\",\n name: \"Docker is amazing\"\n }\n };\n\n Ember.$.ajax = function(hash) {\n hash.success(data, \'ok\', jqXHR);\n };\n\n adapter.ajaxSuccess = function(xhr, json) {\n deepEqual(jqXHR, xhr);\n deepEqual(json, data);\n return json;\n };\n\n try {\n run(function() {\n store.find(\'post\', \'1\');\n });\n } finally {\n Ember.$.ajax = originalAjax;\n }\n});\n\ntest(\'calls ajaxError with jqXHR, jqXHR.responseText\', function() {\n expect(3);\n var originalAjax = Ember.$.ajax;\n var jqXHR = {\n responseText: \'Nope lol\'\n };\n\n Ember.$.ajax = function(hash) {\n hash.error(jqXHR, jqXHR.responseText);\n };\n\n adapter.ajaxError = function(xhr, responseText) {\n deepEqual(xhr, jqXHR);\n deepEqual(responseText, jqXHR.responseText);\n return new Error(\'nope!\');\n };\n\n try {\n run(function() {\n store.find(\'post\', \'1\')[\"catch\"](function(err) {\n ok(err, \'promise rejected\');\n });\n });\n } finally {\n Ember.$.ajax = originalAjax;\n }\n});\n\ntest(\"rejects promise if DS.InvalidError is returned from adapter.ajaxSuccess\", function() {\n expect(3);\n var originalAjax = Ember.$.ajax;\n var jqXHR = {};\n var data = {\n something: \'is invalid\'\n };\n\n Ember.$.ajax = function(hash) {\n hash.success(data, \'ok\', jqXHR);\n };\n\n adapter.ajaxSuccess = function(xhr, json) {\n ok(true, \'ajaxSuccess should be called\');\n return new DS.InvalidError(json);\n };\n\n Ember.run(function() {\n store.find(\'post\', \'1\').then(null, function(reason) {\n ok(true, \'promise should be rejected\');\n ok(reason instanceof DS.InvalidError, \'reason should be an instance of DS.InvalidError\');\n });\n });\n\n Ember.$.ajax = originalAjax;\n});\n\ntest(\'ajaxError appends errorThrown for sanity\', function() {\n expect(6);\n\n var originalAjax = Ember.$.ajax;\n var jqXHR = {\n responseText: \'Nope lol\'\n };\n\n var errorThrown = new Error(\'nope!\');\n\n Ember.$.ajax = function(hash) {\n hash.error(jqXHR, jqXHR.responseText, errorThrown);\n };\n\n var originalAjaxError = adapter.ajaxError;\n adapter.ajaxError = function(xhr, responseText, _errorThrown) {\n deepEqual(_errorThrown, errorThrown);\n ok(errorThrown);\n deepEqual(xhr, jqXHR);\n deepEqual(responseText, jqXHR.responseText);\n return originalAjaxError.apply(adapter, arguments);\n };\n\n try {\n run(function() {\n store.find(\'post\', \'1\')[\"catch\"](function(err) {\n equal(err.errorThrown, errorThrown);\n ok(err, \'promise rejected\');\n });\n });\n } finally {\n Ember.$.ajax = originalAjax;\n }\n});\n\n\ntest(\'ajaxError wraps the error string in an Error object\', function() {\n expect(2);\n\n var originalAjax = Ember.$.ajax;\n var jqXHR = {\n responseText: \'Nope lol\'\n };\n\n var errorThrown = \'nope!\';\n\n Ember.$.ajax = function(hash) {\n hash.error(jqXHR, jqXHR.responseText, errorThrown);\n };\n\n try {\n run(function() {\n store.find(\'post\', \'1\')[\"catch\"](function(err) {\n equal(err.errorThrown.message, errorThrown);\n ok(err, \'promise rejected\');\n });\n });\n } finally {\n Ember.$.ajax = originalAjax;\n }\n});\n})();//# sourceURL=ember-data/integration/adapter/rest-adapter-test.js");
307
+ eval("(function() {var env, store, adapter, Post, Comment, SuperUser;\nvar passedUrl, passedVerb, passedHash;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/rest_adapter - REST Adapter\", {\n setup: function() {\n Post = DS.Model.extend({\n name: DS.attr(\"string\")\n });\n\n Post.toString = function() {\n return \"Post\";\n };\n\n Comment = DS.Model.extend({\n name: DS.attr(\"string\")\n });\n\n SuperUser = DS.Model.extend();\n\n env = setupStore({\n post: Post,\n comment: Comment,\n superUser: SuperUser,\n adapter: DS.RESTAdapter\n });\n\n store = env.store;\n adapter = env.adapter;\n\n passedUrl = passedVerb = passedHash = null;\n }\n});\n\nfunction ajaxResponse(value) {\n adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n passedVerb = verb;\n passedHash = hash;\n\n return run(Ember.RSVP, \'resolve\', value);\n };\n}\n\ntest(\"find - basic payload\", function() {\n ajaxResponse({ posts: [{ id: 1, name: \"Rails is omakase\" }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n }));\n});\n\n\ntest(\"find - passes buildURL a requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/\" + requestType + \"/post/\" + id;\n };\n\n ajaxResponse({ posts: [{ id: 1, name: \"Rails is omakase\" }] });\n\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/find/post/1\");\n }));\n});\n\ntest(\"find - basic payload (with legacy singular name)\", function() {\n ajaxResponse({ post: { id: 1, name: \"Rails is omakase\" } });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n }));\n});\n\ntest(\"find - payload with sideloaded records of the same type\", function() {\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ]\n });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n\n var post2 = store.getById(\'post\', 2);\n equal(post2.get(\'id\'), \"2\");\n equal(post2.get(\'name\'), \"The Parley Letter\");\n }));\n});\n\ntest(\"find - payload with sideloaded records of a different type\", function() {\n ajaxResponse({\n posts: [{ id: 1, name: \"Rails is omakase\" }],\n comments: [{ id: 1, name: \"FIRST\" }]\n });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n\n var comment = store.getById(\'comment\', 1);\n equal(comment.get(\'id\'), \"1\");\n equal(comment.get(\'name\'), \"FIRST\");\n }));\n});\n\n\ntest(\"find - payload with an serializer-specified primary key\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\'\n }));\n\n ajaxResponse({ posts: [{ \"_ID_\": 1, name: \"Rails is omakase\" }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n }));\n});\n\ntest(\"find - payload with a serializer-specified attribute mapping\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n attrs: {\n \'name\': \'_NAME_\',\n \'createdAt\': { key: \'_CREATED_AT_\', someOtherOption: \'option\' }\n }\n }));\n\n Post.reopen({\n createdAt: DS.attr(\"number\")\n });\n\n ajaxResponse({ posts: [{ id: 1, _NAME_: \"Rails is omakase\", _CREATED_AT_: 2013 }] });\n\n run(store, \'find\', \'post\', 1).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"GET\");\n equal(passedHash, undefined);\n\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Rails is omakase\");\n equal(post.get(\'createdAt\'), 2013);\n }));\n});\n\ntest(\"create - an empty payload is a basic success if an id was specified\", function() {\n ajaxResponse();\n var post;\n\n run(function() {\n post = store.createRecord(\'post\', { id: \"some-uuid\", name: \"The Parley Letter\" });\n post.save().then(async(function(post) {\n equal(passedUrl, \"/posts\");\n equal(passedVerb, \"POST\");\n deepEqual(passedHash.data, { post: { id: \"some-uuid\", name: \"The Parley Letter\" } });\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"The Parley Letter\", \"the post was updated\");\n }));\n });\n});\n\ntest(\"create - passes buildURL the requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/post/\" + requestType;\n };\n\n ajaxResponse();\n var post;\n\n run(function() {\n post = store.createRecord(\'post\', { id: \"some-uuid\", name: \"The Parley Letter\" });\n post.save().then(async(function(post) {\n equal(passedUrl, \"/post/createRecord\");\n }));\n });\n});\n\ntest(\"create - a payload with a new ID and data applies the updates\", function() {\n ajaxResponse({ posts: [{ id: \"1\", name: \"Dat Parley Letter\" }] });\n run(function() {\n var post = store.createRecord(\'post\', { name: \"The Parley Letter\" });\n\n post.save().then(async(function(post) {\n equal(passedUrl, \"/posts\");\n equal(passedVerb, \"POST\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'id\'), \"1\", \"the post has the updated ID\");\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n }));\n });\n});\n\ntest(\"create - a payload with a new ID and data applies the updates (with legacy singular name)\", function() {\n var post;\n ajaxResponse({ post: { id: \"1\", name: \"Dat Parley Letter\" } });\n run(function() {\n post = store.createRecord(\'post\', { name: \"The Parley Letter\" });\n });\n\n run(post, \'save\').then(async(function(post) {\n equal(passedUrl, \"/posts\");\n equal(passedVerb, \"POST\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'id\'), \"1\", \"the post has the updated ID\");\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n }));\n});\n\ntest(\"create - findMany doesn\'t overwrite owner\", function() {\n ajaxResponse({ comment: { id: \"1\", name: \"Dat Parley Letter\", post: 1 } });\n var comment;\n\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [] });\n });\n var post = store.getById(\'post\', 1);\n\n run(function() {\n comment = store.createRecord(\'comment\', { name: \"The Parley Letter\" });\n });\n post.get(\'comments\').pushObject(comment);\n\n equal(comment.get(\'post\'), post, \"the post has been set correctly\");\n\n run(function() {\n comment.save().then(async(function(comment) {\n equal(comment.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(comment.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n equal(comment.get(\'post\'), post, \"the post is still set\");\n }));\n });\n});\n\ntest(\"create - a serializer\'s primary key and attributes are consulted when building the payload\", function() {\n var post;\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_id_\',\n\n attrs: {\n name: \'_name_\'\n }\n }));\n\n ajaxResponse();\n\n run(function() {\n post = store.createRecord(\'post\', { id: \"some-uuid\", name: \"The Parley Letter\" });\n });\n\n run(post, \'save\').then(async(function(post) {\n deepEqual(passedHash.data, { post: { _id_: \'some-uuid\', \'_name_\': \"The Parley Letter\" } });\n }));\n});\n\ntest(\"create - a serializer\'s attributes are consulted when building the payload if no id is pre-defined\", function() {\n var post;\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primarykey: \'_id_\',\n\n attrs: {\n name: \'_name_\'\n }\n }));\n\n ajaxResponse();\n\n run(function() {\n post = store.createRecord(\'post\', { name: \"The Parley Letter\" });\n\n post.save().then(async(function(post) {\n deepEqual(passedHash.data, { post: { \'_name_\': \"The Parley Letter\" } });\n }));\n });\n});\n\ntest(\"create - a serializer\'s attribute mapping takes precdence over keyForAttribute when building the payload\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n attrs: {\n name: \'given_name\'\n },\n\n keyForAttribute: function(attr) {\n return attr.toUpperCase();\n }\n }));\n\n ajaxResponse();\n\n run(function() {\n var post = store.createRecord(\'post\', { id: \"some-uuid\", name: \"The Parley Letter\" });\n\n post.save().then(async(function(post) {\n deepEqual(passedHash.data, { post: { \'given_name\': \"The Parley Letter\", id: \"some-uuid\" } });\n }));\n });\n});\n\ntest(\"create - a serializer\'s attribute mapping takes precedence over keyForRelationship (belongsTo) when building the payload\", function() {\n env.registry.register(\'serializer:comment\', DS.RESTSerializer.extend({\n attrs: {\n post: \'article\'\n },\n\n keyForRelationship: function(attr, kind) {\n return attr.toUpperCase();\n }\n }));\n\n ajaxResponse();\n\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n var post = store.createRecord(\'post\', { id: \"a-post-id\", name: \"The Parley Letter\" });\n var comment = store.createRecord(\'comment\', { id: \"some-uuid\", name: \"Letters are fun\", post: post });\n\n comment.save().then(async(function(post) {\n deepEqual(passedHash.data, { comment: { article: \"a-post-id\", id: \"some-uuid\", name: \"Letters are fun\" } });\n }));\n });\n});\n\ntest(\"create - a serializer\'s attribute mapping takes precedence over keyForRelationship (hasMany) when building the payload\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n attrs: {\n comments: \'opinions\'\n },\n\n keyForRelationship: function(attr, kind) {\n return attr.toUpperCase();\n }\n }));\n\n ajaxResponse();\n\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n\n run(function() {\n var comment = store.createRecord(\'comment\', { id: \"a-comment-id\", name: \"First!\" });\n var post = store.createRecord(\'post\', { id: \"some-uuid\", name: \"The Parley Letter\", comments: [comment] });\n\n post.save().then(async(function(post) {\n deepEqual(passedHash.data, { post: { opinions: [\"a-comment-id\"], id: \"some-uuid\", name: \"The Parley Letter\" } });\n }));\n });\n});\n\ntest(\"create - a record on the many side of a hasMany relationship should update relationships when data is sideloaded\", function() {\n expect(3);\n\n ajaxResponse({\n posts: [{\n id: \"1\",\n name: \"Rails is omakase\",\n comments: [1,2]\n }],\n comments: [{\n id: \"2\",\n name: \"Another Comment\",\n post: 1\n },\n {\n id: \"1\",\n name: \"Dat Parley Letter\",\n post: 1\n }]\n // My API is returning a comment:{} as well as a comments:[{...},...]\n //, comment: {\n // id: \"2\",\n // name: \"Another Comment\",\n // post: 1\n // }\n });\n\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1] });\n store.push(\'comment\', { id: 1, name: \"Dat Parlay Letter\", post: 1 });\n });\n\n var post = store.getById(\'post\', 1);\n var commentCount = post.get(\'comments.length\');\n equal(commentCount, 1, \"the post starts life with a comment\");\n\n run(function() {\n var comment = store.createRecord(\'comment\', { name: \"Another Comment\", post: post });\n\n comment.save().then(async(function(comment) {\n equal(comment.get(\'post\'), post, \"the comment is related to the post\");\n }));\n\n post.reload().then(async(function(post) {\n equal(post.get(\'comments.length\'), 2, \"Post comment count has been updated\");\n }));\n });\n});\n\ntest(\"create - sideloaded belongsTo relationships are both marked as loaded\", function () {\n expect(4);\n var post;\n\n Post.reopen({ comment: DS.belongsTo(\'comment\') });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n post = store.createRecord(\'post\', { name: \"man\" });\n });\n\n ajaxResponse({\n posts: [{ id: 1, comment: 1, name: \"marked\" }],\n comments: [{ id: 1, post: 1, name: \"Comcast is a bargain\" }]\n });\n\n run(function() {\n post.save().then(async(function(record) {\n equal(store.getById(\'post\', 1).get(\'comment.isLoaded\'), true, \"post\'s comment isLoaded (via store)\");\n equal(store.getById(\'comment\', 1).get(\'post.isLoaded\'), true, \"comment\'s post isLoaded (via store)\");\n equal(record.get(\'comment.isLoaded\'), true, \"post\'s comment isLoaded (via record)\");\n equal(record.get(\'comment.post.isLoaded\'), true, \"post\'s comment\'s post isLoaded (via record)\");\n }));\n });\n});\n\ntest(\"create - response can contain relationships the client doesn\'t yet know about\", function() {\n expect(3); // while records.length is 2, we are getting 4 assertions\n\n ajaxResponse({\n posts: [{\n id: \"1\",\n name: \"Rails is omakase\",\n comments: [2]\n }],\n comments: [{\n id: \"2\",\n name: \"Another Comment\",\n post: 1\n }]\n });\n\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n var post;\n run(function() {\n post = store.createRecord(\'post\', { name: \"Rails is omakase\" });\n });\n\n run(function() {\n post.save().then(async(function(post) {\n equal(post.get(\'comments.firstObject.post\'), post, \"the comments are related to the correct post model\");\n equal(store.typeMapFor(Post).records.length, 1, \"There should only be one post record in the store\");\n\n var postRecords = store.typeMapFor(Post).records;\n for (var i = 0; i < postRecords.length; i++) {\n equal(post, postRecords[i], \"The object in the identity map is the same\");\n }\n }));\n });\n});\n\ntest(\"create - relationships are not duplicated\", function() {\n var post, comment;\n\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n post = store.createRecord(\'post\', { name: \"Tomtomhuda\" });\n comment = store.createRecord(\'comment\', { id: 2, name: \"Comment title\" });\n });\n\n ajaxResponse({ post: [{ id: 1, name: \"Rails is omakase\", comments: [] }] });\n\n run(post, \'save\').then(async(function(post) {\n equal(post.get(\'comments.length\'), 0, \"post has 0 comments\");\n post.get(\'comments\').pushObject(comment);\n equal(post.get(\'comments.length\'), 1, \"post has 1 comment\");\n\n ajaxResponse({\n post: [{ id: 1, name: \"Rails is omakase\", comments: [2] }],\n comments: [{ id: 2, name: \"Comment title\" }]\n });\n\n return post.save();\n })).then(async(function(post) {\n equal(post.get(\'comments.length\'), 1, \"post has 1 comment\");\n }));\n});\n\ntest(\"update - an empty payload is a basic success\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse();\n\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"PUT\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"The Parley Letter\", \"the post was updated\");\n }));\n});\n\ntest(\"update - passes the requestType to buildURL\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/posts/\" + id + \"/\" + requestType;\n };\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse();\n\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1/updateRecord\");\n }));\n});\n\ntest(\"update - a payload with updates applies the updates\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({ posts: [{ id: 1, name: \"Dat Parley Letter\" }] });\n\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"PUT\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n }));\n});\n\ntest(\"update - a payload with updates applies the updates (with legacy singular name)\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({ post: { id: 1, name: \"Dat Parley Letter\" } });\n\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"PUT\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n }));\n});\n\ntest(\"update - a payload with sideloaded updates pushes the updates\", function() {\n var post;\n ajaxResponse({\n posts: [{ id: 1, name: \"Dat Parley Letter\" }],\n comments: [{ id: 1, name: \"FIRST\" }]\n });\n run(function() {\n post = store.createRecord(\'post\', { name: \"The Parley Letter\" });\n post.save().then(async(function(post) {\n equal(passedUrl, \"/posts\");\n equal(passedVerb, \"POST\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'id\'), \"1\", \"the post has the updated ID\");\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n\n var comment = store.getById(\'comment\', 1);\n equal(comment.get(\'name\'), \"FIRST\", \"The comment was sideloaded\");\n }));\n });\n});\n\ntest(\"update - a payload with sideloaded updates pushes the updates\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n posts: [{ id: 1, name: \"Dat Parley Letter\" }],\n comments: [{ id: 1, name: \"FIRST\" }]\n });\n\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"PUT\");\n deepEqual(passedHash.data, { post: { name: \"The Parley Letter\" } });\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'name\'), \"Dat Parley Letter\", \"the post was updated\");\n\n var comment = store.getById(\'comment\', 1);\n equal(comment.get(\'name\'), \"FIRST\", \"The comment was sideloaded\");\n }));\n});\n\ntest(\"update - a serializer\'s primary key and attributes are consulted when building the payload\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_id_\',\n\n attrs: {\n name: \'_name_\'\n }\n }));\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n ajaxResponse();\n\n store.find(\'post\', 1).then(async(function(post) {\n post.set(\'name\', \"The Parley Letter\");\n return post.save();\n })).then(async(function(post) {\n deepEqual(passedHash.data, { post: { \'_name_\': \"The Parley Letter\" } });\n }));\n});\n\ntest(\"update - hasMany relationships faithfully reflect simultaneous adds and removes\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\') });\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Not everyone uses Rails\", comments: [1] });\n store.push(\'comment\', { id: 1, name: \"Rails is omakase\" });\n store.push(\'comment\', { id: 2, name: \"Yes. Yes it is.\" });\n });\n\n ajaxResponse({\n posts: { id: 1, name: \"Not everyone uses Rails\", comments: [2] }\n });\n\n store.find(\'comment\', 2).then(async(function() {\n return store.find(\'post\', 1);\n })).then(async(function(post) {\n var newComment = store.getById(\'comment\', 2);\n var comments = post.get(\'comments\');\n\n // Replace the comment with a new one\n comments.popObject();\n comments.pushObject(newComment);\n\n return post.save();\n })).then(async(function(post) {\n equal(post.get(\'comments.length\'), 1, \"the post has the correct number of comments\");\n equal(post.get(\'comments.firstObject.name\'), \"Yes. Yes it is.\", \"the post has the correct comment\");\n }));\n});\n\ntest(\"delete - an empty payload is a basic success\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse();\n\n post.deleteRecord();\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"DELETE\");\n equal(passedHash, undefined);\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'isDeleted\'), true, \"the post is now deleted\");\n }));\n});\n\ntest(\"delete - passes the requestType to buildURL\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/posts/\" + id + \"/\" + requestType;\n };\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse();\n\n post.deleteRecord();\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1/deleteRecord\");\n }));\n});\n\ntest(\"delete - a payload with sideloaded updates pushes the updates\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({ comments: [{ id: 1, name: \"FIRST\" }] });\n\n post.deleteRecord();\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"DELETE\");\n equal(passedHash, undefined);\n\n equal(post.get(\'isDirty\'), false, \"the post isn\'t dirty anymore\");\n equal(post.get(\'isDeleted\'), true, \"the post is now deleted\");\n\n var comment = store.getById(\'comment\', 1);\n equal(comment.get(\'name\'), \"FIRST\", \"The comment was sideloaded\");\n }));\n});\n\ntest(\"delete - a payload with sidloaded updates pushes the updates when the original record is omitted\", function() {\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\" });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({ posts: [{ id: 2, name: \"The Parley Letter\" }] });\n\n post.deleteRecord();\n return post.save();\n })).then(async(function(post) {\n equal(passedUrl, \"/posts/1\");\n equal(passedVerb, \"DELETE\");\n equal(passedHash, undefined);\n\n equal(post.get(\'isDirty\'), false, \"the original post isn\'t dirty anymore\");\n equal(post.get(\'isDeleted\'), true, \"the original post is now deleted\");\n\n var newPost = store.getById(\'post\', 2);\n equal(newPost.get(\'name\'), \"The Parley Letter\", \"The new post was added to the store\");\n }));\n});\n\ntest(\"delete - deleting a newly created record should not throw an error\", function() {\n var post;\n run(function() {\n post = store.createRecord(\'post\');\n });\n\n run(function() {\n post.deleteRecord();\n post.save().then(async(function(post) {\n equal(passedUrl, null, \"There is no ajax call to delete a record that has never been saved.\");\n equal(passedVerb, null, \"There is no ajax call to delete a record that has never been saved.\");\n equal(passedHash, null, \"There is no ajax call to delete a record that has never been saved.\");\n\n equal(post.get(\'isDeleted\'), true, \"the post is now deleted\");\n equal(post.get(\'isError\'), false, \"the post is not an error\");\n }));\n });\n});\n\ntest(\"findAll - returning an array populates the array\", function() {\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ]\n });\n\n store.findAll(\'post\').then(async(function(posts) {\n equal(passedUrl, \"/posts\");\n equal(passedVerb, \"GET\");\n equal(passedHash.data, undefined);\n\n var post1 = store.getById(\'post\', 1);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(\n post1.getProperties(\'id\', \'name\'),\n { id: \"1\", name: \"Rails is omakase\" },\n \"Post 1 is loaded\"\n );\n\n deepEqual(\n post2.getProperties(\'id\', \'name\'),\n { id: \"2\", name: \"The Parley Letter\" },\n \"Post 2 is loaded\"\n );\n\n equal(posts.get(\'length\'), 2, \"The posts are in the array\");\n equal(posts.get(\'isLoaded\'), true, \"The RecordArray is loaded\");\n deepEqual(\n posts.toArray(),\n [post1, post2],\n \"The correct records are in the array\"\n );\n }));\n});\n\n\ntest(\"findAll - passes buildURL the requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/\" + requestType + \"/posts\";\n };\n\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ]\n });\n\n store.findAll(\'post\').then(async(function(posts) {\n equal(passedUrl, \"/findAll/posts\");\n }));\n});\n\ntest(\"findAll - returning sideloaded data loads the data\", function() {\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ],\n comments: [{ id: 1, name: \"FIRST\" }] });\n\n store.findAll(\'post\').then(async(function(posts) {\n var comment = store.getById(\'comment\', 1);\n\n deepEqual(comment.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n }));\n});\n\ntest(\"findAll - data is normalized through custom serializers\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n ajaxResponse({\n posts: [\n { _ID_: 1, _NAME_: \"Rails is omakase\" },\n { _ID_: 2, _NAME_: \"The Parley Letter\" }\n ]\n });\n\n store.findAll(\'post\').then(async(function(posts) {\n var post1 = store.getById(\'post\', 1);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(\n post1.getProperties(\'id\', \'name\'),\n { id: \"1\", name: \"Rails is omakase\" },\n \"Post 1 is loaded\"\n );\n deepEqual(\n post2.getProperties(\'id\', \'name\'),\n { id: \"2\", name: \"The Parley Letter\" },\n \"Post 2 is loaded\"\n );\n\n equal(posts.get(\'length\'), 2, \"The posts are in the array\");\n equal(posts.get(\'isLoaded\'), true, \"The RecordArray is loaded\");\n deepEqual(\n posts.toArray(),\n [post1, post2],\n \"The correct records are in the array\"\n );\n }));\n});\n\ntest(\"findAll - since token is passed to the adapter\", function() {\n ajaxResponse({\n meta: { since: \'later\' },\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ]\n });\n\n store.setMetadataFor(\'post\', { since: \'now\' });\n\n store.findAll(\'post\').then(async(function(posts) {\n equal(passedUrl, \'/posts\');\n equal(passedVerb, \'GET\');\n equal(store.typeMapFor(Post).metadata.since, \'later\');\n deepEqual(passedHash.data, { since: \'now\' });\n }));\n});\n\ntest(\"metadata is accessible\", function() {\n ajaxResponse({\n meta: { offset: 5 },\n posts: [{ id: 1, name: \"Rails is very expensive sushi\" }]\n });\n\n store.findAll(\'post\').then(async(function(posts) {\n equal(\n store.metadataFor(\'post\').offset,\n 5,\n \"Metadata can be accessed with metadataFor.\"\n );\n }));\n});\n\ntest(\"findQuery - if `sortQueryParams` option is not provided, query params are sorted alphabetically\", function() {\n adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n passedVerb = verb;\n passedHash = hash;\n\n deepEqual(Object.keys(hash.data), [\"in\", \"order\", \"params\", \"wrong\"], \'query params are received in alphabetical order\');\n\n return run(Ember.RSVP, \'resolve\', { posts: [{ id: 1, name: \"Rails is very expensive sushi\" }] });\n };\n\n store.findQuery(\'post\', { \"params\": 1, \"in\": 2, \"wrong\": 3, \"order\": 4 }).then(async(function() {\n // Noop\n }));\n});\n\ntest(\"findQuery - passes buildURL the requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/\" + requestType + \"/posts\";\n };\n\n adapter.ajax = function(url, verb, hash) {\n equal(url, \'/findQuery/posts\');\n\n return run(Ember.RSVP, \'resolve\', { posts: [{ id: 1, name: \"Rails is very expensive sushi\" }] });\n };\n\n store.findQuery(\'post\', { \"params\": 1, \"in\": 2, \"wrong\": 3, \"order\": 4 }).then(async(function() {\n // NOOP\n }));\n});\n\ntest(\"findQuery - if `sortQueryParams` is falsey, query params are not sorted at all\", function() {\n adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n passedVerb = verb;\n passedHash = hash;\n\n deepEqual(Object.keys(hash.data), [\"params\", \"in\", \"wrong\", \"order\"], \'query params are received in their original order\');\n\n return run(Ember.RSVP, \'resolve\', { posts: [{ id: 1, name: \"Rails is very expensive sushi\" }] });\n };\n\n adapter.sortQueryParams = null;\n\n store.findQuery(\'post\', { \"params\": 1, \"in\": 2, \"wrong\": 3, \"order\": 4 }).then(async(function() {\n // Noop\n }));\n});\n\ntest(\"findQuery - if `sortQueryParams` is a custom function, query params passed through that function\", function() {\n adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n passedVerb = verb;\n passedHash = hash;\n\n deepEqual(Object.keys(hash.data), [\"wrong\", \"params\", \"order\", \"in\"], \'query params are received in reverse alphabetical order\');\n\n return run(Ember.RSVP, \'resolve\', { posts: [{ id: 1, name: \"Rails is very expensive sushi\" }] });\n };\n\n adapter.sortQueryParams = function(obj) {\n var sortedKeys = Object.keys(obj).sort().reverse();\n var len = sortedKeys.length;\n var newQueryParams = {};\n\n for (var i = 0; i < len; i++) {\n newQueryParams[sortedKeys[i]] = obj[sortedKeys[i]];\n }\n return newQueryParams;\n };\n\n store.findQuery(\'post\', { \"params\": 1, \"in\": 2, \"wrong\": 3, \"order\": 4 }).then(async(function() {\n // Noop\n }));\n});\n\ntest(\"findQuery - payload \'meta\' is accessible on the record array\", function() {\n ajaxResponse({\n meta: { offset: 5 },\n posts: [{ id: 1, name: \"Rails is very expensive sushi\" }]\n });\n\n store.findQuery(\'post\', { page: 2 }).then(async(function(posts) {\n equal(\n posts.get(\'meta.offset\'),\n 5,\n \"Reponse metadata can be accessed with recordArray.meta\"\n );\n }));\n});\n\ntest(\"findQuery - each record array can have it\'s own meta object\", function() {\n ajaxResponse({\n meta: { offset: 5 },\n posts: [{ id: 1, name: \"Rails is very expensive sushi\" }]\n });\n\n store.findQuery(\'post\', { page: 2 }).then(async(function(posts) {\n equal(\n posts.get(\'meta.offset\'),\n 5,\n \"Reponse metadata can be accessed with recordArray.meta\"\n );\n ajaxResponse({\n meta: { offset: 1 },\n posts: [{ id: 1, name: \"Rails is very expensive sushi\" }]\n });\n store.findQuery(\'post\', { page: 1 }).then(async(function(newPosts) {\n equal(newPosts.get(\'meta.offset\'), 1, \'new array has correct metadata\');\n equal(posts.get(\'meta.offset\'), 5, \'metadata on the old array hasnt been clobbered\');\n }));\n }));\n});\n\n\ntest(\"findQuery - returning an array populates the array\", function() {\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }]\n });\n\n store.findQuery(\'post\', { page: 1 }).then(async(function(posts) {\n equal(passedUrl, \'/posts\');\n equal(passedVerb, \'GET\');\n deepEqual(passedHash.data, { page: 1 });\n\n var post1 = store.getById(\'post\', 1);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(\n post1.getProperties(\'id\', \'name\'),\n { id: \"1\", name: \"Rails is omakase\" },\n \"Post 1 is loaded\"\n );\n deepEqual(\n post2.getProperties(\'id\', \'name\'),\n { id: \"2\", name: \"The Parley Letter\" },\n \"Post 2 is loaded\"\n );\n\n equal(posts.get(\'length\'), 2, \"The posts are in the array\");\n equal(posts.get(\'isLoaded\'), true, \"The RecordArray is loaded\");\n deepEqual(\n posts.toArray(),\n [post1, post2],\n \"The correct records are in the array\"\n );\n }));\n});\n\ntest(\"findQuery - returning sideloaded data loads the data\", function() {\n ajaxResponse({\n posts: [\n { id: 1, name: \"Rails is omakase\" },\n { id: 2, name: \"The Parley Letter\" }\n ],\n comments: [{ id: 1, name: \"FIRST\" }]\n });\n\n store.findQuery(\'post\', { page: 1 }).then(async(function(posts) {\n var comment = store.getById(\'comment\', 1);\n\n deepEqual(comment.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n }));\n});\n\ntest(\"findQuery - data is normalized through custom serializers\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n ajaxResponse({\n posts: [{ _ID_: 1, _NAME_: \"Rails is omakase\" },\n { _ID_: 2, _NAME_: \"The Parley Letter\" }]\n });\n\n store.findQuery(\'post\', { page: 1 }).then(async(function(posts) {\n var post1 = store.getById(\'post\', 1);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(\n post1.getProperties(\'id\', \'name\'),\n { id: \"1\", name: \"Rails is omakase\" },\n \"Post 1 is loaded\"\n );\n\n deepEqual(\n post2.getProperties(\'id\', \'name\'),\n { id: \"2\", name: \"The Parley Letter\" },\n \"Post 2 is loaded\"\n );\n\n equal(posts.get(\'length\'), 2, \"The posts are in the array\");\n equal(posts.get(\'isLoaded\'), true, \"The RecordArray is loaded\");\n deepEqual(\n posts.toArray(),\n [post1, post2],\n \"The correct records are in the array\"\n );\n }));\n});\n\ntest(\"findMany - findMany uses a correct URL to access the records\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n var post = store.getById(\'post\', 1);\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n run(post, \'get\', \'comments\').then(async(function(comments) {\n equal(passedUrl, \"/comments\");\n deepEqual(passedHash, { data: { ids: [\"1\", \"2\", \"3\"] } });\n }));\n});\n\ntest(\"findMany - passes buildURL the requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n return \"/\" + requestType + \"/\" + type;\n };\n\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n var post = store.getById(\'post\', 1);\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n run(post, \'get\', \'comments\').then(async(function(comments) {\n equal(passedUrl, \"/findMany/comment\");\n }));\n});\n\ntest(\"findMany - findMany does not coalesce by default\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n var post = store.getById(\'post\', 1);\n //It\'s still ok to return this even without coalescing because RESTSerializer supports sideloading\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n run(post, \'get\', \'comments\').then(async(function(comments) {\n equal(passedUrl, \"/comments/3\");\n equal(passedHash, null);\n }));\n});\n\ntest(\"findMany - returning an array populates the array\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n\n deepEqual(comment1.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n deepEqual(comment2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"Rails is unagi\" });\n deepEqual(comment3.getProperties(\'id\', \'name\'), { id: \"3\", name: \"What is omakase?\" });\n\n deepEqual(\n comments.toArray(),\n [comment1, comment2, comment3],\n \"The correct records are in the array\"\n );\n }));\n});\n\ntest(\"findMany - returning sideloaded data loads the data\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" },\n { id: 4, name: \"Unrelated comment\" }\n ],\n posts: [{ id: 2, name: \"The Parley Letter\" }]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n var comment4 = store.getById(\'comment\', 4);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(\n comments.toArray(),\n [comment1, comment2, comment3],\n \"The correct records are in the array\"\n );\n\n deepEqual(comment4.getProperties(\'id\', \'name\'), { id: \"4\", name: \"Unrelated comment\" });\n deepEqual(post2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"The Parley Letter\" });\n }));\n});\n\ntest(\"findMany - a custom serializer is used if present\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n env.registry.register(\'serializer:comment\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n adapter.coalesceFindRequests = true;\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n run(function() {\n store.push(\'post\', { id: 1, name: \"Rails is omakase\", comments: [1, 2, 3] });\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n comments: [\n { _ID_: 1, _NAME_: \"FIRST\" },\n { _ID_: 2, _NAME_: \"Rails is unagi\" },\n { _ID_: 3, _NAME_: \"What is omakase?\" }]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n\n deepEqual(comment1.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n deepEqual(comment2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"Rails is unagi\" });\n deepEqual(comment3.getProperties(\'id\', \'name\'), { id: \"3\", name: \"What is omakase?\" });\n\n deepEqual(comments.toArray(), [comment1, comment2, comment3], \"The correct records are in the array\");\n }));\n});\n\ntest(\"findHasMany - returning an array populates the array\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n run(function() {\n store.push(\n \'post\',\n {\n id: 1,\n name: \"Rails is omakase\",\n links: { comments: \'/posts/1/comments\' }\n }\n );\n });\n\n run(store, \'find\', \'post\', \'1\').then(async(function(post) {\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n equal(passedUrl, \'/posts/1/comments\');\n equal(passedVerb, \'GET\');\n equal(passedHash, undefined);\n\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n\n deepEqual(comment1.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n deepEqual(comment2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"Rails is unagi\" });\n deepEqual(comment3.getProperties(\'id\', \'name\'), { id: \"3\", name: \"What is omakase?\" });\n\n deepEqual(comments.toArray(), [comment1, comment2, comment3], \"The correct records are in the array\");\n }));\n});\n\ntest(\"findHasMany - passes buildURL the requestType\", function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n equal(requestType, \'findHasMany\');\n };\n\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n run(function() {\n store.push(\n \'post\',\n {\n id: 1,\n name: \"Rails is omakase\",\n links: { comments: \'/posts/1/comments\' }\n }\n );\n });\n\n run(store, \'find\', \'post\', \'1\').then(async(function(post) {\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n // NOOP\n }));\n});\n\n\n\ntest(\"findMany - returning sideloaded data loads the data\", function() {\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n run(function() {\n store.push(\n \'post\',\n {\n id: 1,\n name: \"Rails is omakase\",\n links: { comments: \'/posts/1/comments\' }\n }\n );\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n comments: [\n { id: 1, name: \"FIRST\" },\n { id: 2, name: \"Rails is unagi\" },\n { id: 3, name: \"What is omakase?\" }\n ],\n posts: [{ id: 2, name: \"The Parley Letter\" }]\n });\n\n return post.get(\'comments\');\n })).then(async(function(comments) {\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n var post2 = store.getById(\'post\', 2);\n\n deepEqual(comments.toArray(), [comment1, comment2, comment3], \"The correct records are in the array\");\n\n deepEqual(post2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"The Parley Letter\" });\n }));\n});\n\ntest(\"findMany - a custom serializer is used if present\", function() {\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n env.registry.register(\'serializer:comment\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n run(function() {\n store.push(\n \'post\',\n {\n id: 1,\n name: \"Rails is omakase\",\n links: { comments: \'/posts/1/comments\' }\n }\n );\n });\n\n store.find(\'post\', 1).then(async(function(post) {\n ajaxResponse({\n comments: [\n { _ID_: 1, _NAME_: \"FIRST\" },\n { _ID_: 2, _NAME_: \"Rails is unagi\" },\n { _ID_: 3, _NAME_: \"What is omakase?\" }\n ]\n });\n return post.get(\'comments\');\n })).then(async(function(comments) {\n var comment1 = store.getById(\'comment\', 1);\n var comment2 = store.getById(\'comment\', 2);\n var comment3 = store.getById(\'comment\', 3);\n\n deepEqual(comment1.getProperties(\'id\', \'name\'), { id: \"1\", name: \"FIRST\" });\n deepEqual(comment2.getProperties(\'id\', \'name\'), { id: \"2\", name: \"Rails is unagi\" });\n deepEqual(comment3.getProperties(\'id\', \'name\'), { id: \"3\", name: \"What is omakase?\" });\n\n deepEqual(comments.toArray(), [comment1, comment2, comment3], \"The correct records are in the array\");\n }));\n});\n\ntest(\'findBelongsTo - passes buildURL the requestType\', function() {\n adapter.buildURL = function(type, id, snapshot, requestType) {\n equal(requestType, \'findBelongsTo\');\n };\n\n Comment.reopen({ post: DS.belongsTo(\'post\', { async: true }) });\n\n run(function() {\n store.push(\'comment\', {\n id: 1, name: \"FIRST\",\n links: { post: \'/posts/1\' }\n });\n });\n\n run(store, \'find\', \'comment\', 1).then(async(function(comment) {\n ajaxResponse({ post: { id: 1, name: \'Rails is omakase\' } });\n return comment.get(\'post\');\n })).then(async(function(post) {\n // NOOP\n }));\n});\n\ntest(\'coalesceFindRequests warns if the expected records are not returned in the coalesced request\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n adapter.coalesceFindRequests = true;\n\n ajaxResponse({ comments: [{ id: 1 }] });\n var post;\n\n warns(function() {\n run(function() {\n post = store.push(\'post\', { id: 2, comments: [1,2,3] });\n post.get(\'comments\');\n });\n }, /expected to find records with the following ids in the adapter response but they were missing: \\[2,3\\]/);\n});\n\ntest(\'groupRecordsForFindMany groups records based on their url\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n adapter.buildURL = function(type, id, snapshot) {\n if (id === \'1\') {\n return \'/comments/1\';\n } else {\n return \'/other_comments/\' + id;\n }\n };\n\n adapter.find = function(store, type, id, snapshot) {\n equal(id, \'1\');\n return Ember.RSVP.resolve({ comments: { id: 1 } });\n };\n\n adapter.findMany = function(store, type, ids, snapshots) {\n deepEqual(ids, [\'2\', \'3\']);\n return Ember.RSVP.resolve({ comments: [{ id: 2 }, { id: 3 }] });\n };\n\n var post;\n run(function() {\n post = store.push(\'post\', { id: 2, comments: [1,2,3] });\n });\n\n run(function() {\n post.get(\'comments\');\n });\n});\n\ntest(\'groupRecordsForFindMany groups records correctly when singular URLs are encoded as query params\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n adapter.coalesceFindRequests = true;\n\n adapter.buildURL = function(type, id, snapshot) {\n if (id === \'1\') {\n return \'/comments?id=1\';\n } else {\n return \'/other_comments?id=\' + id;\n }\n };\n\n adapter.find = function(store, type, id, snapshot) {\n equal(id, \'1\');\n return Ember.RSVP.resolve({ comments: { id: 1 } });\n };\n\n adapter.findMany = function(store, type, ids, snapshots) {\n deepEqual(ids, [\'2\', \'3\']);\n return Ember.RSVP.resolve({ comments: [{ id: 2 }, { id: 3 }] });\n };\n var post;\n\n run(function() {\n post = store.push(\'post\', { id: 2, comments: [1,2,3] });\n });\n\n run(function() {\n post.get(\'comments\');\n });\n});\n\ntest(\'normalizeKey - to set up _ids and _id\', function() {\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n keyForAttribute: function(attr) {\n return Ember.String.underscore(attr);\n },\n\n keyForBelongsTo: function(belongsTo) {\n },\n\n keyForRelationship: function(rel, kind) {\n if (kind === \'belongsTo\') {\n var underscored = Ember.String.underscore(rel);\n return underscored + \'_id\';\n } else {\n var singular = Ember.String.singularize(rel);\n return Ember.String.underscore(singular) + \'_ids\';\n }\n }\n }));\n\n env.registry.register(\'model:post\', DS.Model.extend({\n name: DS.attr(),\n authorName: DS.attr(),\n author: DS.belongsTo(\'user\'),\n comments: DS.hasMany(\'comment\')\n }));\n\n env.registry.register(\'model:user\', DS.Model.extend({\n createdAt: DS.attr(),\n name: DS.attr()\n }));\n\n env.registry.register(\'model:comment\', DS.Model.extend({\n body: DS.attr()\n }));\n\n ajaxResponse({\n posts: [{\n id: \"1\",\n name: \"Rails is omakase\",\n author_name: \"@d2h\",\n author_id: \"1\",\n comment_ids: [\"1\", \"2\"]\n }],\n\n users: [{\n id: \"1\",\n name: \"D2H\"\n }],\n\n comments: [{\n id: \"1\",\n body: \"Rails is unagi\"\n }, {\n id: \"2\",\n body: \"What is omakase?\"\n }]\n });\n\n run(function() {\n store.find(\'post\', 1).then(async(function(post) {\n equal(post.get(\'authorName\'), \"@d2h\");\n equal(post.get(\'author.name\'), \"D2H\");\n deepEqual(post.get(\'comments\').mapBy(\'body\'), [\"Rails is unagi\", \"What is omakase?\"]);\n }));\n });\n});\n\ntest(\'groupRecordsForFindMany splits up calls for large ids\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n expect(2);\n\n function repeatChar(character, n) {\n return new Array(n+1).join(character);\n }\n\n var a2000 = repeatChar(\'a\', 2000);\n var b2000 = repeatChar(\'b\', 2000);\n var post;\n run(function() {\n post = store.push(\'post\', { id: 1, comments: [a2000, b2000] });\n });\n\n adapter.coalesceFindRequests = true;\n\n adapter.find = function(store, type, id, snapshot) {\n if (id === a2000 || id === b2000) {\n ok(true, \"Found \" + id);\n }\n\n return Ember.RSVP.resolve({ comments: { id: id } });\n };\n\n adapter.findMany = function(store, type, ids, snapshots) {\n ok(false, \"findMany should not be called - we expect 2 calls to find for a2000 and b2000\");\n return Ember.RSVP.reject();\n };\n\n run(function() {\n post.get(\'comments\');\n });\n});\n\ntest(\'groupRecordsForFindMany groups calls for small ids\', function() {\n Comment.reopen({ post: DS.belongsTo(\'post\') });\n Post.reopen({ comments: DS.hasMany(\'comment\', { async: true }) });\n\n expect(1);\n\n function repeatChar(character, n) {\n return new Array(n+1).join(character);\n }\n\n var a100 = repeatChar(\'a\', 100);\n var b100 = repeatChar(\'b\', 100);\n var post;\n\n run(function() {\n post = store.push(\'post\', { id: 1, comments: [a100, b100] });\n });\n\n adapter.coalesceFindRequests = true;\n\n adapter.find = function(store, type, id, snapshot) {\n ok(false, \"find should not be called - we expect 1 call to findMany for a100 and b100\");\n return Ember.RSVP.reject();\n };\n\n adapter.findMany = function(store, type, ids, snapshots) {\n deepEqual(ids, [a100, b100]);\n return Ember.RSVP.resolve({ comments: [{ id: a100 }, { id: b100 }] });\n };\n\n run(function() {\n post.get(\'comments\');\n });\n});\n\n\ntest(\"calls adapter.ajaxSuccess with the jqXHR and json\", function() {\n expect(2);\n var originalAjax = Ember.$.ajax;\n var jqXHR = {};\n var data = {\n post: {\n id: \"1\",\n name: \"Docker is amazing\"\n }\n };\n\n Ember.$.ajax = function(hash) {\n hash.success(data, \'ok\', jqXHR);\n };\n\n adapter.ajaxSuccess = function(xhr, json) {\n deepEqual(jqXHR, xhr);\n deepEqual(json, data);\n return json;\n };\n\n try {\n run(function() {\n store.find(\'post\', \'1\');\n });\n } finally {\n Ember.$.ajax = originalAjax;\n }\n});\n\ntest(\'calls ajaxError with jqXHR, jqXHR.responseText\', function() {\n expect(3);\n var originalAjax = Ember.$.ajax;\n var jqXHR = {\n responseText: \'Nope lol\'\n };\n\n Ember.$.ajax = function(hash) {\n hash.error(jqXHR, jqXHR.responseText);\n };\n\n adapter.ajaxError = function(xhr, responseText) {\n deepEqual(xhr, jqXHR);\n deepEqual(responseText, jqXHR.responseText);\n return new Error(\'nope!\');\n };\n\n try {\n run(function() {\n store.find(\'post\', \'1\')[\"catch\"](function(err) {\n ok(err, \'promise rejected\');\n });\n });\n } finally {\n Ember.$.ajax = originalAjax;\n }\n});\n\ntest(\"rejects promise if DS.InvalidError is returned from adapter.ajaxSuccess\", function() {\n expect(3);\n var originalAjax = Ember.$.ajax;\n var jqXHR = {};\n var data = {\n something: \'is invalid\'\n };\n\n Ember.$.ajax = function(hash) {\n hash.success(data, \'ok\', jqXHR);\n };\n\n adapter.ajaxSuccess = function(xhr, json) {\n ok(true, \'ajaxSuccess should be called\');\n return new DS.InvalidError(json);\n };\n\n Ember.run(function() {\n store.find(\'post\', \'1\').then(null, function(reason) {\n ok(true, \'promise should be rejected\');\n ok(reason instanceof DS.InvalidError, \'reason should be an instance of DS.InvalidError\');\n });\n });\n\n Ember.$.ajax = originalAjax;\n});\n\ntest(\'ajaxError appends errorThrown for sanity\', function() {\n expect(6);\n\n var originalAjax = Ember.$.ajax;\n var jqXHR = {\n responseText: \'Nope lol\'\n };\n\n var errorThrown = new Error(\'nope!\');\n\n Ember.$.ajax = function(hash) {\n hash.error(jqXHR, jqXHR.responseText, errorThrown);\n };\n\n var originalAjaxError = adapter.ajaxError;\n adapter.ajaxError = function(xhr, responseText, _errorThrown) {\n deepEqual(_errorThrown, errorThrown);\n ok(errorThrown);\n deepEqual(xhr, jqXHR);\n deepEqual(responseText, jqXHR.responseText);\n return originalAjaxError.apply(adapter, arguments);\n };\n\n try {\n run(function() {\n store.find(\'post\', \'1\')[\"catch\"](function(err) {\n equal(err.errorThrown, errorThrown);\n ok(err, \'promise rejected\');\n });\n });\n } finally {\n Ember.$.ajax = originalAjax;\n }\n});\n\n\ntest(\'ajaxError wraps the error string in an Error object\', function() {\n expect(2);\n\n var originalAjax = Ember.$.ajax;\n var jqXHR = {\n responseText: \'Nope lol\'\n };\n\n var errorThrown = \'nope!\';\n\n Ember.$.ajax = function(hash) {\n hash.error(jqXHR, jqXHR.responseText, errorThrown);\n };\n\n try {\n run(function() {\n store.find(\'post\', \'1\')[\"catch\"](function(err) {\n equal(err.errorThrown.message, errorThrown);\n ok(err, \'promise rejected\');\n });\n });\n } finally {\n Ember.$.ajax = originalAjax;\n }\n});\n})();//# sourceURL=ember-data/integration/adapter/rest-adapter-test.js");
296
308
 
297
309
  eval("(function() {/*\n This is an integration test that tests the communication between a store\n and its adapter.\n\n Typically, when a method is invoked on the store, it calls a related\n method on its adapter. The adapter notifies the store that it has\n completed the assigned task, either synchronously or asynchronously,\n by calling a method on the store.\n\n These tests ensure that the proper methods get called, and, if applicable,\n the given record or record array changes state appropriately.\n*/\n\nvar get = Ember.get;\nvar set = Ember.set;\nvar run = Ember.run;\nvar Person, Dog, env, store, adapter;\n\nmodule(\"integration/adapter/store_adapter - DS.Store and DS.Adapter integration test\", {\n setup: function() {\n Person = DS.Model.extend({\n updatedAt: DS.attr(\'string\'),\n name: DS.attr(\'string\'),\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\')\n });\n\n Dog = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n env = setupStore({ person: Person, dog: Dog });\n store = env.store;\n adapter = env.adapter;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"Records loaded multiple times and retrieved in recordArray are ready to send state events\", function() {\n adapter.findQuery = function(store, type, query, recordArray) {\n return Ember.RSVP.resolve([{\n id: 1,\n name: \"Mickael Ramírez\"\n }, {\n id: 2,\n name: \"Johny Fontana\"\n }]);\n };\n\n run(store, \'findQuery\', \'person\', { q: \'bla\' }).then(async(function(people) {\n var people2 = store.findQuery(\'person\', { q: \'bla2\' });\n\n return Ember.RSVP.hash({ people: people, people2: people2 });\n })).then(async(function(results) {\n equal(results.people2.get(\'length\'), 2, \'return the elements\');\n ok(results.people2.get(\'isLoaded\'), \'array is loaded\');\n\n var person = results.people.objectAt(0);\n ok(person.get(\'isLoaded\'), \'record is loaded\');\n\n // delete record will not throw exception\n person.deleteRecord();\n }));\n\n});\n\ntest(\"by default, createRecords calls createRecord once per record\", function() {\n var count = 1;\n\n adapter.createRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n\n if (count === 1) {\n equal(snapshot.attr(\'name\'), \"Tom Dale\");\n } else if (count === 2) {\n equal(snapshot.attr(\'name\'), \"Yehuda Katz\");\n } else {\n ok(false, \"should not have invoked more than 2 times\");\n }\n\n var hash = snapshot.attributes();\n hash.id = count;\n hash.updatedAt = \"now\";\n\n count++;\n return Ember.RSVP.resolve(hash);\n };\n var tom, yehuda;\n\n run(function() {\n tom = store.createRecord(\'person\', { name: \"Tom Dale\" });\n yehuda = store.createRecord(\'person\', { name: \"Yehuda Katz\" });\n });\n\n var promise = run(function() {\n return Ember.RSVP.hash({\n tom: tom.save(),\n yehuda: yehuda.save()\n });\n });\n promise.then(async(function(records) {\n tom = records.tom;\n yehuda = records.yehuda;\n\n asyncEqual(tom, store.find(\'person\', 1), \"Once an ID is in, find returns the same object\");\n asyncEqual(yehuda, store.find(\'person\', 2), \"Once an ID is in, find returns the same object\");\n equal(get(tom, \'updatedAt\'), \"now\", \"The new information is received\");\n equal(get(yehuda, \'updatedAt\'), \"now\", \"The new information is received\");\n }));\n});\n\ntest(\"by default, updateRecords calls updateRecord once per record\", function() {\n var count = 0;\n\n adapter.updateRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n\n if (count === 0) {\n equal(snapshot.attr(\'name\'), \"Tom Dale\");\n } else if (count === 1) {\n equal(snapshot.attr(\'name\'), \"Yehuda Katz\");\n } else {\n ok(false, \"should not get here\");\n }\n\n count++;\n\n equal(snapshot.record.get(\'isSaving\'), true, \"record is saving\");\n\n return Ember.RSVP.resolve();\n };\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Braaaahm Dale\" });\n store.push(\'person\', { id: 2, name: \"Brohuda Katz\" });\n });\n\n var promise = run(function() {\n return Ember.RSVP.hash({\n tom: store.find(\'person\', 1),\n yehuda: store.find(\'person\', 2)\n });\n });\n\n promise.then(async(function(records) {\n var tom = records.tom;\n var yehuda = records.yehuda;\n\n set(tom, \"name\", \"Tom Dale\");\n set(yehuda, \"name\", \"Yehuda Katz\");\n\n return Ember.RSVP.hash({ tom: tom.save(), yehuda: yehuda.save() });\n })).then(async(function(records) {\n var tom = records.tom;\n var yehuda = records.yehuda;\n\n equal(tom.get(\'isSaving\'), false, \"record is no longer saving\");\n equal(tom.get(\'isLoaded\'), true, \"record is loaded\");\n\n equal(yehuda.get(\'isSaving\'), false, \"record is no longer saving\");\n equal(yehuda.get(\'isLoaded\'), true, \"record is loaded\");\n }));\n});\n\ntest(\"calling store.didSaveRecord can provide an optional hash\", function() {\n var count = 0;\n\n adapter.updateRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n\n count++;\n if (count === 1) {\n equal(snapshot.attr(\'name\'), \"Tom Dale\");\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\", updatedAt: \"now\" });\n } else if (count === 2) {\n equal(snapshot.attr(\'name\'), \"Yehuda Katz\");\n return Ember.RSVP.resolve({ id: 2, name: \"Yehuda Katz\", updatedAt: \"now!\" });\n } else {\n ok(false, \"should not get here\");\n }\n };\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Braaaahm Dale\" });\n store.push(\'person\', { id: 2, name: \"Brohuda Katz\" });\n });\n\n var promise = run(function() {\n return Ember.RSVP.hash({\n tom: store.find(\'person\', 1),\n yehuda: store.find(\'person\', 2)\n });\n });\n promise.then(async(function(records) {\n var tom = records.tom;\n var yehuda = records.yehuda;\n\n set(tom, \"name\", \"Tom Dale\");\n set(yehuda, \"name\", \"Yehuda Katz\");\n\n return Ember.RSVP.hash({ tom: tom.save(), yehuda: yehuda.save() });\n })).then(async(function(records) {\n var tom = records.tom;\n var yehuda = records.yehuda;\n\n equal(get(tom, \'isDirty\'), false, \"the record should not be dirty\");\n equal(get(tom, \'updatedAt\'), \"now\", \"the hash was updated\");\n\n equal(get(yehuda, \'isDirty\'), false, \"the record should not be dirty\");\n equal(get(yehuda, \'updatedAt\'), \"now!\", \"the hash was updated\");\n }));\n});\n\ntest(\"by default, deleteRecord calls deleteRecord once per record\", function() {\n expect(4);\n\n var count = 0;\n\n adapter.deleteRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n\n if (count === 0) {\n equal(snapshot.attr(\'name\'), \"Tom Dale\");\n } else if (count === 1) {\n equal(snapshot.attr(\'name\'), \"Yehuda Katz\");\n } else {\n ok(false, \"should not get here\");\n }\n\n count++;\n\n return Ember.RSVP.resolve();\n };\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n store.push(\'person\', { id: 2, name: \"Yehuda Katz\" });\n });\n\n var promise = run(function() {\n return Ember.RSVP.hash({\n tom: store.find(\'person\', 1),\n yehuda: store.find(\'person\', 2)\n });\n });\n\n promise.then(async(function(records) {\n var tom = records.tom;\n var yehuda = records.yehuda;\n\n tom.deleteRecord();\n yehuda.deleteRecord();\n\n tom.save();\n yehuda.save();\n }));\n});\n\ntest(\"by default, destroyRecord calls deleteRecord once per record without requiring .save\", function() {\n expect(4);\n\n var count = 0;\n\n adapter.deleteRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n\n if (count === 0) {\n equal(snapshot.attr(\'name\'), \"Tom Dale\");\n } else if (count === 1) {\n equal(snapshot.attr(\'name\'), \"Yehuda Katz\");\n } else {\n ok(false, \"should not get here\");\n }\n\n count++;\n\n return Ember.RSVP.resolve();\n };\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n store.push(\'person\', { id: 2, name: \"Yehuda Katz\" });\n });\n\n var promise = run(function() {\n return Ember.RSVP.hash({\n tom: store.find(\'person\', 1),\n yehuda: store.find(\'person\', 2)\n });\n });\n\n promise.then(async(function(records) {\n var tom = records.tom;\n var yehuda = records.yehuda;\n\n tom.destroyRecord();\n yehuda.destroyRecord();\n }));\n});\n\ntest(\"if an existing model is edited then deleted, deleteRecord is called on the adapter\", function() {\n expect(5);\n\n var count = 0;\n\n adapter.deleteRecord = function(store, type, snapshot) {\n count++;\n equal(snapshot.id, \'deleted-record\', \"should pass correct record to deleteRecord\");\n equal(count, 1, \"should only call deleteRecord method of adapter once\");\n\n return Ember.RSVP.resolve();\n };\n\n adapter.updateRecord = function() {\n ok(false, \"should not have called updateRecord method of adapter\");\n };\n\n // Load data for a record into the store.\n run(function() {\n store.push(\'person\', { id: \'deleted-record\', name: \"Tom Dale\" });\n });\n\n // Retrieve that loaded record and edit it so it becomes dirty\n run(store, \'find\', \'person\', \'deleted-record\').then(async(function(tom) {\n tom.set(\'name\', \"Tom Mothereffin\' Dale\");\n\n equal(get(tom, \'isDirty\'), true, \"precond - record should be dirty after editing\");\n\n tom.deleteRecord();\n return tom.save();\n })).then(async(function(tom) {\n equal(get(tom, \'isDirty\'), false, \"record should not be dirty\");\n equal(get(tom, \'isDeleted\'), true, \"record should be considered deleted\");\n }));\n});\n\ntest(\"if a deleted record errors, it enters the error state\", function() {\n var count = 0;\n\n adapter.deleteRecord = function(store, type, snapshot) {\n if (count++ === 0) {\n return Ember.RSVP.reject();\n } else {\n return Ember.RSVP.resolve();\n }\n };\n\n run(function() {\n store.push(\'person\', { id: \'deleted-record\', name: \"Tom Dale\" });\n });\n\n var tom;\n\n run(function() {\n store.find(\'person\', \'deleted-record\').then(async(function(person) {\n tom = person;\n person.deleteRecord();\n return person.save();\n })).then(null, async(function() {\n equal(tom.get(\'isError\'), true, \"Tom is now errored\");\n\n // this time it succeeds\n return tom.save();\n })).then(async(function() {\n equal(tom.get(\'isError\'), false, \"Tom is not errored anymore\");\n }));\n });\n});\n\ntest(\"if a created record is marked as invalid by the server, it enters an error state\", function() {\n adapter.createRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n\n if (snapshot.attr(\'name\').indexOf(\'Bro\') === -1) {\n return Ember.RSVP.reject(new DS.InvalidError({ name: [\'common... name requires a \"bro\"\'] }));\n } else {\n return Ember.RSVP.resolve();\n }\n };\n\n var yehuda = run(function() {\n return store.createRecord(\'person\', { id: 1, name: \"Yehuda Katz\" });\n });\n // Wrap this in an Ember.run so that all chained async behavior is set up\n // before flushing any scheduled behavior.\n Ember.run(function() {\n yehuda.save().then(null, async(function(error) {\n equal(get(yehuda, \'isValid\'), false, \"the record is invalid\");\n ok(get(yehuda, \'errors.name\'), \"The errors.name property exists\");\n\n set(yehuda, \'updatedAt\', true);\n equal(get(yehuda, \'isValid\'), false, \"the record is still invalid\");\n\n set(yehuda, \'name\', \"Brohuda Brokatz\");\n\n equal(get(yehuda, \'isValid\'), true, \"the record is no longer invalid after changing\");\n equal(get(yehuda, \'isDirty\'), true, \"the record has outstanding changes\");\n\n equal(get(yehuda, \'isNew\'), true, \"precond - record is still new\");\n\n return yehuda.save();\n })).then(async(function(person) {\n strictEqual(person, yehuda, \"The promise resolves with the saved record\");\n\n equal(get(yehuda, \'isValid\'), true, \"record remains valid after committing\");\n equal(get(yehuda, \'isNew\'), false, \"record is no longer new\");\n }));\n });\n});\n\ntest(\"allows errors on arbitrary properties on create\", function() {\n adapter.createRecord = function(store, type, snapshot) {\n if (snapshot.attr(\'name\').indexOf(\'Bro\') === -1) {\n return Ember.RSVP.reject(new DS.InvalidError({ base: [\'is a generally unsavoury character\'] }));\n } else {\n return Ember.RSVP.resolve();\n }\n };\n\n var yehuda = run(function () {\n return store.createRecord(\'person\', { id: 1, name: \"Yehuda Katz\" });\n });\n\n // Wrap this in an Ember.run so that all chained async behavior is set up\n // before flushing any scheduled behavior.\n run(function() {\n yehuda.save().then(null, async(function(error) {\n equal(get(yehuda, \'isValid\'), false, \"the record is invalid\");\n ok(get(yehuda, \'errors.base\'), \"The errors.base property exists\");\n deepEqual(get(yehuda, \'errors\').errorsFor(\'base\'), [{ attribute: \'base\', message: \"is a generally unsavoury character\" }]);\n\n set(yehuda, \'updatedAt\', true);\n equal(get(yehuda, \'isValid\'), false, \"the record is still invalid\");\n\n set(yehuda, \'name\', \"Brohuda Brokatz\");\n\n equal(get(yehuda, \'isValid\'), false, \"the record is still invalid as far as we know\");\n equal(get(yehuda, \'isDirty\'), true, \"the record has outstanding changes\");\n\n equal(get(yehuda, \'isNew\'), true, \"precond - record is still new\");\n\n return yehuda.save();\n })).then(async(function(person) {\n strictEqual(person, yehuda, \"The promise resolves with the saved record\");\n ok(!get(yehuda, \'errors.base\'), \"The errors.base property does not exist\");\n deepEqual(get(yehuda, \'errors\').errorsFor(\'base\'), []);\n equal(get(yehuda, \'isValid\'), true, \"record remains valid after committing\");\n equal(get(yehuda, \'isNew\'), false, \"record is no longer new\");\n }));\n });\n});\n\ntest(\"if a created record is marked as invalid by the server, you can attempt the save again\", function() {\n var saveCount = 0;\n adapter.createRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n saveCount++;\n\n if (snapshot.attr(\'name\').indexOf(\'Bro\') === -1) {\n return Ember.RSVP.reject(new DS.InvalidError({ name: [\'common... name requires a \"bro\"\'] }));\n } else {\n return Ember.RSVP.resolve();\n }\n };\n\n var yehuda = run(function() {\n return store.createRecord(\'person\', { id: 1, name: \"Yehuda Katz\" });\n });\n\n // Wrap this in an Ember.run so that all chained async behavior is set up\n // before flushing any scheduled behavior.\n Ember.run(function() {\n yehuda.save().then(null, async(function(reason) {\n equal(saveCount, 1, \"The record has been saved once\");\n ok(reason.message.match(\"The backend rejected the commit because it was invalid\"), \"It should fail due to being invalid\");\n equal(get(yehuda, \'isValid\'), false, \"the record is invalid\");\n equal(get(yehuda, \'isDirty\'), true, \"the record has outstanding changes\");\n ok(get(yehuda, \'errors.name\'), \"The errors.name property exists\");\n equal(get(yehuda, \'isNew\'), true, \"precond - record is still new\");\n return yehuda.save();\n })).then(null, async(function(reason) {\n equal(saveCount, 2, \"The record has been saved twice\");\n ok(reason.message.match(\"The backend rejected the commit because it was invalid\"), \"It should fail due to being invalid\");\n equal(get(yehuda, \'isValid\'), false, \"the record is still invalid\");\n equal(get(yehuda, \'isDirty\'), true, \"the record has outstanding changes\");\n ok(get(yehuda, \'errors.name\'), \"The errors.name property exists\");\n equal(get(yehuda, \'isNew\'), true, \"precond - record is still new\");\n set(yehuda, \'name\', \'Brohuda Brokatz\');\n return yehuda.save();\n })).then(async(function(person) {\n equal(saveCount, 3, \"The record has been saved thrice\");\n equal(get(yehuda, \'isValid\'), true, \"record is valid\");\n equal(get(yehuda, \'isDirty\'), false, \"record is not dirty\");\n equal(get(yehuda, \'errors.isEmpty\'), true, \"record has no errors\");\n }));\n });\n});\n\ntest(\"if a created record is marked as erred by the server, it enters an error state\", function() {\n adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.reject();\n };\n\n Ember.run(function() {\n var person = store.createRecord(\'person\', { id: 1, name: \"John Doe\" });\n\n person.save().then(null, async(function() {\n ok(get(person, \'isError\'), \"the record is in the error state\");\n }));\n });\n});\n\ntest(\"if an updated record is marked as invalid by the server, it enters an error state\", function() {\n adapter.updateRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n\n if (snapshot.attr(\'name\').indexOf(\'Bro\') === -1) {\n return Ember.RSVP.reject(new DS.InvalidError({ name: [\'common... name requires a \"bro\"\'] }));\n } else {\n return Ember.RSVP.resolve();\n }\n };\n\n var yehuda = run(function() {\n return store.push(\'person\', { id: 1, name: \"Brohuda Brokatz\" });\n });\n\n Ember.run(function() {\n store.find(\'person\', 1).then(async(function(person) {\n equal(person, yehuda, \"The same object is passed through\");\n\n equal(get(yehuda, \'isValid\'), true, \"precond - the record is valid\");\n set(yehuda, \'name\', \"Yehuda Katz\");\n equal(get(yehuda, \'isValid\'), true, \"precond - the record is still valid as far as we know\");\n\n equal(get(yehuda, \'isDirty\'), true, \"the record is dirty\");\n\n return yehuda.save();\n })).then(null, async(function(reason) {\n equal(get(yehuda, \'isDirty\'), true, \"the record is still dirty\");\n equal(get(yehuda, \'isValid\'), false, \"the record is invalid\");\n\n set(yehuda, \'updatedAt\', true);\n equal(get(yehuda, \'isValid\'), false, \"the record is still invalid\");\n\n set(yehuda, \'name\', \"Brohuda Brokatz\");\n equal(get(yehuda, \'isValid\'), true, \"the record is no longer invalid after changing\");\n equal(get(yehuda, \'isDirty\'), true, \"the record has outstanding changes\");\n\n return yehuda.save();\n })).then(async(function(yehuda) {\n equal(get(yehuda, \'isValid\'), true, \"record remains valid after committing\");\n equal(get(yehuda, \'isDirty\'), false, \"record is no longer new\");\n }));\n });\n});\n\n\ntest(\"records can have errors on arbitrary properties after update\", function() {\n adapter.updateRecord = function(store, type, snapshot) {\n if (snapshot.attr(\'name\').indexOf(\'Bro\') === -1) {\n return Ember.RSVP.reject(new DS.InvalidError({ base: [\'is a generally unsavoury character\'] }));\n } else {\n return Ember.RSVP.resolve();\n }\n };\n\n var yehuda = run(function() {\n return store.push(\'person\', { id: 1, name: \"Brohuda Brokatz\" });\n });\n\n run(function() {\n store.find(\'person\', 1).then(async(function(person) {\n equal(person, yehuda, \"The same object is passed through\");\n\n equal(get(yehuda, \'isValid\'), true, \"precond - the record is valid\");\n set(yehuda, \'name\', \"Yehuda Katz\");\n equal(get(yehuda, \'isValid\'), true, \"precond - the record is still valid as far as we know\");\n\n equal(get(yehuda, \'isDirty\'), true, \"the record is dirty\");\n\n return yehuda.save();\n })).then(null, async(function(reason) {\n equal(get(yehuda, \'isDirty\'), true, \"the record is still dirty\");\n equal(get(yehuda, \'isValid\'), false, \"the record is invalid\");\n ok(get(yehuda, \'errors.base\'), \"The errors.base property exists\");\n deepEqual(get(yehuda, \'errors\').errorsFor(\'base\'), [{ attribute: \'base\', message: \"is a generally unsavoury character\" }]);\n\n set(yehuda, \'updatedAt\', true);\n equal(get(yehuda, \'isValid\'), false, \"the record is still invalid\");\n\n set(yehuda, \'name\', \"Brohuda Brokatz\");\n equal(get(yehuda, \'isValid\'), false, \"the record is still invalid after changing (only server can know if it\'s now valid)\");\n equal(get(yehuda, \'isDirty\'), true, \"the record has outstanding changes\");\n\n return yehuda.save();\n })).then(async(function(yehuda) {\n equal(get(yehuda, \'isValid\'), true, \"record remains valid after committing\");\n equal(get(yehuda, \'isDirty\'), false, \"record is no longer new\");\n ok(!get(yehuda, \'errors.base\'), \"The errors.base property does not exist\");\n deepEqual(get(yehuda, \'errors\').errorsFor(\'base\'), []);\n }));\n });\n});\n\n\n\ntest(\"if an updated record is marked as invalid by the server, you can attempt the save again\", function() {\n var saveCount = 0;\n adapter.updateRecord = function(store, type, snapshot) {\n equal(type, Person, \"the type is correct\");\n saveCount++;\n if (snapshot.attr(\'name\').indexOf(\'Bro\') === -1) {\n return Ember.RSVP.reject(new DS.InvalidError({ name: [\'common... name requires a \"bro\"\'] }));\n } else {\n return Ember.RSVP.resolve();\n }\n };\n\n var yehuda = run(function() {\n return store.push(\'person\', { id: 1, name: \"Brohuda Brokatz\" });\n });\n\n Ember.run(function() {\n store.find(\'person\', 1).then(async(function(person) {\n equal(person, yehuda, \"The same object is passed through\");\n\n equal(get(yehuda, \'isValid\'), true, \"precond - the record is valid\");\n set(yehuda, \'name\', \"Yehuda Katz\");\n equal(get(yehuda, \'isValid\'), true, \"precond - the record is still valid as far as we know\");\n\n equal(get(yehuda, \'isDirty\'), true, \"the record is dirty\");\n\n return yehuda.save();\n })).then(null, async(function(reason) {\n equal(saveCount, 1, \"The record has been saved once\");\n ok(reason.message.match(\"The backend rejected the commit because it was invalid\"), \"It should fail due to being invalid\");\n equal(get(yehuda, \'isDirty\'), true, \"the record is still dirty\");\n equal(get(yehuda, \'isValid\'), false, \"the record is invalid\");\n return yehuda.save();\n })).then(null, async(function(reason) {\n equal(saveCount, 2, \"The record has been saved twice\");\n ok(reason.message.match(\"The backend rejected the commit because it was invalid\"), \"It should fail due to being invalid\");\n equal(get(yehuda, \'isValid\'), false, \"record is still invalid\");\n equal(get(yehuda, \'isDirty\'), true, \"record is still dirty\");\n set(yehuda, \'name\', \'Brohuda Brokatz\');\n return yehuda.save();\n })).then(async(function(person) {\n equal(saveCount, 3, \"The record has been saved thrice\");\n equal(get(yehuda, \'isValid\'), true, \"record is valid\");\n equal(get(yehuda, \'isDirty\'), false, \"record is not dirty\");\n equal(get(yehuda, \'errors.isEmpty\'), true, \"record has no errors\");\n }));\n });\n});\n\n\ntest(\"if a updated record is marked as erred by the server, it enters an error state\", function() {\n adapter.updateRecord = function(store, type, snapshot) {\n return Ember.RSVP.reject();\n };\n\n var person = run(function() {\n return store.push(Person, { id: 1, name: \"John Doe\" });\n });\n\n run(store, \'find\', \'person\', 1).then(async(function(record) {\n equal(record, person, \"The person was resolved\");\n person.set(\'name\', \"Jonathan Doe\");\n return person.save();\n })).then(null, async(function(reason) {\n ok(get(person, \'isError\'), \"the record is in the error state\");\n }));\n});\n\ntest(\"can be created after the DS.Store\", function() {\n expect(1);\n\n adapter.find = function(store, type, id, snapshot) {\n equal(type, Person, \"the type is correct\");\n return Ember.RSVP.resolve({ id: 1 });\n };\n\n run(function() {\n store.find(\'person\', 1);\n });\n});\n\ntest(\"the filter method can optionally take a server query as well\", function() {\n adapter.findQuery = function(store, type, query, array) {\n return Ember.RSVP.resolve([\n { id: 1, name: \"Yehuda Katz\" },\n { id: 2, name: \"Tom Dale\" }\n ]);\n };\n\n var asyncFilter = store.filter(\'person\', { page: 1 }, function(data) {\n return data.get(\'name\') === \"Tom Dale\";\n });\n\n var loadedFilter;\n\n asyncFilter.then(async(function(filter) {\n loadedFilter = filter;\n return store.find(\'person\', 2);\n })).then(async(function(tom) {\n equal(get(loadedFilter, \'length\'), 1, \"The filter has an item in it\");\n deepEqual(loadedFilter.toArray(), [tom], \"The filter has a single entry in it\");\n }));\n});\n\ntest(\"relationships returned via `commit` do not trigger additional findManys\", function() {\n Person.reopen({\n dogs: DS.hasMany()\n });\n\n run(function() {\n store.push(\'dog\', { id: 1, name: \"Scruffy\" });\n });\n\n adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\", dogs: [1] });\n };\n\n adapter.updateRecord = function(store, type, snapshot) {\n return new Ember.RSVP.Promise(function(resolve, reject) {\n store.push(\'person\', { id: 1, name: \"Tom Dale\", dogs: [1, 2] });\n store.push(\'dog\', { id: 2, name: \"Scruffles\" });\n resolve({ id: 1, name: \"Scruffy\" });\n });\n };\n\n adapter.findMany = function(store, type, ids, snapshots) {\n ok(false, \"Should not get here\");\n };\n\n run(function() {\n store.find(\'person\', 1).then(async(function(person) {\n return Ember.RSVP.hash({ tom: person, dog: store.find(\'dog\', 1) });\n })).then(async(function(records) {\n records.tom.get(\'dogs\');\n return records.dog.save();\n })).then(async(function(tom) {\n ok(true, \"Tom was saved\");\n }));\n });\n});\n\ntest(\"relationships don\'t get reset if the links is the same\", function() {\n Person.reopen({\n dogs: DS.hasMany({ async: true })\n });\n\n var count = 0;\n\n adapter.findHasMany = function(store, snapshot, link, relationship) {\n ok(count++ === 0, \"findHasMany is only called once\");\n\n return Ember.RSVP.resolve([{ id: 1, name: \"Scruffy\" }]);\n };\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Tom Dale\", links: { dogs: \"/dogs\" } });\n });\n\n var tom, dogs;\n\n run(store, \'find\', \'person\', 1).then(async(function(person) {\n tom = person;\n dogs = tom.get(\'dogs\');\n return dogs;\n })).then(async(function(dogs) {\n equal(dogs.get(\'length\'), 1, \"The dogs are loaded\");\n store.push(\'person\', { id: 1, name: \"Tom Dale\", links: { dogs: \"/dogs\" } });\n ok(tom.get(\'dogs\') instanceof DS.PromiseArray, \'dogs is a promise\');\n return tom.get(\'dogs\');\n })).then(async(function(dogs) {\n equal(dogs.get(\'length\'), 1, \"The same dogs are loaded\");\n }));\n});\n\ntest(\"async hasMany always returns a promise\", function() {\n Person.reopen({\n dogs: DS.hasMany({ async: true })\n });\n\n adapter.createRecord = function(store, type, snapshot) {\n var hash = { name: \"Tom Dale\" };\n hash.dogs = [];\n hash.id = 1;\n return Ember.RSVP.resolve(hash);\n };\n var tom;\n\n run(function() {\n tom = store.createRecord(\'person\', { name: \"Tom Dale\" });\n });\n\n ok(tom.get(\'dogs\') instanceof DS.PromiseArray, \"dogs is a promise before save\");\n\n run(function() {\n tom.save().then(async(function() {\n ok(tom.get(\'dogs\') instanceof DS.PromiseArray, \"dogs is a promise after save\");\n }));\n });\n});\n\ntest(\"createRecord receives a snapshot\", function() {\n expect(1);\n\n adapter.createRecord = function(store, type, snapshot) {\n ok(snapshot instanceof DS.Snapshot, \"snapshot is an instance of DS.Snapshot\");\n return Ember.RSVP.resolve();\n };\n\n var person;\n\n run(function() {\n person = store.createRecord(\'person\', { name: \"Tom Dale\" });\n person.save();\n });\n});\n\ntest(\"updateRecord receives a snapshot\", function() {\n expect(1);\n\n adapter.updateRecord = function(store, type, snapshot) {\n ok(snapshot instanceof DS.Snapshot, \"snapshot is an instance of DS.Snapshot\");\n return Ember.RSVP.resolve();\n };\n\n var person;\n\n run(function() {\n person = store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n\n run(function() {\n set(person, \"name\", \"Tomster\");\n person.save();\n });\n});\n\ntest(\"deleteRecord receives a snapshot\", function() {\n expect(1);\n\n adapter.deleteRecord = function(store, type, snapshot) {\n ok(snapshot instanceof DS.Snapshot, \"snapshot is an instance of DS.Snapshot\");\n return Ember.RSVP.resolve();\n };\n\n var person;\n\n run(function() {\n person = store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n\n run(function() {\n person.deleteRecord();\n person.save();\n });\n});\n\ntest(\"find receives a snapshot\", function() {\n expect(1);\n\n adapter.find = function(store, type, id, snapshot) {\n ok(snapshot instanceof DS.Snapshot, \"snapshot is an instance of DS.Snapshot\");\n return Ember.RSVP.resolve({ id: 1 });\n };\n\n run(function() {\n store.find(\'person\', 1);\n });\n});\n\ntest(\"findMany receives an array of snapshots\", function() {\n expect(2);\n\n Person.reopen({\n dogs: DS.hasMany({ async: true })\n });\n\n adapter.coalesceFindRequests = true;\n adapter.findMany = function(store, type, ids, snapshots) {\n ok(snapshots[0] instanceof DS.Snapshot, \"snapshots[0] is an instance of DS.Snapshot\");\n ok(snapshots[1] instanceof DS.Snapshot, \"snapshots[1] is an instance of DS.Snapshot\");\n return Ember.RSVP.resolve([{ id: 2 }, { id: 3 }]);\n };\n\n var person;\n\n run(function() {\n person = store.push(\'person\', { id: 1, dogs: [2, 3] });\n });\n\n run(function() {\n person.get(\'dogs\');\n });\n});\n\ntest(\"findHasMany receives a snapshot\", function() {\n expect(1);\n\n Person.reopen({\n dogs: DS.hasMany({ async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n ok(snapshot instanceof DS.Snapshot, \"snapshot is an instance of DS.Snapshot\");\n return Ember.RSVP.resolve([{ id: 2 }, { id: 3 }]);\n };\n\n var person;\n\n run(function() {\n person = store.push(\'person\', { id: 1, links: { dogs: \'dogs\' } });\n });\n\n run(function() {\n person.get(\'dogs\');\n });\n});\n\ntest(\"findBelongsTo receives a snapshot\", function() {\n expect(1);\n\n Person.reopen({\n dog: DS.belongsTo({ async: true })\n });\n\n env.adapter.findBelongsTo = async(function(store, snapshot, link, relationship) {\n ok(snapshot instanceof DS.Snapshot, \"snapshot is an instance of DS.Snapshot\");\n return Ember.RSVP.resolve({ id: 2 });\n });\n\n var person;\n\n run(function() {\n person = store.push(\'person\', { id: 1, links: { dog: \'dog\' } });\n });\n\n run(function() {\n person.get(\'dog\');\n });\n});\n})();//# sourceURL=ember-data/integration/adapter/store-adapter-test.js");
298
310
 
@@ -300,6 +312,10 @@ eval("(function() {var get = Ember.get;\nvar run = Ember.run;\n\nvar Person, sto
300
312
 
301
313
  eval("(function() {var run = Ember.run;\nvar Application = Ember.Application;\nvar Controller = Ember.Controller;\nvar View = Ember.View;\nvar Store = DS.Store;\nvar Namespace = Ember.Namespace;\n\nvar app, App, container;\n\n/*\n These tests ensure that Ember Data works with Ember.js\' application\n initialization and dependency injection APIs.\n*/\n\nfunction getStore() {\n return lookup(\'store:main\');\n}\n\nfunction lookup(thing) {\n return run(container, \'lookup\', thing);\n}\n\nmodule(\"integration/application - Injecting a Custom Store\", {\n setup: function() {\n run(function() {\n app = Application.create({\n ApplicationStore: Store.extend({ isCustom: true }),\n FooController: Controller.extend(),\n ApplicationView: View.extend(),\n BazController: {},\n ApplicationController: Controller.extend(),\n rootElement: \'#qunit-fixture\'\n });\n });\n\n container = app.__container__;\n },\n\n teardown: function() {\n run(app, app.destroy);\n Ember.BOOTED = false;\n }\n});\n\ntest(\"If a Store property exists on an Ember.Application, it should be instantiated.\", function() {\n run(function() {\n ok(getStore().get(\'isCustom\'), \"the custom store was instantiated\");\n });\n});\n\ntest(\"If a store is instantiated, it should be made available to each controller.\", function() {\n var fooController = lookup(\'controller:foo\');\n var isCustom = run(fooController, \'get\', \'store.isCustom\');\n ok(isCustom, \"the custom store was injected\");\n});\n\ntest(\"registering App.Store is deprecated but functional\", function() {\n run(app, \'destroy\');\n\n expectDeprecation(function() {\n run(function() {\n app = Application.create({\n Store: DS.Store.extend({ isCustomButDeprecated: true }),\n FooController: Controller.extend()\n });\n });\n container = app.__container__;\n }, \'Specifying a custom Store for Ember Data on your global namespace as `App.Store` \' +\n \'has been deprecated. Please use `App.ApplicationStore` instead.\');\n\n run(function() {\n ok(lookup(\'store:main\').get(\'isCustomButDeprecated\'), \"the custom store was instantiated\");\n });\n\n var fooController = lookup(\'controller:foo\');\n run(function() {\n ok(fooController.get(\'store.isCustomButDeprecated\'), \"the custom store was injected\");\n });\n});\n\nmodule(\"integration/application - Injecting the Default Store\", {\n setup: function() {\n run(function() {\n app = Application.create({\n FooController: Controller.extend(),\n ApplicationView: View.extend(),\n BazController: {},\n ApplicationController: Controller.extend()\n });\n });\n\n container = app.__container__;\n },\n\n teardown: function() {\n run(app, \'destroy\');\n Ember.BOOTED = false;\n }\n});\n\ntest(\"If a Store property exists on an Ember.Application, it should be instantiated.\", function() {\n ok(getStore() instanceof DS.Store, \"the store was instantiated\");\n});\n\ntest(\"If a store is instantiated, it should be made available to each controller.\", function() {\n run(function() {\n var fooController = lookup(\'controller:foo\');\n ok(fooController.get(\'store\') instanceof DS.Store, \"the store was injected\");\n });\n});\n\ntest(\"the DS namespace should be accessible\", function() {\n run(function() {\n ok(Namespace.byName(\'DS\') instanceof Namespace, \"the DS namespace is accessible\");\n });\n});\n\nif (Ember.inject && Ember.inject.service) {\n module(\"integration/application - Using the store as a service\", {\n setup: function() {\n run(function() {\n app = Application.create({\n DoodleService: Ember.Object.extend({ store: Ember.inject.service() })\n });\n });\n\n container = app.__container__;\n },\n\n teardown: function() {\n run(app, \'destroy\');\n Ember.BOOTED = false;\n }\n });\n\n test(\"The store can be injected as a service\", function() {\n run(function() {\n var doodleService = lookup(\'service:doodle\');\n ok(doodleService.get(\'store\') instanceof Store, \"the store can be used as a service\");\n });\n });\n}\n\nmodule(\"integration/application - Attaching initializer\", {\n setup: function() {\n App = Application.extend();\n },\n\n teardown: function() {\n if (app) {\n run(app, app.destroy);\n }\n Ember.BOOTED = false;\n }\n});\n\ntest(\"ember-data initializer is run\", function() {\n var ran = false;\n App.initializer({\n name: \"after-ember-data\",\n after: \"ember-data\",\n initialize: function() { ran = true; }\n });\n\n run(function() {\n app = App.create();\n });\n\n ok(ran, \'ember-data initializer was found\');\n});\n\ntest(\"store initializer is run (DEPRECATED)\", function() {\n var ran = false;\n App.initializer({\n name: \"after-store\",\n after: \'store\',\n initialize: function() { ran = true; }\n });\n\n run(function() {\n app = App.create();\n });\n\n ok(ran, \'store initializer was found\');\n});\n\ntest(\"injectStore initializer is run (DEPRECATED)\", function() {\n var ran = false;\n App.initializer({\n name: \"after-store\",\n after: \'injectStore\',\n initialize: function() { ran = true; }\n });\n\n run(function() {\n app = App.create();\n });\n\n ok(ran, \'injectStore initializer was found\');\n});\n\ntest(\"transforms initializer is run (DEPRECATED)\", function() {\n var ran = false;\n App.initializer({\n name: \"after-store\",\n after: \'transforms\',\n initialize: function() { ran = true; }\n });\n\n run(function() {\n app = App.create();\n });\n\n ok(ran, \'transforms initializer was found\');\n});\n\ntest(\"activeModelAdapter initializer is run (DEPRECATED)\", function() {\n var ran = false;\n App.initializer({\n name: \"after-store\",\n after: \'activeModelAdapter\',\n initialize: function() { ran = true; }\n });\n\n run(function() {\n app = App.create();\n });\n\n ok(ran, \'activeModelAdapter initializer was found\');\n});\n})();//# sourceURL=ember-data/integration/application-test.js");
302
314
 
315
+ eval("(function() {var Post, env;\nmodule(\'integration/backwards-compat/deprecate-type-key\', {\n setup: function() {\n env = setupStore({\n post: DS.Model.extend()\n });\n Post = env.store.modelFor(\'post\');\n },\n\n teardown: function() {\n }\n});\n\ntest(\'typeKey is deprecated\', function() {\n expectDeprecation(function() {\n return Post.typeKey;\n });\n});\n\ntest(\'setting typeKey is not allowed\', function() {\n throws(function() {\n Post.typeKey = \'hello\';\n });\n});\n})();//# sourceURL=ember-data/integration/backwards-compat/deprecate-type-key-test.js");
316
+
317
+ eval("(function() {var App, store;\n\nvar run = Ember.run;\nmodule(\'integration/backwards-compat/non-dasherized-lookups - non dasherized lookups in application code finders\', {\n setup: function() {\n run(function() {\n App = Ember.Application.create();\n App.PostNote = DS.Model.extend({\n name: DS.attr()\n });\n });\n store = App.__container__.lookup(\'store:main\');\n },\n teardown: function() {\n run(App, \'destroy\');\n App = null;\n }\n});\n\ntest(\'can lookup models using camelCase strings\', function() {\n expect(1);\n run(function() {\n store.pushPayload(\'postNote\', {\n postNote: {\n id: 1,\n name: \'Ember Data\'\n }\n });\n });\n\n run(function() {\n store.find(\'postNote\', 1).then(async(function(postNote) {\n equal(postNote.get(\'id\'), 1);\n }));\n });\n});\n\ntest(\'can lookup models using underscored strings\', function() {\n run(function() {\n store.pushPayload(\'post_note\', {\n postNote: {\n id: 1,\n name: \'Ember Data\'\n }\n });\n\n run(function() {\n store.find(\'post_note\', 1).then(async(function(postNote) {\n equal(postNote.get(\'id\'), 1);\n }));\n });\n });\n});\n\nmodule(\'integration/backwards-compat/non-dasherized-lookups - non dasherized lookups in application code relationship macros\', {\n setup: function() {\n run(function() {\n App = Ember.Application.create();\n App.PostNote = DS.Model.extend({\n notePost: DS.belongsTo(\'notePost\'),\n name: DS.attr()\n });\n App.NotePost = DS.Model.extend({\n name: DS.attr()\n });\n App.LongModelName = DS.Model.extend({\n postNotes: DS.hasMany(\'post_note\')\n });\n });\n store = App.__container__.lookup(\'store:main\');\n },\n\n teardown: function() {\n run(App, \'destroy\');\n App = null;\n }\n});\n\ntest(\'looks up using camelCase string\', function() {\n expect(1);\n\n run(function() {\n store.push(\'postNote\', {\n id: 1,\n notePost: 1\n });\n store.push(\'notePost\', {\n id: 1,\n name: \'Inverse\'\n });\n });\n\n run(function() {\n store.find(\'postNote\', 1).then(function(postNote) {\n equal(postNote.get(\'notePost\'), store.getById(\'notePost\', 1));\n });\n });\n});\n\ntest(\'looks up using under_score string\', function() {\n expect(1);\n\n run(function() {\n store.push(\'long_model_name\', {\n id: 1,\n name: \'Inverse\',\n postNotes: [\'1\']\n });\n store.push(\'postNote\', {\n id: 1,\n name: \'Underscore\'\n });\n });\n\n run(function() {\n store.find(\'long_model_name\', 1).then(function(longModelName) {\n deepEqual(longModelName.get(\'postNotes\').toArray(), [store.getById(\'postNote\', 1)]);\n });\n });\n\n});\n})();//# sourceURL=ember-data/integration/backwards-compat/non-dasherized-lookups.js");
318
+
303
319
  eval("(function() {var get = Ember.get;\nvar Post, Comment, env;\nvar run = Ember.run;\n\nmodule(\"integration/client_id_generation - Client-side ID Generation\", {\n setup: function() {\n Comment = DS.Model.extend({\n post: DS.belongsTo(\'post\')\n });\n\n Post = DS.Model.extend({\n comments: DS.hasMany(\'comment\')\n });\n\n env = setupStore({\n post: Post,\n comment: Comment\n });\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"If an adapter implements the `generateIdForRecord` method, the store should be able to assign IDs without saving to the persistence layer.\", function() {\n expect(6);\n\n var idCount = 1;\n\n env.adapter.generateIdForRecord = function(passedStore, record) {\n equal(env.store, passedStore, \"store is the first parameter\");\n\n return \"id-\" + idCount++;\n };\n\n env.adapter.createRecord = function(store, type, snapshot) {\n if (type === Comment) {\n equal(snapshot.id, \'id-1\', \"Comment passed to `createRecord` has \'id-1\' assigned\");\n return Ember.RSVP.resolve();\n } else {\n equal(snapshot.id, \'id-2\', \"Post passed to `createRecord` has \'id-2\' assigned\");\n return Ember.RSVP.resolve();\n }\n };\n\n var comment, post;\n run(function() {\n comment = env.store.createRecord(\'comment\');\n post = env.store.createRecord(\'post\');\n });\n\n equal(get(comment, \'id\'), \'id-1\', \"comment is assigned id \'id-1\'\");\n equal(get(post, \'id\'), \'id-2\', \"post is assigned id \'id-2\'\");\n\n // Despite client-generated IDs, calling commit() on the store should still\n // invoke the adapter\'s `createRecord` method.\n run(function() {\n comment.save();\n post.save();\n });\n});\n})();//# sourceURL=ember-data/integration/client-id-generation-test.js");
304
320
 
305
321
  eval("(function() {var App, store, debugAdapter;\nvar get = Ember.get;\nvar run = Ember.run;\n\nmodule(\"DS.DebugAdapter\", {\n setup: function() {\n Ember.run(function() {\n App = Ember.Application.create();\n App.toString = function() { return \'App\'; };\n\n App.ApplicationStore = DS.Store.extend({\n adapter: DS.Adapter.extend()\n });\n\n App.Post = DS.Model.extend({\n title: DS.attr(\'string\')\n });\n\n });\n\n store = App.__container__.lookup(\'store:main\');\n debugAdapter = App.__container__.lookup(\'data-adapter:main\');\n\n debugAdapter.reopen({\n getModelTypes: function() {\n return Ember.A([{ klass: App.Post, name: \'App.Post\' }]);\n }\n });\n },\n teardown: function() {\n run(App, App.destroy);\n }\n});\n\ntest(\"Watching Model Types\", function() {\n expect(5);\n\n var added = function(types) {\n equal(types.length, 1);\n equal(types[0].name, \'App.Post\');\n equal(types[0].count, 0);\n strictEqual(types[0].object, App.Post);\n };\n\n var updated = function(types) {\n equal(types[0].count, 1);\n };\n\n debugAdapter.watchModelTypes(added, updated);\n\n run(function() {\n store.push(\'post\', { id: 1, title: \'Post Title\' });\n });\n});\n\ntest(\"Watching Records\", function() {\n var post, record, addedRecords, updatedRecords, removedIndex, removedCount;\n\n Ember.run(function() {\n store.push(\'post\', { id: \'1\', title: \'Clean Post\' });\n });\n\n var recordsAdded = function(wrappedRecords) {\n addedRecords = wrappedRecords;\n };\n var recordsUpdated = function(wrappedRecords) {\n updatedRecords = wrappedRecords;\n };\n var recordsRemoved = function(index, count) {\n removedIndex = index;\n removedCount = count;\n };\n\n debugAdapter.watchRecords(App.Post, recordsAdded, recordsUpdated, recordsRemoved);\n\n equal(get(addedRecords, \'length\'), 1);\n record = addedRecords[0];\n deepEqual(record.columnValues, { id: \'1\', title: \'Clean Post\' });\n deepEqual(record.filterValues, { isNew: false, isModified: false, isClean: true });\n deepEqual(record.searchKeywords, [\'1\', \'Clean Post\']);\n deepEqual(record.color, \'black\');\n\n Ember.run(function() {\n post = store.find(\'post\', 1);\n });\n\n Ember.run(function() {\n post.set(\'title\', \'Modified Post\');\n });\n\n equal(get(updatedRecords, \'length\'), 1);\n record = updatedRecords[0];\n deepEqual(record.columnValues, { id: \'1\', title: \'Modified Post\' });\n deepEqual(record.filterValues, { isNew: false, isModified: true, isClean: false });\n deepEqual(record.searchKeywords, [\'1\', \'Modified Post\']);\n deepEqual(record.color, \'blue\');\n\n run(function() {\n post = store.createRecord(\'post\', { id: \'2\', title: \'New Post\' });\n });\n equal(get(addedRecords, \'length\'), 1);\n record = addedRecords[0];\n deepEqual(record.columnValues, { id: \'2\', title: \'New Post\' });\n deepEqual(record.filterValues, { isNew: true, isModified: false, isClean: false });\n deepEqual(record.searchKeywords, [\'2\', \'New Post\']);\n deepEqual(record.color, \'green\');\n\n Ember.run(post, \'deleteRecord\');\n\n equal(removedIndex, 1);\n equal(removedCount, 1);\n});\n})();//# sourceURL=ember-data/integration/debug-adapter-test.js");
@@ -310,7 +326,7 @@ eval("(function() {var env, store, User, Job, ReflexiveModel;\n\nvar attr = DS.a
310
326
 
311
327
  eval("(function() {var Person, env;\nvar attr = DS.attr;\nvar resolve = Ember.RSVP.resolve;\nvar run = Ember.run;\n\nmodule(\"integration/lifecycle_hooks - Lifecycle Hooks\", {\n setup: function() {\n Person = DS.Model.extend({\n name: attr(\'string\')\n });\n\n env = setupStore({\n person: Person\n });\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\nasyncTest(\"When the adapter acknowledges that a record has been created, a `didCreate` event is triggered.\", function() {\n expect(3);\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return resolve({ id: 99, name: \"Yehuda Katz\" });\n };\n var person;\n\n run(function() {\n person = env.store.createRecord(Person, { name: \"Yehuda Katz\" });\n });\n\n person.on(\'didCreate\', function() {\n equal(this, person, \"this is bound to the record\");\n equal(this.get(\'id\'), \"99\", \"the ID has been assigned\");\n equal(this.get(\'name\'), \"Yehuda Katz\", \"the attribute has been assigned\");\n start();\n });\n\n run(person, \'save\');\n});\n\ntest(\"When the adapter acknowledges that a record has been created without a new data payload, a `didCreate` event is triggered.\", function() {\n expect(3);\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.resolve();\n };\n var person;\n\n run(function() {\n person = env.store.createRecord(Person, { id: 99, name: \"Yehuda Katz\" });\n });\n\n person.on(\'didCreate\', function() {\n equal(this, person, \"this is bound to the record\");\n equal(this.get(\'id\'), \"99\", \"the ID has been assigned\");\n equal(this.get(\'name\'), \"Yehuda Katz\", \"the attribute has been assigned\");\n });\n\n run(person, \'save\');\n});\n})();//# sourceURL=ember-data/integration/lifecycle-hooks-test.js");
312
328
 
313
- eval("(function() {var env;\nvar SuperVillain, HomePlanet, EvilMinion;\nvar run = Ember.run;\n\nmodule(\"integration/multiple_stores - Multiple Stores Tests\", {\n setup: function() {\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n homePlanet: DS.belongsTo(\"homePlanet\", { inverse: \'villains\' }),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n HomePlanet = DS.Model.extend({\n name: DS.attr(\'string\'),\n villains: DS.hasMany(\'superVillain\', { inverse: \'homePlanet\' })\n });\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n\n env = setupStore({\n superVillain: SuperVillain,\n homePlanet: HomePlanet,\n evilMinion: EvilMinion\n });\n\n env.registry.register(\'serializer:application\', DS.ActiveModelSerializer);\n env.registry.register(\'serializer:-active-model\', DS.ActiveModelSerializer);\n env.registry.register(\'adapter:-active-model\', DS.ActiveModelAdapter);\n\n env.registry.register(\'store:store-a\', DS.Store);\n env.registry.register(\'store:store-b\', DS.Store);\n\n env.store_a = env.container.lookup(\'store:store-a\');\n env.store_b = env.container.lookup(\'store:store-b\');\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"should be able to push into multiple stores\", function() {\n env.registry.register(\'adapter:homePlanet\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:homePlanet\', DS.ActiveModelSerializer);\n\n var home_planet_main = { id: \'1\', name: \'Earth\' };\n var home_planet_a = { id: \'1\', name: \'Mars\' };\n var home_planet_b = { id: \'1\', name: \'Saturn\' };\n\n run(env.store, \'push\', \'homePlanet\', home_planet_main);\n run(env.store_a, \'push\', \'homePlanet\', home_planet_a);\n run(env.store_b, \'push\', \'homePlanet\', home_planet_b);\n\n run(env.store, \'find\', \'homePlanet\', 1).then(async(function(homePlanet) {\n equal(homePlanet.get(\'name\'), \"Earth\");\n }));\n\n run(env.store_a, \'find\', \'homePlanet\', 1).then(async(function(homePlanet) {\n equal(homePlanet.get(\'name\'), \"Mars\");\n }));\n\n run(env.store_b, \'find\', \'homePlanet\', 1).then(async(function(homePlanet) {\n equal(homePlanet.get(\'name\'), \"Saturn\");\n }));\n\n});\n\ntest(\"embedded records should be created in multiple stores\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'adapter:homePlanet\', DS.ActiveModelAdapter);\n\n env.registry.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n\n var serializer_main = env.store.serializerFor(\"homePlanet\");\n var serializer_a = env.store_a.serializerFor(\"homePlanet\");\n var serializer_b = env.store_b.serializerFor(\"homePlanet\");\n\n var json_hash_main = {\n home_planet: {\n id: \"1\",\n name: \"Earth\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\"\n }]\n }\n };\n var json_hash_a = {\n home_planet: {\n id: \"1\",\n name: \"Mars\",\n villains: [{\n id: \"1\",\n first_name: \"James\",\n last_name: \"Murphy\"\n }]\n }\n };\n var json_hash_b = {\n home_planet: {\n id: \"1\",\n name: \"Saturn\",\n villains: [{\n id: \"1\",\n first_name: \"Jade\",\n last_name: \"John\"\n }]\n }\n };\n var json_main, json_a, json_b;\n\n run(function() {\n json_main = serializer_main.extractSingle(env.store, HomePlanet, json_hash_main);\n equal(env.store.hasRecordForId(\"superVillain\", \"1\"), true, \"superVillain should exist in store:main\");\n });\n\n run(function() {\n json_a = serializer_a.extractSingle(env.store_a, HomePlanet, json_hash_a);\n equal(env.store_a.hasRecordForId(\"superVillain\", \"1\"), true, \"superVillain should exist in store:store-a\");\n });\n\n run(function() {\n json_b = serializer_b.extractSingle(env.store_b, HomePlanet, json_hash_b);\n equal(env.store_b.hasRecordForId(\"superVillain\", \"1\"), true, \"superVillain should exist in store:store-b\");\n });\n\n});\n})();//# sourceURL=ember-data/integration/multiple_stores_test.js");
329
+ eval("(function() {var env;\nvar SuperVillain, HomePlanet, EvilMinion;\nvar run = Ember.run;\n\nmodule(\"integration/multiple_stores - Multiple Stores Tests\", {\n setup: function() {\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n homePlanet: DS.belongsTo(\"homePlanet\", { inverse: \'villains\' }),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n HomePlanet = DS.Model.extend({\n name: DS.attr(\'string\'),\n villains: DS.hasMany(\'superVillain\', { inverse: \'homePlanet\' })\n });\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n\n env = setupStore({\n superVillain: SuperVillain,\n homePlanet: HomePlanet,\n evilMinion: EvilMinion\n });\n\n env.registry.register(\'serializer:application\', DS.ActiveModelSerializer);\n env.registry.register(\'serializer:-active-model\', DS.ActiveModelSerializer);\n env.registry.register(\'adapter:-active-model\', DS.ActiveModelAdapter);\n\n env.registry.register(\'store:store-a\', DS.Store);\n env.registry.register(\'store:store-b\', DS.Store);\n\n env.store_a = env.container.lookup(\'store:store-a\');\n env.store_b = env.container.lookup(\'store:store-b\');\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"should be able to push into multiple stores\", function() {\n env.registry.register(\'adapter:home-planet\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer);\n\n var home_planet_main = { id: \'1\', name: \'Earth\' };\n var home_planet_a = { id: \'1\', name: \'Mars\' };\n var home_planet_b = { id: \'1\', name: \'Saturn\' };\n\n run(env.store, \'push\', \'homePlanet\', home_planet_main);\n run(env.store_a, \'push\', \'homePlanet\', home_planet_a);\n run(env.store_b, \'push\', \'homePlanet\', home_planet_b);\n\n run(env.store, \'find\', \'homePlanet\', 1).then(async(function(homePlanet) {\n equal(homePlanet.get(\'name\'), \"Earth\");\n }));\n\n run(env.store_a, \'find\', \'homePlanet\', 1).then(async(function(homePlanet) {\n equal(homePlanet.get(\'name\'), \"Mars\");\n }));\n\n run(env.store_b, \'find\', \'homePlanet\', 1).then(async(function(homePlanet) {\n equal(homePlanet.get(\'name\'), \"Saturn\");\n }));\n\n});\n\ntest(\"embedded records should be created in multiple stores\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'adapter:home-planet\', DS.ActiveModelAdapter);\n\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n\n var serializer_main = env.store.serializerFor(\"homePlanet\");\n var serializer_a = env.store_a.serializerFor(\"homePlanet\");\n var serializer_b = env.store_b.serializerFor(\"homePlanet\");\n\n var json_hash_main = {\n home_planet: {\n id: \"1\",\n name: \"Earth\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\"\n }]\n }\n };\n var json_hash_a = {\n home_planet: {\n id: \"1\",\n name: \"Mars\",\n villains: [{\n id: \"1\",\n first_name: \"James\",\n last_name: \"Murphy\"\n }]\n }\n };\n var json_hash_b = {\n home_planet: {\n id: \"1\",\n name: \"Saturn\",\n villains: [{\n id: \"1\",\n first_name: \"Jade\",\n last_name: \"John\"\n }]\n }\n };\n var json_main, json_a, json_b;\n\n run(function() {\n json_main = serializer_main.extractSingle(env.store, HomePlanet, json_hash_main);\n equal(env.store.hasRecordForId(\"superVillain\", \"1\"), true, \"superVillain should exist in store:main\");\n });\n\n run(function() {\n json_a = serializer_a.extractSingle(env.store_a, HomePlanet, json_hash_a);\n equal(env.store_a.hasRecordForId(\"superVillain\", \"1\"), true, \"superVillain should exist in store:store-a\");\n });\n\n run(function() {\n json_b = serializer_b.extractSingle(env.store_b, HomePlanet, json_hash_b);\n equal(env.store_b.hasRecordForId(\"superVillain\", \"1\"), true, \"superVillain should exist in store:store-b\");\n });\n\n});\n})();//# sourceURL=ember-data/integration/multiple_stores_test.js");
314
330
 
315
331
  eval("(function() {var store, env;\nvar run = Ember.run;\n\nvar Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n cars: DS.hasMany(\'car\')\n});\n\nPerson.toString = function() { return \"Person\"; };\n\nvar Car = DS.Model.extend({\n make: DS.attr(\'string\'),\n model: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n});\n\nCar.toString = function() { return \"Car\"; };\n\nvar manager;\n\nmodule(\"integration/record_array_manager- destroy\", {\n setup: function() {\n env = setupStore({\n adapter: DS.FixtureAdapter.extend()\n });\n store = env.store;\n\n manager = store.recordArrayManager;\n\n env.registry.register(\'model:car\', Car);\n env.registry.register(\'model:person\', Person);\n }\n});\n\nfunction tap(obj, methodName, callback) {\n var old = obj[methodName];\n\n var summary = { called: [] };\n\n obj[methodName] = function() {\n var result = old.apply(obj, arguments);\n if (callback) {\n callback.apply(obj, arguments);\n }\n summary.called.push(arguments);\n return result;\n };\n\n return summary;\n}\n\ntest(\"destroying the store correctly cleans everything up\", function() {\n var query = { };\n var person;\n\n run(function() {\n store.push(\'car\', {\n id: 1,\n make: \'BMC\',\n model: \'Mini Cooper\',\n person: 1\n });\n });\n\n run(function() {\n person = store.push(\'person\', {\n id: 1,\n name: \'Tom Dale\',\n cars: [1]\n });\n });\n\n var filterd = manager.createFilteredRecordArray(Person, function() { return true; });\n var filterd2 = manager.createFilteredRecordArray(Person, function() { return true; });\n var adapterPopulated = manager.createAdapterPopulatedRecordArray(Person, query);\n\n var filterdSummary = tap(filterd, \'willDestroy\');\n var filterd2Summary = tap(filterd2, \'willDestroy\');\n\n var adapterPopulatedSummary = tap(adapterPopulated, \'willDestroy\');\n\n equal(filterdSummary.called.length, 0);\n equal(adapterPopulatedSummary.called.length, 0);\n\n equal(filterd2Summary.called.length, 0);\n\n equal(person._recordArrays.list.length, 2, \'expected the person to be a member of 2 recordArrays\');\n\n Ember.run(filterd2, filterd2.destroy);\n\n equal(person._recordArrays.list.length, 1, \'expected the person to be a member of 1 recordArrays\');\n\n equal(filterd2Summary.called.length, 1);\n\n Ember.run(manager, manager.destroy);\n\n equal(person._recordArrays.list.length, 0, \'expected the person to be a member of no recordArrays\');\n\n equal(filterd2Summary.called.length, 1);\n\n equal(filterdSummary.called.length, 1);\n equal(adapterPopulatedSummary.called.length, 1);\n});\n\n\ntest(\"Should not filter a stor.all() array when a record property is changed\", function() {\n var car;\n var filterdSummary = tap(store.recordArrayManager, \'updateRecordArray\');\n\n store.all(\'car\');\n\n run(function() {\n car = store.push(\'car\', {\n id: 1,\n make: \'BMC\',\n model: \'Mini Cooper\',\n person: 1\n });\n });\n\n equal(filterdSummary.called.length, 1);\n\n run(function() {\n car.set(\'model\', \'Mini\');\n });\n\n equal(filterdSummary.called.length, 1);\n\n});\n})();//# sourceURL=ember-data/integration/record-array-manager-test.js");
316
332
 
@@ -320,7 +336,7 @@ eval("(function() {var attr = DS.attr;\nvar Person, env;\nvar run = Ember.run;\n
320
336
 
321
337
  eval("(function() {var hasMany = DS.hasMany;\nvar Post, Comment, env;\nvar run = Ember.run;\n\nmodule(\"integration/load - Loading Records\", {\n setup: function() {\n Post = DS.Model.extend({\n comments: hasMany({ async: true })\n });\n\n Comment = DS.Model.extend();\n\n Post.toString = function() { return \"Post\"; };\n Comment.toString = function() { return \"Comment\"; };\n\n env = setupStore({ post: Post, comment: Comment });\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"When loading a record fails, the isLoading is set to false\", function() {\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.reject();\n };\n\n run(function() {\n env.store.find(\'post\', 1).then(null, function() {\n // store.recordForId is private, but there is currently no other way to\n // get the specific record instance, since it is not passed to this\n // rejection handler\n var post = env.store.recordForId(\'post\', 1);\n\n equal(post.get(\"isLoading\"), false, \"post is not loading anymore\");\n });\n });\n});\n})();//# sourceURL=ember-data/integration/records/load-test.js");
322
338
 
323
- eval("(function() {var get = Ember.get;\nvar attr = DS.attr;\nvar Person, env;\nvar run = Ember.run;\n\nmodule(\"integration/reload - Reloading Records\", {\n setup: function() {\n Person = DS.Model.extend({\n updatedAt: attr(\'string\'),\n name: attr(\'string\'),\n firstName: attr(\'string\'),\n lastName: attr(\'string\')\n });\n\n Person.toString = function() { return \"Person\"; };\n\n env = setupStore({ person: Person });\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"When a single record is requested, the adapter\'s find method should be called unless it\'s loaded.\", function() {\n var count = 0;\n\n env.adapter.find = function(store, type, id, snapshot) {\n if (count === 0) {\n count++;\n return Ember.RSVP.resolve({ id: id, name: \"Tom Dale\" });\n } else if (count === 1) {\n count++;\n return Ember.RSVP.resolve({ id: id, name: \"Braaaahm Dale\" });\n } else {\n ok(false, \"Should not get here\");\n }\n };\n\n run(function() {\n env.store.find(\'person\', 1).then(function(person) {\n equal(get(person, \'name\'), \"Tom Dale\", \"The person is loaded with the right name\");\n equal(get(person, \'isLoaded\'), true, \"The person is now loaded\");\n var promise = person.reload();\n equal(get(person, \'isReloading\'), true, \"The person is now reloading\");\n return promise;\n }).then(function(person) {\n equal(get(person, \'isReloading\'), false, \"The person is no longer reloading\");\n equal(get(person, \'name\'), \"Braaaahm Dale\", \"The person is now updated with the right name\");\n });\n });\n});\n\ntest(\"When a record is reloaded and fails, it can try again\", function() {\n var tom;\n run(function() {\n tom = env.store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n\n var count = 0;\n env.adapter.find = function(store, type, id, snapshot) {\n equal(tom.get(\'isReloading\'), true, \"Tom is reloading\");\n if (count++ === 0) {\n return Ember.RSVP.reject();\n } else {\n return Ember.RSVP.resolve({ id: 1, name: \"Thomas Dale\" });\n }\n };\n\n run(function() {\n tom.reload().then(null, function() {\n equal(tom.get(\'isError\'), true, \"Tom is now errored\");\n equal(tom.get(\'isReloading\'), false, \"Tom is no longer reloading\");\n return tom.reload();\n }).then(function(person) {\n equal(person, tom, \"The resolved value is the record\");\n equal(tom.get(\'isError\'), false, \"Tom is no longer errored\");\n equal(tom.get(\'isReloading\'), false, \"Tom is no longer reloading\");\n equal(tom.get(\'name\'), \"Thomas Dale\", \"the updates apply\");\n });\n });\n});\n\ntest(\"When a record is loaded a second time, isLoaded stays true\", function() {\n run(function() {\n env.store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n\n run(function() {\n env.store.find(\'person\', 1).then(function(person) {\n equal(get(person, \'isLoaded\'), true, \"The person is loaded\");\n person.addObserver(\'isLoaded\', isLoadedDidChange);\n\n // Reload the record\n env.store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n equal(get(person, \'isLoaded\'), true, \"The person is still loaded after load\");\n\n person.removeObserver(\'isLoaded\', isLoadedDidChange);\n });\n });\n\n function isLoadedDidChange() {\n // This shouldn\'t be hit\n equal(get(this, \'isLoaded\'), true, \"The person is still loaded after change\");\n }\n});\n\ntest(\"When a record is reloaded, its async hasMany relationships still work\", function() {\n env.registry.register(\'model:person\', DS.Model.extend({\n name: DS.attr(),\n tags: DS.hasMany(\'tag\', { async: true })\n }));\n\n env.registry.register(\'model:tag\', DS.Model.extend({\n name: DS.attr()\n }));\n\n var tags = { 1: \"hipster\", 2: \"hair\" };\n\n env.adapter.find = function(store, type, id, snapshot) {\n switch (type.typeKey) {\n case \'person\':\n return Ember.RSVP.resolve({ id: 1, name: \"Tom\", tags: [1, 2] });\n case \'tag\':\n return Ember.RSVP.resolve({ id: id, name: tags[id] });\n }\n };\n\n var tom;\n\n run(function() {\n env.store.find(\'person\', 1).then(function(person) {\n tom = person;\n equal(person.get(\'name\'), \"Tom\", \"precond\");\n\n return person.get(\'tags\');\n }).then(function(tags) {\n deepEqual(tags.mapBy(\'name\'), [\'hipster\', \'hair\']);\n\n return tom.reload();\n }).then(function(person) {\n equal(person.get(\'name\'), \"Tom\", \"precond\");\n\n return person.get(\'tags\');\n }).then(function(tags) {\n deepEqual(tags.mapBy(\'name\'), [\'hipster\', \'hair\'], \"The tags are still there\");\n });\n });\n});\n})();//# sourceURL=ember-data/integration/records/reload-test.js");
339
+ eval("(function() {var get = Ember.get;\nvar attr = DS.attr;\nvar Person, env;\nvar run = Ember.run;\n\nmodule(\"integration/reload - Reloading Records\", {\n setup: function() {\n Person = DS.Model.extend({\n updatedAt: attr(\'string\'),\n name: attr(\'string\'),\n firstName: attr(\'string\'),\n lastName: attr(\'string\')\n });\n\n Person.toString = function() { return \"Person\"; };\n\n env = setupStore({ person: Person });\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"When a single record is requested, the adapter\'s find method should be called unless it\'s loaded.\", function() {\n var count = 0;\n\n env.adapter.find = function(store, type, id, snapshot) {\n if (count === 0) {\n count++;\n return Ember.RSVP.resolve({ id: id, name: \"Tom Dale\" });\n } else if (count === 1) {\n count++;\n return Ember.RSVP.resolve({ id: id, name: \"Braaaahm Dale\" });\n } else {\n ok(false, \"Should not get here\");\n }\n };\n\n run(function() {\n env.store.find(\'person\', 1).then(function(person) {\n equal(get(person, \'name\'), \"Tom Dale\", \"The person is loaded with the right name\");\n equal(get(person, \'isLoaded\'), true, \"The person is now loaded\");\n var promise = person.reload();\n equal(get(person, \'isReloading\'), true, \"The person is now reloading\");\n return promise;\n }).then(function(person) {\n equal(get(person, \'isReloading\'), false, \"The person is no longer reloading\");\n equal(get(person, \'name\'), \"Braaaahm Dale\", \"The person is now updated with the right name\");\n });\n });\n});\n\ntest(\"When a record is reloaded and fails, it can try again\", function() {\n var tom;\n run(function() {\n tom = env.store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n\n var count = 0;\n env.adapter.find = function(store, type, id, snapshot) {\n equal(tom.get(\'isReloading\'), true, \"Tom is reloading\");\n if (count++ === 0) {\n return Ember.RSVP.reject();\n } else {\n return Ember.RSVP.resolve({ id: 1, name: \"Thomas Dale\" });\n }\n };\n\n run(function() {\n tom.reload().then(null, function() {\n equal(tom.get(\'isError\'), true, \"Tom is now errored\");\n equal(tom.get(\'isReloading\'), false, \"Tom is no longer reloading\");\n return tom.reload();\n }).then(function(person) {\n equal(person, tom, \"The resolved value is the record\");\n equal(tom.get(\'isError\'), false, \"Tom is no longer errored\");\n equal(tom.get(\'isReloading\'), false, \"Tom is no longer reloading\");\n equal(tom.get(\'name\'), \"Thomas Dale\", \"the updates apply\");\n });\n });\n});\n\ntest(\"When a record is loaded a second time, isLoaded stays true\", function() {\n run(function() {\n env.store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n\n run(function() {\n env.store.find(\'person\', 1).then(function(person) {\n equal(get(person, \'isLoaded\'), true, \"The person is loaded\");\n person.addObserver(\'isLoaded\', isLoadedDidChange);\n\n // Reload the record\n env.store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n equal(get(person, \'isLoaded\'), true, \"The person is still loaded after load\");\n\n person.removeObserver(\'isLoaded\', isLoadedDidChange);\n });\n });\n\n function isLoadedDidChange() {\n // This shouldn\'t be hit\n equal(get(this, \'isLoaded\'), true, \"The person is still loaded after change\");\n }\n});\n\ntest(\"When a record is reloaded, its async hasMany relationships still work\", function() {\n env.registry.register(\'model:person\', DS.Model.extend({\n name: DS.attr(),\n tags: DS.hasMany(\'tag\', { async: true })\n }));\n\n env.registry.register(\'model:tag\', DS.Model.extend({\n name: DS.attr()\n }));\n\n var tags = { 1: \"hipster\", 2: \"hair\" };\n\n env.adapter.find = function(store, type, id, snapshot) {\n switch (type.modelName) {\n case \'person\':\n return Ember.RSVP.resolve({ id: 1, name: \"Tom\", tags: [1, 2] });\n case \'tag\':\n return Ember.RSVP.resolve({ id: id, name: tags[id] });\n }\n };\n\n var tom;\n\n run(function() {\n env.store.find(\'person\', 1).then(function(person) {\n tom = person;\n equal(person.get(\'name\'), \"Tom\", \"precond\");\n\n return person.get(\'tags\');\n }).then(function(tags) {\n deepEqual(tags.mapBy(\'name\'), [\'hipster\', \'hair\']);\n\n return tom.reload();\n }).then(function(person) {\n equal(person.get(\'name\'), \"Tom\", \"precond\");\n\n return person.get(\'tags\');\n }).then(function(tags) {\n deepEqual(tags.mapBy(\'name\'), [\'hipster\', \'hair\'], \"The tags are still there\");\n });\n });\n});\n})();//# sourceURL=ember-data/integration/records/reload-test.js");
324
340
 
325
341
  eval("(function() {var Post, env;\nvar run = Ember.run;\n\nmodule(\"integration/records/save - Save Record\", {\n setup: function() {\n Post = DS.Model.extend({\n title: DS.attr(\'string\')\n });\n\n Post.toString = function() { return \"Post\"; };\n\n env = setupStore({ post: Post });\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"Will resolve save on success\", function() {\n expect(1);\n var post;\n run(function() {\n post = env.store.createRecord(\'post\', { title: \'toto\' });\n });\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.resolve({ id: 123 });\n };\n\n run(function() {\n post.save().then(function() {\n ok(true, \'save operation was resolved\');\n });\n });\n});\n\ntest(\"Will reject save on error\", function() {\n var post;\n run(function() {\n post = env.store.createRecord(\'post\', { title: \'toto\' });\n });\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.reject();\n };\n\n run(function() {\n post.save().then(function() {}, function() {\n ok(true, \'save operation was rejected\');\n });\n });\n});\n\ntest(\"Retry is allowed in a failure handler\", function() {\n var post;\n run(function() {\n post = env.store.createRecord(\'post\', { title: \'toto\' });\n });\n\n var count = 0;\n\n env.adapter.createRecord = function(store, type, snapshot) {\n if (count++ === 0) {\n return Ember.RSVP.reject();\n } else {\n return Ember.RSVP.resolve({ id: 123 });\n }\n };\n\n run(function() {\n post.save().then(function() {}, function() {\n return post.save();\n }).then(function(post) {\n equal(post.get(\'id\'), \'123\', \"The post ID made it through\");\n });\n });\n});\n\ntest(\"Repeated failed saves keeps the record in uncommited state\", function() {\n expect(2);\n var post;\n\n run(function() {\n post = env.store.createRecord(\'post\', { title: \'toto\' });\n });\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.reject();\n };\n\n run(function() {\n post.save().then(null, function() {\n equal(post.get(\'currentState.stateName\'), \'root.loaded.created.uncommitted\');\n\n post.save().then(null, function() {\n equal(post.get(\'currentState.stateName\'), \'root.loaded.created.uncommitted\');\n });\n });\n });\n});\n\ntest(\"Will reject save on invalid\", function() {\n expect(1);\n var post;\n run(function() {\n post = env.store.createRecord(\'post\', { title: \'toto\' });\n });\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.reject({ title: \'invalid\' });\n };\n\n run(function() {\n post.save().then(function() {}, function() {\n ok(true, \'save operation was rejected\');\n });\n });\n});\n})();//# sourceURL=ember-data/integration/records/save-test.js");
326
342
 
@@ -328,7 +344,7 @@ eval("(function() {var attr = DS.attr;\nvar belongsTo = DS.belongsTo;\nvar hasMa
328
344
 
329
345
  eval("(function() {var env, store, User, Message, Post, Contact, Comment, Book, Chapter, Author, NewMessage;\nvar get = Ember.get;\nvar run = Ember.run;\n\nvar attr = DS.attr;\nvar hasMany = DS.hasMany;\nvar belongsTo = DS.belongsTo;\nvar hash = Ember.RSVP.hash;\n\n// Before https://github.com/emberjs/ember.js/pull/10323 the computed\n// property descriptor was stored on the ember meta object. After that\n// pr it was moved to the ember object. This code normalized that\n// lookup because the Ember Data ci tests run against diferent version\n// of Ember. Once that code reaches the release branch this code can\n// be removed.\nfunction getComputedPropertyDesc(model, key) {\n if (Ember.meta(model).descs) {\n return Ember.meta(model).descs[key];\n }\n var possibleDesc = model[key];\n var desc = (possibleDesc !== null && typeof possibleDesc === \'object\' && possibleDesc.isDescriptor) ? possibleDesc : undefined;\n return desc;\n}\n\nmodule(\"integration/relationship/belongs_to Belongs-To Relationships\", {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n messages: hasMany(\'message\', { polymorphic: true }),\n favouriteMessage: belongsTo(\'message\', { polymorphic: true, inverse: null })\n });\n\n Message = DS.Model.extend({\n user: belongsTo(\'user\', { inverse: \'messages\' }),\n created_at: attr(\'date\')\n });\n\n Post = Message.extend({\n title: attr(\'string\'),\n comments: hasMany(\'comment\')\n });\n\n Comment = Message.extend({\n body: DS.attr(\'string\'),\n message: DS.belongsTo(\'message\', { polymorphic: true })\n });\n\n Book = DS.Model.extend({\n name: attr(\'string\'),\n author: belongsTo(\'author\'),\n chapters: hasMany(\'chapters\')\n });\n\n Chapter = DS.Model.extend({\n title: attr(\'string\'),\n belongsTo: belongsTo(\'book\')\n });\n\n Author = DS.Model.extend({\n name: attr(\'string\'),\n books: hasMany(\'books\')\n });\n\n env = setupStore({\n user: User,\n post: Post,\n comment: Comment,\n message: Message,\n book: Book,\n chapter: Chapter,\n author: Author\n });\n\n\n env.registry.optionsForType(\'serializer\', { singleton: false });\n env.registry.optionsForType(\'adapter\', { singleton: false });\n\n env.registry.register(\'serializer:user\', DS.JSONSerializer.extend({\n attrs: {\n favouriteMessage: { embedded: \'always\' }\n }\n }));\n\n store = env.store;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"The store can materialize a non loaded monomorphic belongsTo association\", function() {\n expect(1);\n\n env.store.modelFor(\'post\').reopen({\n user: DS.belongsTo(\'user\', {\n async: true,\n inverse: \'messages\'\n })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n ok(true, \"The adapter\'s find method should be called\");\n return Ember.RSVP.resolve({\n id: 1\n });\n };\n\n run(function() {\n env.store.push(\'post\', {\n id: 1,\n user: 2\n });\n });\n\n run(function() {\n env.store.find(\'post\', 1).then(function(post) {\n post.get(\'user\');\n });\n });\n});\n\ntest(\"Only a record of the same type can be used with a monomorphic belongsTo relationship\", function() {\n expect(1);\n\n run(function() {\n store.push(\'post\', { id: 1 });\n store.push(\'comment\', { id: 2 });\n });\n\n run(function() {\n hash({\n post: store.find(\'post\', 1),\n comment: store.find(\'comment\', 2)\n }).then(function(records) {\n expectAssertion(function() {\n records.post.set(\'user\', records.comment);\n }, /You can only add a \'user\' record to this relationship/);\n });\n });\n});\n\ntest(\"Only a record of the same base type can be used with a polymorphic belongsTo relationship\", function() {\n expect(1);\n run(function() {\n store.push(\'comment\', { id: 1 });\n store.push(\'comment\', { id: 2 });\n store.push(\'post\', { id: 1 });\n store.push(\'user\', { id: 3 });\n });\n\n run(function() {\n var asyncRecords = hash({\n user: store.find(\'user\', 3),\n post: store.find(\'post\', 1),\n comment: store.find(\'comment\', 1),\n anotherComment: store.find(\'comment\', 2)\n });\n\n asyncRecords.then(function(records) {\n var comment = records.comment;\n\n comment.set(\'message\', records.anotherComment);\n comment.set(\'message\', records.post);\n comment.set(\'message\', null);\n\n expectAssertion(function() {\n comment.set(\'message\', records.user);\n }, /You cannot add a \'user\' record to the \'comment.message\'. You can only add a \'message\' record to this relationship./);\n });\n });\n});\n\ntest(\"The store can load a polymorphic belongsTo association\", function() {\n run(function() {\n env.store.push(\'post\', { id: 1 });\n env.store.push(\'comment\', { id: 2, message: 1, messageType: \'post\' });\n });\n\n run(function() {\n hash({\n message: store.find(\'post\', 1),\n comment: store.find(\'comment\', 2)\n }).then(function(records) {\n equal(records.comment.get(\'message\'), records.message);\n });\n });\n});\n\ntest(\"The store can serialize a polymorphic belongsTo association\", function() {\n var serializerInstance = store.serializerFor(\'comment\');\n\n serializerInstance.serializePolymorphicType = function(record, json, relationship) {\n ok(true, \"The serializer\'s serializePolymorphicType method should be called\");\n json[\"message_type\"] = \"post\";\n };\n run(function() {\n env.store.push(\'post\', { id: 1 });\n env.store.push(\'comment\', { id: 2, message: 1, messageType: \'post\' });\n\n store.find(\'comment\', 2).then(function(comment) {\n var serialized = store.serialize(comment, { includeId: true });\n equal(serialized[\'message\'], 1);\n equal(serialized[\'message_type\'], \'post\');\n });\n });\n});\n\ntest(\"A serializer can materialize a belongsTo as a link that gets sent back to findBelongsTo\", function() {\n var Group = DS.Model.extend({\n people: DS.hasMany()\n });\n\n var Person = DS.Model.extend({\n group: DS.belongsTo({ async: true })\n });\n\n env.registry.register(\'model:group\', Group);\n env.registry.register(\'model:person\', Person);\n\n run(function() {\n store.push(\'person\', { id: 1, links: { group: \'/people/1/group\' } });\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n throw new Error(\"Adapter\'s find method should not be called\");\n };\n\n env.adapter.findBelongsTo = async(function(store, snapshot, link, relationship) {\n equal(relationship.type, Group);\n equal(relationship.key, \'group\');\n equal(link, \"/people/1/group\");\n\n return Ember.RSVP.resolve({ id: 1, people: [1] });\n });\n\n run(function() {\n env.store.find(\'person\', 1).then(function(person) {\n return person.get(\'group\');\n }).then(function(group) {\n ok(group instanceof Group, \"A group object is loaded\");\n ok(group.get(\'id\') === \'1\', \'It is the group we are expecting\');\n });\n });\n});\n\ntest(\'A record with an async belongsTo relationship always returns a promise for that relationship\', function () {\n var Seat = DS.Model.extend({\n person: DS.belongsTo(\'person\')\n });\n\n var Person = DS.Model.extend({\n seat: DS.belongsTo(\'seat\', { async: true })\n });\n\n env.registry.register(\'model:seat\', Seat);\n env.registry.register(\'model:person\', Person);\n\n run(function() {\n store.push(\'person\', { id: 1, links: { seat: \'/people/1/seat\' } });\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n throw new Error(\"Adapter\'s find method should not be called\");\n };\n\n env.adapter.findBelongsTo = async(function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve({ id: 1 });\n });\n\n run(function() {\n env.store.find(\'person\', 1).then(function(person) {\n person.get(\'seat\').then(function(seat) {\n // this assertion fails too\n // ok(seat.get(\'person\') === person, \'parent relationship should be populated\');\n seat.set(\'person\', person);\n ok(person.get(\'seat\').then, \'seat should be a PromiseObject\');\n });\n });\n });\n});\n\ntest(\"A record with an async belongsTo relationship returning null should resolve null\", function() {\n expect(1);\n\n var Group = DS.Model.extend({\n people: DS.hasMany()\n });\n\n var Person = DS.Model.extend({\n group: DS.belongsTo({ async: true })\n });\n\n env.registry.register(\'model:group\', Group);\n env.registry.register(\'model:person\', Person);\n\n run(function() {\n store.push(\'person\', { id: 1, links: { group: \'/people/1/group\' } });\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n throw new Error(\"Adapter\'s find method should not be called\");\n };\n\n env.adapter.findBelongsTo = async(function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve(null);\n });\n\n env.store.find(\'person\', 1).then(async(function(person) {\n return person.get(\'group\');\n })).then(async(function(group) {\n ok(group === null, \"group should be null\");\n }));\n});\n\ntest(\"polymorphic belongsTo type-checks check the superclass when MODEL_FACTORY_INJECTIONS is enabled\", function() {\n expect(1);\n\n var injectionValue = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n try {\n run(function () {\n var igor = env.store.createRecord(\'user\', { name: \'Igor\' });\n var post = env.store.createRecord(\'post\', { title: \"Igor\'s unimaginative blog post\" });\n\n igor.set(\'favouriteMessage\', post);\n\n equal(igor.get(\'favouriteMessage.title\'), \"Igor\'s unimaginative blog post\");\n });\n } finally {\n Ember.MODEL_FACTORY_INJECTIONS = injectionValue;\n }\n});\n\ntest(\"the subclass in a polymorphic belongsTo relationship is an instanceof its superclass\", function() {\n expect(1);\n\n var injectionValue = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n try {\n run(function () {\n var message = env.store.createRecord(\'message\', { id: 1 });\n var comment = env.store.createRecord(\'comment\', { id: 2, message: message });\n ok(comment instanceof Message, \'a comment is an instance of a message\');\n });\n\n } finally {\n Ember.MODEL_FACTORY_INJECTIONS = injectionValue;\n }\n});\n\ntest(\"relationshipsByName does not cache a factory\", function() {\n\n // The model is loaded up via a container. It has relationshipsByName\n // called on it.\n var modelViaFirstFactory = store.modelFor(\'user\');\n get(modelViaFirstFactory, \'relationshipsByName\');\n\n // An app is reset, or the container otherwise destroyed.\n run(env.container, \'destroy\');\n\n // A new model for a relationship is created. Note that this may happen\n // due to an extend call internal to MODEL_FACTORY_INJECTIONS.\n NewMessage = Message.extend();\n\n // A new store is created.\n env = setupStore({\n user: User,\n message: NewMessage\n });\n store = env.store;\n\n // relationshipsByName is called again.\n var modelViaSecondFactory = store.modelFor(\'user\');\n var relationshipsByName = get(modelViaSecondFactory, \'relationshipsByName\');\n var messageType = relationshipsByName.get(\'messages\').type;\n\n // A model is looked up in the store based on a string, via user input\n var messageModelFromStore = store.modelFor(\'message\');\n // And the model is lookup up internally via the relationship type\n var messageModelFromRelationType = store.modelFor(messageType);\n\n equal(messageModelFromRelationType, messageModelFromStore,\n \"model factory based on relationship type matches the model based on store.modelFor\");\n});\n\ntest(\"relationshipsByName is cached in production\", function() {\n var model = store.modelFor(\'user\');\n var oldTesting = Ember.testing;\n //We set the cacheable to true because that is the default state for any CP and then assert that it\n //did not get dynamically changed when accessed\n var relationshipsByName = getComputedPropertyDesc(model, \'relationshipsByName\');\n var oldCacheable = relationshipsByName._cacheable;\n relationshipsByName._cacheable = true;\n Ember.testing = false;\n try {\n equal(get(model, \'relationshipsByName\'), get(model, \'relationshipsByName\'), \'relationshipsByName are cached\');\n equal(get(model, \'relationshipsByName\'), get(model, \'relationshipsByName\'), \'relationshipsByName are cached\');\n } finally {\n Ember.testing = oldTesting;\n relationshipsByName._cacheable = oldCacheable;\n }\n});\n\ntest(\"relatedTypes is cached in production\", function() {\n var model = store.modelFor(\'user\');\n var oldTesting = Ember.testing;\n //We set the cacheable to true because that is the default state for any CP and then assert that it\n //did not get dynamically changed when accessed\n var relatedTypes = getComputedPropertyDesc(model, \'relatedTypes\');\n var oldCacheable = relatedTypes._cacheable;\n relatedTypes._cacheable = true;\n Ember.testing = false;\n try {\n equal(get(model, \'relatedTypes\'), get(model, \'relatedTypes\'), \'relatedTypes are cached\');\n equal(get(model, \'relatedTypes\'), get(model, \'relatedTypes\'), \'relatedTypes are cached\');\n } finally {\n Ember.testing = oldTesting;\n relatedTypes._cacheable = oldCacheable;\n }\n});\n\ntest(\"relationships is cached in production\", function() {\n var model = store.modelFor(\'user\');\n var oldTesting = Ember.testing;\n //We set the cacheable to true because that is the default state for any CP and then assert that it\n //did not get dynamically changed when accessed\n var relationships = getComputedPropertyDesc(model, \'relationships\');\n var oldCacheable = relationships._cacheable;\n relationships._cacheable = true;\n Ember.testing = false;\n try {\n equal(get(model, \'relationships\'), get(model, \'relationships\'), \'relationships are cached\');\n equal(get(model, \'relationships\'), get(model, \'relationships\'), \'relationships are cached\');\n } finally {\n Ember.testing = oldTesting;\n relationships._cacheable = oldCacheable;\n }\n});\n\ntest(\"relationship changes shouldn’t cause async fetches\", function() {\n expect(2);\n\n /* Scenario:\n * ---------\n *\n * post HM async comments\n * comments bt sync post\n *\n * scenario:\n * - post hm C [1,2,3]\n * - post has a partially realized comments array comment#1 has been realized\n * - comment has not yet realized its post relationship\n * - comment is destroyed\n */\n\n env.store.modelFor(\'post\').reopen({\n comments: DS.hasMany(\'comment\', {\n async: true,\n inverse: \'post\'\n })\n });\n\n env.store.modelFor(\'comment\').reopen({\n post: DS.belongsTo(\'post\', {\n })\n });\n var post, comment;\n run(function() {\n post = env.store.push(\'post\', {\n id: 1,\n comments: [1, 2, 3]\n });\n\n comment = env.store.push(\'comment\', {\n id: 1,\n post: 1\n });\n });\n\n env.adapter.deleteRecord = function(store, type, snapshot) {\n ok(snapshot.record instanceof type);\n equal(snapshot.id, 1, \'should first comment\');\n return snapshot.record.toJSON({ includeId: true });\n };\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n ok(false, \'should not need to findMay more comments, but attempted to anyways\');\n };\n\n run(comment, \'destroyRecord\');\n});\n\ntest(\"Destroying a record with an unloaded aync belongsTo association does not fetch the record\", function() {\n expect(2);\n var post;\n\n env.store.modelFor(\'message\').reopen({\n user: DS.hasMany(\'user\', {\n async: true\n })\n });\n\n env.store.modelFor(\'post\').reopen({\n user: DS.belongsTo(\'user\', {\n async: true,\n inverse: \'messages\'\n })\n });\n\n run(function() {\n post = env.store.push(\'post\', {\n id: 1,\n user: 2\n });\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n throw new Error(\"Adapter\'s find method should not be called\");\n };\n\n env.adapter.deleteRecord = function(store, type, snapshot) {\n ok(snapshot.record instanceof type);\n equal(snapshot.id, 1, \'should first post\');\n return {\n id: \"1\",\n title: null,\n created_at: null,\n user: \"2\"\n };\n };\n\n run(post, \'destroyRecord\');\n});\n\ntest(\"A sync belongsTo errors out if the record is unlaoded\", function() {\n var message;\n run(function() {\n message = env.store.push(\'message\', { id: 1, user: 2 });\n });\n\n expectAssertion(function() {\n message.get(\'user\');\n }, /You looked up the \'user\' relationship on a \'message\' with id 1 but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async \\(`DS.belongsTo\\({ async: true }\\)`\\)/);\n});\n\ntest(\"Rollbacking a deleted record restores implicit relationship - async\", function () {\n Book.reopen({\n author: DS.belongsTo(\'author\', { async: true })\n });\n var book, author;\n run(function() {\n book = env.store.push(\'book\', { id: 1, name: \"Stanley\'s Amazing Adventures\", author: 2 });\n author = env.store.push(\'author\', { id: 2, name: \'Stanley\' });\n });\n run(function() {\n author.deleteRecord();\n author.rollback();\n book.get(\'author\').then(function(fetchedAuthor) {\n equal(fetchedAuthor, author, \'Book has an author after rollback\');\n });\n });\n});\n\ntest(\"Rollbacking a deleted record restores implicit relationship - sync\", function () {\n var book, author;\n run(function() {\n book = env.store.push(\'book\', { id: 1, name: \"Stanley\'s Amazing Adventures\", author: 2 });\n author = env.store.push(\'author\', { id: 2, name: \'Stanley\' });\n });\n run(function() {\n author.deleteRecord();\n author.rollback();\n });\n equal(book.get(\'author\'), author, \'Book has an author after rollback\');\n});\n\ntest(\"Passing a model as type to belongsTo should not work\", function () {\n expect(1);\n\n expectAssertion(function() {\n User = DS.Model.extend();\n\n Contact = DS.Model.extend({\n user: belongsTo(User)\n });\n }, /The first argument to DS.belongsTo must be a string/);\n});\n\ntest(\"belongsTo hasData async loaded\", function () {\n expect(1);\n\n Book.reopen({\n author: belongsTo(\'author\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, name: \'The Greatest Book\', author: 2 });\n };\n\n run(function() {\n store.find(\'book\', 1).then(function(book) {\n var relationship = book._relationships[\'author\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n });\n});\n\ntest(\"belongsTo hasData sync loaded\", function () {\n expect(1);\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, name: \'The Greatest Book\', author: 2 });\n };\n\n run(function() {\n store.find(\'book\', 1).then(function(book) {\n var relationship = book._relationships[\'author\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n });\n});\n\ntest(\"belongsTo hasData async not loaded\", function () {\n expect(1);\n\n Book.reopen({\n author: belongsTo(\'author\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, name: \'The Greatest Book\', links: { author: \'author\' } });\n };\n\n run(function() {\n store.find(\'book\', 1).then(function(book) {\n var relationship = book._relationships[\'author\'];\n equal(relationship.hasData, false, \'relationship does not have data\');\n });\n });\n});\n\ntest(\"belongsTo hasData sync not loaded\", function () {\n expect(1);\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, name: \'The Greatest Book\' });\n };\n\n run(function() {\n store.find(\'book\', 1).then(function(book) {\n var relationship = book._relationships[\'author\'];\n equal(relationship.hasData, false, \'relationship does not have data\');\n });\n });\n});\n\ntest(\"belongsTo hasData async created\", function () {\n expect(1);\n\n Book.reopen({\n author: belongsTo(\'author\', { async: true })\n });\n\n run(function() {\n var book = store.createRecord(\'book\', { name: \'The Greatest Book\' });\n var relationship = book._relationships[\'author\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n});\n\ntest(\"belongsTo hasData sync created\", function () {\n expect(1);\n\n run(function() {\n var book = store.createRecord(\'book\', { name: \'The Greatest Book\' });\n var relationship = book._relationships[\'author\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n});\n})();//# sourceURL=ember-data/integration/relationships/belongs-to-test.js");
330
346
 
331
- eval("(function() {var env, store, User, Contact, Email, Phone, Message, Post, Comment;\nvar Book, Chapter, Page;\nvar get = Ember.get;\nvar resolve = Ember.RSVP.resolve;\nvar run = Ember.run;\n\nvar attr = DS.attr;\nvar hasMany = DS.hasMany;\nvar belongsTo = DS.belongsTo;\n\nfunction stringify(string) {\n return function() { return string; };\n}\n\nmodule(\"integration/relationships/has_many - Has-Many Relationships\", {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n messages: hasMany(\'message\', { polymorphic: true }),\n contacts: hasMany(\'user\', { inverse: null })\n });\n\n Contact = DS.Model.extend({\n user: belongsTo(\'user\')\n });\n\n Email = Contact.extend({\n email: attr(\'string\')\n });\n\n Phone = Contact.extend({\n number: attr(\'string\')\n });\n\n Message = DS.Model.extend({\n user: belongsTo(\'user\'),\n created_at: attr(\'date\')\n });\n Message.toString = stringify(\'Message\');\n\n Post = Message.extend({\n title: attr(\'string\'),\n comments: hasMany(\'comment\')\n });\n Post.toString = stringify(\'Post\');\n\n Comment = Message.extend({\n body: DS.attr(\'string\'),\n message: DS.belongsTo(\'post\', { polymorphic: true })\n });\n Comment.toString = stringify(\'Comment\');\n\n Book = DS.Model.extend({\n title: attr(),\n chapters: hasMany(\'chapter\', { async: true })\n });\n Book.toString = stringify(\'Book\');\n\n Chapter = DS.Model.extend({\n title: attr(),\n pages: hasMany(\'page\')\n });\n Chapter.toString = stringify(\'Chapter\');\n\n Page = DS.Model.extend({\n number: attr(\'number\'),\n chapter: belongsTo(\'chapter\')\n });\n Page.toString = stringify(\'Page\');\n\n env = setupStore({\n user: User,\n contact: Contact,\n email: Email,\n phone: Phone,\n post: Post,\n comment: Comment,\n message: Message,\n book: Book,\n chapter: Chapter,\n page: Page\n });\n\n store = env.store;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"When a hasMany relationship is accessed, the adapter\'s findMany method should not be called if all the records in the relationship are already loaded\", function() {\n expect(0);\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n ok(false, \"The adapter\'s find method should not be called\");\n };\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [1] });\n env.store.push(\'comment\', { id: 1 });\n env.store.find(\'post\', 1).then(function(post) {\n return post.get(\'comments\');\n });\n });\n});\n\ntest(\"adapter.findMany only gets unique IDs even if duplicate IDs are present in the hasMany relationship\", function() {\n expect(2);\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n equal(type, Chapter, \'type passed to adapter.findMany is correct\');\n deepEqual(ids, [\'2\', \'3\'], \'ids passed to adapter.findMany are unique\');\n\n return Ember.RSVP.resolve([\n { id: 2, title: \'Chapter One\' },\n { id: 3, title: \'Chapter Two\' }\n ]);\n };\n\n run(function() {\n env.store.push(\'book\', { id: 1, chapters: [2, 3, 3] });\n env.store.find(\'book\', 1).then(function(book) {\n return book.get(\'chapters\');\n });\n });\n});\n\n// This tests the case where a serializer materializes a has-many\n// relationship as a reference that it can fetch lazily. The most\n// common use case of this is to provide a URL to a collection that\n// is loaded later.\ntest(\"A serializer can materialize a hasMany as an opaque token that can be lazily fetched via the adapter\'s findHasMany hook\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n // When the store asks the adapter for the record with ID 1,\n // provide some fake data.\n env.adapter.find = function(store, type, id, snapshot) {\n equal(type, Post, \"find type was Post\");\n equal(id, \"1\", \"find id was 1\");\n\n return Ember.RSVP.resolve({ id: 1, links: { comments: \"/posts/1/comments\" } });\n };\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n throw new Error(\"Adapter\'s findMany should not be called\");\n };\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n equal(link, \"/posts/1/comments\", \"findHasMany link was /posts/1/comments\");\n equal(relationship.type.typeKey, \"comment\", \"relationship was passed correctly\");\n\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n run(function() {\n env.store.find(\'post\', 1).then(async(function(post) {\n return post.get(\'comments\');\n })).then(async(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n equal(comments.objectAt(0).get(\'body\'), \'First\', \"comment loaded successfully\");\n }));\n });\n});\n\ntest(\"Accessing a hasMany backed by a link multiple times triggers only one request\", function() {\n expect(2);\n var count = 0;\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n Comment.reopen({\n message: DS.belongsTo(\'post\', { async: true })\n });\n var post;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, links: { comments: \'/posts/1/comments\' } });\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n start();\n count++;\n equal(count, 1, \"findHasMany has only been called once\");\n stop();\n return new Ember.RSVP.Promise(function(resolve, reject) {\n setTimeout(function() {\n var value = [\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ];\n resolve(value);\n }, 100);\n });\n };\n\n stop();\n var promise1, promise2;\n run(function() {\n promise1 = post.get(\'comments\');\n //Invalidate the post.comments CP\n env.store.push(\'comment\', { id: 1, message: 1 });\n promise2 = post.get(\'comments\');\n });\n Ember.RSVP.all([promise1, promise2]).then(function() {\n start();\n });\n equal(promise1.promise, promise2.promise, \"Same promise is returned both times\");\n});\n\ntest(\"A hasMany backed by a link remains a promise after a record has been added to it\", function() {\n expect(1);\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n Comment.reopen({\n message: DS.belongsTo(\'post\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n var post;\n run(function() {\n post = env.store.push(\'post\', { id: 1, links: { comments: \'/posts/1/comments\' } });\n });\n\n run(function() {\n post.get(\'comments\').then(function() {\n env.store.push(\'comment\', { id: 3, message: 1 });\n post.get(\'comments\').then(function() {\n ok(true, \'Promise was called\');\n });\n });\n });\n});\n\ntest(\"A hasMany updated link should not remove new children\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n Comment.reopen({\n message: DS.belongsTo(\'post\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([]);\n };\n\n env.adapter.createRecord = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve({\n links: {\n comments: \'/some/link\'\n }\n });\n };\n\n run(function() {\n var post = env.store.createRecord(\'post\', {});\n env.store.createRecord(\'comment\', { message: post });\n\n post.get(\'comments\')\n .then(function(comments) {\n equal(comments.get(\'length\'), 1);\n\n return post.save();\n })\n .then(function() {\n return post.get(\'comments\');\n })\n .then(function(comments) {\n equal(comments.get(\'length\'), 1);\n });\n });\n});\n\ntest(\"A hasMany updated link should not remove new children when the parent record has children already\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n Comment.reopen({\n message: DS.belongsTo(\'post\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([{ id: 5, body: \'hello\' }]);\n };\n\n env.adapter.createRecord = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve({\n links: {\n comments: \'/some/link\'\n }\n });\n };\n\n run(function() {\n var post = env.store.createRecord(\'post\', {});\n env.store.createRecord(\'comment\', { message: post });\n\n post.get(\'comments\')\n .then(function(comments) {\n equal(comments.get(\'length\'), 1);\n\n return post.save();\n })\n .then(function() {\n return post.get(\'comments\');\n })\n .then(function(comments) {\n equal(comments.get(\'length\'), 2);\n });\n });\n});\n\n\ntest(\"A hasMany relationship can be reloaded if it was fetched via a link\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n equal(type, Post, \"find type was Post\");\n equal(id, \"1\", \"find id was 1\");\n\n return Ember.RSVP.resolve({ id: 1, links: { comments: \"/posts/1/comments\" } });\n };\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n equal(relationship.type, Comment, \"findHasMany relationship type was Comment\");\n equal(relationship.key, \'comments\', \"findHasMany relationship key was comments\");\n equal(link, \"/posts/1/comments\", \"findHasMany link was /posts/1/comments\");\n\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n run(function() {\n run(env.store, \'find\', \'post\', 1).then(function(post) {\n return post.get(\'comments\');\n }).then(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n equal(relationship.type, Comment, \"findHasMany relationship type was Comment\");\n equal(relationship.key, \'comments\', \"findHasMany relationship key was comments\");\n equal(link, \"/posts/1/comments\", \"findHasMany link was /posts/1/comments\");\n\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" },\n { id: 3, body: \"Thirds\" }\n ]);\n };\n\n return comments.reload();\n }).then(function(newComments) {\n equal(newComments.get(\'length\'), 3, \"reloaded comments have 3 length\");\n });\n });\n});\n\ntest(\"A sync hasMany relationship can be reloaded if it was fetched via ids\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\')\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n equal(type, Post, \"find type was Post\");\n equal(id, \"1\", \"find id was 1\");\n\n return Ember.RSVP.resolve({ id: 1, comments: [1, 2] });\n };\n\n run(function() {\n env.store.pushMany(\'comment\', [{ id: 1, body: \"First\" }, { id: 2, body: \"Second\" }]);\n\n env.store.find(\'post\', \'1\').then(function(post) {\n var comments = post.get(\'comments\');\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have a length of 2\");\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"FirstUpdated\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n return comments.reload();\n }).then(function(newComments) {\n equal(newComments.get(\'firstObject.body\'), \'FirstUpdated\', \"Record body was correctly updated\");\n });\n });\n});\n\ntest(\"A hasMany relationship can be reloaded if it was fetched via ids\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n equal(type, Post, \"find type was Post\");\n equal(id, \"1\", \"find id was 1\");\n\n return Ember.RSVP.resolve({ id: 1, comments: [1,2] });\n };\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n run(function() {\n env.store.find(\'post\', 1).then(function(post) {\n return post.get(\'comments\');\n }).then(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"FirstUpdated\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n return comments.reload();\n }).then(function(newComments) {\n equal(newComments.get(\'firstObject.body\'), \'FirstUpdated\', \"Record body was correctly updated\");\n });\n });\n});\n\ntest(\"A hasMany relationship can be directly reloaded if it was fetched via ids\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n equal(type, Post, \"find type was Post\");\n equal(id, \"1\", \"find id was 1\");\n\n return Ember.RSVP.resolve({ id: 1, comments: [1,2] });\n };\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"FirstUpdated\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n run(function() {\n env.store.find(\'post\', 1).then(function(post) {\n return post.get(\'comments\').reload().then(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n equal(comments.get(\'firstObject.body\'), \"FirstUpdated\", \"Record body was correctly updated\");\n });\n });\n });\n});\n\ntest(\"PromiseArray proxies createRecord to its ManyArray once the hasMany is loaded\", function() {\n expect(4);\n\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n var post;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, links: { comments: \'someLink\' } });\n });\n\n run(function() {\n post.get(\'comments\').then(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n\n var newComment = post.get(\'comments\').createRecord({ body: \'Third\' });\n equal(newComment.get(\'body\'), \'Third\', \"new comment is returned\");\n equal(comments.get(\'length\'), 3, \"comments have 3 length, including new record\");\n });\n });\n});\n\ntest(\"PromiseArray proxies evented methods to its ManyArray\", function() {\n expect(6);\n\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n var post, comments;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, links: { comments: \'someLink\' } });\n comments = post.get(\'comments\');\n });\n\n\n comments.on(\'on-event\', function() {\n ok(true);\n });\n\n run(function() {\n comments.trigger(\'on-event\');\n });\n\n equal(comments.has(\'on-event\'), true);\n\n comments.on(\'off-event\', function() {\n ok(false);\n });\n\n comments.off(\'off-event\');\n\n equal(comments.has(\'off-event\'), false);\n\n comments.one(\'one-event\', function() {\n ok(true);\n });\n\n equal(comments.has(\'one-event\'), true);\n\n run(function() {\n comments.trigger(\'one-event\');\n });\n\n equal(comments.has(\'one-event\'), false);\n});\n\ntest(\"An updated `links` value should invalidate a relationship cache\", function() {\n expect(8);\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n equal(relationship.type.typeKey, \"comment\", \"relationship was passed correctly\");\n\n if (link === \'/first\') {\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n } else if (link === \'/second\') {\n return Ember.RSVP.resolve([\n { id: 3, body: \"Third\" },\n { id: 4, body: \"Fourth\" },\n { id: 5, body: \"Fifth\" }\n ]);\n }\n };\n var post;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, links: { comments: \'/first\' } });\n });\n\n run(function() {\n post.get(\'comments\').then(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n equal(comments.objectAt(0).get(\'body\'), \'First\', \"comment 1 successfully loaded\");\n env.store.push(\'post\', { id: 1, links: { comments: \'/second\' } });\n post.get(\'comments\').then(function(newComments) {\n equal(comments, newComments, \"hasMany array was kept the same\");\n equal(newComments.get(\'length\'), 3, \"comments updated successfully\");\n equal(newComments.objectAt(0).get(\'body\'), \'Third\', \"third comment loaded successfully\");\n });\n });\n });\n});\n\ntest(\"When a polymorphic hasMany relationship is accessed, the adapter\'s findMany method should not be called if all the records in the relationship are already loaded\", function() {\n expect(1);\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n ok(false, \"The adapter\'s find method should not be called\");\n };\n\n run(function() {\n env.store.push(\'user\', { id: 1, messages: [{ id: 1, type: \'post\' }, { id: 3, type: \'comment\' }] });\n env.store.push(\'post\', { id: 1 });\n env.store.push(\'comment\', { id: 3 });\n });\n\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n var messages = user.get(\'messages\');\n equal(messages.get(\'length\'), 2, \"The messages are correctly loaded\");\n });\n });\n});\n\ntest(\"When a polymorphic hasMany relationship is accessed, the store can call multiple adapters\' findMany or find methods if the records are not loaded\", function() {\n User.reopen({\n messages: hasMany(\'message\', { polymorphic: true, async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n if (type === Post) {\n return Ember.RSVP.resolve({ id: 1 });\n } else if (type === Comment) {\n return Ember.RSVP.resolve({ id: 3 });\n }\n };\n\n run(function() {\n env.store.push(\'user\', { id: 1, messages: [{ id: 1, type: \'post\' }, { id: 3, type: \'comment\' }] });\n });\n\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n return user.get(\'messages\');\n }).then(function(messages) {\n equal(messages.get(\'length\'), 2, \"The messages are correctly loaded\");\n });\n });\n});\n\ntest(\"polymorphic hasMany type-checks check the superclass when MODEL_FACTORY_INJECTIONS is enabled\", function() {\n expect(1);\n\n var injectionValue = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n try {\n run(function () {\n var igor = env.store.createRecord(\'user\', { name: \'Igor\' });\n var comment = env.store.createRecord(\'comment\', { body: \"Well I thought the title was fine\" });\n\n igor.get(\'messages\').addObject(comment);\n\n equal(igor.get(\'messages.firstObject.body\'), \"Well I thought the title was fine\");\n });\n } finally {\n Ember.MODEL_FACTORY_INJECTIONS = injectionValue;\n }\n});\n\n\n\ntest(\"Type can be inferred from the key of a hasMany relationship\", function() {\n expect(1);\n run(function() {\n env.store.push(\'user\', { id: 1, contacts: [1] });\n env.store.push(\'contact\', { id: 1 });\n });\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n return user.get(\'contacts\');\n }).then(function(contacts) {\n equal(contacts.get(\'length\'), 1, \"The contacts relationship is correctly set up\");\n });\n });\n});\n\ntest(\"Type can be inferred from the key of an async hasMany relationship\", function() {\n User.reopen({\n contacts: DS.hasMany({ async: true })\n });\n\n expect(1);\n run(function() {\n env.store.push(\'user\', { id: 1, contacts: [1] });\n env.store.push(\'contact\', { id: 1 });\n });\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n return user.get(\'contacts\');\n }).then(function(contacts) {\n equal(contacts.get(\'length\'), 1, \"The contacts relationship is correctly set up\");\n });\n });\n});\n\ntest(\"Polymorphic relationships work with a hasMany whose type is inferred\", function() {\n User.reopen({\n contacts: DS.hasMany({ polymorphic: true })\n });\n\n expect(1);\n run(function() {\n env.store.push(\'user\', { id: 1, contacts: [{ id: 1, type: \'email\' }, { id: 2, type: \'phone\' }] });\n env.store.push(\'email\', { id: 1 });\n env.store.push(\'phone\', { id: 2 });\n });\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n return user.get(\'contacts\');\n }).then(function(contacts) {\n equal(contacts.get(\'length\'), 2, \"The contacts relationship is correctly set up\");\n });\n });\n});\n\ntest(\"Polymorphic relationships with a hasMany is set up correctly on both sides\", function() {\n expect(2);\n\n Contact.reopen({\n posts: DS.hasMany(\'post\')\n });\n\n Post.reopen({\n contact: DS.belongsTo(\'contact\', { polymorphic: true })\n });\n var email, post;\n\n run(function () {\n email = env.store.createRecord(\'email\');\n post = env.store.createRecord(\'post\', {\n contact: email\n });\n });\n\n equal(post.get(\'contact\'), email, \'The polymorphic belongsTo is set up correctly\');\n equal(get(email, \'posts.length\'), 1, \"The inverse has many is set up correctly on the email side.\");\n});\n\ntest(\"A record can\'t be created from a polymorphic hasMany relationship\", function() {\n run(function() {\n env.store.push(\'user\', { id: 1, messages: [] });\n });\n\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n return user.get(\'messages\');\n }).then(function(messages) {\n expectAssertion(function() {\n messages.createRecord();\n }, /You cannot add \'message\' records to this polymorphic relationship/);\n });\n });\n});\n\ntest(\"Only records of the same type can be added to a monomorphic hasMany relationship\", function() {\n expect(1);\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [] });\n env.store.push(\'post\', { id: 2 });\n });\n\n run(function() {\n Ember.RSVP.all([\n env.store.find(\'post\', 1),\n env.store.find(\'post\', 2)\n ]).then(function(records) {\n expectAssertion(function() {\n records[0].get(\'comments\').pushObject(records[1]);\n }, /You cannot add \'post\' records to the post.comments relationship \\(only \'comment\' allowed\\)/);\n });\n });\n});\n\ntest(\"Only records of the same base type can be added to a polymorphic hasMany relationship\", function() {\n expect(2);\n run(function() {\n env.store.push(\'user\', { id: 1, messages: [] });\n env.store.push(\'user\', { id: 2, messages: [] });\n env.store.push(\'post\', { id: 1, comments: [] });\n env.store.push(\'comment\', { id: 3 });\n });\n var asyncRecords;\n\n run(function() {\n asyncRecords = Ember.RSVP.hash({\n user: env.store.find(\'user\', 1),\n anotherUser: env.store.find(\'user\', 2),\n post: env.store.find(\'post\', 1),\n comment: env.store.find(\'comment\', 3)\n });\n\n asyncRecords.then(function(records) {\n records.messages = records.user.get(\'messages\');\n return Ember.RSVP.hash(records);\n }).then(function(records) {\n records.messages.pushObject(records.post);\n records.messages.pushObject(records.comment);\n equal(records.messages.get(\'length\'), 2, \"The messages are correctly added\");\n\n expectAssertion(function() {\n records.messages.pushObject(records.anotherUser);\n }, /You cannot add \'user\' records to the user.messages relationship \\(only \'message\' allowed\\)/);\n });\n });\n});\n\ntest(\"A record can be removed from a polymorphic association\", function() {\n expect(4);\n\n run(function() {\n env.store.push(\'user\', { id: 1 , messages: [{ id: 3, type: \'comment\' }] });\n env.store.push(\'comment\', { id: 3 });\n });\n var asyncRecords;\n\n run(function() {\n asyncRecords = Ember.RSVP.hash({\n user: env.store.find(\'user\', 1),\n comment: env.store.find(\'comment\', 3)\n });\n\n asyncRecords.then(function(records) {\n records.messages = records.user.get(\'messages\');\n return Ember.RSVP.hash(records);\n }).then(function(records) {\n equal(records.messages.get(\'length\'), 1, \"The user has 1 message\");\n\n var removedObject = records.messages.popObject();\n\n equal(removedObject, records.comment, \"The message is correctly removed\");\n equal(records.messages.get(\'length\'), 0, \"The user does not have any messages\");\n equal(records.messages.objectAt(0), null, \"No messages can\'t be fetched\");\n });\n });\n});\n\ntest(\"When a record is created on the client, its hasMany arrays should be in a loaded state\", function() {\n expect(3);\n\n var post;\n\n run(function() {\n post = env.store.createRecord(\'post\');\n });\n\n ok(get(post, \'isLoaded\'), \"The post should have isLoaded flag\");\n var comments;\n run(function() {\n comments = get(post, \'comments\');\n });\n\n equal(get(comments, \'length\'), 0, \"The comments should be an empty array\");\n\n ok(get(comments, \'isLoaded\'), \"The comments should have isLoaded flag\");\n});\n\ntest(\"When a record is created on the client, its async hasMany arrays should be in a loaded state\", function() {\n expect(4);\n\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n var post = run(function() {\n return env.store.createRecord(\'post\');\n });\n\n ok(get(post, \'isLoaded\'), \"The post should have isLoaded flag\");\n\n run(function() {\n get(post, \'comments\').then(function(comments) {\n ok(true, \"Comments array successfully resolves\");\n equal(get(comments, \'length\'), 0, \"The comments should be an empty array\");\n ok(get(comments, \'isLoaded\'), \"The comments should have isLoaded flag\");\n });\n });\n});\n\ntest(\"a records SYNC HM relationship property is readOnly\", function() {\n expect(1);\n var post = run(function() {\n return env.store.createRecord(\'post\');\n });\n\n raises(function() {\n post.set(\'comments\');\n }, \'Cannot Set: comments on: \' + Ember.inspect(post));\n});\n\n\ntest(\"a records ASYNC HM relationship property is readOnly\", function() {\n expect(1);\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n var post = run(function() {\n return env.store.createRecord(\'post\');\n });\n\n raises(function() {\n run(post, \'set\', \'comments\');\n }, \'Cannot Set: comments on: \' + Ember.inspect(post));\n});\n\ntest(\"When a record is saved, its unsaved hasMany records should be kept\", function () {\n expect(1);\n\n var post, comment;\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.resolve({ id: 1 });\n };\n\n run(function () {\n post = env.store.createRecord(\'post\');\n comment = env.store.createRecord(\'comment\');\n post.get(\'comments\').pushObject(comment);\n post.save();\n });\n\n equal(get(post, \'comments.length\'), 1, \"The unsaved comment should be in the post\'s comments array\");\n});\n\ntest(\"dual non-async HM <-> BT\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { inverse: \'post\' })\n });\n\n Comment.reopen({\n post: DS.belongsTo(\'post\')\n });\n\n env.adapter.createRecord = function(store, type, snapshot) {\n var data = snapshot.record.serialize();\n data.id = 2;\n return Ember.RSVP.resolve(data);\n };\n var post, firstComment;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, comments: [1] });\n firstComment = env.store.push(\'comment\', { id: 1, post: 1 });\n\n env.store.createRecord(\'comment\', {\n post: post\n }).save().then(function(comment) {\n var commentPost = comment.get(\'post\');\n var postComments = comment.get(\'post.comments\');\n var postCommentsLength = comment.get(\'post.comments.length\');\n\n deepEqual(post, commentPost, \'expect the new comments post, to be the correct post\');\n ok(postComments, \"comments should exist\");\n equal(postCommentsLength, 2, \"comment\'s post should have a reference back to comment\");\n ok(postComments && postComments.indexOf(firstComment) !== -1, \'expect to contain first comment\');\n ok(postComments && postComments.indexOf(comment) !== -1, \'expected to contain the new comment\');\n });\n });\n});\n\ntest(\"When an unloaded record is added to the hasMany, it gets fetched once the hasMany is accessed even if the hasMany has been already fetched\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n return resolve([{ id: 1, body: \'first\' }, { id: 2, body: \'second\' }]);\n };\n\n env.adapter.find = function(store, type, id, snapshot) {\n return resolve({ id: 3, body: \'third\' });\n };\n var post;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, comments: [1, 2] });\n });\n\n run(function() {\n post.get(\'comments\').then(async(function(fetchedComments) {\n equal(fetchedComments.get(\'length\'), 2, \'comments fetched successfully\');\n equal(fetchedComments.objectAt(0).get(\'body\'), \'first\', \'first comment loaded successfully\');\n env.store.push(\'post\', { id: 1, comments: [1, 2, 3] });\n post.get(\'comments\').then(async(function(newlyFetchedComments) {\n equal(newlyFetchedComments.get(\'length\'), 3, \'all three comments fetched successfully\');\n equal(newlyFetchedComments.objectAt(2).get(\'body\'), \'third\', \'third comment loaded successfully\');\n }));\n }));\n });\n});\n\ntest(\"A sync hasMany errors out if there are unlaoded records in it\", function() {\n var post;\n run(function() {\n post = env.store.push(\'post\', { id: 1, comments: [1, 2] });\n });\n\n expectAssertion(function() {\n run(post, \'get\', \'comments\');\n }, /You looked up the \'comments\' relationship on a \'post\' with id 1 but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async \\(`DS.hasMany\\({ async: true }\\)`\\)/);\n});\n\ntest(\"If reordered hasMany data has been pushed to the store, the many array reflects the ordering change - sync\", function() {\n var comment1, comment2, comment3, comment4;\n var post;\n run(function() {\n comment1 = env.store.push(\'comment\', { id: 1 });\n comment2 = env.store.push(\'comment\', { id: 2 });\n comment3 = env.store.push(\'comment\', { id: 3 });\n comment4 = env.store.push(\'comment\', { id: 4 });\n });\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, comments: [1, 2] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment1, comment2], \'Initial ordering is correct\');\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [2, 1] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment2, comment1], \'Updated ordering is correct\');\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [2] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment2], \'Updated ordering is correct\');\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [1,2,3,4] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment1, comment2, comment3, comment4], \'Updated ordering is correct\');\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [4,3] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment4, comment3], \'Updated ordering is correct\');\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [4,2,3,1] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment4, comment2, comment3, comment1], \'Updated ordering is correct\');\n});\n\ntest(\"Rollbacking a deleted record restores implicit relationship correctly when the hasMany side has been deleted - async\", function () {\n var book, chapter;\n run(function() {\n book = env.store.push(\'book\', { id: 1, title: \"Stanley\'s Amazing Adventures\", chapters: [2] });\n chapter = env.store.push(\'chapter\', { id: 2, title: \'Sailing the Seven Seas\' });\n });\n run(function() {\n chapter.deleteRecord();\n chapter.rollback();\n });\n run(function() {\n book.get(\'chapters\').then(function(fetchedChapters) {\n equal(fetchedChapters.objectAt(0), chapter, \'Book has a chapter after rollback\');\n });\n });\n});\n\ntest(\"Rollbacking a deleted record restores implicit relationship correctly when the hasMany side has been deleted - sync\", function () {\n var book, chapter;\n run(function() {\n book = env.store.push(\'book\', { id: 1, title: \"Stanley\'s Amazing Adventures\", chapters: [2] });\n chapter = env.store.push(\'chapter\', { id: 2, title: \'Sailing the Seven Seas\' });\n });\n run(function() {\n chapter.deleteRecord();\n chapter.rollback();\n });\n run(function() {\n equal(book.get(\'chapters.firstObject\'), chapter, \"Book has a chapter after rollback\");\n });\n});\n\ntest(\"Rollbacking a deleted record restores implicit relationship correctly when the belongsTo side has been deleted - async\", function () {\n Page.reopen({\n chapter: DS.belongsTo(\'chapter\', { async: true })\n });\n var chapter, page;\n run(function() {\n chapter = env.store.push(\'chapter\', { id: 2, title: \'Sailing the Seven Seas\' });\n page = env.store.push(\'page\', { id: 3, number: 1, chapter: 2 });\n });\n run(function() {\n chapter.deleteRecord();\n chapter.rollback();\n });\n run(function() {\n page.get(\'chapter\').then(function(fetchedChapter) {\n equal(fetchedChapter, chapter, \'Page has a chapter after rollback\');\n });\n });\n});\n\ntest(\"Rollbacking a deleted record restores implicit relationship correctly when the belongsTo side has been deleted - sync\", function () {\n var chapter, page;\n run(function() {\n chapter = env.store.push(\'chapter\', { id: 2, title: \'Sailing the Seven Seas\' });\n page = env.store.push(\'page\', { id: 3, number: 1, chapter: 2 });\n });\n run(function() {\n chapter.deleteRecord();\n chapter.rollback();\n });\n run(function() {\n equal(page.get(\'chapter\'), chapter, \"Page has a chapter after rollback\");\n });\n});\n\ntest(\"ManyArray notifies the array observers and flushes bindings when removing\", function () {\n expect(2);\n var chapter, page, page2;\n var observe = false;\n\n run(function() {\n page = env.store.push(\'page\', { id: 1, number: 1 });\n page2 = env.store.push(\'page\', { id: 2, number: 2 });\n chapter = env.store.push(\'chapter\', { id: 1, title: \'Sailing the Seven Seas\', pages: [1, 2] });\n chapter.get(\'pages\').addEnumerableObserver(this, {\n willChange: function(pages, removing, addCount) {\n if (observe) {\n equal(removing[0], page2, \'page2 is passed to willChange\');\n }\n },\n didChange: function(pages, removeCount, adding) {\n if (observe) {\n equal(removeCount, 1, \'removeCount is correct\');\n }\n }\n });\n });\n run(function() {\n observe = true;\n page2.set(\'chapter\', null);\n observe = false;\n });\n});\n\ntest(\"ManyArray notifies the array observers and flushes bindings when adding\", function () {\n expect(2);\n var chapter, page, page2;\n var observe = false;\n\n run(function() {\n page = env.store.push(\'page\', { id: 1, number: 1 });\n page2 = env.store.push(\'page\', { id: 2, number: 2 });\n chapter = env.store.push(\'chapter\', { id: 1, title: \'Sailing the Seven Seas\', pages: [1] });\n chapter.get(\'pages\').addEnumerableObserver(this, {\n willChange: function(pages, removing, addCount) {\n if (observe) {\n equal(addCount, 1, \'addCount is correct\');\n }\n },\n didChange: function(pages, removeCount, adding) {\n if (observe) {\n equal(adding[0], page2, \'page2 is passed to didChange\');\n }\n }\n });\n });\n run(function() {\n observe = true;\n page2.set(\'chapter\', chapter);\n observe = false;\n });\n});\n\ntest(\"Passing a model as type to hasMany should not work\", function () {\n expect(1);\n\n expectAssertion(function() {\n User = DS.Model.extend();\n\n Contact = DS.Model.extend({\n users: hasMany(User)\n });\n }, /The first argument to DS.hasMany must be a string/);\n});\n\ntest(\"Relationship.clear removes all records correctly\", function() {\n var post;\n\n Comment.reopen({\n post: DS.belongsTo(\'post\')\n });\n\n Post.reopen({\n comments: DS.hasMany(\'comment\', { inverse: \'post\' })\n });\n\n run(function() {\n post = env.store.push(\'post\', { id: 2, title: \'Sailing the Seven Seas\', comments: [1, 2] });\n env.store.pushMany(\'comment\', [\n { id: 1, post: 2 },\n { id: 2, post: 2 },\n { id: 3, post: 2 }\n ]);\n });\n\n run(function() {\n post._relationships[\'comments\'].clear();\n var comments = Ember.A(env.store.all(\'comment\'));\n deepEqual(comments.mapBy(\'post\'), [null, null, null]);\n });\n\n});\n\n\ntest(\'unloading a record with associated records does not prevent the store from tearing down\', function() {\n var post;\n\n Comment.reopen({\n post: DS.belongsTo(\'post\')\n });\n\n Post.reopen({\n comments: DS.hasMany(\'comment\', { inverse: \'post\' })\n });\n\n run(function() {\n post = env.store.push(\'post\', { id: 2, title: \'Sailing the Seven Seas\', comments: [1,2] });\n env.store.pushMany(\'comment\', [\n { id: 1, post: 2 },\n { id: 2, post: 2 }\n ]);\n\n // This line triggers the original bug that gets manifested\n // in teardown for apps, e.g. store.destroy that is caused by\n // App.destroy().\n // Relationship#clear uses Ember.Set#forEach, which does incorrect\n // iteration when the set is being mutated (in our case, the index gets off\n // because records are being removed)\n env.store.unloadRecord(post);\n });\n try {\n run(function() {\n env.store.destroy();\n });\n ok(true, \"store destroyed correctly\");\n } catch (error) {\n ok(false, \"store prevented from being destroyed\");\n }\n});\n\ntest(\"adding and removing records from hasMany relationship #2666\", function() {\n expect(4);\n\n var Post = DS.Model.extend({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n Post.reopenClass({\n FIXTURES: [\n { id: 1, comments: [1, 2, 3] }\n ]\n });\n\n var Comment = DS.Model.extend({\n post: DS.belongsTo(\'post\')\n });\n Comment.reopenClass({\n FIXTURES: [\n { id: 1 },\n { id: 2 },\n { id: 3 }\n ]\n });\n\n env = setupStore({ post: Post, comment: Comment, adapter: DS.FixtureAdapter });\n\n run(function() {\n stop();\n env.store.find(\'post\', 1).then(function (post) {\n var comments = post.get(\'comments\');\n equal(comments.get(\'length\'), 3, \"Initial comments count\");\n\n // Add comment #4\n var comment = env.store.createRecord(\'comment\');\n comments.addObject(comment);\n return comment.save().then(function() {\n var comments = post.get(\'comments\');\n equal(comments.get(\'length\'), 4, \"Comments count after first add\");\n\n // Delete comment #4\n return comments.get(\'lastObject\').destroyRecord();\n }).then(function() {\n var comments = post.get(\'comments\');\n equal(comments.get(\'length\'), 3, \"Comments count after delete\");\n\n // Add another comment #4\n var comment = env.store.createRecord(\'comment\');\n comments.addObject(comment);\n return comment.save();\n }).then(function() {\n var comments = post.get(\'comments\');\n equal(comments.get(\'length\'), 4, \"Comments count after second add\");\n start();\n });\n });\n });\n});\n\ntest(\"hasMany hasData async loaded\", function () {\n expect(1);\n\n Chapter.reopen({\n pages: hasMany(\'pages\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, title: \'The Story Begins\', pages: [2, 3] });\n };\n\n run(function() {\n store.find(\'chapter\', 1).then(function(chapter) {\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n });\n});\n\ntest(\"hasMany hasData sync loaded\", function () {\n expect(1);\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, title: \'The Story Begins\', pages: [2, 3] });\n };\n\n run(function() {\n store.find(\'chapter\', 1).then(function(chapter) {\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n });\n});\n\ntest(\"hasMany hasData async not loaded\", function () {\n expect(1);\n\n Chapter.reopen({\n pages: hasMany(\'pages\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, title: \'The Story Begins\', links: { pages: \'pages\' } });\n };\n\n run(function() {\n store.find(\'chapter\', 1).then(function(chapter) {\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, false, \'relationship does not have data\');\n });\n });\n});\n\ntest(\"hasMany hasData sync not loaded\", function () {\n expect(1);\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, title: \'The Story Begins\' });\n };\n\n run(function() {\n store.find(\'chapter\', 1).then(function(chapter) {\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, false, \'relationship does not have data\');\n });\n });\n});\n\ntest(\"hasMany hasData async created\", function () {\n expect(1);\n\n Chapter.reopen({\n pages: hasMany(\'pages\', { async: true })\n });\n\n run(function() {\n var chapter = store.createRecord(\'chapter\', { title: \'The Story Begins\' });\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n});\n\ntest(\"hasMany hasData sync created\", function () {\n expect(1);\n\n run(function() {\n var chapter = store.createRecord(\'chapter\', { title: \'The Story Begins\' });\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n});\n})();//# sourceURL=ember-data/integration/relationships/has-many-test.js");
347
+ eval("(function() {var env, store, User, Contact, Email, Phone, Message, Post, Comment;\nvar Book, Chapter, Page;\nvar get = Ember.get;\nvar resolve = Ember.RSVP.resolve;\nvar run = Ember.run;\n\nvar attr = DS.attr;\nvar hasMany = DS.hasMany;\nvar belongsTo = DS.belongsTo;\n\nfunction stringify(string) {\n return function() { return string; };\n}\n\nmodule(\"integration/relationships/has_many - Has-Many Relationships\", {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n messages: hasMany(\'message\', { polymorphic: true }),\n contacts: hasMany(\'user\', { inverse: null })\n });\n\n Contact = DS.Model.extend({\n user: belongsTo(\'user\')\n });\n\n Email = Contact.extend({\n email: attr(\'string\')\n });\n\n Phone = Contact.extend({\n number: attr(\'string\')\n });\n\n Message = DS.Model.extend({\n user: belongsTo(\'user\'),\n created_at: attr(\'date\')\n });\n Message.toString = stringify(\'Message\');\n\n Post = Message.extend({\n title: attr(\'string\'),\n comments: hasMany(\'comment\')\n });\n Post.toString = stringify(\'Post\');\n\n Comment = Message.extend({\n body: DS.attr(\'string\'),\n message: DS.belongsTo(\'post\', { polymorphic: true })\n });\n Comment.toString = stringify(\'Comment\');\n\n Book = DS.Model.extend({\n title: attr(),\n chapters: hasMany(\'chapter\', { async: true })\n });\n Book.toString = stringify(\'Book\');\n\n Chapter = DS.Model.extend({\n title: attr(),\n pages: hasMany(\'page\')\n });\n Chapter.toString = stringify(\'Chapter\');\n\n Page = DS.Model.extend({\n number: attr(\'number\'),\n chapter: belongsTo(\'chapter\')\n });\n Page.toString = stringify(\'Page\');\n\n env = setupStore({\n user: User,\n contact: Contact,\n email: Email,\n phone: Phone,\n post: Post,\n comment: Comment,\n message: Message,\n book: Book,\n chapter: Chapter,\n page: Page\n });\n\n store = env.store;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"When a hasMany relationship is accessed, the adapter\'s findMany method should not be called if all the records in the relationship are already loaded\", function() {\n expect(0);\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n ok(false, \"The adapter\'s find method should not be called\");\n };\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [1] });\n env.store.push(\'comment\', { id: 1 });\n env.store.find(\'post\', 1).then(function(post) {\n return post.get(\'comments\');\n });\n });\n});\n\ntest(\"adapter.findMany only gets unique IDs even if duplicate IDs are present in the hasMany relationship\", function() {\n expect(2);\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n equal(type, Chapter, \'type passed to adapter.findMany is correct\');\n deepEqual(ids, [\'2\', \'3\'], \'ids passed to adapter.findMany are unique\');\n\n return Ember.RSVP.resolve([\n { id: 2, title: \'Chapter One\' },\n { id: 3, title: \'Chapter Two\' }\n ]);\n };\n\n run(function() {\n env.store.push(\'book\', { id: 1, chapters: [2, 3, 3] });\n env.store.find(\'book\', 1).then(function(book) {\n return book.get(\'chapters\');\n });\n });\n});\n\n// This tests the case where a serializer materializes a has-many\n// relationship as a reference that it can fetch lazily. The most\n// common use case of this is to provide a URL to a collection that\n// is loaded later.\ntest(\"A serializer can materialize a hasMany as an opaque token that can be lazily fetched via the adapter\'s findHasMany hook\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n // When the store asks the adapter for the record with ID 1,\n // provide some fake data.\n env.adapter.find = function(store, type, id, snapshot) {\n equal(type, Post, \"find type was Post\");\n equal(id, \"1\", \"find id was 1\");\n\n return Ember.RSVP.resolve({ id: 1, links: { comments: \"/posts/1/comments\" } });\n };\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n throw new Error(\"Adapter\'s findMany should not be called\");\n };\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n equal(link, \"/posts/1/comments\", \"findHasMany link was /posts/1/comments\");\n equal(relationship.type.modelName, \"comment\", \"relationship was passed correctly\");\n\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n run(function() {\n env.store.find(\'post\', 1).then(async(function(post) {\n return post.get(\'comments\');\n })).then(async(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n equal(comments.objectAt(0).get(\'body\'), \'First\', \"comment loaded successfully\");\n }));\n });\n});\n\ntest(\"Accessing a hasMany backed by a link multiple times triggers only one request\", function() {\n expect(2);\n var count = 0;\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n Comment.reopen({\n message: DS.belongsTo(\'post\', { async: true })\n });\n var post;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, links: { comments: \'/posts/1/comments\' } });\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n start();\n count++;\n equal(count, 1, \"findHasMany has only been called once\");\n stop();\n return new Ember.RSVP.Promise(function(resolve, reject) {\n setTimeout(function() {\n var value = [\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ];\n resolve(value);\n }, 100);\n });\n };\n\n stop();\n var promise1, promise2;\n run(function() {\n promise1 = post.get(\'comments\');\n //Invalidate the post.comments CP\n env.store.push(\'comment\', { id: 1, message: 1 });\n promise2 = post.get(\'comments\');\n });\n Ember.RSVP.all([promise1, promise2]).then(function() {\n start();\n });\n equal(promise1.promise, promise2.promise, \"Same promise is returned both times\");\n});\n\ntest(\"A hasMany backed by a link remains a promise after a record has been added to it\", function() {\n expect(1);\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n Comment.reopen({\n message: DS.belongsTo(\'post\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n var post;\n run(function() {\n post = env.store.push(\'post\', { id: 1, links: { comments: \'/posts/1/comments\' } });\n });\n\n run(function() {\n post.get(\'comments\').then(function() {\n env.store.push(\'comment\', { id: 3, message: 1 });\n post.get(\'comments\').then(function() {\n ok(true, \'Promise was called\');\n });\n });\n });\n});\n\ntest(\"A hasMany updated link should not remove new children\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n Comment.reopen({\n message: DS.belongsTo(\'post\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([]);\n };\n\n env.adapter.createRecord = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve({\n links: {\n comments: \'/some/link\'\n }\n });\n };\n\n run(function() {\n var post = env.store.createRecord(\'post\', {});\n env.store.createRecord(\'comment\', { message: post });\n\n post.get(\'comments\')\n .then(function(comments) {\n equal(comments.get(\'length\'), 1);\n\n return post.save();\n })\n .then(function() {\n return post.get(\'comments\');\n })\n .then(function(comments) {\n equal(comments.get(\'length\'), 1);\n });\n });\n});\n\ntest(\"A hasMany updated link should not remove new children when the parent record has children already\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n Comment.reopen({\n message: DS.belongsTo(\'post\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([{ id: 5, body: \'hello\' }]);\n };\n\n env.adapter.createRecord = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve({\n links: {\n comments: \'/some/link\'\n }\n });\n };\n\n run(function() {\n var post = env.store.createRecord(\'post\', {});\n env.store.createRecord(\'comment\', { message: post });\n\n post.get(\'comments\')\n .then(function(comments) {\n equal(comments.get(\'length\'), 1);\n\n return post.save();\n })\n .then(function() {\n return post.get(\'comments\');\n })\n .then(function(comments) {\n equal(comments.get(\'length\'), 2);\n });\n });\n});\n\n\ntest(\"A hasMany relationship can be reloaded if it was fetched via a link\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n equal(type, Post, \"find type was Post\");\n equal(id, \"1\", \"find id was 1\");\n\n return Ember.RSVP.resolve({ id: 1, links: { comments: \"/posts/1/comments\" } });\n };\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n equal(relationship.type, Comment, \"findHasMany relationship type was Comment\");\n equal(relationship.key, \'comments\', \"findHasMany relationship key was comments\");\n equal(link, \"/posts/1/comments\", \"findHasMany link was /posts/1/comments\");\n\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n run(function() {\n run(env.store, \'find\', \'post\', 1).then(function(post) {\n return post.get(\'comments\');\n }).then(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n equal(relationship.type, Comment, \"findHasMany relationship type was Comment\");\n equal(relationship.key, \'comments\', \"findHasMany relationship key was comments\");\n equal(link, \"/posts/1/comments\", \"findHasMany link was /posts/1/comments\");\n\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" },\n { id: 3, body: \"Thirds\" }\n ]);\n };\n\n return comments.reload();\n }).then(function(newComments) {\n equal(newComments.get(\'length\'), 3, \"reloaded comments have 3 length\");\n });\n });\n});\n\ntest(\"A sync hasMany relationship can be reloaded if it was fetched via ids\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\')\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n equal(type, Post, \"find type was Post\");\n equal(id, \"1\", \"find id was 1\");\n\n return Ember.RSVP.resolve({ id: 1, comments: [1, 2] });\n };\n\n run(function() {\n env.store.pushMany(\'comment\', [{ id: 1, body: \"First\" }, { id: 2, body: \"Second\" }]);\n\n env.store.find(\'post\', \'1\').then(function(post) {\n var comments = post.get(\'comments\');\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have a length of 2\");\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"FirstUpdated\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n return comments.reload();\n }).then(function(newComments) {\n equal(newComments.get(\'firstObject.body\'), \'FirstUpdated\', \"Record body was correctly updated\");\n });\n });\n});\n\ntest(\"A hasMany relationship can be reloaded if it was fetched via ids\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n equal(type, Post, \"find type was Post\");\n equal(id, \"1\", \"find id was 1\");\n\n return Ember.RSVP.resolve({ id: 1, comments: [1,2] });\n };\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n run(function() {\n env.store.find(\'post\', 1).then(function(post) {\n return post.get(\'comments\');\n }).then(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"FirstUpdated\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n return comments.reload();\n }).then(function(newComments) {\n equal(newComments.get(\'firstObject.body\'), \'FirstUpdated\', \"Record body was correctly updated\");\n });\n });\n});\n\ntest(\"A hasMany relationship can be directly reloaded if it was fetched via ids\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n equal(type, Post, \"find type was Post\");\n equal(id, \"1\", \"find id was 1\");\n\n return Ember.RSVP.resolve({ id: 1, comments: [1,2] });\n };\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"FirstUpdated\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n\n run(function() {\n env.store.find(\'post\', 1).then(function(post) {\n return post.get(\'comments\').reload().then(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n equal(comments.get(\'firstObject.body\'), \"FirstUpdated\", \"Record body was correctly updated\");\n });\n });\n });\n});\n\ntest(\"PromiseArray proxies createRecord to its ManyArray once the hasMany is loaded\", function() {\n expect(4);\n\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n var post;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, links: { comments: \'someLink\' } });\n });\n\n run(function() {\n post.get(\'comments\').then(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n\n var newComment = post.get(\'comments\').createRecord({ body: \'Third\' });\n equal(newComment.get(\'body\'), \'Third\', \"new comment is returned\");\n equal(comments.get(\'length\'), 3, \"comments have 3 length, including new record\");\n });\n });\n});\n\ntest(\"PromiseArray proxies evented methods to its ManyArray\", function() {\n expect(6);\n\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n };\n var post, comments;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, links: { comments: \'someLink\' } });\n comments = post.get(\'comments\');\n });\n\n\n comments.on(\'on-event\', function() {\n ok(true);\n });\n\n run(function() {\n comments.trigger(\'on-event\');\n });\n\n equal(comments.has(\'on-event\'), true);\n\n comments.on(\'off-event\', function() {\n ok(false);\n });\n\n comments.off(\'off-event\');\n\n equal(comments.has(\'off-event\'), false);\n\n comments.one(\'one-event\', function() {\n ok(true);\n });\n\n equal(comments.has(\'one-event\'), true);\n\n run(function() {\n comments.trigger(\'one-event\');\n });\n\n equal(comments.has(\'one-event\'), false);\n});\n\ntest(\"An updated `links` value should invalidate a relationship cache\", function() {\n expect(8);\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n equal(relationship.type.modelName, \"comment\", \"relationship was passed correctly\");\n\n if (link === \'/first\') {\n return Ember.RSVP.resolve([\n { id: 1, body: \"First\" },\n { id: 2, body: \"Second\" }\n ]);\n } else if (link === \'/second\') {\n return Ember.RSVP.resolve([\n { id: 3, body: \"Third\" },\n { id: 4, body: \"Fourth\" },\n { id: 5, body: \"Fifth\" }\n ]);\n }\n };\n var post;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, links: { comments: \'/first\' } });\n });\n\n run(function() {\n post.get(\'comments\').then(function(comments) {\n equal(comments.get(\'isLoaded\'), true, \"comments are loaded\");\n equal(comments.get(\'length\'), 2, \"comments have 2 length\");\n equal(comments.objectAt(0).get(\'body\'), \'First\', \"comment 1 successfully loaded\");\n env.store.push(\'post\', { id: 1, links: { comments: \'/second\' } });\n post.get(\'comments\').then(function(newComments) {\n equal(comments, newComments, \"hasMany array was kept the same\");\n equal(newComments.get(\'length\'), 3, \"comments updated successfully\");\n equal(newComments.objectAt(0).get(\'body\'), \'Third\', \"third comment loaded successfully\");\n });\n });\n });\n});\n\ntest(\"When a polymorphic hasMany relationship is accessed, the adapter\'s findMany method should not be called if all the records in the relationship are already loaded\", function() {\n expect(1);\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n ok(false, \"The adapter\'s find method should not be called\");\n };\n\n run(function() {\n env.store.push(\'user\', { id: 1, messages: [{ id: 1, type: \'post\' }, { id: 3, type: \'comment\' }] });\n env.store.push(\'post\', { id: 1 });\n env.store.push(\'comment\', { id: 3 });\n });\n\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n var messages = user.get(\'messages\');\n equal(messages.get(\'length\'), 2, \"The messages are correctly loaded\");\n });\n });\n});\n\ntest(\"When a polymorphic hasMany relationship is accessed, the store can call multiple adapters\' findMany or find methods if the records are not loaded\", function() {\n User.reopen({\n messages: hasMany(\'message\', { polymorphic: true, async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n if (type === Post) {\n return Ember.RSVP.resolve({ id: 1 });\n } else if (type === Comment) {\n return Ember.RSVP.resolve({ id: 3 });\n }\n };\n\n run(function() {\n env.store.push(\'user\', { id: 1, messages: [{ id: 1, type: \'post\' }, { id: 3, type: \'comment\' }] });\n });\n\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n return user.get(\'messages\');\n }).then(function(messages) {\n equal(messages.get(\'length\'), 2, \"The messages are correctly loaded\");\n });\n });\n});\n\ntest(\"polymorphic hasMany type-checks check the superclass when MODEL_FACTORY_INJECTIONS is enabled\", function() {\n expect(1);\n\n var injectionValue = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n try {\n run(function () {\n var igor = env.store.createRecord(\'user\', { name: \'Igor\' });\n var comment = env.store.createRecord(\'comment\', { body: \"Well I thought the title was fine\" });\n\n igor.get(\'messages\').addObject(comment);\n\n equal(igor.get(\'messages.firstObject.body\'), \"Well I thought the title was fine\");\n });\n } finally {\n Ember.MODEL_FACTORY_INJECTIONS = injectionValue;\n }\n});\n\n\n\ntest(\"Type can be inferred from the key of a hasMany relationship\", function() {\n expect(1);\n run(function() {\n env.store.push(\'user\', { id: 1, contacts: [1] });\n env.store.push(\'contact\', { id: 1 });\n });\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n return user.get(\'contacts\');\n }).then(function(contacts) {\n equal(contacts.get(\'length\'), 1, \"The contacts relationship is correctly set up\");\n });\n });\n});\n\ntest(\"Type can be inferred from the key of an async hasMany relationship\", function() {\n User.reopen({\n contacts: DS.hasMany({ async: true })\n });\n\n expect(1);\n run(function() {\n env.store.push(\'user\', { id: 1, contacts: [1] });\n env.store.push(\'contact\', { id: 1 });\n });\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n return user.get(\'contacts\');\n }).then(function(contacts) {\n equal(contacts.get(\'length\'), 1, \"The contacts relationship is correctly set up\");\n });\n });\n});\n\ntest(\"Polymorphic relationships work with a hasMany whose type is inferred\", function() {\n User.reopen({\n contacts: DS.hasMany({ polymorphic: true })\n });\n\n expect(1);\n run(function() {\n env.store.push(\'user\', { id: 1, contacts: [{ id: 1, type: \'email\' }, { id: 2, type: \'phone\' }] });\n env.store.push(\'email\', { id: 1 });\n env.store.push(\'phone\', { id: 2 });\n });\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n return user.get(\'contacts\');\n }).then(function(contacts) {\n equal(contacts.get(\'length\'), 2, \"The contacts relationship is correctly set up\");\n });\n });\n});\n\ntest(\"Polymorphic relationships with a hasMany is set up correctly on both sides\", function() {\n expect(2);\n\n Contact.reopen({\n posts: DS.hasMany(\'post\')\n });\n\n Post.reopen({\n contact: DS.belongsTo(\'contact\', { polymorphic: true })\n });\n var email, post;\n\n run(function () {\n email = env.store.createRecord(\'email\');\n post = env.store.createRecord(\'post\', {\n contact: email\n });\n });\n\n equal(post.get(\'contact\'), email, \'The polymorphic belongsTo is set up correctly\');\n equal(get(email, \'posts.length\'), 1, \"The inverse has many is set up correctly on the email side.\");\n});\n\ntest(\"A record can\'t be created from a polymorphic hasMany relationship\", function() {\n run(function() {\n env.store.push(\'user\', { id: 1, messages: [] });\n });\n\n run(function() {\n env.store.find(\'user\', 1).then(function(user) {\n return user.get(\'messages\');\n }).then(function(messages) {\n expectAssertion(function() {\n messages.createRecord();\n }, /You cannot add \'message\' records to this polymorphic relationship/);\n });\n });\n});\n\ntest(\"Only records of the same type can be added to a monomorphic hasMany relationship\", function() {\n expect(1);\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [] });\n env.store.push(\'post\', { id: 2 });\n });\n\n run(function() {\n Ember.RSVP.all([\n env.store.find(\'post\', 1),\n env.store.find(\'post\', 2)\n ]).then(function(records) {\n expectAssertion(function() {\n records[0].get(\'comments\').pushObject(records[1]);\n }, /You cannot add \'post\' records to the post.comments relationship \\(only \'comment\' allowed\\)/);\n });\n });\n});\n\ntest(\"Only records of the same base type can be added to a polymorphic hasMany relationship\", function() {\n expect(2);\n run(function() {\n env.store.push(\'user\', { id: 1, messages: [] });\n env.store.push(\'user\', { id: 2, messages: [] });\n env.store.push(\'post\', { id: 1, comments: [] });\n env.store.push(\'comment\', { id: 3 });\n });\n var asyncRecords;\n\n run(function() {\n asyncRecords = Ember.RSVP.hash({\n user: env.store.find(\'user\', 1),\n anotherUser: env.store.find(\'user\', 2),\n post: env.store.find(\'post\', 1),\n comment: env.store.find(\'comment\', 3)\n });\n\n asyncRecords.then(function(records) {\n records.messages = records.user.get(\'messages\');\n return Ember.RSVP.hash(records);\n }).then(function(records) {\n records.messages.pushObject(records.post);\n records.messages.pushObject(records.comment);\n equal(records.messages.get(\'length\'), 2, \"The messages are correctly added\");\n\n expectAssertion(function() {\n records.messages.pushObject(records.anotherUser);\n }, /You cannot add \'user\' records to the user.messages relationship \\(only \'message\' allowed\\)/);\n });\n });\n});\n\ntest(\"A record can be removed from a polymorphic association\", function() {\n expect(4);\n\n run(function() {\n env.store.push(\'user\', { id: 1 , messages: [{ id: 3, type: \'comment\' }] });\n env.store.push(\'comment\', { id: 3 });\n });\n var asyncRecords;\n\n run(function() {\n asyncRecords = Ember.RSVP.hash({\n user: env.store.find(\'user\', 1),\n comment: env.store.find(\'comment\', 3)\n });\n\n asyncRecords.then(function(records) {\n records.messages = records.user.get(\'messages\');\n return Ember.RSVP.hash(records);\n }).then(function(records) {\n equal(records.messages.get(\'length\'), 1, \"The user has 1 message\");\n\n var removedObject = records.messages.popObject();\n\n equal(removedObject, records.comment, \"The message is correctly removed\");\n equal(records.messages.get(\'length\'), 0, \"The user does not have any messages\");\n equal(records.messages.objectAt(0), null, \"No messages can\'t be fetched\");\n });\n });\n});\n\ntest(\"When a record is created on the client, its hasMany arrays should be in a loaded state\", function() {\n expect(3);\n\n var post;\n\n run(function() {\n post = env.store.createRecord(\'post\');\n });\n\n ok(get(post, \'isLoaded\'), \"The post should have isLoaded flag\");\n var comments;\n run(function() {\n comments = get(post, \'comments\');\n });\n\n equal(get(comments, \'length\'), 0, \"The comments should be an empty array\");\n\n ok(get(comments, \'isLoaded\'), \"The comments should have isLoaded flag\");\n});\n\ntest(\"When a record is created on the client, its async hasMany arrays should be in a loaded state\", function() {\n expect(4);\n\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n var post = run(function() {\n return env.store.createRecord(\'post\');\n });\n\n ok(get(post, \'isLoaded\'), \"The post should have isLoaded flag\");\n\n run(function() {\n get(post, \'comments\').then(function(comments) {\n ok(true, \"Comments array successfully resolves\");\n equal(get(comments, \'length\'), 0, \"The comments should be an empty array\");\n ok(get(comments, \'isLoaded\'), \"The comments should have isLoaded flag\");\n });\n });\n});\n\ntest(\"we can set records SYNC HM relationship\", function() {\n expect(1);\n var post = run(function() {\n return env.store.createRecord(\'post\');\n });\n run(function() {\n post.set(\'comments\', env.store.pushMany(\'comment\', [{ id: 1, body: \"First\" }, { id: 2, body: \"Second\" }]));\n });\n equal(get(post, \'comments.length\'), 2, \"we can set HM relationship\");\n});\n\n\ntest(\"We can set records ASYNC HM relationship\", function() {\n expect(1);\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n var post = run(function() {\n return env.store.createRecord(\'post\');\n });\n run(function() {\n post.set(\'comments\', env.store.pushMany(\'comment\', [{ id: 1, body: \"First\" }, { id: 2, body: \"Second\" }]));\n });\n\n post.get(\'comments\').then(async(function(comments) {\n equal(comments.get(\'length\') , 2, \"we can set async HM relationship\");\n }));\n});\n\ntest(\"When a record is saved, its unsaved hasMany records should be kept\", function () {\n expect(1);\n\n var post, comment;\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.resolve({ id: 1 });\n };\n\n run(function () {\n post = env.store.createRecord(\'post\');\n comment = env.store.createRecord(\'comment\');\n post.get(\'comments\').pushObject(comment);\n post.save();\n });\n\n equal(get(post, \'comments.length\'), 1, \"The unsaved comment should be in the post\'s comments array\");\n});\n\ntest(\"dual non-async HM <-> BT\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { inverse: \'post\' })\n });\n\n Comment.reopen({\n post: DS.belongsTo(\'post\')\n });\n\n env.adapter.createRecord = function(store, type, snapshot) {\n var data = snapshot.record.serialize();\n data.id = 2;\n return Ember.RSVP.resolve(data);\n };\n var post, firstComment;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, comments: [1] });\n firstComment = env.store.push(\'comment\', { id: 1, post: 1 });\n\n env.store.createRecord(\'comment\', {\n post: post\n }).save().then(function(comment) {\n var commentPost = comment.get(\'post\');\n var postComments = comment.get(\'post.comments\');\n var postCommentsLength = comment.get(\'post.comments.length\');\n\n deepEqual(post, commentPost, \'expect the new comments post, to be the correct post\');\n ok(postComments, \"comments should exist\");\n equal(postCommentsLength, 2, \"comment\'s post should have a reference back to comment\");\n ok(postComments && postComments.indexOf(firstComment) !== -1, \'expect to contain first comment\');\n ok(postComments && postComments.indexOf(comment) !== -1, \'expected to contain the new comment\');\n });\n });\n});\n\ntest(\"When an unloaded record is added to the hasMany, it gets fetched once the hasMany is accessed even if the hasMany has been already fetched\", function() {\n Post.reopen({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n\n env.adapter.findMany = function(store, type, ids, snapshots) {\n return resolve([{ id: 1, body: \'first\' }, { id: 2, body: \'second\' }]);\n };\n\n env.adapter.find = function(store, type, id, snapshot) {\n return resolve({ id: 3, body: \'third\' });\n };\n var post;\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, comments: [1, 2] });\n });\n\n run(function() {\n post.get(\'comments\').then(async(function(fetchedComments) {\n equal(fetchedComments.get(\'length\'), 2, \'comments fetched successfully\');\n equal(fetchedComments.objectAt(0).get(\'body\'), \'first\', \'first comment loaded successfully\');\n env.store.push(\'post\', { id: 1, comments: [1, 2, 3] });\n post.get(\'comments\').then(async(function(newlyFetchedComments) {\n equal(newlyFetchedComments.get(\'length\'), 3, \'all three comments fetched successfully\');\n equal(newlyFetchedComments.objectAt(2).get(\'body\'), \'third\', \'third comment loaded successfully\');\n }));\n }));\n });\n});\n\ntest(\"A sync hasMany errors out if there are unlaoded records in it\", function() {\n var post;\n run(function() {\n post = env.store.push(\'post\', { id: 1, comments: [1, 2] });\n });\n\n expectAssertion(function() {\n run(post, \'get\', \'comments\');\n }, /You looked up the \'comments\' relationship on a \'post\' with id 1 but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async \\(`DS.hasMany\\({ async: true }\\)`\\)/);\n});\n\ntest(\"If reordered hasMany data has been pushed to the store, the many array reflects the ordering change - sync\", function() {\n var comment1, comment2, comment3, comment4;\n var post;\n run(function() {\n comment1 = env.store.push(\'comment\', { id: 1 });\n comment2 = env.store.push(\'comment\', { id: 2 });\n comment3 = env.store.push(\'comment\', { id: 3 });\n comment4 = env.store.push(\'comment\', { id: 4 });\n });\n\n run(function() {\n post = env.store.push(\'post\', { id: 1, comments: [1, 2] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment1, comment2], \'Initial ordering is correct\');\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [2, 1] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment2, comment1], \'Updated ordering is correct\');\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [2] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment2], \'Updated ordering is correct\');\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [1,2,3,4] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment1, comment2, comment3, comment4], \'Updated ordering is correct\');\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [4,3] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment4, comment3], \'Updated ordering is correct\');\n\n run(function() {\n env.store.push(\'post\', { id: 1, comments: [4,2,3,1] });\n });\n deepEqual(post.get(\'comments\').toArray(), [comment4, comment2, comment3, comment1], \'Updated ordering is correct\');\n});\n\ntest(\"Rollbacking a deleted record restores implicit relationship correctly when the hasMany side has been deleted - async\", function () {\n var book, chapter;\n run(function() {\n book = env.store.push(\'book\', { id: 1, title: \"Stanley\'s Amazing Adventures\", chapters: [2] });\n chapter = env.store.push(\'chapter\', { id: 2, title: \'Sailing the Seven Seas\' });\n });\n run(function() {\n chapter.deleteRecord();\n chapter.rollback();\n });\n run(function() {\n book.get(\'chapters\').then(function(fetchedChapters) {\n equal(fetchedChapters.objectAt(0), chapter, \'Book has a chapter after rollback\');\n });\n });\n});\n\ntest(\"Rollbacking a deleted record restores implicit relationship correctly when the hasMany side has been deleted - sync\", function () {\n var book, chapter;\n run(function() {\n book = env.store.push(\'book\', { id: 1, title: \"Stanley\'s Amazing Adventures\", chapters: [2] });\n chapter = env.store.push(\'chapter\', { id: 2, title: \'Sailing the Seven Seas\' });\n });\n run(function() {\n chapter.deleteRecord();\n chapter.rollback();\n });\n run(function() {\n equal(book.get(\'chapters.firstObject\'), chapter, \"Book has a chapter after rollback\");\n });\n});\n\ntest(\"Rollbacking a deleted record restores implicit relationship correctly when the belongsTo side has been deleted - async\", function () {\n Page.reopen({\n chapter: DS.belongsTo(\'chapter\', { async: true })\n });\n var chapter, page;\n run(function() {\n chapter = env.store.push(\'chapter\', { id: 2, title: \'Sailing the Seven Seas\' });\n page = env.store.push(\'page\', { id: 3, number: 1, chapter: 2 });\n });\n run(function() {\n chapter.deleteRecord();\n chapter.rollback();\n });\n run(function() {\n page.get(\'chapter\').then(function(fetchedChapter) {\n equal(fetchedChapter, chapter, \'Page has a chapter after rollback\');\n });\n });\n});\n\ntest(\"Rollbacking a deleted record restores implicit relationship correctly when the belongsTo side has been deleted - sync\", function () {\n var chapter, page;\n run(function() {\n chapter = env.store.push(\'chapter\', { id: 2, title: \'Sailing the Seven Seas\' });\n page = env.store.push(\'page\', { id: 3, number: 1, chapter: 2 });\n });\n run(function() {\n chapter.deleteRecord();\n chapter.rollback();\n });\n run(function() {\n equal(page.get(\'chapter\'), chapter, \"Page has a chapter after rollback\");\n });\n});\n\ntest(\"ManyArray notifies the array observers and flushes bindings when removing\", function () {\n expect(2);\n var chapter, page, page2;\n var observe = false;\n\n run(function() {\n page = env.store.push(\'page\', { id: 1, number: 1 });\n page2 = env.store.push(\'page\', { id: 2, number: 2 });\n chapter = env.store.push(\'chapter\', { id: 1, title: \'Sailing the Seven Seas\', pages: [1, 2] });\n chapter.get(\'pages\').addEnumerableObserver(this, {\n willChange: function(pages, removing, addCount) {\n if (observe) {\n equal(removing[0], page2, \'page2 is passed to willChange\');\n }\n },\n didChange: function(pages, removeCount, adding) {\n if (observe) {\n equal(removeCount, 1, \'removeCount is correct\');\n }\n }\n });\n });\n run(function() {\n observe = true;\n page2.set(\'chapter\', null);\n observe = false;\n });\n});\n\ntest(\"ManyArray notifies the array observers and flushes bindings when adding\", function () {\n expect(2);\n var chapter, page, page2;\n var observe = false;\n\n run(function() {\n page = env.store.push(\'page\', { id: 1, number: 1 });\n page2 = env.store.push(\'page\', { id: 2, number: 2 });\n chapter = env.store.push(\'chapter\', { id: 1, title: \'Sailing the Seven Seas\', pages: [1] });\n chapter.get(\'pages\').addEnumerableObserver(this, {\n willChange: function(pages, removing, addCount) {\n if (observe) {\n equal(addCount, 1, \'addCount is correct\');\n }\n },\n didChange: function(pages, removeCount, adding) {\n if (observe) {\n equal(adding[0], page2, \'page2 is passed to didChange\');\n }\n }\n });\n });\n run(function() {\n observe = true;\n page2.set(\'chapter\', chapter);\n observe = false;\n });\n});\n\ntest(\"Passing a model as type to hasMany should not work\", function () {\n expect(1);\n\n expectAssertion(function() {\n User = DS.Model.extend();\n\n Contact = DS.Model.extend({\n users: hasMany(User)\n });\n }, /The first argument to DS.hasMany must be a string/);\n});\n\ntest(\"Relationship.clear removes all records correctly\", function() {\n var post;\n\n Comment.reopen({\n post: DS.belongsTo(\'post\')\n });\n\n Post.reopen({\n comments: DS.hasMany(\'comment\', { inverse: \'post\' })\n });\n\n run(function() {\n post = env.store.push(\'post\', { id: 2, title: \'Sailing the Seven Seas\', comments: [1, 2] });\n env.store.pushMany(\'comment\', [\n { id: 1, post: 2 },\n { id: 2, post: 2 },\n { id: 3, post: 2 }\n ]);\n });\n\n run(function() {\n post._relationships[\'comments\'].clear();\n var comments = Ember.A(env.store.all(\'comment\'));\n deepEqual(comments.mapBy(\'post\'), [null, null, null]);\n });\n\n});\n\n\ntest(\'unloading a record with associated records does not prevent the store from tearing down\', function() {\n var post;\n\n Comment.reopen({\n post: DS.belongsTo(\'post\')\n });\n\n Post.reopen({\n comments: DS.hasMany(\'comment\', { inverse: \'post\' })\n });\n\n run(function() {\n post = env.store.push(\'post\', { id: 2, title: \'Sailing the Seven Seas\', comments: [1,2] });\n env.store.pushMany(\'comment\', [\n { id: 1, post: 2 },\n { id: 2, post: 2 }\n ]);\n\n // This line triggers the original bug that gets manifested\n // in teardown for apps, e.g. store.destroy that is caused by\n // App.destroy().\n // Relationship#clear uses Ember.Set#forEach, which does incorrect\n // iteration when the set is being mutated (in our case, the index gets off\n // because records are being removed)\n env.store.unloadRecord(post);\n });\n try {\n run(function() {\n env.store.destroy();\n });\n ok(true, \"store destroyed correctly\");\n } catch (error) {\n ok(false, \"store prevented from being destroyed\");\n }\n});\n\ntest(\"adding and removing records from hasMany relationship #2666\", function() {\n expect(4);\n\n var Post = DS.Model.extend({\n comments: DS.hasMany(\'comment\', { async: true })\n });\n Post.reopenClass({\n FIXTURES: [\n { id: 1, comments: [1, 2, 3] }\n ]\n });\n\n var Comment = DS.Model.extend({\n post: DS.belongsTo(\'post\')\n });\n Comment.reopenClass({\n FIXTURES: [\n { id: 1 },\n { id: 2 },\n { id: 3 }\n ]\n });\n\n env = setupStore({ post: Post, comment: Comment, adapter: DS.FixtureAdapter });\n\n run(function() {\n stop();\n env.store.find(\'post\', 1).then(function (post) {\n var comments = post.get(\'comments\');\n equal(comments.get(\'length\'), 3, \"Initial comments count\");\n\n // Add comment #4\n var comment = env.store.createRecord(\'comment\');\n comments.addObject(comment);\n return comment.save().then(function() {\n var comments = post.get(\'comments\');\n equal(comments.get(\'length\'), 4, \"Comments count after first add\");\n\n // Delete comment #4\n return comments.get(\'lastObject\').destroyRecord();\n }).then(function() {\n var comments = post.get(\'comments\');\n equal(comments.get(\'length\'), 3, \"Comments count after delete\");\n\n // Add another comment #4\n var comment = env.store.createRecord(\'comment\');\n comments.addObject(comment);\n return comment.save();\n }).then(function() {\n var comments = post.get(\'comments\');\n equal(comments.get(\'length\'), 4, \"Comments count after second add\");\n start();\n });\n });\n });\n});\n\ntest(\"hasMany hasData async loaded\", function () {\n expect(1);\n\n Chapter.reopen({\n pages: hasMany(\'pages\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, title: \'The Story Begins\', pages: [2, 3] });\n };\n\n run(function() {\n store.find(\'chapter\', 1).then(function(chapter) {\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n });\n});\n\ntest(\"hasMany hasData sync loaded\", function () {\n expect(1);\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, title: \'The Story Begins\', pages: [2, 3] });\n };\n\n run(function() {\n store.find(\'chapter\', 1).then(function(chapter) {\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n });\n});\n\ntest(\"hasMany hasData async not loaded\", function () {\n expect(1);\n\n Chapter.reopen({\n pages: hasMany(\'pages\', { async: true })\n });\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, title: \'The Story Begins\', links: { pages: \'pages\' } });\n };\n\n run(function() {\n store.find(\'chapter\', 1).then(function(chapter) {\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, false, \'relationship does not have data\');\n });\n });\n});\n\ntest(\"hasMany hasData sync not loaded\", function () {\n expect(1);\n\n env.adapter.find = function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, title: \'The Story Begins\' });\n };\n\n run(function() {\n store.find(\'chapter\', 1).then(function(chapter) {\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, false, \'relationship does not have data\');\n });\n });\n});\n\ntest(\"hasMany hasData async created\", function () {\n expect(1);\n\n Chapter.reopen({\n pages: hasMany(\'pages\', { async: true })\n });\n\n run(function() {\n var chapter = store.createRecord(\'chapter\', { title: \'The Story Begins\' });\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n});\n\ntest(\"hasMany hasData sync created\", function () {\n expect(1);\n\n run(function() {\n var chapter = store.createRecord(\'chapter\', { title: \'The Story Begins\' });\n var relationship = chapter._relationships[\'pages\'];\n equal(relationship.hasData, true, \'relationship has data\');\n });\n});\n})();//# sourceURL=ember-data/integration/relationships/has-many-test.js");
332
348
 
333
349
  eval("(function() {var Post, Comment, Message, User;\nvar run = Ember.run;\n\nmodule(\'integration/relationships/inverse_relationships - Inverse Relationships\');\n\ntest(\"When a record is added to a has-many relationship, the inverse belongsTo is determined automatically\", function() {\n Post = DS.Model.extend({\n comments: DS.hasMany(\'comment\')\n });\n\n Comment = DS.Model.extend({\n post: DS.belongsTo(\'post\')\n });\n\n var env = setupStore({ post: Post, comment: Comment });\n var store = env.store;\n var comment, post;\n\n run(function() {\n comment = store.createRecord(\'comment\');\n post = store.createRecord(\'post\');\n });\n\n equal(comment.get(\'post\'), null, \"no post has been set on the comment\");\n\n run(function() {\n post.get(\'comments\').pushObject(comment);\n });\n equal(comment.get(\'post\'), post, \"post was set on the comment\");\n});\n\ntest(\"Inverse relationships can be explicitly nullable\", function () {\n User = DS.Model.extend();\n\n Post = DS.Model.extend({\n lastParticipant: DS.belongsTo(\'user\', { inverse: null }),\n participants: DS.hasMany(\'user\', { inverse: \'posts\' })\n });\n\n User.reopen({\n posts: DS.hasMany(\'post\', { inverse: \'participants\' })\n });\n\n var store = createStore({\n user: User,\n post: Post\n });\n var user, post;\n\n run(function() {\n user = store.createRecord(\'user\');\n post = store.createRecord(\'post\');\n });\n\n equal(user.inverseFor(\'posts\').name, \'participants\', \'User.posts inverse is Post.participants\');\n equal(post.inverseFor(\'lastParticipant\'), null, \'Post.lastParticipant has no inverse\');\n equal(post.inverseFor(\'participants\').name, \'posts\', \'Post.participants inverse is User.posts\');\n});\n\ntest(\"When a record is added to a has-many relationship, the inverse belongsTo can be set explicitly\", function() {\n Post = DS.Model.extend({\n comments: DS.hasMany(\'comment\', { inverse: \'redPost\' })\n });\n\n Comment = DS.Model.extend({\n onePost: DS.belongsTo(\'post\'),\n twoPost: DS.belongsTo(\'post\'),\n redPost: DS.belongsTo(\'post\'),\n bluePost: DS.belongsTo(\'post\')\n });\n\n var env = setupStore({ post: Post, comment: Comment });\n var store = env.store;\n var comment, post;\n\n run(function() {\n comment = store.createRecord(\'comment\');\n post = store.createRecord(\'post\');\n });\n\n equal(comment.get(\'onePost\'), null, \"onePost has not been set on the comment\");\n equal(comment.get(\'twoPost\'), null, \"twoPost has not been set on the comment\");\n equal(comment.get(\'redPost\'), null, \"redPost has not been set on the comment\");\n equal(comment.get(\'bluePost\'), null, \"bluePost has not been set on the comment\");\n\n run(function() {\n post.get(\'comments\').pushObject(comment);\n });\n\n equal(comment.get(\'onePost\'), null, \"onePost has not been set on the comment\");\n equal(comment.get(\'twoPost\'), null, \"twoPost has not been set on the comment\");\n equal(comment.get(\'redPost\'), post, \"redPost has been set on the comment\");\n equal(comment.get(\'bluePost\'), null, \"bluePost has not been set on the comment\");\n});\n\ntest(\"When a record\'s belongsTo relationship is set, it can specify the inverse hasMany to which the new child should be added\", function() {\n Post = DS.Model.extend({\n meComments: DS.hasMany(\'comment\'),\n youComments: DS.hasMany(\'comment\'),\n everyoneWeKnowComments: DS.hasMany(\'comment\')\n });\n\n Comment = DS.Model.extend({\n post: DS.belongsTo(\'post\', { inverse: \'youComments\' })\n });\n\n var env = setupStore({ post: Post, comment: Comment });\n var store = env.store;\n var comment, post;\n\n run(function() {\n comment = store.createRecord(\'comment\');\n post = store.createRecord(\'post\');\n });\n\n equal(post.get(\'meComments.length\'), 0, \"meComments has no posts\");\n equal(post.get(\'youComments.length\'), 0, \"youComments has no posts\");\n equal(post.get(\'everyoneWeKnowComments.length\'), 0, \"everyoneWeKnowComments has no posts\");\n\n run(function() {\n comment.set(\'post\', post);\n });\n\n equal(comment.get(\'post\'), post, \'The post that was set can be retrieved\');\n\n equal(post.get(\'meComments.length\'), 0, \"meComments has no posts\");\n equal(post.get(\'youComments.length\'), 1, \"youComments had the post added\");\n equal(post.get(\'everyoneWeKnowComments.length\'), 0, \"everyoneWeKnowComments has no posts\");\n});\n\ntest(\"When setting a belongsTo, the OneToOne invariant is respected even when other records have been previously used\", function() {\n Post = DS.Model.extend({\n bestComment: DS.belongsTo(\'comment\')\n });\n\n Comment = DS.Model.extend({\n post: DS.belongsTo(\'post\')\n });\n\n var env = setupStore({ post: Post, comment: Comment });\n var store = env.store;\n var comment, post, post2;\n\n run(function() {\n comment = store.createRecord(\'comment\');\n post = store.createRecord(\'post\');\n post2 = store.createRecord(\'post\');\n });\n run(function() {\n comment.set(\'post\', post);\n post2.set(\'bestComment\', null);\n });\n\n equal(comment.get(\'post\'), post);\n equal(post.get(\'bestComment\'), comment);\n equal(post2.get(\'bestComment\'), null);\n\n run(function() {\n comment.set(\'post\', post2);\n });\n\n equal(comment.get(\'post\'), post2);\n equal(post.get(\'bestComment\'), null);\n equal(post2.get(\'bestComment\'), comment);\n});\n\ntest(\"When setting a belongsTo, the OneToOne invariant is transitive\", function() {\n Post = DS.Model.extend({\n bestComment: DS.belongsTo(\'comment\')\n });\n\n Comment = DS.Model.extend({\n post: DS.belongsTo(\'post\')\n });\n\n var store = createStore({\n post: Post,\n comment: Comment\n });\n var post, post2, comment;\n\n run(function() {\n comment = store.createRecord(\'comment\');\n post = store.createRecord(\'post\');\n post2 = store.createRecord(\'post\');\n });\n\n run(function() {\n comment.set(\'post\', post);\n });\n\n equal(comment.get(\'post\'), post);\n equal(post.get(\'bestComment\'), comment);\n equal(post2.get(\'bestComment\'), null);\n\n run(function() {\n post2.set(\'bestComment\', comment);\n });\n\n equal(comment.get(\'post\'), post2);\n equal(post.get(\'bestComment\'), null);\n equal(post2.get(\'bestComment\'), comment);\n});\n\ntest(\"When setting a belongsTo, the OneToOne invariant is commutative\", function() {\n Post = DS.Model.extend({\n bestComment: DS.belongsTo(\'comment\')\n });\n\n Comment = DS.Model.extend({\n post: DS.belongsTo(\'post\')\n });\n\n var store = createStore({\n post: Post,\n comment: Comment\n });\n var post, comment, comment2;\n\n run(function() {\n post = store.createRecord(\'post\');\n comment = store.createRecord(\'comment\');\n comment2 = store.createRecord(\'comment\');\n\n comment.set(\'post\', post);\n });\n\n equal(comment.get(\'post\'), post);\n equal(post.get(\'bestComment\'), comment);\n equal(comment2.get(\'post\'), null);\n\n run(function() {\n post.set(\'bestComment\', comment2);\n });\n\n equal(comment.get(\'post\'), null);\n equal(post.get(\'bestComment\'), comment2);\n equal(comment2.get(\'post\'), post);\n});\n\ntest(\"OneToNone relationship works\", function() {\n expect(3);\n Post = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n Comment = DS.Model.extend({\n post: DS.belongsTo(\'post\')\n });\n\n var env = setupStore({ post: Post, comment: Comment });\n var store = env.store;\n var comment, post1, post2;\n\n run(function() {\n comment = store.createRecord(\'comment\');\n post1 = store.createRecord(\'post\');\n post2 = store.createRecord(\'post\');\n });\n\n run(function() {\n comment.set(\'post\', post1);\n });\n equal(comment.get(\'post\'), post1, \'the post is set to the first one\');\n\n run(function() {\n comment.set(\'post\', post2);\n });\n equal(comment.get(\'post\'), post2, \'the post is set to the second one\');\n\n run(function() {\n comment.set(\'post\', post1);\n });\n equal(comment.get(\'post\'), post1, \'the post is re-set to the first one\');\n});\n\n\ntest(\"When a record is added to or removed from a polymorphic has-many relationship, the inverse belongsTo can be set explicitly\", function() {\n User = DS.Model.extend({\n messages: DS.hasMany(\'message\', {\n inverse: \'redUser\',\n polymorphic: true\n })\n });\n\n Message = DS.Model.extend({\n oneUser: DS.belongsTo(\'user\'),\n twoUser: DS.belongsTo(\'user\'),\n redUser: DS.belongsTo(\'user\'),\n blueUser: DS.belongsTo(\'user\')\n });\n\n Post = Message.extend();\n\n var env = setupStore({ user: User, message: Message, post: Post });\n var store = env.store;\n var post, user;\n\n run(function() {\n post = store.createRecord(\'post\');\n user = store.createRecord(\'user\');\n });\n\n equal(post.get(\'oneUser\'), null, \"oneUser has not been set on the user\");\n equal(post.get(\'twoUser\'), null, \"twoUser has not been set on the user\");\n equal(post.get(\'redUser\'), null, \"redUser has not been set on the user\");\n equal(post.get(\'blueUser\'), null, \"blueUser has not been set on the user\");\n\n run(function() {\n user.get(\'messages\').pushObject(post);\n });\n\n equal(post.get(\'oneUser\'), null, \"oneUser has not been set on the user\");\n equal(post.get(\'twoUser\'), null, \"twoUser has not been set on the user\");\n equal(post.get(\'redUser\'), user, \"redUser has been set on the user\");\n equal(post.get(\'blueUser\'), null, \"blueUser has not been set on the user\");\n\n run(function() {\n user.get(\'messages\').popObject();\n });\n\n equal(post.get(\'oneUser\'), null, \"oneUser has not been set on the user\");\n equal(post.get(\'twoUser\'), null, \"twoUser has not been set on the user\");\n equal(post.get(\'redUser\'), null, \"redUser has bot been set on the user\");\n equal(post.get(\'blueUser\'), null, \"blueUser has not been set on the user\");\n});\n\ntest(\"When a record\'s belongsTo relationship is set, it can specify the inverse polymorphic hasMany to which the new child should be added or removed\", function() {\n User = DS.Model.extend({\n meMessages: DS.hasMany(\'message\', { polymorphic: true }),\n youMessages: DS.hasMany(\'message\', { polymorphic: true }),\n everyoneWeKnowMessages: DS.hasMany(\'message\', { polymorphic: true })\n });\n\n Message = DS.Model.extend({\n user: DS.belongsTo(\'user\', { inverse: \'youMessages\' })\n });\n\n Post = Message.extend();\n\n var env = setupStore({ user: User, message: Message, post: Post });\n var store = env.store;\n var user, post;\n\n run(function() {\n user = store.createRecord(\'user\');\n post = store.createRecord(\'post\');\n });\n\n equal(user.get(\'meMessages.length\'), 0, \"meMessages has no posts\");\n equal(user.get(\'youMessages.length\'), 0, \"youMessages has no posts\");\n equal(user.get(\'everyoneWeKnowMessages.length\'), 0, \"everyoneWeKnowMessages has no posts\");\n\n run(function() {\n post.set(\'user\', user);\n });\n\n equal(user.get(\'meMessages.length\'), 0, \"meMessages has no posts\");\n equal(user.get(\'youMessages.length\'), 1, \"youMessages had the post added\");\n equal(user.get(\'everyoneWeKnowMessages.length\'), 0, \"everyoneWeKnowMessages has no posts\");\n\n run(function() {\n post.set(\'user\', null);\n });\n\n equal(user.get(\'meMessages.length\'), 0, \"meMessages has no posts\");\n equal(user.get(\'youMessages.length\'), 0, \"youMessages has no posts\");\n equal(user.get(\'everyoneWeKnowMessages.length\'), 0, \"everyoneWeKnowMessages has no posts\");\n});\n\ntest(\"When a record\'s polymorphic belongsTo relationship is set, it can specify the inverse hasMany to which the new child should be added\", function() {\n Message = DS.Model.extend({\n meMessages: DS.hasMany(\'comment\', { inverse: null }),\n youMessages: DS.hasMany(\'comment\', { inverse: \'message\' }),\n everyoneWeKnowMessages: DS.hasMany(\'comment\', { inverse: null })\n });\n\n Post = Message.extend();\n\n Comment = Message.extend({\n message: DS.belongsTo(\'message\', {\n polymorphic: true,\n inverse: \'youMessages\'\n })\n });\n\n var env = setupStore({ comment: Comment, message: Message, post: Post });\n var store = env.store;\n var comment, post;\n\n run(function() {\n comment = store.createRecord(\'comment\');\n post = store.createRecord(\'post\');\n });\n\n equal(post.get(\'meMessages.length\'), 0, \"meMessages has no posts\");\n equal(post.get(\'youMessages.length\'), 0, \"youMessages has no posts\");\n equal(post.get(\'everyoneWeKnowMessages.length\'), 0, \"everyoneWeKnowMessages has no posts\");\n\n run(function() {\n comment.set(\'message\', post);\n });\n\n equal(post.get(\'meMessages.length\'), 0, \"meMessages has no posts\");\n equal(post.get(\'youMessages.length\'), 1, \"youMessages had the post added\");\n equal(post.get(\'everyoneWeKnowMessages.length\'), 0, \"everyoneWeKnowMessages has no posts\");\n\n run(function() {\n comment.set(\'message\', null);\n });\n\n equal(post.get(\'meMessages.length\'), 0, \"meMessages has no posts\");\n equal(post.get(\'youMessages.length\'), 0, \"youMessages has no posts\");\n equal(post.get(\'everyoneWeKnowMessages.length\'), 0, \"everyoneWeKnowMessages has no posts\");\n});\n\ntest(\"Inverse relationships that don\'t exist throw a nice error for a hasMany\", function () {\n User = DS.Model.extend();\n Comment = DS.Model.extend();\n\n Post = DS.Model.extend({\n comments: DS.hasMany(\'comment\', { inverse: \'testPost\' })\n });\n\n var env = setupStore({ post: Post, comment: Comment, user: User });\n var comment;\n run(function() {\n comment = env.store.createRecord(\'comment\');\n });\n\n expectAssertion(function() {\n run(function() {\n env.store.createRecord(\'post\');\n });\n }, /We found no inverse relationships by the name of \'testPost\' on the \'comment\' model/);\n});\n\ntest(\"Inverse relationships that don\'t exist throw a nice error for a belongsTo\", function () {\n User = DS.Model.extend();\n Comment = DS.Model.extend();\n\n Post = DS.Model.extend({\n user: DS.belongsTo(\'user\', { inverse: \'testPost\' })\n });\n\n var env = setupStore({ post: Post, comment: Comment, user: User });\n var user;\n run(function() {\n user = env.store.createRecord(\'user\');\n });\n\n expectAssertion(function() {\n run(function() {\n env.store.createRecord(\'post\');\n });\n }, /We found no inverse relationships by the name of \'testPost\' on the \'user\' model/);\n});\n})();//# sourceURL=ember-data/integration/relationships/inverse-relationships-test.js");
334
350
 
@@ -340,25 +356,25 @@ eval("(function() {var env, store, User, Job;\nvar run = Ember.run;\n\nvar attr
340
356
 
341
357
  eval("(function() {var env, store, User, Message, Video, NotMessage;\nvar run = Ember.run;\n\nvar attr = DS.attr;\nvar belongsTo = DS.belongsTo;\n\nfunction stringify(string) {\n return function() { return string; };\n}\n\nmodule(\'integration/relationships/polymorphic_mixins_belongs_to_test - Polymorphic belongsTo relationships with mixins\', {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n bestMessage: belongsTo(\'message\', { async: true, polymorphic: true })\n });\n User.toString = stringify(\'User\');\n\n Message = Ember.Mixin.create({\n title: attr(\'string\'),\n user: belongsTo(\'user\', { async: true })\n });\n Message.toString = stringify(\'Message\');\n\n NotMessage = DS.Model.extend({\n video: attr()\n });\n\n Video = DS.Model.extend(Message, {\n video: attr()\n });\n\n env = setupStore({\n user: User,\n video: Video,\n notMessage: NotMessage\n });\n\n env.registry.register(\'mixin:message\', Message);\n store = env.store;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\n/*\n Server loading tests\n*/\n\ntest(\"Relationship is available from the belongsTo side even if only loaded from the inverse side - async\", function () {\n var user, video;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', bestMessage: 2, bestMessageType: \'video\' });\n video = store.push(\'video\', { id: 2, video: \'Here comes Youtube\' });\n });\n run(function() {\n user.get(\'bestMessage\').then(function(message) {\n equal(message, video, \'The message was loaded correctly\');\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'The inverse was setup correctly\');\n });\n });\n });\n});\n\n/*\n Local edits\n*/\ntest(\"Setting the polymorphic belongsTo gets propagated to the inverse side - async\", function () {\n var user, video;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n video = store.push(\'video\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n user.set(\'bestMessage\', video);\n video.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \"user got set correctly\");\n });\n user.get(\'bestMessage\').then(function(message) {\n equal(message, video, \'The message was set correctly\');\n });\n });\n});\n\ntest(\"Setting the polymorphic belongsTo with an object that does not implement the mixin errors out\", function () {\n var user, video;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n video = store.push(\'notMessage\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n expectAssertion(function() {\n user.set(\'bestMessage\', video);\n }, /You can only add a \'message\' record to this relationship/);\n });\n});\n\n\ntest(\"Setting the polymorphic belongsTo gets propagated to the inverse side - model injections true\", function () {\n expect(2);\n var injectionValue = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n try {\n var user, video;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n video = store.push(\'video\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n user.set(\'bestMessage\', video);\n video.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \"user got set correctly\");\n });\n user.get(\'bestMessage\').then(function(message) {\n equal(message, video, \'The message was set correctly\');\n });\n });\n } finally {\n Ember.MODEL_FACTORY_INJECTIONS = injectionValue;\n }\n});\n\ntest(\"Setting the polymorphic belongsTo with an object that does not implement the mixin errors out - model injections true\", function () {\n var injectionValue = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n try {\n var user, video;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n video = store.push(\'notMessage\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n expectAssertion(function() {\n user.set(\'bestMessage\', video);\n }, /You can only add a \'message\' record to this relationship/);\n });\n } finally {\n Ember.MODEL_FACTORY_INJECTIONS = injectionValue;\n }\n});\n})();//# sourceURL=ember-data/integration/relationships/polymorphic-mixins-belongs-to-test.js");
342
358
 
343
- eval("(function() {var env, store, User, Message, NotMessage, Video;\nvar run = Ember.run;\n\nvar attr = DS.attr;\nvar hasMany = DS.hasMany;\nvar belongsTo = DS.belongsTo;\n\nfunction stringify(string) {\n return function() { return string; };\n}\n\nmodule(\'integration/relationships/polymorphic_mixins_has_many_test - Polymorphic hasMany relationships with mixins\', {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n messages: hasMany(\'message\', { async: true, polymorphic: true })\n });\n User.toString = stringify(\'User\');\n\n Message = Ember.Mixin.create({\n title: attr(\'string\'),\n user: belongsTo(\'user\', { async: true })\n });\n Message.toString = stringify(\'Message\');\n\n Video = DS.Model.extend(Message, {\n video: attr()\n });\n\n NotMessage = DS.Model.extend({\n video: attr()\n });\n\n env = setupStore({\n user: User,\n video: Video,\n notMessage: NotMessage\n });\n\n env.registry.register(\'mixin:message\', Message);\n store = env.store;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\n/*\n Server loading tests\n*/\n\ntest(\"Relationship is available from the belongsTo side even if only loaded from the hasMany side - async\", function () {\n var user, video;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [{ id: 2, type: \'video\' }] });\n video = store.push(\'video\', { id: 2, video: \'Here comes Youtube\' });\n });\n run(function() {\n user.get(\'messages\').then(function(messages) {\n equal(messages.objectAt(0), video, \'The hasMany has loaded correctly\');\n messages.objectAt(0).get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'The inverse was setup correctly\');\n });\n });\n });\n});\n\n/*\n Local edits\n*/\ntest(\"Pushing to the hasMany reflects the change on the belongsTo side - async\", function () {\n var user, video;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [] });\n video = store.push(\'video\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n fetchedMessages.pushObject(video);\n video.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \"user got set correctly\");\n });\n });\n });\n});\n\n/*\n Local edits\n*/\ntest(\"Pushing a an object that does not implement the mixin to the mixin accepting array errors out\", function () {\n var user,notMessage;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [] });\n notMessage = store.push(\'notMessage\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n expectAssertion(function() {\n fetchedMessages.pushObject(notMessage);\n }, /You cannot add \'notMessage\' records to the user\\.messages relationship \\(only \'message\' allowed\\)/);\n });\n });\n});\n\ntest(\"Pushing to the hasMany reflects the change on the belongsTo side - model injections true\", function () {\n var injectionValue = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n try {\n var user, video;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [] });\n video = store.push(\'video\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n fetchedMessages.pushObject(video);\n video.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \"user got set correctly\");\n });\n });\n });\n } finally {\n Ember.MODEL_FACTORY_INJECTIONS = injectionValue;\n }\n});\n\n/*\n Local edits\n*/\ntest(\"Pushing a an object that does not implement the mixin to the mixin accepting array errors out - model injections true\", function () {\n var injectionValue = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n try {\n var user,notMessage;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [] });\n notMessage = store.push(\'notMessage\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n expectAssertion(function() {\n fetchedMessages.pushObject(notMessage);\n }, /You cannot add \'notMessage\' records to the user\\.messages relationship \\(only \'message\' allowed\\)/);\n });\n });\n } finally {\n Ember.MODEL_FACTORY_INJECTIONS = injectionValue;\n }\n});\n\n})();//# sourceURL=ember-data/integration/relationships/polymorphic-mixins-has-many-test.js");
359
+ eval("(function() {var env, store, User, Message, NotMessage, Video;\nvar run = Ember.run;\n\nvar attr = DS.attr;\nvar hasMany = DS.hasMany;\nvar belongsTo = DS.belongsTo;\n\nfunction stringify(string) {\n return function() { return string; };\n}\n\nmodule(\'integration/relationships/polymorphic_mixins_has_many_test - Polymorphic hasMany relationships with mixins\', {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n messages: hasMany(\'message\', { async: true, polymorphic: true })\n });\n User.toString = stringify(\'User\');\n\n Message = Ember.Mixin.create({\n title: attr(\'string\'),\n user: belongsTo(\'user\', { async: true })\n });\n Message.toString = stringify(\'Message\');\n\n Video = DS.Model.extend(Message, {\n video: attr()\n });\n\n NotMessage = DS.Model.extend({\n video: attr()\n });\n\n env = setupStore({\n user: User,\n video: Video,\n notMessage: NotMessage\n });\n\n env.registry.register(\'mixin:message\', Message);\n store = env.store;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\n/*\n Server loading tests\n*/\n\ntest(\"Relationship is available from the belongsTo side even if only loaded from the hasMany side - async\", function () {\n var user, video;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [{ id: 2, type: \'video\' }] });\n video = store.push(\'video\', { id: 2, video: \'Here comes Youtube\' });\n });\n run(function() {\n user.get(\'messages\').then(function(messages) {\n equal(messages.objectAt(0), video, \'The hasMany has loaded correctly\');\n messages.objectAt(0).get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'The inverse was setup correctly\');\n });\n });\n });\n});\n\n/*\n Local edits\n*/\ntest(\"Pushing to the hasMany reflects the change on the belongsTo side - async\", function () {\n var user, video;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [] });\n video = store.push(\'video\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n fetchedMessages.pushObject(video);\n video.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \"user got set correctly\");\n });\n });\n });\n});\n\n/*\n Local edits\n*/\ntest(\"Pushing a an object that does not implement the mixin to the mixin accepting array errors out\", function () {\n var user,notMessage;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [] });\n notMessage = store.push(\'notMessage\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n expectAssertion(function() {\n fetchedMessages.pushObject(notMessage);\n }, /You cannot add \'not-message\' records to the user\\.messages relationship \\(only \'message\' allowed\\)/);\n });\n });\n});\n\ntest(\"Pushing to the hasMany reflects the change on the belongsTo side - model injections true\", function () {\n var injectionValue = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n try {\n var user, video;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [] });\n video = store.push(\'video\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n fetchedMessages.pushObject(video);\n video.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \"user got set correctly\");\n });\n });\n });\n } finally {\n Ember.MODEL_FACTORY_INJECTIONS = injectionValue;\n }\n});\n\n/*\n Local edits\n*/\ntest(\"Pushing a an object that does not implement the mixin to the mixin accepting array errors out - model injections true\", function () {\n var injectionValue = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n try {\n var user,notMessage;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [] });\n notMessage = store.push(\'notMessage\', { id: 2, video: \'Here comes Youtube\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n expectAssertion(function() {\n fetchedMessages.pushObject(notMessage);\n }, /You cannot add \'not-message\' records to the user\\.messages relationship \\(only \'message\' allowed\\)/);\n });\n });\n } finally {\n Ember.MODEL_FACTORY_INJECTIONS = injectionValue;\n }\n});\n\n})();//# sourceURL=ember-data/integration/relationships/polymorphic-mixins-has-many-test.js");
344
360
 
345
- eval("(function() {var get = Ember.get;\nvar HomePlanet, SuperVillain, EvilMinion, SecretLab, SecretWeapon, BatCave, Comment,\n league, superVillain, evilMinion, secretWeapon, homePlanet, secretLab, env;\nvar indexOf = Ember.EnumerableUtils.indexOf;\nvar run = Ember.run;\nvar LightSaber;\n\nmodule(\"integration/embedded_records_mixin - EmbeddedRecordsMixin\", {\n setup: function() {\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n homePlanet: DS.belongsTo(\"homePlanet\", { inverse: \'villains\' }),\n secretLab: DS.belongsTo(\"secretLab\"),\n secretWeapons: DS.hasMany(\"secretWeapon\"),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n HomePlanet = DS.Model.extend({\n name: DS.attr(\'string\'),\n villains: DS.hasMany(\'superVillain\', { inverse: \'homePlanet\' })\n });\n SecretLab = DS.Model.extend({\n minionCapacity: DS.attr(\'number\'),\n vicinity: DS.attr(\'string\'),\n superVillain: DS.belongsTo(\'superVillain\')\n });\n BatCave = SecretLab.extend({\n infiltrated: DS.attr(\'boolean\')\n });\n SecretWeapon = DS.Model.extend({\n name: DS.attr(\'string\'),\n superVillain: DS.belongsTo(\'superVillain\')\n });\n LightSaber = SecretWeapon.extend({\n color: DS.attr(\'string\')\n });\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n Comment = DS.Model.extend({\n body: DS.attr(\'string\'),\n root: DS.attr(\'boolean\'),\n children: DS.hasMany(\'comment\', { inverse: null })\n });\n env = setupStore({\n superVillain: SuperVillain,\n homePlanet: HomePlanet,\n secretLab: SecretLab,\n batCave: BatCave,\n secretWeapon: SecretWeapon,\n lightSaber: LightSaber,\n evilMinion: EvilMinion,\n comment: Comment\n });\n env.store.modelFor(\'superVillain\');\n env.store.modelFor(\'homePlanet\');\n env.store.modelFor(\'secretLab\');\n env.store.modelFor(\'batCave\');\n env.store.modelFor(\'secretWeapon\');\n env.store.modelFor(\'lightSaber\');\n env.store.modelFor(\'evilMinion\');\n env.store.modelFor(\'comment\');\n env.registry.register(\'serializer:application\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin));\n env.registry.register(\'serializer:-active-model\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin));\n env.registry.register(\'adapter:-active-model\', DS.ActiveModelAdapter);\n env.amsSerializer = env.container.lookup(\"serializer:-active-model\");\n env.amsAdapter = env.container.lookup(\"adapter:-active-model\");\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"extractSingle with embedded objects\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n var json_hash = {\n home_planet: {\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\"\n }]\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n });\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"extractSingle with embedded objects inside embedded objects\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n var json_hash = {\n home_planet: {\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n evil_minions: [{\n id: \"1\",\n name: \"Alex\"\n }]\n }]\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n });\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(villain) {\n equal(villain.get(\'firstName\'), \"Tom\");\n equal(villain.get(\'evilMinions.length\'), 1, \"Should load the embedded child\");\n equal(villain.get(\'evilMinions.firstObject.name\'), \"Alex\", \"Should load the embedded child\");\n });\n env.store.find(\"evilMinion\", 1).then(function(minion) {\n equal(minion.get(\'name\'), \"Alex\");\n });\n });\n});\n\ntest(\"extractSingle with embedded objects of same type\", function() {\n env.registry.register(\'adapter:comment\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:comment\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n children: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:comment\");\n var json_hash = {\n comment: {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [{\n id: \"2\",\n body: \"World\",\n root: false\n },\n {\n id: \"3\",\n body: \"Foo\",\n root: false\n }]\n }\n };\n var json;\n run(function() {\n json = serializer.extractSingle(env.store, Comment, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [\"2\", \"3\"]\n }, \"Primary record was correct\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"World\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Foo\", \"Secondary records found in the store\");\n});\n\ntest(\"extractSingle with embedded objects inside embedded objects of same type\", function() {\n env.registry.register(\'adapter:comment\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:comment\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n children: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:comment\");\n var json_hash = {\n comment: {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [{\n id: \"2\",\n body: \"World\",\n root: false,\n children: [{\n id: \"4\",\n body: \"Another\",\n root: false\n }]\n },\n {\n id: \"3\",\n body: \"Foo\",\n root: false\n }]\n }\n };\n var json;\n run(function() {\n json = serializer.extractSingle(env.store, Comment, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [\"2\", \"3\"]\n }, \"Primary record was correct\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"World\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Foo\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"4\").get(\"body\"), \"Another\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"children.length\"), 1, \"Should have one embedded record\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"children.firstObject.body\"), \"Another\", \"Should have one embedded record\");\n});\n\ntest(\"extractSingle with embedded objects of same type, but from separate attributes\", function() {\n HomePlanet.reopen({\n reformedVillains: DS.hasMany(\'superVillain\', { inverse: null })\n });\n\n env.registry.register(\'adapter:home_planet\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:home_planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' },\n reformedVillains: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:home_planet\");\n var json_hash = {\n home_planet: {\n id: \"1\",\n name: \"Earth\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\"\n }, {\n id: \"3\",\n first_name: \"Yehuda\"\n }],\n reformed_villains: [{\n id: \"2\",\n first_name: \"Alex\"\n },{\n id: \"4\",\n first_name: \"Erik\"\n }]\n }\n };\n var json;\n run(function() {\n json = serializer.extractSingle(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Earth\",\n villains: [\"1\", \"3\"],\n reformedVillains: [\"2\", \"4\"]\n }, \"Primary hash was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"2\").get(\"firstName\"), \"Alex\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"3\").get(\"firstName\"), \"Yehuda\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"4\").get(\"firstName\"), \"Erik\", \"Secondary records found in the store\");\n});\n\ntest(\"extractArray with embedded objects\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\"\n }]\n }]\n };\n var array;\n\n run(function() {\n array = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n }]);\n\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"extractArray with embedded objects with custom primary key\", function() {\n expect(2);\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend({\n primaryKey: \'villain_id\'\n }));\n env.registry.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Umber\",\n villains: [{\n villain_id: \"1\",\n first_name: \"Alex\",\n last_name: \"Baizeau\"\n }]\n }]\n };\n var array;\n\n run(function() {\n array = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n }]);\n\n run(function() {\n return env.store.find(\"superVillain\", 1).then(function(minion) {\n env.registry.unregister(\'serializer:superVillain\');\n equal(minion.get(\'firstName\'), \"Alex\");\n });\n });\n});\ntest(\"extractArray with embedded objects with identical relationship and attribute key \", function() {\n expect(2);\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n },\n //Makes the keyForRelationship and keyForAttribute collide.\n keyForRelationship: function(key, type) {\n return this.keyForAttribute(key, type);\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Alex\",\n last_name: \"Baizeau\"\n }]\n }]\n };\n var array;\n\n run(function() {\n array = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n }]);\n\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Alex\");\n });\n });\n});\ntest(\"extractArray with embedded objects of same type as primary type\", function() {\n env.registry.register(\'adapter:comment\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:comment\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n children: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:comment\");\n\n var json_hash = {\n comments: [{\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [{\n id: \"2\",\n body: \"World\",\n root: false\n },\n {\n id: \"3\",\n body: \"Foo\",\n root: false\n }]\n }]\n };\n var array;\n\n run(function() {\n array = serializer.extractArray(env.store, Comment, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [\"2\", \"3\"]\n }], \"Primary array is correct\");\n\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"World\", \"Secondary record found in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Foo\", \"Secondary record found in the store\");\n});\n\ntest(\"extractArray with embedded objects of same type, but from separate attributes\", function() {\n HomePlanet.reopen({\n reformedVillains: DS.hasMany(\'superVillain\')\n });\n\n env.registry.register(\'adapter:homePlanet\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' },\n reformedVillains: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Earth\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\"\n },{\n id: \"3\",\n first_name: \"Yehuda\"\n }],\n reformed_villains: [{\n id: \"2\",\n first_name: \"Alex\"\n },{\n id: \"4\",\n first_name: \"Erik\"\n }]\n },{\n id: \"2\",\n name: \"Mars\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\"\n },{\n id: \"3\",\n first_name: \"Yehuda\"\n }],\n reformed_villains: [{\n id: \"5\",\n first_name: \"Peter\"\n },{\n id: \"6\",\n first_name: \"Trek\"\n }]\n }]\n };\n var json;\n run(function() {\n json = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, [{\n id: \"1\",\n name: \"Earth\",\n villains: [\"1\", \"3\"],\n reformedVillains: [\"2\", \"4\"]\n },{\n id: \"2\",\n name: \"Mars\",\n villains: [\"1\", \"3\"],\n reformedVillains: [\"5\", \"6\"]\n }], \"Primary array was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"2\").get(\"firstName\"), \"Alex\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"3\").get(\"firstName\"), \"Yehuda\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"4\").get(\"firstName\"), \"Erik\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"5\").get(\"firstName\"), \"Peter\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"6\").get(\"firstName\"), \"Trek\", \"Secondary records found in the store\");\n});\n\ntest(\"serialize supports serialize:false on non-relationship properties\", function() {\n var tom;\n run(function() {\n tom = env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", id: \'1\' });\n });\n\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n firstName: { serialize: false }\n }\n }));\n var serializer, json;\n run(function() {\n serializer = env.container.lookup(\"serializer:superVillain\");\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n last_name: \"Dale\",\n home_planet_id: null,\n secret_lab_id: null\n });\n});\n\ntest(\"serialize with embedded objects (hasMany relationship)\", function() {\n var tom, league;\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n tom = env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", homePlanet: league, id: \'1\' });\n });\n\n env.registry.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n\n var serializer, json;\n run(function() {\n serializer = env.container.lookup(\"serializer:homePlanet\");\n\n json = serializer.serialize(league._createSnapshot());\n });\n\n deepEqual(json, {\n name: \"Villain League\",\n villains: [{\n id: get(tom, \"id\"),\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: get(league, \"id\"),\n secret_lab_id: null\n }]\n });\n});\n\ntest(\"serialize with embedded objects (hasMany relationship) supports serialize:false\", function() {\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", homePlanet: league, id: \'1\' });\n });\n\n env.registry.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { serialize: false }\n }\n }));\n var serializer, json;\n run(function() {\n serializer = env.container.lookup(\"serializer:homePlanet\");\n\n json = serializer.serialize(league._createSnapshot());\n });\n\n deepEqual(json, {\n name: \"Villain League\"\n });\n});\n\ntest(\"serialize with (new) embedded objects (hasMany relationship)\", function() {\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", homePlanet: league });\n });\n\n env.registry.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n var serializer, json;\n run(function() {\n serializer = env.container.lookup(\"serializer:homePlanet\");\n\n json = serializer.serialize(league._createSnapshot());\n });\n deepEqual(json, {\n name: \"Villain League\",\n villains: [{\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: get(league, \"id\"),\n secret_lab_id: null\n }]\n });\n});\n\ntest(\"serialize with embedded objects (hasMany relationships, including related objects not embedded)\", function() {\n run(function() {\n superVillain = env.store.createRecord(SuperVillain, { id: 1, firstName: \"Super\", lastName: \"Villian\" });\n evilMinion = env.store.createRecord(EvilMinion, { id: 1, name: \"Evil Minion\", superVillian: superVillain });\n secretWeapon = env.store.createRecord(SecretWeapon, { id: 1, name: \"Secret Weapon\", superVillain: superVillain });\n superVillain.get(\'evilMinions\').pushObject(evilMinion);\n superVillain.get(\'secretWeapons\').pushObject(secretWeapon);\n });\n\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: { serialize: \'records\', deserialize: \'records\' },\n secretWeapons: { serialize: \'ids\' }\n }\n }));\n var serializer, json;\n run(function() {\n serializer = env.container.lookup(\"serializer:superVillain\");\n\n json = serializer.serialize(superVillain._createSnapshot());\n });\n deepEqual(json, {\n first_name: get(superVillain, \"firstName\"),\n last_name: get(superVillain, \"lastName\"),\n home_planet_id: null,\n evil_minions: [{\n id: get(evilMinion, \"id\"),\n name: get(evilMinion, \"name\"),\n super_villain_id: \"1\"\n }],\n secret_lab_id: null,\n secret_weapon_ids: [\"1\"]\n });\n});\n\ntest(\"extractSingle with embedded object (belongsTo relationship)\", function() {\n expect(4);\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n var json_hash = {\n super_villain: {\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: \"123\",\n evil_minion_ids: [\"1\", \"2\", \"3\"],\n secret_lab: {\n minion_capacity: 5000,\n vicinity: \"California, USA\",\n id: \"101\"\n },\n secret_weapon_ids: []\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, SuperVillain, json_hash);\n });\n\n deepEqual(json, {\n \"id\": \"1\",\n \"firstName\": \"Tom\",\n \"lastName\": \"Dale\",\n \"homePlanet\": \"123\",\n \"evilMinions\": [\"1\", \"2\", \"3\"],\n \"secretLab\": \"101\",\n \"secretWeapons\": []\n });\n\n run(function() {\n env.store.find(\"secretLab\", 101).then(function(secretLab) {\n equal(secretLab.get(\'id\'), \'101\');\n equal(secretLab.get(\'minionCapacity\'), 5000);\n equal(secretLab.get(\'vicinity\'), \'California, USA\');\n });\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship)\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n var serializer, json, tom;\n run(function() {\n serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: {\n id: get(tom, \"secretLab\").get(\"id\"),\n minion_capacity: get(tom, \"secretLab\").get(\"minionCapacity\"),\n vicinity: get(tom, \"secretLab\").get(\"vicinity\")\n }\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) works with different primaryKeys\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n primaryKey: \'_id\',\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n env.registry.register(\'serializer:secretLab\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n primaryKey: \'crazy_id\'\n }));\n\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: {\n crazy_id: get(tom, \"secretLab\").get(\"id\"),\n minion_capacity: get(tom, \"secretLab\").get(\"minionCapacity\"),\n vicinity: get(tom, \"secretLab\").get(\"vicinity\")\n }\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship, new no id)\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records without ids, new\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: {\n minion_capacity: get(tom, \"secretLab\").get(\"minionCapacity\"),\n vicinity: get(tom, \"secretLab\").get(\"vicinity\")\n }\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) supports serialize:ids\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { serialize: \'ids\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab_id: get(tom, \"secretLab\").get(\"id\")\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) supports serialize:id\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { serialize: \'id\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab_id: get(tom, \"secretLab\").get(\"id\")\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) supports serialize:id in conjunction with deserialize:records\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { serialize: \'id\', deserialize: \'records\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab_id: get(tom, \"secretLab\").get(\"id\")\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) supports serialize:false\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { serialize: false }\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n var tom, json;\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\")\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) serializes the id by default if no option specified\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab_id: get(tom, \"secretLab\").get(\"id\")\n });\n});\n\ntest(\"when related record is not present, serialize embedded record (with a belongsTo relationship) as null\", function() {\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: null\n });\n});\n\ntest(\"extractSingle with multiply-nested belongsTo\", function() {\n env.registry.register(\'adapter:evilMinion\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:evilMinion\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n superVillain: { embedded: \'always\' }\n }\n }));\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n homePlanet: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:evilMinion\");\n var json_hash = {\n evil_minion: {\n id: \"1\",\n name: \"Alex\",\n super_villain: {\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n evil_minion_ids: [\"1\"],\n home_planet: {\n id: \"1\",\n name: \"Umber\",\n villain_ids: [\"1\"]\n }\n }\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, EvilMinion, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Alex\",\n superVillain: \"1\"\n }, \"Primary hash was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary record, Tom, found in the steore\");\n equal(env.store.recordForId(\"homePlanet\", \"1\").get(\"name\"), \"Umber\", \"Nested Secondary record, Umber, found in the store\");\n});\n\ntest(\"extractSingle with polymorphic hasMany\", function() {\n SuperVillain.reopen({\n secretWeapons: DS.hasMany(\"secretWeapon\", { polymorphic: true })\n });\n\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretWeapons: { embedded: \'always\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n var json_hash = {\n super_villain: {\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n secret_weapons: [\n {\n id: \"1\",\n type: \"LightSaber\",\n name: \"Tom\'s LightSaber\",\n color: \"Red\"\n },\n {\n id: \"1\",\n type: \"SecretWeapon\",\n name: \"The Death Star\"\n }\n ]\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, SuperVillain, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n firstName: \"Tom\",\n lastName: \"Dale\",\n secretWeapons: [\n { id: \"1\", type: \"lightSaber\" },\n { id: \"1\", type: \"secretWeapon\" }\n ]\n }, \"Primary hash was correct\");\n\n equal(env.store.recordForId(\"secretWeapon\", \"1\").get(\"name\"), \"The Death Star\", \"Embedded polymorphic SecretWeapon found\");\n equal(env.store.recordForId(\"lightSaber\", \"1\").get(\"name\"), \"Tom\'s LightSaber\", \"Embedded polymorphic LightSaber found\");\n\n\n});\n\ntest(\"extractSingle with polymorphic belongsTo\", function() {\n expect(2);\n\n SuperVillain.reopen({\n secretLab: DS.belongsTo(\"secretLab\", { polymorphic: true })\n });\n\n env.registry.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n var json_hash = {\n super_villain: {\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n secret_lab: {\n id: \"1\",\n type: \"BatCave\",\n infiltrated: true\n }\n }\n };\n\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, SuperVillain, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n firstName: \"Tom\",\n lastName: \"Dale\",\n secretLab: \"1\",\n secretLabType: \"batCave\"\n }, \"Primary has was correct\");\n\n equal(env.store.recordForId(\"batCave\", \"1\").get(\"infiltrated\"), true, \"Embedded polymorphic BatCave was found\");\n\n});\n\ntest(\"Mixin can be used with RESTSerializer which does not define keyForAttribute\", function() {\n run(function() {\n homePlanet = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n secretLab = env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" });\n superVillain = env.store.createRecord(SuperVillain, {\n id: \"1\", firstName: \"Super\", lastName: \"Villian\", homePlanet: homePlanet, secretLab: secretLab\n });\n secretWeapon = env.store.createRecord(SecretWeapon, { id: \"1\", name: \"Secret Weapon\", superVillain: superVillain });\n superVillain.get(\'secretWeapons\').pushObject(secretWeapon);\n evilMinion = env.store.createRecord(EvilMinion, { id: \"1\", name: \"Evil Minion\", superVillian: superVillain });\n superVillain.get(\'evilMinions\').pushObject(evilMinion);\n });\n\n env.registry.register(\'serializer:evilMinion\', DS.RESTSerializer);\n env.registry.register(\'serializer:secretWeapon\', DS.RESTSerializer);\n env.registry.register(\'serializer:superVillain\', DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: { serialize: \'records\', deserialize: \'records\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n var json;\n\n run(function() {\n json = serializer.serialize(superVillain._createSnapshot());\n });\n\n deepEqual(json, {\n firstName: get(superVillain, \"firstName\"),\n lastName: get(superVillain, \"lastName\"),\n homePlanet: \"123\",\n evilMinions: [{\n id: get(evilMinion, \"id\"),\n name: get(evilMinion, \"name\"),\n superVillain: \"1\"\n }],\n secretLab: \"101\"\n // \"manyToOne\" relation does not serialize ids\n // sersecretWeapons: [\"1\"]\n });\n});\n\ntest(\"normalize with custom belongsTo primary key\", function() {\n env.registry.register(\'adapter:evilMinion\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:evilMinion\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n superVillain: { embedded: \'always\' }\n }\n }));\n env.registry.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend({\n primaryKey: \'custom\'\n }));\n\n var serializer = env.container.lookup(\"serializer:evilMinion\");\n var json_hash = {\n evil_minion: {\n id: \"1\",\n name: \"Alex\",\n super_villain: {\n custom: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\"\n }\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, EvilMinion, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Alex\",\n superVillain: \"1\"\n }, \"Primary hash was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary record, Tom, found in the steore\");\n});\n\ntest(\"serializing relationships with an embedded and without calls super when not attr not present\", function() {\n run(function() {\n homePlanet = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n secretLab = env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" });\n superVillain = env.store.createRecord(SuperVillain, {\n id: \"1\", firstName: \"Super\", lastName: \"Villian\", homePlanet: homePlanet, secretLab: secretLab\n });\n secretWeapon = env.store.createRecord(SecretWeapon, { id: \"1\", name: \"Secret Weapon\", superVillain: superVillain });\n superVillain.get(\'secretWeapons\').pushObject(secretWeapon);\n evilMinion = env.store.createRecord(EvilMinion, { id: \"1\", name: \"Evil Minion\", superVillian: superVillain });\n superVillain.get(\'evilMinions\').pushObject(evilMinion);\n });\n\n var calledSerializeBelongsTo = false;\n var calledSerializeHasMany = false;\n\n var Serializer = DS.RESTSerializer.extend({\n serializeBelongsTo: function(snapshot, json, relationship) {\n calledSerializeBelongsTo = true;\n return this._super(snapshot, json, relationship);\n },\n serializeHasMany: function(snapshot, json, relationship) {\n calledSerializeHasMany = true;\n var key = relationship.key;\n var payloadKey = this.keyForRelationship ? this.keyForRelationship(key, \"hasMany\") : key;\n var relationshipType = snapshot.type.determineRelationshipType(relationship);\n // \"manyToOne\" not supported in DS.RESTSerializer.prototype.serializeHasMany\n var relationshipTypes = Ember.String.w(\'manyToNone manyToMany manyToOne\');\n if (indexOf(relationshipTypes, relationshipType) > -1) {\n json[payloadKey] = snapshot.hasMany(key, { ids: true });\n }\n }\n });\n env.registry.register(\'serializer:evilMinion\', Serializer);\n env.registry.register(\'serializer:secretWeapon\', Serializer);\n env.registry.register(\'serializer:superVillain\', Serializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: { serialize: \'records\', deserialize: \'records\' }\n // some relationships are not listed here, so super should be called on those\n // e.g. secretWeapons: { serialize: \'ids\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n var json;\n run(function() {\n json = serializer.serialize(superVillain._createSnapshot());\n });\n\n deepEqual(json, {\n firstName: get(superVillain, \"firstName\"),\n lastName: get(superVillain, \"lastName\"),\n homePlanet: \"123\",\n evilMinions: [{\n id: get(evilMinion, \"id\"),\n name: get(evilMinion, \"name\"),\n superVillain: \"1\"\n }],\n secretLab: \"101\",\n // customized serializeHasMany method to generate ids for \"manyToOne\" relation\n secretWeapons: [\"1\"]\n });\n ok(calledSerializeBelongsTo);\n ok(calledSerializeHasMany);\n});\n})();//# sourceURL=ember-data/integration/serializers/embedded-records-mixin-test.js");
361
+ eval("(function() {var get = Ember.get;\nvar HomePlanet, SuperVillain, EvilMinion, SecretLab, SecretWeapon, BatCave, Comment,\n league, superVillain, evilMinion, secretWeapon, homePlanet, secretLab, env;\nvar indexOf = Ember.EnumerableUtils.indexOf;\nvar run = Ember.run;\nvar LightSaber;\n\nmodule(\"integration/embedded_records_mixin - EmbeddedRecordsMixin\", {\n setup: function() {\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n homePlanet: DS.belongsTo(\"homePlanet\", { inverse: \'villains\' }),\n secretLab: DS.belongsTo(\"secretLab\"),\n secretWeapons: DS.hasMany(\"secretWeapon\"),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n HomePlanet = DS.Model.extend({\n name: DS.attr(\'string\'),\n villains: DS.hasMany(\'superVillain\', { inverse: \'homePlanet\' })\n });\n SecretLab = DS.Model.extend({\n minionCapacity: DS.attr(\'number\'),\n vicinity: DS.attr(\'string\'),\n superVillain: DS.belongsTo(\'superVillain\')\n });\n BatCave = SecretLab.extend({\n infiltrated: DS.attr(\'boolean\')\n });\n SecretWeapon = DS.Model.extend({\n name: DS.attr(\'string\'),\n superVillain: DS.belongsTo(\'superVillain\')\n });\n LightSaber = SecretWeapon.extend({\n color: DS.attr(\'string\')\n });\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n Comment = DS.Model.extend({\n body: DS.attr(\'string\'),\n root: DS.attr(\'boolean\'),\n children: DS.hasMany(\'comment\', { inverse: null })\n });\n env = setupStore({\n superVillain: SuperVillain,\n homePlanet: HomePlanet,\n secretLab: SecretLab,\n batCave: BatCave,\n secretWeapon: SecretWeapon,\n lightSaber: LightSaber,\n evilMinion: EvilMinion,\n comment: Comment\n });\n env.store.modelFor(\'superVillain\');\n env.store.modelFor(\'homePlanet\');\n env.store.modelFor(\'secretLab\');\n env.store.modelFor(\'batCave\');\n env.store.modelFor(\'secretWeapon\');\n env.store.modelFor(\'lightSaber\');\n env.store.modelFor(\'evilMinion\');\n env.store.modelFor(\'comment\');\n env.registry.register(\'serializer:application\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin));\n env.registry.register(\'serializer:-active-model\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin));\n env.registry.register(\'adapter:-active-model\', DS.ActiveModelAdapter);\n env.amsSerializer = env.container.lookup(\"serializer:-active-model\");\n env.amsAdapter = env.container.lookup(\"adapter:-active-model\");\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"extractSingle with embedded objects\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:home-planet\");\n var json_hash = {\n home_planet: {\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\"\n }]\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n });\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"extractSingle with embedded objects inside embedded objects\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:home-planet\");\n var json_hash = {\n home_planet: {\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n evil_minions: [{\n id: \"1\",\n name: \"Alex\"\n }]\n }]\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n });\n run(function() {\n env.store.find(\"superVillain\", 1).then(async(function(villain) {\n equal(villain.get(\'firstName\'), \"Tom\");\n equal(villain.get(\'evilMinions.length\'), 1, \"Should load the embedded child\");\n equal(villain.get(\'evilMinions.firstObject.name\'), \"Alex\", \"Should load the embedded child\");\n }));\n env.store.find(\"evilMinion\", 1).then(async(function(minion) {\n equal(minion.get(\'name\'), \"Alex\");\n }));\n });\n});\n\ntest(\"extractSingle with embedded objects of same type\", function() {\n env.registry.register(\'adapter:comment\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:comment\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n children: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:comment\");\n var json_hash = {\n comment: {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [{\n id: \"2\",\n body: \"World\",\n root: false\n },\n {\n id: \"3\",\n body: \"Foo\",\n root: false\n }]\n }\n };\n var json;\n run(function() {\n json = serializer.extractSingle(env.store, Comment, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [\"2\", \"3\"]\n }, \"Primary record was correct\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"World\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Foo\", \"Secondary records found in the store\");\n});\n\ntest(\"extractSingle with embedded objects inside embedded objects of same type\", function() {\n env.registry.register(\'adapter:comment\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:comment\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n children: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:comment\");\n var json_hash = {\n comment: {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [{\n id: \"2\",\n body: \"World\",\n root: false,\n children: [{\n id: \"4\",\n body: \"Another\",\n root: false\n }]\n },\n {\n id: \"3\",\n body: \"Foo\",\n root: false\n }]\n }\n };\n var json;\n run(function() {\n json = serializer.extractSingle(env.store, Comment, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [\"2\", \"3\"]\n }, \"Primary record was correct\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"World\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Foo\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"4\").get(\"body\"), \"Another\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"children.length\"), 1, \"Should have one embedded record\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"children.firstObject.body\"), \"Another\", \"Should have one embedded record\");\n});\n\ntest(\"extractSingle with embedded objects of same type, but from separate attributes\", function() {\n HomePlanet.reopen({\n reformedVillains: DS.hasMany(\'superVillain\', { inverse: null })\n });\n\n env.registry.register(\'adapter:home-planet\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' },\n reformedVillains: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:home-planet\");\n var json_hash = {\n home_planet: {\n id: \"1\",\n name: \"Earth\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\"\n }, {\n id: \"3\",\n first_name: \"Yehuda\"\n }],\n reformed_villains: [{\n id: \"2\",\n first_name: \"Alex\"\n },{\n id: \"4\",\n first_name: \"Erik\"\n }]\n }\n };\n var json;\n run(function() {\n json = serializer.extractSingle(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Earth\",\n villains: [\"1\", \"3\"],\n reformedVillains: [\"2\", \"4\"]\n }, \"Primary hash was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"2\").get(\"firstName\"), \"Alex\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"3\").get(\"firstName\"), \"Yehuda\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"4\").get(\"firstName\"), \"Erik\", \"Secondary records found in the store\");\n});\n\ntest(\"extractArray with embedded objects\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:home-planet\");\n\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\"\n }]\n }]\n };\n var array;\n\n run(function() {\n array = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n }]);\n\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"extractArray with embedded objects with custom primary key\", function() {\n expect(2);\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend({\n primaryKey: \'villain_id\'\n }));\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:home-planet\");\n\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Umber\",\n villains: [{\n villain_id: \"1\",\n first_name: \"Alex\",\n last_name: \"Baizeau\"\n }]\n }]\n };\n var array;\n\n run(function() {\n array = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n }]);\n\n run(function() {\n return env.store.find(\"superVillain\", 1).then(function(minion) {\n env.registry.unregister(\'serializer:super-villain\');\n equal(minion.get(\'firstName\'), \"Alex\");\n });\n });\n});\ntest(\"extractArray with embedded objects with identical relationship and attribute key \", function() {\n expect(2);\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n },\n //Makes the keyForRelationship and keyForAttribute collide.\n keyForRelationship: function(key, type) {\n return this.keyForAttribute(key, type);\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:home-planet\");\n\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Alex\",\n last_name: \"Baizeau\"\n }]\n }]\n };\n var array;\n\n run(function() {\n array = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n }]);\n\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Alex\");\n });\n });\n});\ntest(\"extractArray with embedded objects of same type as primary type\", function() {\n env.registry.register(\'adapter:comment\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:comment\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n children: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:comment\");\n\n var json_hash = {\n comments: [{\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [{\n id: \"2\",\n body: \"World\",\n root: false\n },\n {\n id: \"3\",\n body: \"Foo\",\n root: false\n }]\n }]\n };\n var array;\n\n run(function() {\n array = serializer.extractArray(env.store, Comment, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [\"2\", \"3\"]\n }], \"Primary array is correct\");\n\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"World\", \"Secondary record found in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Foo\", \"Secondary record found in the store\");\n});\n\ntest(\"extractArray with embedded objects of same type, but from separate attributes\", function() {\n HomePlanet.reopen({\n reformedVillains: DS.hasMany(\'superVillain\')\n });\n\n env.registry.register(\'adapter:home-planet\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' },\n reformedVillains: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:home-planet\");\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Earth\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\"\n },{\n id: \"3\",\n first_name: \"Yehuda\"\n }],\n reformed_villains: [{\n id: \"2\",\n first_name: \"Alex\"\n },{\n id: \"4\",\n first_name: \"Erik\"\n }]\n },{\n id: \"2\",\n name: \"Mars\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\"\n },{\n id: \"3\",\n first_name: \"Yehuda\"\n }],\n reformed_villains: [{\n id: \"5\",\n first_name: \"Peter\"\n },{\n id: \"6\",\n first_name: \"Trek\"\n }]\n }]\n };\n var json;\n run(function() {\n json = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, [{\n id: \"1\",\n name: \"Earth\",\n villains: [\"1\", \"3\"],\n reformedVillains: [\"2\", \"4\"]\n },{\n id: \"2\",\n name: \"Mars\",\n villains: [\"1\", \"3\"],\n reformedVillains: [\"5\", \"6\"]\n }], \"Primary array was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"2\").get(\"firstName\"), \"Alex\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"3\").get(\"firstName\"), \"Yehuda\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"4\").get(\"firstName\"), \"Erik\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"5\").get(\"firstName\"), \"Peter\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"6\").get(\"firstName\"), \"Trek\", \"Secondary records found in the store\");\n});\n\ntest(\"serialize supports serialize:false on non-relationship properties\", function() {\n var tom;\n run(function() {\n tom = env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", id: \'1\' });\n });\n\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n firstName: { serialize: false }\n }\n }));\n var serializer, json;\n run(function() {\n serializer = env.container.lookup(\"serializer:super-villain\");\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n last_name: \"Dale\",\n home_planet_id: null,\n secret_lab_id: null\n });\n});\n\ntest(\"serialize with embedded objects (hasMany relationship)\", function() {\n var tom, league;\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n tom = env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", homePlanet: league, id: \'1\' });\n });\n\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n\n var serializer, json;\n run(function() {\n serializer = env.container.lookup(\"serializer:home-planet\");\n\n json = serializer.serialize(league._createSnapshot());\n });\n\n deepEqual(json, {\n name: \"Villain League\",\n villains: [{\n id: get(tom, \"id\"),\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: get(league, \"id\"),\n secret_lab_id: null\n }]\n });\n});\n\ntest(\"serialize with embedded objects (hasMany relationship) supports serialize:false\", function() {\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", homePlanet: league, id: \'1\' });\n });\n\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { serialize: false }\n }\n }));\n var serializer, json;\n run(function() {\n serializer = env.container.lookup(\"serializer:home-planet\");\n\n json = serializer.serialize(league._createSnapshot());\n });\n\n deepEqual(json, {\n name: \"Villain League\"\n });\n});\n\ntest(\"serialize with (new) embedded objects (hasMany relationship)\", function() {\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", homePlanet: league });\n });\n\n env.registry.register(\'serializer:home-planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: { embedded: \'always\' }\n }\n }));\n var serializer, json;\n run(function() {\n serializer = env.container.lookup(\"serializer:home-planet\");\n\n json = serializer.serialize(league._createSnapshot());\n });\n deepEqual(json, {\n name: \"Villain League\",\n villains: [{\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: get(league, \"id\"),\n secret_lab_id: null\n }]\n });\n});\n\ntest(\"serialize with embedded objects (hasMany relationships, including related objects not embedded)\", function() {\n run(function() {\n superVillain = env.store.createRecord(SuperVillain, { id: 1, firstName: \"Super\", lastName: \"Villian\" });\n evilMinion = env.store.createRecord(EvilMinion, { id: 1, name: \"Evil Minion\", superVillian: superVillain });\n secretWeapon = env.store.createRecord(SecretWeapon, { id: 1, name: \"Secret Weapon\", superVillain: superVillain });\n superVillain.get(\'evilMinions\').pushObject(evilMinion);\n superVillain.get(\'secretWeapons\').pushObject(secretWeapon);\n });\n\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: { serialize: \'records\', deserialize: \'records\' },\n secretWeapons: { serialize: \'ids\' }\n }\n }));\n var serializer, json;\n run(function() {\n serializer = env.container.lookup(\"serializer:super-villain\");\n\n json = serializer.serialize(superVillain._createSnapshot());\n });\n deepEqual(json, {\n first_name: get(superVillain, \"firstName\"),\n last_name: get(superVillain, \"lastName\"),\n home_planet_id: null,\n evil_minions: [{\n id: get(evilMinion, \"id\"),\n name: get(evilMinion, \"name\"),\n super_villain_id: \"1\"\n }],\n secret_lab_id: null,\n secret_weapon_ids: [\"1\"]\n });\n});\n\ntest(\"extractSingle with embedded object (belongsTo relationship)\", function() {\n expect(4);\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:super-villain\");\n\n var json_hash = {\n super_villain: {\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: \"123\",\n evil_minion_ids: [\"1\", \"2\", \"3\"],\n secret_lab: {\n minion_capacity: 5000,\n vicinity: \"California, USA\",\n id: \"101\"\n },\n secret_weapon_ids: []\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, SuperVillain, json_hash);\n });\n\n deepEqual(json, {\n \"id\": \"1\",\n \"firstName\": \"Tom\",\n \"lastName\": \"Dale\",\n \"homePlanet\": \"123\",\n \"evilMinions\": [\"1\", \"2\", \"3\"],\n \"secretLab\": \"101\",\n \"secretWeapons\": []\n });\n\n run(function() {\n env.store.find(\"secretLab\", 101).then(function(secretLab) {\n equal(secretLab.get(\'id\'), \'101\');\n equal(secretLab.get(\'minionCapacity\'), 5000);\n equal(secretLab.get(\'vicinity\'), \'California, USA\');\n });\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship)\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n var serializer, json, tom;\n run(function() {\n serializer = env.container.lookup(\"serializer:super-villain\");\n\n // records with an id, persisted\n\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: {\n id: get(tom, \"secretLab\").get(\"id\"),\n minion_capacity: get(tom, \"secretLab\").get(\"minionCapacity\"),\n vicinity: get(tom, \"secretLab\").get(\"vicinity\")\n }\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) works with different primaryKeys\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n primaryKey: \'_id\',\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n env.registry.register(\'serializer:secret-lab\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n primaryKey: \'crazy_id\'\n }));\n\n var serializer = env.container.lookup(\"serializer:super-villain\");\n\n // records with an id, persisted\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(\'secret-lab\', { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(\'home-planet\', { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: {\n crazy_id: get(tom, \"secretLab\").get(\"id\"),\n minion_capacity: get(tom, \"secretLab\").get(\"minionCapacity\"),\n vicinity: get(tom, \"secretLab\").get(\"vicinity\")\n }\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship, new no id)\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:super-villain\");\n\n // records without ids, new\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: {\n minion_capacity: get(tom, \"secretLab\").get(\"minionCapacity\"),\n vicinity: get(tom, \"secretLab\").get(\"vicinity\")\n }\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) supports serialize:ids\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { serialize: \'ids\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:super-villain\");\n\n // records with an id, persisted\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab_id: get(tom, \"secretLab\").get(\"id\")\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) supports serialize:id\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { serialize: \'id\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:super-villain\");\n\n // records with an id, persisted\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab_id: get(tom, \"secretLab\").get(\"id\")\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) supports serialize:id in conjunction with deserialize:records\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { serialize: \'id\', deserialize: \'records\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:super-villain\");\n\n // records with an id, persisted\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(\'secretLab\', { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(\'homePlanet\', { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab_id: get(tom, \"secretLab\").get(\"id\")\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) supports serialize:false\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { serialize: false }\n }\n }));\n var serializer = env.container.lookup(\"serializer:super-villain\");\n\n // records with an id, persisted\n var tom, json;\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\")\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) serializes the id by default if no option specified\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin));\n var serializer = env.container.lookup(\"serializer:super-villain\");\n\n // records with an id, persisted\n\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab_id: get(tom, \"secretLab\").get(\"id\")\n });\n});\n\ntest(\"when related record is not present, serialize embedded record (with a belongsTo relationship) as null\", function() {\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:super-villain\");\n var tom, json;\n\n run(function() {\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function() {\n json = serializer.serialize(tom._createSnapshot());\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: null\n });\n});\n\ntest(\"extractSingle with multiply-nested belongsTo\", function() {\n env.registry.register(\'adapter:evil-minion\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:evil-minion\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n superVillain: { embedded: \'always\' }\n }\n }));\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n homePlanet: { embedded: \'always\' }\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:evil-minion\");\n var json_hash = {\n evil_minion: {\n id: \"1\",\n name: \"Alex\",\n super_villain: {\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n evil_minion_ids: [\"1\"],\n home_planet: {\n id: \"1\",\n name: \"Umber\",\n villain_ids: [\"1\"]\n }\n }\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, EvilMinion, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Alex\",\n superVillain: \"1\"\n }, \"Primary hash was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary record, Tom, found in the steore\");\n equal(env.store.recordForId(\"homePlanet\", \"1\").get(\"name\"), \"Umber\", \"Nested Secondary record, Umber, found in the store\");\n});\n\ntest(\"extractSingle with polymorphic hasMany\", function() {\n SuperVillain.reopen({\n secretWeapons: DS.hasMany(\"secretWeapon\", { polymorphic: true })\n });\n\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretWeapons: { embedded: \'always\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:super-villain\");\n\n var json_hash = {\n super_villain: {\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n secret_weapons: [\n {\n id: \"1\",\n type: \"LightSaber\",\n name: \"Tom\'s LightSaber\",\n color: \"Red\"\n },\n {\n id: \"1\",\n type: \"SecretWeapon\",\n name: \"The Death Star\"\n }\n ]\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, SuperVillain, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n firstName: \"Tom\",\n lastName: \"Dale\",\n secretWeapons: [\n { id: \"1\", type: \"light-saber\" },\n { id: \"1\", type: \"secret-weapon\" }\n ]\n }, \"Primary hash was correct\");\n\n equal(env.store.recordForId(\"secretWeapon\", \"1\").get(\"name\"), \"The Death Star\", \"Embedded polymorphic SecretWeapon found\");\n equal(env.store.recordForId(\"lightSaber\", \"1\").get(\"name\"), \"Tom\'s LightSaber\", \"Embedded polymorphic LightSaber found\");\n\n\n});\n\ntest(\"extractSingle with polymorphic belongsTo\", function() {\n expect(2);\n\n SuperVillain.reopen({\n secretLab: DS.belongsTo(\"secretLab\", { polymorphic: true })\n });\n\n env.registry.register(\'adapter:super-villain\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: { embedded: \'always\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:super-villain\");\n\n var json_hash = {\n super_villain: {\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n secret_lab: {\n id: \"1\",\n type: \"bat-cave\",\n infiltrated: true\n }\n }\n };\n\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, SuperVillain, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n firstName: \"Tom\",\n lastName: \"Dale\",\n secretLab: \"1\",\n secretLabType: \"bat-cave\"\n }, \"Primary has was correct\");\n\n equal(env.store.recordForId(\"batCave\", \"1\").get(\"infiltrated\"), true, \"Embedded polymorphic BatCave was found\");\n\n});\n\ntest(\"Mixin can be used with RESTSerializer which does not define keyForAttribute\", function() {\n run(function() {\n homePlanet = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n secretLab = env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" });\n superVillain = env.store.createRecord(SuperVillain, {\n id: \"1\", firstName: \"Super\", lastName: \"Villian\", homePlanet: homePlanet, secretLab: secretLab\n });\n secretWeapon = env.store.createRecord(SecretWeapon, { id: \"1\", name: \"Secret Weapon\", superVillain: superVillain });\n superVillain.get(\'secretWeapons\').pushObject(secretWeapon);\n evilMinion = env.store.createRecord(EvilMinion, { id: \"1\", name: \"Evil Minion\", superVillian: superVillain });\n superVillain.get(\'evilMinions\').pushObject(evilMinion);\n });\n\n env.registry.register(\'serializer:evil-minion\', DS.RESTSerializer);\n env.registry.register(\'serializer:secret-weapon\', DS.RESTSerializer);\n env.registry.register(\'serializer:super-villain\', DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: { serialize: \'records\', deserialize: \'records\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:super-villain\");\n var json;\n\n run(function() {\n json = serializer.serialize(superVillain._createSnapshot());\n });\n\n deepEqual(json, {\n firstName: get(superVillain, \"firstName\"),\n lastName: get(superVillain, \"lastName\"),\n homePlanet: \"123\",\n evilMinions: [{\n id: get(evilMinion, \"id\"),\n name: get(evilMinion, \"name\"),\n superVillain: \"1\"\n }],\n secretLab: \"101\"\n // \"manyToOne\" relation does not serialize ids\n // sersecretWeapons: [\"1\"]\n });\n});\n\ntest(\"normalize with custom belongsTo primary key\", function() {\n env.registry.register(\'adapter:evil-minion\', DS.ActiveModelAdapter);\n env.registry.register(\'serializer:evil-minion\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n superVillain: { embedded: \'always\' }\n }\n }));\n env.registry.register(\'serializer:super-villain\', DS.ActiveModelSerializer.extend({\n primaryKey: \'custom\'\n }));\n\n var serializer = env.container.lookup(\"serializer:evil-minion\");\n var json_hash = {\n evil_minion: {\n id: \"1\",\n name: \"Alex\",\n super_villain: {\n custom: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\"\n }\n }\n };\n var json;\n\n run(function() {\n json = serializer.extractSingle(env.store, EvilMinion, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Alex\",\n superVillain: \"1\"\n }, \"Primary hash was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary record, Tom, found in the steore\");\n});\n\ntest(\"serializing relationships with an embedded and without calls super when not attr not present\", function() {\n run(function() {\n homePlanet = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n secretLab = env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" });\n superVillain = env.store.createRecord(SuperVillain, {\n id: \"1\", firstName: \"Super\", lastName: \"Villian\", homePlanet: homePlanet, secretLab: secretLab\n });\n secretWeapon = env.store.createRecord(SecretWeapon, { id: \"1\", name: \"Secret Weapon\", superVillain: superVillain });\n superVillain.get(\'secretWeapons\').pushObject(secretWeapon);\n evilMinion = env.store.createRecord(EvilMinion, { id: \"1\", name: \"Evil Minion\", superVillian: superVillain });\n superVillain.get(\'evilMinions\').pushObject(evilMinion);\n });\n\n var calledSerializeBelongsTo = false;\n var calledSerializeHasMany = false;\n\n var Serializer = DS.RESTSerializer.extend({\n serializeBelongsTo: function(snapshot, json, relationship) {\n calledSerializeBelongsTo = true;\n return this._super(snapshot, json, relationship);\n },\n serializeHasMany: function(snapshot, json, relationship) {\n calledSerializeHasMany = true;\n var key = relationship.key;\n var payloadKey = this.keyForRelationship ? this.keyForRelationship(key, \"hasMany\") : key;\n var relationshipType = snapshot.type.determineRelationshipType(relationship);\n // \"manyToOne\" not supported in DS.RESTSerializer.prototype.serializeHasMany\n var relationshipTypes = Ember.String.w(\'manyToNone manyToMany manyToOne\');\n if (indexOf(relationshipTypes, relationshipType) > -1) {\n json[payloadKey] = snapshot.hasMany(key, { ids: true });\n }\n }\n });\n env.registry.register(\'serializer:evil-minion\', Serializer);\n env.registry.register(\'serializer:secret-weapon\', Serializer);\n env.registry.register(\'serializer:super-villain\', Serializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: { serialize: \'records\', deserialize: \'records\' }\n // some relationships are not listed here, so super should be called on those\n // e.g. secretWeapons: { serialize: \'ids\' }\n }\n }));\n var serializer = env.container.lookup(\"serializer:super-villain\");\n\n var json;\n run(function() {\n json = serializer.serialize(superVillain._createSnapshot());\n });\n\n deepEqual(json, {\n firstName: get(superVillain, \"firstName\"),\n lastName: get(superVillain, \"lastName\"),\n homePlanet: \"123\",\n evilMinions: [{\n id: get(evilMinion, \"id\"),\n name: get(evilMinion, \"name\"),\n superVillain: \"1\"\n }],\n secretLab: \"101\",\n // customized serializeHasMany method to generate ids for \"manyToOne\" relation\n secretWeapons: [\"1\"]\n });\n ok(calledSerializeBelongsTo);\n ok(calledSerializeHasMany);\n});\n})();//# sourceURL=ember-data/integration/serializers/embedded-records-mixin-test.js");
346
362
 
347
- eval("(function() {var Post, post, Comment, comment, Favorite, favorite, env;\nvar run = Ember.run;\n\nmodule(\"integration/serializer/json - JSONSerializer\", {\n setup: function() {\n Post = DS.Model.extend({\n title: DS.attr(\'string\'),\n comments: DS.hasMany(\'comment\', { inverse: null })\n });\n Comment = DS.Model.extend({\n body: DS.attr(\'string\'),\n post: DS.belongsTo(\'post\')\n });\n Favorite = DS.Model.extend({\n post: DS.belongsTo(\'post\', { async: true, polymorphic: true })\n });\n env = setupStore({\n post: Post,\n comment: Comment,\n favorite: Favorite\n });\n env.store.modelFor(\'post\');\n env.store.modelFor(\'comment\');\n env.store.modelFor(\'favorite\');\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"serializeAttribute\", function() {\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n });\n var json = {};\n\n env.serializer.serializeAttribute(post._createSnapshot(), json, \"title\", { type: \"string\" });\n\n deepEqual(json, {\n title: \"Rails is omakase\"\n });\n});\n\ntest(\"serializeAttribute respects keyForAttribute\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForAttribute: function(key) {\n return key.toUpperCase();\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n });\n var json = {};\n\n env.container.lookup(\"serializer:post\").serializeAttribute(post._createSnapshot(), json, \"title\", { type: \"string\" });\n\n deepEqual(json, { TITLE: \"Rails is omakase\" });\n});\n\ntest(\"serializeBelongsTo\", function() {\n run(function() {\n post = env.store.createRecord(Post, { title: \"Rails is omakase\", id: \"1\" });\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post });\n });\n\n var json = {};\n\n env.serializer.serializeBelongsTo(comment._createSnapshot(), json, { key: \"post\", options: {} });\n\n deepEqual(json, { post: \"1\" });\n});\n\ntest(\"serializeBelongsTo with null\", function() {\n run(function() {\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: null });\n });\n var json = {};\n\n env.serializer.serializeBelongsTo(comment._createSnapshot(), json, { key: \"post\", options: {} });\n\n deepEqual(json, {\n post: null\n }, \"Can set a belongsTo to a null value\");\n});\n\ntest(\"async serializeBelongsTo with null\", function() {\n Comment.reopen({\n post: DS.belongsTo(\'post\', { async: true })\n });\n run(function() {\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: null });\n });\n var json = {};\n\n env.serializer.serializeBelongsTo(comment._createSnapshot(), json, { key: \"post\", options: {} });\n\n deepEqual(json, {\n post: null\n }, \"Can set a belongsTo to a null value\");\n});\n\ntest(\"serializeBelongsTo respects keyForRelationship\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForRelationship: function(key, type) {\n return key.toUpperCase();\n }\n }));\n run(function() {\n post = env.store.createRecord(Post, { title: \"Rails is omakase\", id: \"1\" });\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post });\n });\n var json = {};\n\n env.container.lookup(\"serializer:post\").serializeBelongsTo(comment._createSnapshot(), json, { key: \"post\", options: {} });\n\n deepEqual(json, {\n POST: \"1\"\n });\n});\n\ntest(\"serializeHasMany respects keyForRelationship\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForRelationship: function(key, type) {\n return key.toUpperCase();\n }\n }));\n\n run(function() {\n post = env.store.createRecord(Post, { title: \"Rails is omakase\", id: \"1\" });\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post, id: \"1\" });\n });\n\n var json = {};\n\n env.container.lookup(\"serializer:post\").serializeHasMany(post._createSnapshot(), json, { key: \"comments\", options: {} });\n\n deepEqual(json, {\n COMMENTS: [\"1\"]\n });\n});\n\ntest(\"serializeIntoHash\", function() {\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n });\n\n var json = {};\n\n env.serializer.serializeIntoHash(json, Post, post._createSnapshot());\n\n deepEqual(json, {\n title: \"Rails is omakase\",\n comments: []\n });\n});\n\ntest(\"serializePolymorphicType sync\", function() {\n expect(1);\n\n env.registry.register(\'serializer:comment\', DS.JSONSerializer.extend({\n serializePolymorphicType: function(record, json, relationship) {\n var key = relationship.key;\n var belongsTo = record.belongsTo(key);\n json[relationship.key + \"TYPE\"] = belongsTo.typeKey;\n\n ok(true, \'serializePolymorphicType is called when serialize a polymorphic belongsTo\');\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\'post\', { title: \'Rails is omakase\', id: 1 });\n comment = env.store.createRecord(\'comment\', { body: \'Omakase is delicious\', post: post });\n });\n\n env.container.lookup(\'serializer:comment\').serializeBelongsTo(comment._createSnapshot(), {}, { key: \'post\', options: { polymorphic: true } });\n});\n\ntest(\"serializePolymorphicType async\", function() {\n expect(1);\n\n Comment.reopen({\n post: DS.belongsTo(\'post\', { async: true })\n });\n\n env.registry.register(\'serializer:comment\', DS.JSONSerializer.extend({\n serializePolymorphicType: function(record, json, relationship) {\n ok(true, \'serializePolymorphicType is called when serialize a polymorphic belongsTo\');\n }\n }));\n\n run(function() {\n post = env.store.createRecord(Post, { title: \'Rails is omakase\', id: 1 });\n comment = env.store.createRecord(Comment, { body: \'Omakase is delicious\', post: post });\n });\n\n env.container.lookup(\'serializer:comment\').serializeBelongsTo(comment._createSnapshot(), {}, { key: \'post\', options: { async: true, polymorphic: true } });\n});\n\ntest(\"extractArray normalizes each record in the array\", function() {\n var postNormalizeCount = 0;\n var posts = [\n { title: \"Rails is omakase\" },\n { title: \"Another Post\" }\n ];\n\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n normalize: function () {\n postNormalizeCount++;\n return this._super.apply(this, arguments);\n }\n }));\n\n run(function() {\n env.container.lookup(\"serializer:post\").extractArray(env.store, Post, posts);\n });\n equal(postNormalizeCount, 2, \"two posts are normalized\");\n});\n\ntest(\'Serializer should respect the attrs hash when extracting records\', function() {\n env.registry.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n title: \"title_payload_key\",\n comments: { key: \'my_comments\' }\n }\n }));\n\n var jsonHash = {\n title_payload_key: \"Rails is omakase\",\n my_comments: [1, 2]\n };\n\n var post = env.container.lookup(\"serializer:post\").extractSingle(env.store, Post, jsonHash);\n\n equal(post.title, \"Rails is omakase\");\n deepEqual(post.comments, [1,2]);\n});\n\ntest(\'Serializer should respect the attrs hash when serializing records\', function() {\n Post.reopen({\n parentPost: DS.belongsTo(\'post\', { inverse: null })\n });\n env.registry.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n title: \"title_payload_key\",\n parentPost: { key: \"my_parent\" }\n }\n }));\n var parentPost;\n\n run(function() {\n parentPost = env.store.push(\"post\", { id: 2, title: \"Rails is omakase\" });\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\", parentPost: parentPost });\n });\n\n var payload = env.container.lookup(\"serializer:post\").serialize(post._createSnapshot());\n\n equal(payload.title_payload_key, \"Rails is omakase\");\n equal(payload.my_parent, \'2\');\n});\n\ntest(\'Serializer respects `serialize: false` on the attrs hash\', function() {\n expect(2);\n env.registry.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n title: { serialize: false }\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n });\n\n var payload = env.container.lookup(\"serializer:post\").serialize(post._createSnapshot());\n\n ok(!payload.hasOwnProperty(\'title\'), \"Does not add the key to instance\");\n ok(!payload.hasOwnProperty(\'[object Object]\'), \"Does not add some random key like [object Object]\");\n});\n\ntest(\'Serializer respects `serialize: false` on the attrs hash for a `hasMany` property\', function() {\n expect(1);\n env.registry.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n comments: { serialize: false }\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post });\n });\n\n var serializer = env.container.lookup(\"serializer:post\");\n var serializedProperty = serializer.keyForRelationship(\'comments\', \'hasMany\');\n\n var payload = serializer.serialize(post._createSnapshot());\n ok(!payload.hasOwnProperty(serializedProperty), \"Does not add the key to instance\");\n});\n\ntest(\'Serializer respects `serialize: false` on the attrs hash for a `belongsTo` property\', function() {\n expect(1);\n env.registry.register(\"serializer:comment\", DS.JSONSerializer.extend({\n attrs: {\n post: { serialize: false }\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post });\n });\n\n var serializer = env.container.lookup(\"serializer:comment\");\n var serializedProperty = serializer.keyForRelationship(\'post\', \'belongsTo\');\n\n var payload = serializer.serialize(comment._createSnapshot());\n ok(!payload.hasOwnProperty(serializedProperty), \"Does not add the key to instance\");\n});\n\ntest(\"Serializer should merge attrs from superclasses\", function() {\n expect(4);\n Post.reopen({\n description: DS.attr(\'string\'),\n anotherString: DS.attr(\'string\')\n });\n var BaseSerializer = DS.JSONSerializer.extend({\n attrs: {\n title: \"title_payload_key\",\n anotherString: \"base_another_string_key\"\n }\n });\n env.registry.register(\"serializer:post\", BaseSerializer.extend({\n attrs: {\n description: \"description_payload_key\",\n anotherString: \"overwritten_another_string_key\"\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\", description: \"Omakase is delicious\", anotherString: \"yet another string\" });\n });\n\n var payload = env.container.lookup(\"serializer:post\").serialize(post._createSnapshot());\n\n equal(payload.title_payload_key, \"Rails is omakase\");\n equal(payload.description_payload_key, \"Omakase is delicious\");\n equal(payload.overwritten_another_string_key, \"yet another string\");\n ok(!payload.base_another_string_key, \"overwritten key is not added\");\n});\n\ntest(\"Serializer should respect the primaryKey attribute when extracting records\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n primaryKey: \'_ID_\'\n }));\n\n var jsonHash = { \"_ID_\": 1, title: \"Rails is omakase\" };\n\n run(function() {\n post = env.container.lookup(\"serializer:post\").extractSingle(env.store, Post, jsonHash);\n });\n\n equal(post.id, \"1\");\n equal(post.title, \"Rails is omakase\");\n});\n\ntest(\"Serializer should respect the primaryKey attribute when serializing records\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n primaryKey: \'_ID_\'\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { id: \"1\", title: \"Rails is omakase\" });\n });\n\n var payload = env.container.lookup(\"serializer:post\").serialize(post._createSnapshot(), { includeId: true });\n\n equal(payload._ID_, \"1\");\n});\n\ntest(\"Serializer should respect keyForAttribute when extracting records\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForAttribute: function(key) {\n return key.toUpperCase();\n }\n }));\n\n var jsonHash = { id: 1, TITLE: \'Rails is omakase\' };\n\n post = env.container.lookup(\"serializer:post\").normalize(Post, jsonHash);\n\n equal(post.id, \"1\");\n equal(post.title, \"Rails is omakase\");\n});\n\ntest(\"Serializer should respect keyForRelationship when extracting records\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForRelationship: function(key, type) {\n return key.toUpperCase();\n }\n }));\n\n var jsonHash = { id: 1, title: \'Rails is omakase\', COMMENTS: [\'1\'] };\n\n post = env.container.lookup(\"serializer:post\").normalize(Post, jsonHash);\n\n deepEqual(post.comments, [\'1\']);\n});\n\ntest(\"normalizePayload is called during extractSingle\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n normalizePayload: function(payload) {\n return payload.response;\n }\n }));\n\n var jsonHash = {\n response: {\n id: 1,\n title: \"Rails is omakase\"\n }\n };\n\n run(function() {\n post = env.container.lookup(\"serializer:post\").extractSingle(env.store, Post, jsonHash);\n });\n\n equal(post.id, \"1\");\n equal(post.title, \"Rails is omakase\");\n});\n\ntest(\"Calling normalize should normalize the payload (only the passed keys)\", function () {\n expect(1);\n var Person = DS.Model.extend({\n posts: DS.hasMany(\'post\')\n });\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n attrs: {\n notInHash: \'aCustomAttrNotInHash\',\n inHash: \'aCustomAttrInHash\'\n }\n }));\n\n env.registry.register(\'model:person\', Person);\n\n Post.reopen({\n content: DS.attr(\'string\'),\n author: DS.belongsTo(\'person\'),\n notInHash: DS.attr(\'string\'),\n inHash: DS.attr(\'string\')\n });\n\n var normalizedPayload = env.container.lookup(\"serializer:post\").normalize(Post, {\n id: \'1\',\n title: \'Ember rocks\',\n author: 1,\n aCustomAttrInHash: \'blah\'\n });\n\n deepEqual(normalizedPayload, {\n id: \'1\',\n title: \'Ember rocks\',\n author: 1,\n inHash: \'blah\'\n });\n});\n\ntest(\'serializeBelongsTo with async polymorphic\', function() {\n var json = {};\n var expected = { post: \'1\', postTYPE: \'post\' };\n\n env.registry.register(\'serializer:favorite\', DS.JSONSerializer.extend({\n serializePolymorphicType: function(snapshot, json, relationship) {\n var key = relationship.key;\n json[key + \'TYPE\'] = snapshot.belongsTo(key).typeKey;\n }\n }));\n\n run(function() {\n post = env.store.createRecord(Post, { title: \'Kitties are omakase\', id: \'1\' });\n favorite = env.store.createRecord(Favorite, { post: post, id: \'3\' });\n });\n\n env.container.lookup(\'serializer:favorite\').serializeBelongsTo(favorite._createSnapshot(), json, { key: \'post\', options: { polymorphic: true, async: true } });\n\n deepEqual(json, expected, \'returned JSON is correct\');\n});\n\ntest(\'extractErrors respects custom key mappings\', function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n attrs: {\n title: \'le_title\',\n comments: { key: \'my_comments\' }\n }\n }));\n\n var payload = {\n errors: {\n le_title: [\"title errors\"],\n my_comments: [\"comments errors\"]\n }\n };\n\n var errors = env.container.lookup(\'serializer:post\').extractErrors(env.store, Post, payload);\n\n deepEqual(errors, {\n title: [\"title errors\"],\n comments: [\"comments errors\"]\n });\n});\n\ntest(\'extractErrors expects error information located on the errors property of payload\', function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend());\n\n var payload = {\n attributeWhichWillBeRemovedinExtractErrors: [\"true\"],\n errors: {\n title: [\"title errors\"]\n }\n };\n\n var errors = env.container.lookup(\'serializer:post\').extractErrors(env.store, Post, payload);\n\n deepEqual(errors, { title: [\"title errors\"] });\n});\n\ntest(\'extractErrors leaves payload untouched if it has no errors property\', function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend());\n\n var payload = {\n untouchedSinceNoErrorsSiblingPresent: [\"true\"]\n };\n\n var errors = env.container.lookup(\'serializer:post\').extractErrors(env.store, Post, payload);\n\n deepEqual(errors, { untouchedSinceNoErrorsSiblingPresent: [\"true\"] });\n});\n})();//# sourceURL=ember-data/integration/serializers/json-serializer-test.js");
363
+ eval("(function() {var Post, post, Comment, comment, Favorite, favorite, env;\nvar run = Ember.run;\n\nmodule(\"integration/serializer/json - JSONSerializer\", {\n setup: function() {\n Post = DS.Model.extend({\n title: DS.attr(\'string\'),\n comments: DS.hasMany(\'comment\', { inverse: null })\n });\n Comment = DS.Model.extend({\n body: DS.attr(\'string\'),\n post: DS.belongsTo(\'post\')\n });\n Favorite = DS.Model.extend({\n post: DS.belongsTo(\'post\', { async: true, polymorphic: true })\n });\n env = setupStore({\n post: Post,\n comment: Comment,\n favorite: Favorite\n });\n env.store.modelFor(\'post\');\n env.store.modelFor(\'comment\');\n env.store.modelFor(\'favorite\');\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"serializeAttribute\", function() {\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n });\n var json = {};\n\n env.serializer.serializeAttribute(post._createSnapshot(), json, \"title\", { type: \"string\" });\n\n deepEqual(json, {\n title: \"Rails is omakase\"\n });\n});\n\ntest(\"serializeAttribute respects keyForAttribute\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForAttribute: function(key) {\n return key.toUpperCase();\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n });\n var json = {};\n\n env.container.lookup(\"serializer:post\").serializeAttribute(post._createSnapshot(), json, \"title\", { type: \"string\" });\n\n deepEqual(json, { TITLE: \"Rails is omakase\" });\n});\n\ntest(\"serializeBelongsTo\", function() {\n run(function() {\n post = env.store.createRecord(Post, { title: \"Rails is omakase\", id: \"1\" });\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post });\n });\n\n var json = {};\n\n env.serializer.serializeBelongsTo(comment._createSnapshot(), json, { key: \"post\", options: {} });\n\n deepEqual(json, { post: \"1\" });\n});\n\ntest(\"serializeBelongsTo with null\", function() {\n run(function() {\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: null });\n });\n var json = {};\n\n env.serializer.serializeBelongsTo(comment._createSnapshot(), json, { key: \"post\", options: {} });\n\n deepEqual(json, {\n post: null\n }, \"Can set a belongsTo to a null value\");\n});\n\ntest(\"async serializeBelongsTo with null\", function() {\n Comment.reopen({\n post: DS.belongsTo(\'post\', { async: true })\n });\n run(function() {\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: null });\n });\n var json = {};\n\n env.serializer.serializeBelongsTo(comment._createSnapshot(), json, { key: \"post\", options: {} });\n\n deepEqual(json, {\n post: null\n }, \"Can set a belongsTo to a null value\");\n});\n\ntest(\"serializeBelongsTo respects keyForRelationship\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForRelationship: function(key, type) {\n return key.toUpperCase();\n }\n }));\n run(function() {\n post = env.store.createRecord(Post, { title: \"Rails is omakase\", id: \"1\" });\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post });\n });\n var json = {};\n\n env.container.lookup(\"serializer:post\").serializeBelongsTo(comment._createSnapshot(), json, { key: \"post\", options: {} });\n\n deepEqual(json, {\n POST: \"1\"\n });\n});\n\ntest(\"serializeHasMany respects keyForRelationship\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForRelationship: function(key, type) {\n return key.toUpperCase();\n }\n }));\n\n run(function() {\n post = env.store.createRecord(Post, { title: \"Rails is omakase\", id: \"1\" });\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post, id: \"1\" });\n });\n\n var json = {};\n\n env.container.lookup(\"serializer:post\").serializeHasMany(post._createSnapshot(), json, { key: \"comments\", options: {} });\n\n deepEqual(json, {\n COMMENTS: [\"1\"]\n });\n});\n\ntest(\"serializeIntoHash\", function() {\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n });\n\n var json = {};\n\n env.serializer.serializeIntoHash(json, Post, post._createSnapshot());\n\n deepEqual(json, {\n title: \"Rails is omakase\",\n comments: []\n });\n});\n\ntest(\"serializePolymorphicType sync\", function() {\n expect(1);\n\n env.registry.register(\'serializer:comment\', DS.JSONSerializer.extend({\n serializePolymorphicType: function(record, json, relationship) {\n var key = relationship.key;\n var belongsTo = record.belongsTo(key);\n json[relationship.key + \"TYPE\"] = belongsTo.modelName;\n\n ok(true, \'serializePolymorphicType is called when serialize a polymorphic belongsTo\');\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\'post\', { title: \'Rails is omakase\', id: 1 });\n comment = env.store.createRecord(\'comment\', { body: \'Omakase is delicious\', post: post });\n });\n\n env.container.lookup(\'serializer:comment\').serializeBelongsTo(comment._createSnapshot(), {}, { key: \'post\', options: { polymorphic: true } });\n});\n\ntest(\"serializePolymorphicType async\", function() {\n expect(1);\n\n Comment.reopen({\n post: DS.belongsTo(\'post\', { async: true })\n });\n\n env.registry.register(\'serializer:comment\', DS.JSONSerializer.extend({\n serializePolymorphicType: function(record, json, relationship) {\n ok(true, \'serializePolymorphicType is called when serialize a polymorphic belongsTo\');\n }\n }));\n\n run(function() {\n post = env.store.createRecord(Post, { title: \'Rails is omakase\', id: 1 });\n comment = env.store.createRecord(Comment, { body: \'Omakase is delicious\', post: post });\n });\n\n env.container.lookup(\'serializer:comment\').serializeBelongsTo(comment._createSnapshot(), {}, { key: \'post\', options: { async: true, polymorphic: true } });\n});\n\ntest(\"extractArray normalizes each record in the array\", function() {\n var postNormalizeCount = 0;\n var posts = [\n { title: \"Rails is omakase\" },\n { title: \"Another Post\" }\n ];\n\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n normalize: function () {\n postNormalizeCount++;\n return this._super.apply(this, arguments);\n }\n }));\n\n run(function() {\n env.container.lookup(\"serializer:post\").extractArray(env.store, Post, posts);\n });\n equal(postNormalizeCount, 2, \"two posts are normalized\");\n});\n\ntest(\'Serializer should respect the attrs hash when extracting records\', function() {\n env.registry.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n title: \"title_payload_key\",\n comments: { key: \'my_comments\' }\n }\n }));\n\n var jsonHash = {\n title_payload_key: \"Rails is omakase\",\n my_comments: [1, 2]\n };\n\n var post = env.container.lookup(\"serializer:post\").extractSingle(env.store, Post, jsonHash);\n\n equal(post.title, \"Rails is omakase\");\n deepEqual(post.comments, [1,2]);\n});\n\ntest(\'Serializer should respect the attrs hash when serializing records\', function() {\n Post.reopen({\n parentPost: DS.belongsTo(\'post\', { inverse: null })\n });\n env.registry.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n title: \"title_payload_key\",\n parentPost: { key: \"my_parent\" }\n }\n }));\n var parentPost;\n\n run(function() {\n parentPost = env.store.push(\"post\", { id: 2, title: \"Rails is omakase\" });\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\", parentPost: parentPost });\n });\n\n var payload = env.container.lookup(\"serializer:post\").serialize(post._createSnapshot());\n\n equal(payload.title_payload_key, \"Rails is omakase\");\n equal(payload.my_parent, \'2\');\n});\n\ntest(\'Serializer respects `serialize: false` on the attrs hash\', function() {\n expect(2);\n env.registry.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n title: { serialize: false }\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n });\n\n var payload = env.container.lookup(\"serializer:post\").serialize(post._createSnapshot());\n\n ok(!payload.hasOwnProperty(\'title\'), \"Does not add the key to instance\");\n ok(!payload.hasOwnProperty(\'[object Object]\'), \"Does not add some random key like [object Object]\");\n});\n\ntest(\'Serializer respects `serialize: false` on the attrs hash for a `hasMany` property\', function() {\n expect(1);\n env.registry.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n comments: { serialize: false }\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post });\n });\n\n var serializer = env.container.lookup(\"serializer:post\");\n var serializedProperty = serializer.keyForRelationship(\'comments\', \'hasMany\');\n\n var payload = serializer.serialize(post._createSnapshot());\n ok(!payload.hasOwnProperty(serializedProperty), \"Does not add the key to instance\");\n});\n\ntest(\'Serializer respects `serialize: false` on the attrs hash for a `belongsTo` property\', function() {\n expect(1);\n env.registry.register(\"serializer:comment\", DS.JSONSerializer.extend({\n attrs: {\n post: { serialize: false }\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\" });\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post });\n });\n\n var serializer = env.container.lookup(\"serializer:comment\");\n var serializedProperty = serializer.keyForRelationship(\'post\', \'belongsTo\');\n\n var payload = serializer.serialize(comment._createSnapshot());\n ok(!payload.hasOwnProperty(serializedProperty), \"Does not add the key to instance\");\n});\n\ntest(\"Serializer should merge attrs from superclasses\", function() {\n expect(4);\n Post.reopen({\n description: DS.attr(\'string\'),\n anotherString: DS.attr(\'string\')\n });\n var BaseSerializer = DS.JSONSerializer.extend({\n attrs: {\n title: \"title_payload_key\",\n anotherString: \"base_another_string_key\"\n }\n });\n env.registry.register(\"serializer:post\", BaseSerializer.extend({\n attrs: {\n description: \"description_payload_key\",\n anotherString: \"overwritten_another_string_key\"\n }\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\", description: \"Omakase is delicious\", anotherString: \"yet another string\" });\n });\n\n var payload = env.container.lookup(\"serializer:post\").serialize(post._createSnapshot());\n\n equal(payload.title_payload_key, \"Rails is omakase\");\n equal(payload.description_payload_key, \"Omakase is delicious\");\n equal(payload.overwritten_another_string_key, \"yet another string\");\n ok(!payload.base_another_string_key, \"overwritten key is not added\");\n});\n\ntest(\"Serializer should respect the primaryKey attribute when extracting records\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n primaryKey: \'_ID_\'\n }));\n\n var jsonHash = { \"_ID_\": 1, title: \"Rails is omakase\" };\n\n run(function() {\n post = env.container.lookup(\"serializer:post\").extractSingle(env.store, Post, jsonHash);\n });\n\n equal(post.id, \"1\");\n equal(post.title, \"Rails is omakase\");\n});\n\ntest(\"Serializer should respect the primaryKey attribute when serializing records\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n primaryKey: \'_ID_\'\n }));\n\n run(function() {\n post = env.store.createRecord(\"post\", { id: \"1\", title: \"Rails is omakase\" });\n });\n\n var payload = env.container.lookup(\"serializer:post\").serialize(post._createSnapshot(), { includeId: true });\n\n equal(payload._ID_, \"1\");\n});\n\ntest(\"Serializer should respect keyForAttribute when extracting records\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForAttribute: function(key) {\n return key.toUpperCase();\n }\n }));\n\n var jsonHash = { id: 1, TITLE: \'Rails is omakase\' };\n\n post = env.container.lookup(\"serializer:post\").normalize(Post, jsonHash);\n\n equal(post.id, \"1\");\n equal(post.title, \"Rails is omakase\");\n});\n\ntest(\"Serializer should respect keyForRelationship when extracting records\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForRelationship: function(key, type) {\n return key.toUpperCase();\n }\n }));\n\n var jsonHash = { id: 1, title: \'Rails is omakase\', COMMENTS: [\'1\'] };\n\n post = env.container.lookup(\"serializer:post\").normalize(Post, jsonHash);\n\n deepEqual(post.comments, [\'1\']);\n});\n\ntest(\"normalizePayload is called during extractSingle\", function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n normalizePayload: function(payload) {\n return payload.response;\n }\n }));\n\n var jsonHash = {\n response: {\n id: 1,\n title: \"Rails is omakase\"\n }\n };\n\n run(function() {\n post = env.container.lookup(\"serializer:post\").extractSingle(env.store, Post, jsonHash);\n });\n\n equal(post.id, \"1\");\n equal(post.title, \"Rails is omakase\");\n});\n\ntest(\"Calling normalize should normalize the payload (only the passed keys)\", function () {\n expect(1);\n var Person = DS.Model.extend({\n posts: DS.hasMany(\'post\')\n });\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n attrs: {\n notInHash: \'aCustomAttrNotInHash\',\n inHash: \'aCustomAttrInHash\'\n }\n }));\n\n env.registry.register(\'model:person\', Person);\n\n Post.reopen({\n content: DS.attr(\'string\'),\n author: DS.belongsTo(\'person\'),\n notInHash: DS.attr(\'string\'),\n inHash: DS.attr(\'string\')\n });\n\n var normalizedPayload = env.container.lookup(\"serializer:post\").normalize(Post, {\n id: \'1\',\n title: \'Ember rocks\',\n author: 1,\n aCustomAttrInHash: \'blah\'\n });\n\n deepEqual(normalizedPayload, {\n id: \'1\',\n title: \'Ember rocks\',\n author: 1,\n inHash: \'blah\'\n });\n});\n\ntest(\'serializeBelongsTo with async polymorphic\', function() {\n var json = {};\n var expected = { post: \'1\', postTYPE: \'post\' };\n\n env.registry.register(\'serializer:favorite\', DS.JSONSerializer.extend({\n serializePolymorphicType: function(snapshot, json, relationship) {\n var key = relationship.key;\n json[key + \'TYPE\'] = snapshot.belongsTo(key).modelName;\n }\n }));\n\n run(function() {\n post = env.store.createRecord(Post, { title: \'Kitties are omakase\', id: \'1\' });\n favorite = env.store.createRecord(Favorite, { post: post, id: \'3\' });\n });\n\n env.container.lookup(\'serializer:favorite\').serializeBelongsTo(favorite._createSnapshot(), json, { key: \'post\', options: { polymorphic: true, async: true } });\n\n deepEqual(json, expected, \'returned JSON is correct\');\n});\n\ntest(\'extractErrors respects custom key mappings\', function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend({\n attrs: {\n title: \'le_title\',\n comments: { key: \'my_comments\' }\n }\n }));\n\n var payload = {\n errors: {\n le_title: [\"title errors\"],\n my_comments: [\"comments errors\"]\n }\n };\n\n var errors = env.container.lookup(\'serializer:post\').extractErrors(env.store, Post, payload);\n\n deepEqual(errors, {\n title: [\"title errors\"],\n comments: [\"comments errors\"]\n });\n});\n\ntest(\'extractErrors expects error information located on the errors property of payload\', function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend());\n\n var payload = {\n attributeWhichWillBeRemovedinExtractErrors: [\"true\"],\n errors: {\n title: [\"title errors\"]\n }\n };\n\n var errors = env.container.lookup(\'serializer:post\').extractErrors(env.store, Post, payload);\n\n deepEqual(errors, { title: [\"title errors\"] });\n});\n\ntest(\'extractErrors leaves payload untouched if it has no errors property\', function() {\n env.registry.register(\'serializer:post\', DS.JSONSerializer.extend());\n\n var payload = {\n untouchedSinceNoErrorsSiblingPresent: [\"true\"]\n };\n\n var errors = env.container.lookup(\'serializer:post\').extractErrors(env.store, Post, payload);\n\n deepEqual(errors, { untouchedSinceNoErrorsSiblingPresent: [\"true\"] });\n});\n})();//# sourceURL=ember-data/integration/serializers/json-serializer-test.js");
348
364
 
349
- eval("(function() {var get = Ember.get;\nvar HomePlanet, league, SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, Comment, env;\nvar run = Ember.run;\n\nmodule(\"integration/serializer/rest - RESTSerializer\", {\n setup: function() {\n HomePlanet = DS.Model.extend({\n name: DS.attr(\'string\'),\n superVillains: DS.hasMany(\'superVillain\')\n });\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n homePlanet: DS.belongsTo(\"homePlanet\"),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n YellowMinion = EvilMinion.extend();\n DoomsdayDevice = DS.Model.extend({\n name: DS.attr(\'string\'),\n evilMinion: DS.belongsTo(\'evilMinion\', { polymorphic: true })\n });\n Comment = DS.Model.extend({\n body: DS.attr(\'string\'),\n root: DS.attr(\'boolean\'),\n children: DS.hasMany(\'comment\', { inverse: null })\n });\n env = setupStore({\n superVillain: SuperVillain,\n homePlanet: HomePlanet,\n evilMinion: EvilMinion,\n yellowMinion: YellowMinion,\n doomsdayDevice: DoomsdayDevice,\n comment: Comment\n });\n env.store.modelFor(\'superVillain\');\n env.store.modelFor(\'homePlanet\');\n env.store.modelFor(\'evilMinion\');\n env.store.modelFor(\'yellowMinion\');\n env.store.modelFor(\'doomsdayDevice\');\n env.store.modelFor(\'comment\');\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"typeForRoot returns always same typeKey even for uncountable multi words keys\", function() {\n expect(2);\n Ember.Inflector.inflector.uncountable(\'words\');\n var expectedTypeKey = \'multiWords\';\n equal(env.restSerializer.typeForRoot(\'multi_words\'), expectedTypeKey);\n equal(env.restSerializer.typeForRoot(\'multiWords\'), expectedTypeKey);\n});\n\ntest(\"extractArray with custom typeForRoot\", function() {\n env.restSerializer.typeForRoot = function(root) {\n var camelized = Ember.String.camelize(root);\n return Ember.String.singularize(camelized);\n };\n\n var jsonHash = {\n home_planets: [{ id: \"1\", name: \"Umber\", superVillains: [1] }],\n super_villains: [{ id: \"1\", firstName: \"Tom\", lastName: \"Dale\", homePlanet: \"1\" }]\n };\n var array;\n\n run(function() {\n array = env.restSerializer.extractArray(env.store, HomePlanet, jsonHash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n name: \"Umber\",\n superVillains: [1]\n }]);\n\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"extractArray warning with custom typeForRoot\", function() {\n var homePlanets;\n env.restSerializer.typeForRoot = function(root) {\n //return some garbage that won\"t resolve in the container\n return \"garbage\";\n };\n\n var jsonHash = {\n home_planets: [{ id: \"1\", name: \"Umber\", superVillains: [1] }]\n };\n\n warns(function() {\n env.restSerializer.extractArray(env.store, HomePlanet, jsonHash);\n }, /Encountered \"home_planets\" in payload, but no model was found for model name \"garbage\"/);\n\n // should not warn if a model is found.\n env.restSerializer.typeForRoot = function(root) {\n return Ember.String.camelize(Ember.String.singularize(root));\n };\n\n jsonHash = {\n home_planets: [{ id: \"1\", name: \"Umber\", superVillains: [1] }]\n };\n\n noWarns(function() {\n run(function() {\n homePlanets = Ember.A(env.restSerializer.extractArray(env.store, HomePlanet, jsonHash));\n });\n });\n\n equal(get(homePlanets, \"length\"), 1);\n equal(get(homePlanets, \"firstObject.name\"), \"Umber\");\n deepEqual(get(homePlanets, \"firstObject.superVillains\"), [1]);\n});\n\ntest(\"extractSingle warning with custom typeForRoot\", function() {\n var homePlanet;\n env.restSerializer.typeForRoot = function(root) {\n //return some garbage that won\"t resolve in the container\n return \"garbage\";\n };\n\n var jsonHash = {\n home_planet: { id: \"1\", name: \"Umber\", superVillains: [1] }\n };\n\n warns(Ember.run.bind(null, function() {\n run(function() {\n env.restSerializer.extractSingle(env.store, HomePlanet, jsonHash);\n });\n }), /Encountered \"home_planet\" in payload, but no model was found for model name \"garbage\"/);\n\n // should not warn if a model is found.\n env.restSerializer.typeForRoot = function(root) {\n return Ember.String.camelize(Ember.String.singularize(root));\n };\n\n jsonHash = {\n home_planet: { id: \"1\", name: \"Umber\", superVillains: [1] }\n };\n\n noWarns(function() {\n run(function() {\n homePlanet = env.restSerializer.extractSingle(env.store, HomePlanet, jsonHash);\n });\n });\n\n equal(get(homePlanet, \"name\"), \"Umber\");\n deepEqual(get(homePlanet, \"superVillains\"), [1]);\n});\n\ntest(\"pushPayload - single record payload - warning with custom typeForRoot\", function() {\n var homePlanet;\n var HomePlanetRestSerializer = DS.RESTSerializer.extend({\n typeForRoot: function(root) {\n //return some garbage that won\"t resolve in the container\n if (root === \"home_planet\") {\n return \"garbage\";\n } else {\n return Ember.String.singularize(Ember.String.camelize(root));\n }\n }\n });\n\n env.registry.register(\"serializer:homePlanet\", HomePlanetRestSerializer);\n\n var jsonHash = {\n home_planet: { id: \"1\", name: \"Umber\", superVillains: [1] },\n super_villains: [{ id: \"1\", firstName: \"Stanley\" }]\n };\n\n warns(function() {\n run(function() {\n env.store.pushPayload(\"homePlanet\", jsonHash);\n });\n }, /Encountered \"home_planet\" in payload, but no model was found for model name \"garbage\"/);\n\n\n // assert non-warned records get pushed into store correctly\n var superVillain = env.store.getById(\"superVillain\", \"1\");\n equal(get(superVillain, \"firstName\"), \"Stanley\");\n\n // Serializers are singletons, so that\"s why we use the store which\n // looks at the container to look it up\n env.store.serializerFor(\"homePlanet\").reopen({\n typeForRoot: function(root) {\n // should not warn if a model is found.\n return Ember.String.camelize(Ember.String.singularize(root));\n }\n });\n\n jsonHash = {\n home_planet: { id: \"1\", name: \"Umber\", superVillains: [1] },\n super_villains: [{ id: \"1\", firstName: \"Stanley\" }]\n };\n\n noWarns(function() {\n run(function() {\n env.store.pushPayload(\"homePlanet\", jsonHash);\n homePlanet = env.store.getById(\"homePlanet\", \"1\");\n });\n });\n\n equal(get(homePlanet, \"name\"), \"Umber\");\n deepEqual(get(homePlanet, \"superVillains.firstObject.firstName\"), \"Stanley\");\n});\n\ntest(\"pushPayload - multiple record payload (extractArray) - warning with custom typeForRoot\", function() {\n var homePlanet;\n var HomePlanetRestSerializer = DS.RESTSerializer.extend({\n typeForRoot: function(root) {\n //return some garbage that won\"t resolve in the container\n if (root === \"home_planets\") {\n return \"garbage\";\n } else {\n return Ember.String.singularize(Ember.String.camelize(root));\n }\n }\n });\n\n env.registry.register(\"serializer:homePlanet\", HomePlanetRestSerializer);\n\n var jsonHash = {\n home_planets: [{ id: \"1\", name: \"Umber\", superVillains: [1] }],\n super_villains: [{ id: \"1\", firstName: \"Stanley\" }]\n };\n\n warns(function() {\n run(function() {\n env.store.pushPayload(\"homePlanet\", jsonHash);\n });\n }, /Encountered \"home_planets\" in payload, but no model was found for model name \"garbage\"/);\n\n // assert non-warned records get pushed into store correctly\n var superVillain = env.store.getById(\"superVillain\", \"1\");\n equal(get(superVillain, \"firstName\"), \"Stanley\");\n\n // Serializers are singletons, so that\"s why we use the store which\n // looks at the container to look it up\n env.store.serializerFor(\"homePlanet\").reopen({\n typeForRoot: function(root) {\n // should not warn if a model is found.\n return Ember.String.camelize(Ember.String.singularize(root));\n }\n });\n\n jsonHash = {\n home_planets: [{ id: \"1\", name: \"Umber\", superVillains: [1] }],\n super_villains: [{ id: \"1\", firstName: \"Stanley\" }]\n };\n\n noWarns(function() {\n run(function() {\n env.store.pushPayload(\"homePlanet\", jsonHash);\n homePlanet = env.store.getById(\"homePlanet\", \"1\");\n });\n });\n\n equal(get(homePlanet, \"name\"), \"Umber\");\n deepEqual(get(homePlanet, \"superVillains.firstObject.firstName\"), \"Stanley\");\n});\n\ntest(\"serialize polymorphicType\", function() {\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(YellowMinion, { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.restSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json, {\n name: \"DeathRay\",\n evilMinionType: \"yellowMinion\",\n evilMinion: \"124\"\n });\n});\n\ntest(\"serialize polymorphicType with decamelized typeKey\", function() {\n YellowMinion.typeKey = \'yellow-minion\';\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(YellowMinion, { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.restSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json[\"evilMinionType\"], \"yellowMinion\");\n});\n\ntest(\"normalizePayload is called during extractSingle\", function() {\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n normalizePayload: function(payload) {\n return payload.response;\n }\n }));\n\n var jsonHash = {\n response: {\n evilMinion: { id: \"1\", name: \"Tom Dale\", superVillain: 1 },\n superVillains: [{ id: \"1\", firstName: \"Yehuda\", lastName: \"Katz\", homePlanet: \"1\" }]\n }\n };\n\n var applicationSerializer = env.container.lookup(\'serializer:application\');\n var data;\n\n run(function() {\n data = applicationSerializer.extractSingle(env.store, EvilMinion, jsonHash);\n });\n\n equal(data.name, jsonHash.response.evilMinion.name, \"normalize reads off the response\");\n\n});\ntest(\"serialize polymorphic when associated object is null\", function() {\n var ray;\n run(function() {\n ray = env.store.createRecord(DoomsdayDevice, { name: \"DeathRay\" });\n });\n\n var json = env.restSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json[\"evilMinionType\"], null);\n});\n\ntest(\"extractArray can load secondary records of the same type without affecting the query count\", function() {\n var jsonHash = {\n comments: [{ id: \"1\", body: \"Parent Comment\", root: true, children: [2, 3] }],\n _comments: [\n { id: \"2\", body: \"Child Comment 1\", root: false },\n { id: \"3\", body: \"Child Comment 2\", root: false }\n ]\n };\n var array;\n\n run(function() {\n array = env.restSerializer.extractArray(env.store, Comment, jsonHash);\n });\n\n deepEqual(array, [{\n \"id\": \"1\",\n \"body\": \"Parent Comment\",\n \"root\": true,\n \"children\": [2, 3]\n }]);\n\n equal(array.length, 1, \"The query count is unaffected\");\n\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"Child Comment 1\", \"Secondary records are in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Child Comment 2\", \"Secondary records are in the store\");\n});\n\ntest(\"extractSingle loads secondary records with correct serializer\", function() {\n var superVillainNormalizeCount = 0;\n\n env.registry.register(\'serializer:superVillain\', DS.RESTSerializer.extend({\n normalize: function() {\n superVillainNormalizeCount++;\n return this._super.apply(this, arguments);\n }\n }));\n\n var jsonHash = {\n evilMinion: { id: \"1\", name: \"Tom Dale\", superVillain: 1 },\n superVillains: [{ id: \"1\", firstName: \"Yehuda\", lastName: \"Katz\", homePlanet: \"1\" }]\n };\n\n run(function() {\n env.restSerializer.extractSingle(env.store, EvilMinion, jsonHash);\n });\n\n equal(superVillainNormalizeCount, 1, \"superVillain is normalized once\");\n});\n\ntest(\"extractSingle returns null if payload contains null\", function() {\n expect(1);\n\n var jsonHash = {\n evilMinion: null\n };\n var value;\n\n run(function() {\n value = env.restSerializer.extractSingle(env.store, EvilMinion, jsonHash);\n });\n\n equal(value, null, \"returned value is null\");\n});\n\ntest(\"extractArray loads secondary records with correct serializer\", function() {\n var superVillainNormalizeCount = 0;\n\n env.registry.register(\'serializer:superVillain\', DS.RESTSerializer.extend({\n normalize: function() {\n superVillainNormalizeCount++;\n return this._super.apply(this, arguments);\n }\n }));\n\n var jsonHash = {\n evilMinions: [{ id: \"1\", name: \"Tom Dale\", superVillain: 1 }],\n superVillains: [{ id: \"1\", firstName: \"Yehuda\", lastName: \"Katz\", homePlanet: \"1\" }]\n };\n\n run(function() {\n env.restSerializer.extractArray(env.store, EvilMinion, jsonHash);\n });\n\n equal(superVillainNormalizeCount, 1, \"superVillain is normalized once\");\n});\n\ntest(\'normalizeHash normalizes specific parts of the payload\', function() {\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n normalizeHash: {\n homePlanets: function(hash) {\n hash.id = hash._id;\n delete hash._id;\n return hash;\n }\n }\n }));\n\n var jsonHash = {\n homePlanets: [{ _id: \"1\", name: \"Umber\", superVillains: [1] }]\n };\n var array;\n\n run(function() {\n array = env.restSerializer.extractArray(env.store, HomePlanet, jsonHash);\n });\n\n deepEqual(array, [{\n \"id\": \"1\",\n \"name\": \"Umber\",\n \"superVillains\": [1]\n }]);\n});\n\ntest(\'normalizeHash works with transforms\', function() {\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n normalizeHash: {\n evilMinions: function(hash) {\n hash.condition = hash._condition;\n delete hash._condition;\n return hash;\n }\n }\n }));\n\n env.registry.register(\'transform:condition\', DS.Transform.extend({\n deserialize: function(serialized) {\n if (serialized === 1) {\n return \"healing\";\n } else {\n return \"unknown\";\n }\n },\n serialize: function(deserialized) {\n if (deserialized === \"healing\") {\n return 1;\n } else {\n return 2;\n }\n }\n }));\n\n EvilMinion.reopen({ condition: DS.attr(\'condition\') });\n\n var jsonHash = {\n evilMinions: [{ id: \"1\", name: \"Tom Dale\", superVillain: 1, _condition: 1 }]\n };\n var array;\n\n run(function() {\n array = env.restSerializer.extractArray(env.store, EvilMinion, jsonHash);\n });\n\n equal(array[0].condition, \"healing\");\n});\n\ntest(\'normalize should allow for different levels of normalization\', function() {\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n attrs: {\n superVillain: \'is_super_villain\'\n },\n keyForAttribute: function(attr) {\n return Ember.String.decamelize(attr);\n }\n }));\n\n var jsonHash = {\n evilMinions: [{ id: \"1\", name: \"Tom Dale\", is_super_villain: 1 }]\n };\n var array;\n\n run(function() {\n array = env.restSerializer.extractArray(env.store, EvilMinion, jsonHash);\n });\n\n equal(array[0].superVillain, 1);\n});\n\ntest(\"serializeIntoHash\", function() {\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Umber\", id: \"123\" });\n });\n var json = {};\n\n env.restSerializer.serializeIntoHash(json, HomePlanet, league._createSnapshot());\n\n deepEqual(json, {\n homePlanet: {\n name: \"Umber\"\n }\n });\n});\n\ntest(\"serializeIntoHash with decamelized typeKey\", function() {\n HomePlanet.typeKey = \'home-planet\';\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Umber\", id: \"123\" });\n });\n var json = {};\n\n env.restSerializer.serializeIntoHash(json, HomePlanet, league._createSnapshot());\n\n deepEqual(json, {\n homePlanet: {\n name: \"Umber\"\n }\n });\n});\n\ntest(\'serializeBelongsTo with async polymorphic\', function() {\n var evilMinion, doomsdayDevice;\n var json = {};\n var expected = { evilMinion: \'1\', evilMinionType: \'evilMinion\' };\n\n run(function() {\n evilMinion = env.store.createRecord(\'evilMinion\', { id: 1, name: \'Tomster\' });\n doomsdayDevice = env.store.createRecord(\'doomsdayDevice\', { id: 2, name: \'Yehuda\', evilMinion: evilMinion });\n });\n\n env.restSerializer.serializeBelongsTo(doomsdayDevice._createSnapshot(), json, { key: \'evilMinion\', options: { polymorphic: true, async: true } });\n\n deepEqual(json, expected, \'returned JSON is correct\');\n});\n})();//# sourceURL=ember-data/integration/serializers/rest-serializer-test.js");
365
+ eval("(function() {var get = Ember.get;\nvar HomePlanet, league, SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, Comment, env;\nvar run = Ember.run;\n\nmodule(\"integration/serializer/rest - RESTSerializer\", {\n setup: function() {\n HomePlanet = DS.Model.extend({\n name: DS.attr(\'string\'),\n superVillains: DS.hasMany(\'superVillain\')\n });\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n homePlanet: DS.belongsTo(\"homePlanet\"),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n YellowMinion = EvilMinion.extend();\n DoomsdayDevice = DS.Model.extend({\n name: DS.attr(\'string\'),\n evilMinion: DS.belongsTo(\'evilMinion\', { polymorphic: true })\n });\n Comment = DS.Model.extend({\n body: DS.attr(\'string\'),\n root: DS.attr(\'boolean\'),\n children: DS.hasMany(\'comment\', { inverse: null })\n });\n env = setupStore({\n superVillain: SuperVillain,\n homePlanet: HomePlanet,\n evilMinion: EvilMinion,\n yellowMinion: YellowMinion,\n doomsdayDevice: DoomsdayDevice,\n comment: Comment\n });\n env.store.modelFor(\'superVillain\');\n env.store.modelFor(\'homePlanet\');\n env.store.modelFor(\'evilMinion\');\n env.store.modelFor(\'yellowMinion\');\n env.store.modelFor(\'doomsdayDevice\');\n env.store.modelFor(\'comment\');\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"modelNameFromPayloadKey returns always same modelName even for uncountable multi words keys\", function() {\n expect(2);\n Ember.Inflector.inflector.uncountable(\'words\');\n var expectedModelName = \'multi-words\';\n equal(env.restSerializer.modelNameFromPayloadKey(\'multi_words\'), expectedModelName);\n equal(env.restSerializer.modelNameFromPayloadKey(\'multi-words\'), expectedModelName);\n});\n\ntest(\"extractArray with custom modelNameFromPayloadKey\", function() {\n env.restSerializer.modelNameFromPayloadKey = function(root) {\n var camelized = Ember.String.camelize(root);\n return Ember.String.singularize(camelized);\n };\n\n var jsonHash = {\n home_planets: [{ id: \"1\", name: \"Umber\", superVillains: [1] }],\n super_villains: [{ id: \"1\", firstName: \"Tom\", lastName: \"Dale\", homePlanet: \"1\" }]\n };\n var array;\n\n run(function() {\n array = env.restSerializer.extractArray(env.store, HomePlanet, jsonHash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n name: \"Umber\",\n superVillains: [1]\n }]);\n\n run(function() {\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"extractArray warning with custom modelNameFromPayloadKey\", function() {\n var homePlanets;\n env.restSerializer.modelNameFromPayloadKey = function(root) {\n //return some garbage that won\"t resolve in the container\n return \"garbage\";\n };\n\n var jsonHash = {\n home_planets: [{ id: \"1\", name: \"Umber\", superVillains: [1] }]\n };\n\n warns(function() {\n env.restSerializer.extractArray(env.store, HomePlanet, jsonHash);\n }, /Encountered \"home_planets\" in payload, but no model was found for model name \"garbage\"/);\n\n // should not warn if a model is found.\n env.restSerializer.modelNameFromPayloadKey = function(root) {\n return Ember.String.camelize(Ember.String.singularize(root));\n };\n\n jsonHash = {\n home_planets: [{ id: \"1\", name: \"Umber\", superVillains: [1] }]\n };\n\n noWarns(function() {\n run(function() {\n homePlanets = Ember.A(env.restSerializer.extractArray(env.store, HomePlanet, jsonHash));\n });\n });\n\n equal(get(homePlanets, \"length\"), 1);\n equal(get(homePlanets, \"firstObject.name\"), \"Umber\");\n deepEqual(get(homePlanets, \"firstObject.superVillains\"), [1]);\n});\n\ntest(\"extractSingle warning with custom modelNameFromPayloadKey\", function() {\n var homePlanet;\n env.restSerializer.modelNameFromPayloadKey = function(root) {\n //return some garbage that won\"t resolve in the container\n return \"garbage\";\n };\n\n var jsonHash = {\n home_planet: { id: \"1\", name: \"Umber\", superVillains: [1] }\n };\n\n warns(Ember.run.bind(null, function() {\n run(function() {\n env.restSerializer.extractSingle(env.store, HomePlanet, jsonHash);\n });\n }), /Encountered \"home_planet\" in payload, but no model was found for model name \"garbage\"/);\n\n // should not warn if a model is found.\n env.restSerializer.modelNameFromPayloadKey = function(root) {\n return Ember.String.camelize(Ember.String.singularize(root));\n };\n\n jsonHash = {\n home_planet: { id: \"1\", name: \"Umber\", superVillains: [1] }\n };\n\n noWarns(function() {\n run(function() {\n homePlanet = env.restSerializer.extractSingle(env.store, HomePlanet, jsonHash);\n });\n });\n\n equal(get(homePlanet, \"name\"), \"Umber\");\n deepEqual(get(homePlanet, \"superVillains\"), [1]);\n});\n\ntest(\"pushPayload - single record payload - warning with custom modelNameFromPayloadKey\", function() {\n var homePlanet;\n var HomePlanetRestSerializer = DS.RESTSerializer.extend({\n modelNameFromPayloadKey: function(root) {\n //return some garbage that won\"t resolve in the container\n if (root === \"home_planet\") {\n return \"garbage\";\n } else {\n return Ember.String.singularize(Ember.String.camelize(root));\n }\n }\n });\n\n env.registry.register(\"serializer:home-planet\", HomePlanetRestSerializer);\n\n var jsonHash = {\n home_planet: { id: \"1\", name: \"Umber\", superVillains: [1] },\n super_villains: [{ id: \"1\", firstName: \"Stanley\" }]\n };\n\n warns(function() {\n run(function() {\n env.store.pushPayload(\"homePlanet\", jsonHash);\n });\n }, /Encountered \"home_planet\" in payload, but no model was found for model name \"garbage\"/);\n\n\n // assert non-warned records get pushed into store correctly\n var superVillain = env.store.getById(\"superVillain\", \"1\");\n equal(get(superVillain, \"firstName\"), \"Stanley\");\n\n // Serializers are singletons, so that\"s why we use the store which\n // looks at the container to look it up\n env.store.serializerFor(\"homePlanet\").reopen({\n modelNameFromPayloadKey: function(root) {\n // should not warn if a model is found.\n return Ember.String.camelize(Ember.String.singularize(root));\n }\n });\n\n jsonHash = {\n home_planet: { id: \"1\", name: \"Umber\", superVillains: [1] },\n super_villains: [{ id: \"1\", firstName: \"Stanley\" }]\n };\n\n noWarns(function() {\n run(function() {\n env.store.pushPayload(\"homePlanet\", jsonHash);\n homePlanet = env.store.getById(\"homePlanet\", \"1\");\n });\n });\n\n equal(get(homePlanet, \"name\"), \"Umber\");\n deepEqual(get(homePlanet, \"superVillains.firstObject.firstName\"), \"Stanley\");\n});\n\ntest(\"pushPayload - multiple record payload (extractArray) - warning with custom modelNameFromPayloadKey\", function() {\n var homePlanet;\n var HomePlanetRestSerializer = DS.RESTSerializer.extend({\n modelNameFromPayloadKey: function(root) {\n //return some garbage that won\"t resolve in the container\n if (root === \"home_planets\") {\n return \"garbage\";\n } else {\n return Ember.String.singularize(Ember.String.camelize(root));\n }\n }\n });\n\n env.registry.register(\"serializer:home-planet\", HomePlanetRestSerializer);\n\n var jsonHash = {\n home_planets: [{ id: \"1\", name: \"Umber\", superVillains: [1] }],\n super_villains: [{ id: \"1\", firstName: \"Stanley\" }]\n };\n\n warns(function() {\n run(function() {\n env.store.pushPayload(\"homePlanet\", jsonHash);\n });\n }, /Encountered \"home_planets\" in payload, but no model was found for model name \"garbage\"/);\n\n // assert non-warned records get pushed into store correctly\n var superVillain = env.store.getById(\"superVillain\", \"1\");\n equal(get(superVillain, \"firstName\"), \"Stanley\");\n\n // Serializers are singletons, so that\"s why we use the store which\n // looks at the container to look it up\n env.store.serializerFor(\"homePlanet\").reopen({\n modelNameFromPayloadKey: function(root) {\n // should not warn if a model is found.\n return Ember.String.camelize(Ember.String.singularize(root));\n }\n });\n\n jsonHash = {\n home_planets: [{ id: \"1\", name: \"Umber\", superVillains: [1] }],\n super_villains: [{ id: \"1\", firstName: \"Stanley\" }]\n };\n\n noWarns(function() {\n run(function() {\n env.store.pushPayload(\"homePlanet\", jsonHash);\n homePlanet = env.store.getById(\"homePlanet\", \"1\");\n });\n });\n\n equal(get(homePlanet, \"name\"), \"Umber\");\n deepEqual(get(homePlanet, \"superVillains.firstObject.firstName\"), \"Stanley\");\n});\n\ntest(\"serialize polymorphicType\", function() {\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(YellowMinion, { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.restSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json, {\n name: \"DeathRay\",\n evilMinionType: \"yellowMinion\",\n evilMinion: \"124\"\n });\n});\n\ntest(\"serialize polymorphicType with decamelized modelName\", function() {\n YellowMinion.modelName = \'yellow-minion\';\n var tom, ray;\n run(function() {\n tom = env.store.createRecord(YellowMinion, { name: \"Alex\", id: \"124\" });\n ray = env.store.createRecord(DoomsdayDevice, { evilMinion: tom, name: \"DeathRay\" });\n });\n\n var json = env.restSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json[\"evilMinionType\"], \"yellowMinion\");\n});\n\ntest(\"normalizePayload is called during extractSingle\", function() {\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n normalizePayload: function(payload) {\n return payload.response;\n }\n }));\n\n var jsonHash = {\n response: {\n evilMinion: { id: \"1\", name: \"Tom Dale\", superVillain: 1 },\n superVillains: [{ id: \"1\", firstName: \"Yehuda\", lastName: \"Katz\", homePlanet: \"1\" }]\n }\n };\n\n var applicationSerializer = env.container.lookup(\'serializer:application\');\n var data;\n\n run(function() {\n data = applicationSerializer.extractSingle(env.store, EvilMinion, jsonHash);\n });\n\n equal(data.name, jsonHash.response.evilMinion.name, \"normalize reads off the response\");\n\n});\ntest(\"serialize polymorphic when associated object is null\", function() {\n var ray;\n run(function() {\n ray = env.store.createRecord(DoomsdayDevice, { name: \"DeathRay\" });\n });\n\n var json = env.restSerializer.serialize(ray._createSnapshot());\n\n deepEqual(json[\"evilMinionType\"], null);\n});\n\ntest(\"extractArray can load secondary records of the same type without affecting the query count\", function() {\n var jsonHash = {\n comments: [{ id: \"1\", body: \"Parent Comment\", root: true, children: [2, 3] }],\n _comments: [\n { id: \"2\", body: \"Child Comment 1\", root: false },\n { id: \"3\", body: \"Child Comment 2\", root: false }\n ]\n };\n var array;\n\n run(function() {\n array = env.restSerializer.extractArray(env.store, Comment, jsonHash);\n });\n\n deepEqual(array, [{\n \"id\": \"1\",\n \"body\": \"Parent Comment\",\n \"root\": true,\n \"children\": [2, 3]\n }]);\n\n equal(array.length, 1, \"The query count is unaffected\");\n\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"Child Comment 1\", \"Secondary records are in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Child Comment 2\", \"Secondary records are in the store\");\n});\n\ntest(\"extractSingle loads secondary records with correct serializer\", function() {\n var superVillainNormalizeCount = 0;\n\n env.registry.register(\'serializer:super-villain\', DS.RESTSerializer.extend({\n normalize: function() {\n superVillainNormalizeCount++;\n return this._super.apply(this, arguments);\n }\n }));\n\n var jsonHash = {\n evilMinion: { id: \"1\", name: \"Tom Dale\", superVillain: 1 },\n superVillains: [{ id: \"1\", firstName: \"Yehuda\", lastName: \"Katz\", homePlanet: \"1\" }]\n };\n\n run(function() {\n env.restSerializer.extractSingle(env.store, EvilMinion, jsonHash);\n });\n\n equal(superVillainNormalizeCount, 1, \"superVillain is normalized once\");\n});\n\ntest(\"extractSingle returns null if payload contains null\", function() {\n expect(1);\n\n var jsonHash = {\n evilMinion: null\n };\n var value;\n\n run(function() {\n value = env.restSerializer.extractSingle(env.store, EvilMinion, jsonHash);\n });\n\n equal(value, null, \"returned value is null\");\n});\n\ntest(\"extractArray loads secondary records with correct serializer\", function() {\n var superVillainNormalizeCount = 0;\n\n env.registry.register(\'serializer:super-villain\', DS.RESTSerializer.extend({\n normalize: function() {\n superVillainNormalizeCount++;\n return this._super.apply(this, arguments);\n }\n }));\n\n var jsonHash = {\n evilMinions: [{ id: \"1\", name: \"Tom Dale\", superVillain: 1 }],\n superVillains: [{ id: \"1\", firstName: \"Yehuda\", lastName: \"Katz\", homePlanet: \"1\" }]\n };\n\n run(function() {\n env.restSerializer.extractArray(env.store, EvilMinion, jsonHash);\n });\n\n equal(superVillainNormalizeCount, 1, \"superVillain is normalized once\");\n});\n\ntest(\'normalizeHash normalizes specific parts of the payload\', function() {\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n normalizeHash: {\n homePlanets: function(hash) {\n hash.id = hash._id;\n delete hash._id;\n return hash;\n }\n }\n }));\n\n var jsonHash = {\n homePlanets: [{ _id: \"1\", name: \"Umber\", superVillains: [1] }]\n };\n var array;\n\n run(function() {\n array = env.restSerializer.extractArray(env.store, HomePlanet, jsonHash);\n });\n\n deepEqual(array, [{\n \"id\": \"1\",\n \"name\": \"Umber\",\n \"superVillains\": [1]\n }]);\n});\n\ntest(\'normalizeHash works with transforms\', function() {\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n normalizeHash: {\n evilMinions: function(hash) {\n hash.condition = hash._condition;\n delete hash._condition;\n return hash;\n }\n }\n }));\n\n env.registry.register(\'transform:condition\', DS.Transform.extend({\n deserialize: function(serialized) {\n if (serialized === 1) {\n return \"healing\";\n } else {\n return \"unknown\";\n }\n },\n serialize: function(deserialized) {\n if (deserialized === \"healing\") {\n return 1;\n } else {\n return 2;\n }\n }\n }));\n\n EvilMinion.reopen({ condition: DS.attr(\'condition\') });\n\n var jsonHash = {\n evilMinions: [{ id: \"1\", name: \"Tom Dale\", superVillain: 1, _condition: 1 }]\n };\n var array;\n\n run(function() {\n array = env.restSerializer.extractArray(env.store, EvilMinion, jsonHash);\n });\n\n equal(array[0].condition, \"healing\");\n});\n\ntest(\'normalize should allow for different levels of normalization\', function() {\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n attrs: {\n superVillain: \'is_super_villain\'\n },\n keyForAttribute: function(attr) {\n return Ember.String.decamelize(attr);\n }\n }));\n\n var jsonHash = {\n evilMinions: [{ id: \"1\", name: \"Tom Dale\", is_super_villain: 1 }]\n };\n var array;\n\n run(function() {\n array = env.restSerializer.extractArray(env.store, EvilMinion, jsonHash);\n });\n\n equal(array[0].superVillain, 1);\n});\n\ntest(\"serializeIntoHash\", function() {\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Umber\", id: \"123\" });\n });\n var json = {};\n\n env.restSerializer.serializeIntoHash(json, HomePlanet, league._createSnapshot());\n\n deepEqual(json, {\n homePlanet: {\n name: \"Umber\"\n }\n });\n});\n\ntest(\"serializeIntoHash with decamelized modelName\", function() {\n HomePlanet.modelName = \'home-planet\';\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Umber\", id: \"123\" });\n });\n var json = {};\n\n env.restSerializer.serializeIntoHash(json, HomePlanet, league._createSnapshot());\n\n deepEqual(json, {\n homePlanet: {\n name: \"Umber\"\n }\n });\n});\n\ntest(\'serializeBelongsTo with async polymorphic\', function() {\n var evilMinion, doomsdayDevice;\n var json = {};\n var expected = { evilMinion: \'1\', evilMinionType: \'evilMinion\' };\n\n run(function() {\n evilMinion = env.store.createRecord(\'evilMinion\', { id: 1, name: \'Tomster\' });\n doomsdayDevice = env.store.createRecord(\'doomsdayDevice\', { id: 2, name: \'Yehuda\', evilMinion: evilMinion });\n });\n\n env.restSerializer.serializeBelongsTo(doomsdayDevice._createSnapshot(), json, { key: \'evilMinion\', options: { polymorphic: true, async: true } });\n\n deepEqual(json, expected, \'returned JSON is correct\');\n});\n\ntest(\'serializeIntoHash uses payloadKeyFromModelName to normalize the payload root key\', function() {\n run(function() {\n league = env.store.createRecord(HomePlanet, { name: \"Umber\", id: \"123\" });\n });\n var json = {};\n env.registry.register(\'serializer:home-planet\', DS.RESTSerializer.extend({\n payloadKeyFromModelName: function(modelName) {\n return Ember.String.dasherize(modelName);\n }\n }));\n\n env.container.lookup(\'serializer:home-planet\').serializeIntoHash(json, HomePlanet, league._createSnapshot());\n\n deepEqual(json, {\n \'home-planet\': {\n name: \"Umber\"\n }\n });\n});\n\ntest(\'pathForType is deprecated\', function() {\n expect(1);\n\n expectDeprecation(function() {\n Ember.Inflector.inflector.uncountable(\'words\');\n return env.restSerializer.typeForRoot(\'multi_words\');\n });\n});\n})();//# sourceURL=ember-data/integration/serializers/rest-serializer-test.js");
350
366
 
351
367
  eval("(function() {var run = Ember.run;\nvar Container = Ember.Container;\nvar Registry = Ember.Registry;\nvar Store = DS.Store;\nvar EmberObject = Ember.Object;\nvar setupContainer = DS._setupContainer;\n\nvar container, registry;\n\n/*\n These tests ensure that Ember Data works with Ember.js\' container\n initialization and dependency injection API.\n*/\n\nmodule(\"integration/setup-container - Setting up a container\", {\n setup: function() {\n if (Registry) {\n registry = new Registry();\n container = registry.container();\n } else {\n container = new Container();\n registry = container;\n }\n setupContainer(registry);\n },\n\n teardown: function() {\n run(container, container.destroy);\n }\n});\n\ntest(\"The store should be registered into a container.\", function() {\n ok(container.lookup(\'store:main\') instanceof Store, \"the custom store is instantiated\");\n});\n\ntest(\"The store should be registered into the container as a service.\", function() {\n ok(container.lookup(\'service:store\') instanceof Store, \"the store as a service is registered\");\n});\n\ntest(\"If a store is instantiated, it should be made available to each controller.\", function() {\n registry.register(\'controller:foo\', EmberObject.extend({}));\n var fooController = container.lookup(\'controller:foo\');\n ok(fooController.get(\'store\') instanceof Store, \"the store was injected\");\n});\n\ntest(\"the deprecated serializer:_default is resolved as serializer:default\", function() {\n var deprecated;\n var valid = container.lookup(\'serializer:-default\');\n expectDeprecation(function() {\n deprecated = container.lookup(\'serializer:_default\');\n });\n\n ok(deprecated.constructor === valid.constructor, \"they should resolve to the same thing\");\n});\n\ntest(\"the deprecated serializer:_rest is resolved as serializer:rest\", function() {\n var deprecated;\n var valid = container.lookup(\'serializer:-rest\');\n expectDeprecation(function() {\n deprecated = container.lookup(\'serializer:_rest\');\n });\n\n ok(deprecated.constructor === valid.constructor, \"they should resolve to the same thing\");\n});\n\ntest(\"the deprecated adapter:_rest is resolved as adapter:rest\", function() {\n var deprecated;\n var valid = container.lookup(\'adapter:-rest\');\n expectDeprecation(function() {\n deprecated = container.lookup(\'adapter:_rest\');\n });\n\n ok(deprecated.constructor === valid.constructor, \"they should resolve to the same thing\");\n});\n\ntest(\"a deprecation is made when looking up adapter:_rest\", function() {\n expectDeprecation(function() {\n container.lookup(\'serializer:_default\');\n }, \"You tried to look up \'serializer:_default\', but this has been deprecated in favor of \'serializer:-default\'.\");\n});\n\ntest(\"serializers are not returned as singletons - each lookup should return a different instance\", function() {\n var serializer1, serializer2;\n serializer1 = container.lookup(\'serializer:-rest\');\n serializer2 = container.lookup(\'serializer:-rest\');\n notEqual(serializer1, serializer2);\n});\n\ntest(\"adapters are not returned as singletons - each lookup should return a different instance\", function() {\n var adapter1, adapter2;\n adapter1 = container.lookup(\'adapter:-rest\');\n adapter2 = container.lookup(\'adapter:-rest\');\n notEqual(adapter1, adapter2);\n});\n})();//# sourceURL=ember-data/integration/setup-container-test.js");
352
368
 
353
- eval("(function() {var run = Ember.run;\nvar env, Post, Comment;\n\nmodule(\"integration/snapshot - DS.Snapshot\", {\n setup: function() {\n Post = DS.Model.extend({\n author: DS.attr(),\n title: DS.attr(),\n comments: DS.hasMany({ async: true })\n });\n Comment = DS.Model.extend({\n body: DS.attr(),\n post: DS.belongsTo({ async: true })\n });\n\n env = setupStore({\n post: Post,\n comment: Comment\n });\n },\n\n teardown: function() {\n run(function() {\n env.store.destroy();\n });\n }\n});\n\ntest(\"record._createSnapshot() returns a snapshot\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n ok(snapshot instanceof DS.Snapshot, \'snapshot is an instance of DS.Snapshot\');\n });\n});\n\ntest(\"snapshot._createSnapshot() returns a snapshot (self) but is deprecated\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot1 = post._createSnapshot();\n var snapshot2;\n\n expectDeprecation(function() {\n snapshot2 = snapshot1._createSnapshot();\n }, /You called _createSnapshot on what\'s already a DS.Snapshot. You shouldn\'t manually create snapshots in your adapter since the store passes snapshots to adapters by default./);\n\n ok(snapshot2 === snapshot1, \'snapshot._createSnapshot() returns self\');\n });\n\n});\n\ntest(\"snapshot.id, snapshot.type and snapshot.typeKey returns correctly\", function() {\n expect(3);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n equal(snapshot.id, \'1\', \'id is correct\');\n ok(DS.Model.detect(snapshot.type), \'type is correct\');\n equal(snapshot.typeKey, \'post\', \'typeKey is correct\');\n });\n});\n\ntest(\"snapshot.constructor is unique and deprecated\", function() {\n expect(4);\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 1, body: \'This is comment\' });\n var post = env.store.push(\'post\', { id: 2, title: \'Hello World\' });\n var commentSnapshot = comment._createSnapshot();\n var postSnapshot = post._createSnapshot();\n\n expectDeprecation(function() {\n equal(commentSnapshot.constructor.typeKey, \'comment\', \'constructor.typeKey is unique per type\');\n });\n\n expectDeprecation(function() {\n equal(postSnapshot.constructor.typeKey, \'post\', \'constructor.typeKey is unique per type\');\n });\n });\n});\n\ntest(\"snapshot.attr() does not change when record changes\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n equal(snapshot.attr(\'title\'), \'Hello World\', \'snapshot title is correct\');\n post.set(\'title\', \'Tomster\');\n equal(snapshot.attr(\'title\'), \'Hello World\', \'snapshot title is still correct\');\n });\n});\n\ntest(\"snapshot.attributes() returns a copy of all attributes for the current snapshot\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n var attributes = snapshot.attributes();\n\n deepEqual(attributes, { author: undefined, title: \'Hello World\' }, \'attributes are returned correctly\');\n });\n});\n\ntest(\"snapshot.belongsTo() returns undefined if relationship is undefined\", function() {\n expect(1);\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 1, body: \'This is comment\' });\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\');\n\n equal(relationship, undefined, \'relationship is undefined\');\n });\n});\n\ntest(\"snapshot.belongsTo() returns null if relationship is unset\", function() {\n expect(1);\n\n run(function() {\n env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', post: null });\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\');\n\n equal(relationship, null, \'relationship is unset\');\n });\n});\n\ntest(\"snapshot.belongsTo() returns a snapshot if relationship is set\", function() {\n expect(3);\n\n run(function() {\n env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', post: 1 });\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\');\n\n ok(relationship instanceof DS.Snapshot, \'snapshot is an instance of DS.Snapshot\');\n equal(relationship.id, \'1\', \'post id is correct\');\n equal(relationship.attr(\'title\'), \'Hello World\', \'post title is correct\');\n });\n});\n\ntest(\"snapshot.belongsTo() returns undefined if relationship is a link\", function() {\n expect(1);\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', links: { post: \'post\' } });\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\');\n\n equal(relationship, undefined, \'relationship is undefined\');\n });\n});\n\ntest(\"snapshot.belongsTo() returns a snapshot if relationship link has been fetched\", function() {\n expect(2);\n\n env.adapter.findBelongsTo = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve({ id: 1, title: \'Hello World\' });\n };\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', links: { post: \'post\' } });\n\n comment.get(\'post\').then(function(post) {\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\');\n\n ok(relationship instanceof DS.Snapshot, \'snapshot is an instance of DS.Snapshot\');\n equal(relationship.id, \'1\', \'post id is correct\');\n });\n });\n});\n\ntest(\"snapshot.belongsTo() and snapshot.hasMany() returns correctly when adding an object to a hasMany relationship\", function() {\n expect(4);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var comment = env.store.push(\'comment\', { id: 2, body: \'blabla\' });\n\n post.get(\'comments\').then(function(comments) {\n comments.addObject(comment);\n\n var postSnapshot = post._createSnapshot();\n var commentSnapshot = comment._createSnapshot();\n\n var hasManyRelationship = postSnapshot.hasMany(\'comments\');\n var belongsToRelationship = commentSnapshot.belongsTo(\'post\');\n\n ok(hasManyRelationship instanceof Array, \'hasMany relationship is an instance of Array\');\n equal(hasManyRelationship.length, 1, \'hasMany relationship contains related object\');\n\n ok(belongsToRelationship instanceof DS.Snapshot, \'belongsTo relationship is an instance of DS.Snapshot\');\n equal(belongsToRelationship.attr(\'title\'), \'Hello World\', \'belongsTo relationship contains related object\');\n });\n });\n});\n\ntest(\"snapshot.belongsTo() and snapshot.hasMany() returns correctly when setting an object to a belongsTo relationship\", function() {\n expect(4);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var comment = env.store.push(\'comment\', { id: 2, body: \'blabla\' });\n\n comment.set(\'post\', post);\n\n var postSnapshot = post._createSnapshot();\n var commentSnapshot = comment._createSnapshot();\n\n var hasManyRelationship = postSnapshot.hasMany(\'comments\');\n var belongsToRelationship = commentSnapshot.belongsTo(\'post\');\n\n ok(hasManyRelationship instanceof Array, \'hasMany relationship is an instance of Array\');\n equal(hasManyRelationship.length, 1, \'hasMany relationship contains related object\');\n\n ok(belongsToRelationship instanceof DS.Snapshot, \'belongsTo relationship is an instance of DS.Snapshot\');\n equal(belongsToRelationship.attr(\'title\'), \'Hello World\', \'belongsTo relationship contains related object\');\n });\n});\n\ntest(\"snapshot.hasMany() returns ID if option.id is set\", function() {\n expect(1);\n\n run(function() {\n env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', post: 1 });\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\', { id: true });\n\n equal(relationship, \'1\', \'relationship ID correctly returned\');\n });\n});\n\ntest(\"snapshot.hasMany() returns undefined if relationship is undefined\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n equal(relationship, undefined, \'relationship is undefined\');\n });\n});\n\ntest(\"snapshot.hasMany() returns empty array if relationship is unset\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', comments: null });\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n ok(relationship instanceof Array, \'relationship is an instance of Array\');\n equal(relationship.length, 0, \'relationship is empty\');\n });\n});\n\ntest(\"snapshot.hasMany() returns array of snapshots if relationship is set\", function() {\n expect(5);\n\n run(function() {\n env.store.push(\'comment\', { id: 1, body: \'This is the first comment\' });\n env.store.push(\'comment\', { id: 2, body: \'This is the second comment\' });\n var post = env.store.push(\'post\', { id: 3, title: \'Hello World\', comments: [1, 2] });\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n ok(relationship instanceof Array, \'relationship is an instance of Array\');\n equal(relationship.length, 2, \'relationship has two items\');\n\n var relationship1 = relationship[0];\n\n ok(relationship1 instanceof DS.Snapshot, \'relationship item is an instance of DS.Snapshot\');\n\n equal(relationship1.id, \'1\', \'relationship item id is correct\');\n equal(relationship1.attr(\'body\'), \'This is the first comment\', \'relationship item body is correct\');\n });\n});\n\ntest(\"snapshot.hasMany() returns array of IDs if option.ids is set\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', comments: [2, 3] });\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\', { ids: true });\n\n deepEqual(relationship, [\'2\', \'3\'], \'relationship IDs correctly returned\');\n });\n});\n\ntest(\"snapshot.hasMany() returns undefined if relationship is a link\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', links: { comments: \'comments\' } });\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n equal(relationship, undefined, \'relationship is undefined\');\n });\n});\n\ntest(\"snapshot.hasMany() returns array of snapshots if relationship link has been fetched\", function() {\n expect(2);\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([{ id: 2, body: \'This is comment\' }]);\n };\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', links: { comments: \'comments\' } });\n\n post.get(\'comments\').then(function(comments) {\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n ok(relationship instanceof Array, \'relationship is an instance of Array\');\n equal(relationship.length, 1, \'relationship has one item\');\n });\n });\n});\n\ntest(\"snapshot.hasMany() respects the order of items in the relationship\", function() {\n expect(3);\n\n run(function() {\n env.store.push(\'comment\', { id: 1, body: \'This is the first comment\' });\n env.store.push(\'comment\', { id: 2, body: \'This is the second comment\' });\n var comment3 = env.store.push(\'comment\', { id: 3, body: \'This is the third comment\' });\n var post = env.store.push(\'post\', { id: 4, title: \'Hello World\', comments: [1, 2, 3] });\n\n post.get(\'comments\').removeObject(comment3);\n post.get(\'comments\').insertAt(0, comment3);\n\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n equal(relationship[0].id, \'3\', \'order of comment 3 is correct\');\n equal(relationship[1].id, \'1\', \'order of comment 1 is correct\');\n equal(relationship[2].id, \'2\', \'order of comment 2 is correct\');\n });\n});\n\ntest(\"snapshot.eachAttribute() proxies to record\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n var attributes = [];\n snapshot.eachAttribute(function(name) {\n attributes.push(name);\n });\n deepEqual(attributes, [\'author\', \'title\'], \'attributes are iterated correctly\');\n });\n});\n\ntest(\"snapshot.eachRelationship() proxies to record\", function() {\n expect(2);\n\n var getRelationships = function(snapshot) {\n var relationships = [];\n snapshot.eachRelationship(function(name) {\n relationships.push(name);\n });\n return relationships;\n };\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 1, body: \'This is the first comment\' });\n var post = env.store.push(\'post\', { id: 2, title: \'Hello World\' });\n var snapshot;\n\n snapshot = comment._createSnapshot();\n deepEqual(getRelationships(snapshot), [\'post\'], \'relationships are iterated correctly\');\n\n snapshot = post._createSnapshot();\n deepEqual(getRelationships(snapshot), [\'comments\'], \'relationships are iterated correctly\');\n });\n});\n\ntest(\"snapshot.belongsTo() does not trigger a call to store.scheduleFetch\", function() {\n expect(0);\n\n env.store.scheduleFetch = function() {\n ok(false, \'store.scheduleFetch should not be called\');\n };\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', post: 1 });\n var snapshot = comment._createSnapshot();\n\n snapshot.belongsTo(\'post\');\n });\n});\n\ntest(\"snapshot.hasMany() does not trigger a call to store.scheduleFetch\", function() {\n expect(0);\n\n env.store.scheduleFetch = function() {\n ok(false, \'store.scheduleFetch should not be called\');\n };\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', comments: [2, 3] });\n var snapshot = post._createSnapshot();\n\n snapshot.hasMany(\'comments\');\n });\n});\n\ntest(\"snapshot.get() is deprecated\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n expectDeprecation(function() {\n snapshot.get(\'title\');\n }, \'Using DS.Snapshot.get() is deprecated. Use .attr(), .belongsTo() or .hasMany() instead.\');\n });\n});\n\ntest(\"snapshot.get() returns id\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n expectDeprecation(function() {\n equal(snapshot.get(\'id\'), \'1\', \'snapshot id is correct\');\n });\n });\n});\n\ntest(\"snapshot.get() returns attribute\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n expectDeprecation(function() {\n equal(snapshot.get(\'title\'), \'Hello World\', \'snapshot title is correct\');\n });\n });\n});\n\ntest(\"snapshot.get() returns belongsTo\", function() {\n expect(3);\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 1, body: \'This is a comment\', post: 2 });\n var snapshot = comment._createSnapshot();\n var relationship;\n\n expectDeprecation(function() {\n relationship = snapshot.get(\'post\');\n });\n\n ok(relationship instanceof DS.Snapshot, \'relationship is an instance of DS.Snapshot\');\n equal(relationship.id, \'2\', \'relationship id is correct\');\n });\n});\n\ntest(\"snapshot.get() returns hasMany\", function() {\n expect(3);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', comments: [2, 3] });\n var snapshot = post._createSnapshot();\n var relationship;\n\n expectDeprecation(function() {\n relationship = snapshot.get(\'comments\');\n });\n\n ok(relationship instanceof Array, \'relationship is an instance of Array\');\n equal(relationship.length, 2, \'relationship has two items\');\n });\n});\n\ntest(\"snapshot.get() proxies property to record unless identified as id, attribute or relationship\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n post.set(\'category\', \'Ember.js\'); // category is not defined as an DS.attr()\n\n expectDeprecation(function() {\n equal(snapshot.get(\'category\'), \'Ember.js\', \'snapshot proxies unknown property correctly\');\n });\n });\n});\n})();//# sourceURL=ember-data/integration/snapshot-test.js");
369
+ eval("(function() {var run = Ember.run;\nvar env, Post, Comment;\n\nmodule(\"integration/snapshot - DS.Snapshot\", {\n setup: function() {\n Post = DS.Model.extend({\n author: DS.attr(),\n title: DS.attr(),\n comments: DS.hasMany({ async: true })\n });\n Comment = DS.Model.extend({\n body: DS.attr(),\n post: DS.belongsTo({ async: true })\n });\n\n env = setupStore({\n post: Post,\n comment: Comment\n });\n },\n\n teardown: function() {\n run(function() {\n env.store.destroy();\n });\n }\n});\n\ntest(\"record._createSnapshot() returns a snapshot\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n ok(snapshot instanceof DS.Snapshot, \'snapshot is an instance of DS.Snapshot\');\n });\n});\n\ntest(\"snapshot._createSnapshot() returns a snapshot (self) but is deprecated\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot1 = post._createSnapshot();\n var snapshot2;\n\n expectDeprecation(function() {\n snapshot2 = snapshot1._createSnapshot();\n }, /You called _createSnapshot on what\'s already a DS.Snapshot. You shouldn\'t manually create snapshots in your adapter since the store passes snapshots to adapters by default./);\n\n ok(snapshot2 === snapshot1, \'snapshot._createSnapshot() returns self\');\n });\n\n});\n\ntest(\"snapshot.id, snapshot.type and snapshot.modelName returns correctly\", function() {\n expect(3);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n equal(snapshot.id, \'1\', \'id is correct\');\n ok(DS.Model.detect(snapshot.type), \'type is correct\');\n equal(snapshot.modelName, \'post\', \'modelName is correct\');\n });\n});\n\ntest(\"snapshot.constructor is unique and deprecated\", function() {\n expect(4);\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 1, body: \'This is comment\' });\n var post = env.store.push(\'post\', { id: 2, title: \'Hello World\' });\n var commentSnapshot = comment._createSnapshot();\n var postSnapshot = post._createSnapshot();\n\n expectDeprecation(function() {\n equal(commentSnapshot.constructor.modelName, \'comment\', \'constructor.modelName is unique per type\');\n });\n\n expectDeprecation(function() {\n equal(postSnapshot.constructor.modelName, \'post\', \'constructor.modelName is unique per type\');\n });\n });\n});\n\ntest(\"snapshot.attr() does not change when record changes\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n equal(snapshot.attr(\'title\'), \'Hello World\', \'snapshot title is correct\');\n post.set(\'title\', \'Tomster\');\n equal(snapshot.attr(\'title\'), \'Hello World\', \'snapshot title is still correct\');\n });\n});\n\ntest(\"snapshot.attributes() returns a copy of all attributes for the current snapshot\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n var attributes = snapshot.attributes();\n\n deepEqual(attributes, { author: undefined, title: \'Hello World\' }, \'attributes are returned correctly\');\n });\n});\n\ntest(\"snapshot.belongsTo() returns undefined if relationship is undefined\", function() {\n expect(1);\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 1, body: \'This is comment\' });\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\');\n\n equal(relationship, undefined, \'relationship is undefined\');\n });\n});\n\ntest(\"snapshot.belongsTo() returns null if relationship is unset\", function() {\n expect(1);\n\n run(function() {\n env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', post: null });\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\');\n\n equal(relationship, null, \'relationship is unset\');\n });\n});\n\ntest(\"snapshot.belongsTo() returns a snapshot if relationship is set\", function() {\n expect(3);\n\n run(function() {\n env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', post: 1 });\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\');\n\n ok(relationship instanceof DS.Snapshot, \'snapshot is an instance of DS.Snapshot\');\n equal(relationship.id, \'1\', \'post id is correct\');\n equal(relationship.attr(\'title\'), \'Hello World\', \'post title is correct\');\n });\n});\n\ntest(\"snapshot.belongsTo() returns undefined if relationship is a link\", function() {\n expect(1);\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', links: { post: \'post\' } });\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\');\n\n equal(relationship, undefined, \'relationship is undefined\');\n });\n});\n\ntest(\"snapshot.belongsTo() returns a snapshot if relationship link has been fetched\", function() {\n expect(2);\n\n env.adapter.findBelongsTo = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve({ id: 1, title: \'Hello World\' });\n };\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', links: { post: \'post\' } });\n\n comment.get(\'post\').then(function(post) {\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\');\n\n ok(relationship instanceof DS.Snapshot, \'snapshot is an instance of DS.Snapshot\');\n equal(relationship.id, \'1\', \'post id is correct\');\n });\n });\n});\n\ntest(\"snapshot.belongsTo() and snapshot.hasMany() returns correctly when adding an object to a hasMany relationship\", function() {\n expect(4);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var comment = env.store.push(\'comment\', { id: 2, body: \'blabla\' });\n\n post.get(\'comments\').then(function(comments) {\n comments.addObject(comment);\n\n var postSnapshot = post._createSnapshot();\n var commentSnapshot = comment._createSnapshot();\n\n var hasManyRelationship = postSnapshot.hasMany(\'comments\');\n var belongsToRelationship = commentSnapshot.belongsTo(\'post\');\n\n ok(hasManyRelationship instanceof Array, \'hasMany relationship is an instance of Array\');\n equal(hasManyRelationship.length, 1, \'hasMany relationship contains related object\');\n\n ok(belongsToRelationship instanceof DS.Snapshot, \'belongsTo relationship is an instance of DS.Snapshot\');\n equal(belongsToRelationship.attr(\'title\'), \'Hello World\', \'belongsTo relationship contains related object\');\n });\n });\n});\n\ntest(\"snapshot.belongsTo() and snapshot.hasMany() returns correctly when setting an object to a belongsTo relationship\", function() {\n expect(4);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var comment = env.store.push(\'comment\', { id: 2, body: \'blabla\' });\n\n comment.set(\'post\', post);\n\n var postSnapshot = post._createSnapshot();\n var commentSnapshot = comment._createSnapshot();\n\n var hasManyRelationship = postSnapshot.hasMany(\'comments\');\n var belongsToRelationship = commentSnapshot.belongsTo(\'post\');\n\n ok(hasManyRelationship instanceof Array, \'hasMany relationship is an instance of Array\');\n equal(hasManyRelationship.length, 1, \'hasMany relationship contains related object\');\n\n ok(belongsToRelationship instanceof DS.Snapshot, \'belongsTo relationship is an instance of DS.Snapshot\');\n equal(belongsToRelationship.attr(\'title\'), \'Hello World\', \'belongsTo relationship contains related object\');\n });\n});\n\ntest(\"snapshot.hasMany() returns ID if option.id is set\", function() {\n expect(1);\n\n run(function() {\n env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', post: 1 });\n var snapshot = comment._createSnapshot();\n var relationship = snapshot.belongsTo(\'post\', { id: true });\n\n equal(relationship, \'1\', \'relationship ID correctly returned\');\n });\n});\n\ntest(\"snapshot.hasMany() returns undefined if relationship is undefined\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n equal(relationship, undefined, \'relationship is undefined\');\n });\n});\n\ntest(\"snapshot.hasMany() returns empty array if relationship is unset\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', comments: null });\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n ok(relationship instanceof Array, \'relationship is an instance of Array\');\n equal(relationship.length, 0, \'relationship is empty\');\n });\n});\n\ntest(\"snapshot.hasMany() returns array of snapshots if relationship is set\", function() {\n expect(5);\n\n run(function() {\n env.store.push(\'comment\', { id: 1, body: \'This is the first comment\' });\n env.store.push(\'comment\', { id: 2, body: \'This is the second comment\' });\n var post = env.store.push(\'post\', { id: 3, title: \'Hello World\', comments: [1, 2] });\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n ok(relationship instanceof Array, \'relationship is an instance of Array\');\n equal(relationship.length, 2, \'relationship has two items\');\n\n var relationship1 = relationship[0];\n\n ok(relationship1 instanceof DS.Snapshot, \'relationship item is an instance of DS.Snapshot\');\n\n equal(relationship1.id, \'1\', \'relationship item id is correct\');\n equal(relationship1.attr(\'body\'), \'This is the first comment\', \'relationship item body is correct\');\n });\n});\n\ntest(\"snapshot.hasMany() returns array of IDs if option.ids is set\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', comments: [2, 3] });\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\', { ids: true });\n\n deepEqual(relationship, [\'2\', \'3\'], \'relationship IDs correctly returned\');\n });\n});\n\ntest(\"snapshot.hasMany() returns undefined if relationship is a link\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', links: { comments: \'comments\' } });\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n equal(relationship, undefined, \'relationship is undefined\');\n });\n});\n\ntest(\"snapshot.hasMany() returns array of snapshots if relationship link has been fetched\", function() {\n expect(2);\n\n env.adapter.findHasMany = function(store, snapshot, link, relationship) {\n return Ember.RSVP.resolve([{ id: 2, body: \'This is comment\' }]);\n };\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', links: { comments: \'comments\' } });\n\n post.get(\'comments\').then(function(comments) {\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n ok(relationship instanceof Array, \'relationship is an instance of Array\');\n equal(relationship.length, 1, \'relationship has one item\');\n });\n });\n});\n\ntest(\"snapshot.hasMany() respects the order of items in the relationship\", function() {\n expect(3);\n\n run(function() {\n env.store.push(\'comment\', { id: 1, body: \'This is the first comment\' });\n env.store.push(\'comment\', { id: 2, body: \'This is the second comment\' });\n var comment3 = env.store.push(\'comment\', { id: 3, body: \'This is the third comment\' });\n var post = env.store.push(\'post\', { id: 4, title: \'Hello World\', comments: [1, 2, 3] });\n\n post.get(\'comments\').removeObject(comment3);\n post.get(\'comments\').insertAt(0, comment3);\n\n var snapshot = post._createSnapshot();\n var relationship = snapshot.hasMany(\'comments\');\n\n equal(relationship[0].id, \'3\', \'order of comment 3 is correct\');\n equal(relationship[1].id, \'1\', \'order of comment 1 is correct\');\n equal(relationship[2].id, \'2\', \'order of comment 2 is correct\');\n });\n});\n\ntest(\"snapshot.eachAttribute() proxies to record\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n var attributes = [];\n snapshot.eachAttribute(function(name) {\n attributes.push(name);\n });\n deepEqual(attributes, [\'author\', \'title\'], \'attributes are iterated correctly\');\n });\n});\n\ntest(\"snapshot.eachRelationship() proxies to record\", function() {\n expect(2);\n\n var getRelationships = function(snapshot) {\n var relationships = [];\n snapshot.eachRelationship(function(name) {\n relationships.push(name);\n });\n return relationships;\n };\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 1, body: \'This is the first comment\' });\n var post = env.store.push(\'post\', { id: 2, title: \'Hello World\' });\n var snapshot;\n\n snapshot = comment._createSnapshot();\n deepEqual(getRelationships(snapshot), [\'post\'], \'relationships are iterated correctly\');\n\n snapshot = post._createSnapshot();\n deepEqual(getRelationships(snapshot), [\'comments\'], \'relationships are iterated correctly\');\n });\n});\n\ntest(\"snapshot.belongsTo() does not trigger a call to store.scheduleFetch\", function() {\n expect(0);\n\n env.store.scheduleFetch = function() {\n ok(false, \'store.scheduleFetch should not be called\');\n };\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 2, body: \'This is comment\', post: 1 });\n var snapshot = comment._createSnapshot();\n\n snapshot.belongsTo(\'post\');\n });\n});\n\ntest(\"snapshot.hasMany() does not trigger a call to store.scheduleFetch\", function() {\n expect(0);\n\n env.store.scheduleFetch = function() {\n ok(false, \'store.scheduleFetch should not be called\');\n };\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', comments: [2, 3] });\n var snapshot = post._createSnapshot();\n\n snapshot.hasMany(\'comments\');\n });\n});\n\ntest(\"snapshot.get() is deprecated\", function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n expectDeprecation(function() {\n snapshot.get(\'title\');\n }, \'Using DS.Snapshot.get() is deprecated. Use .attr(), .belongsTo() or .hasMany() instead.\');\n });\n});\n\ntest(\"snapshot.get() returns id\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n expectDeprecation(function() {\n equal(snapshot.get(\'id\'), \'1\', \'snapshot id is correct\');\n });\n });\n});\n\ntest(\"snapshot.get() returns attribute\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n expectDeprecation(function() {\n equal(snapshot.get(\'title\'), \'Hello World\', \'snapshot title is correct\');\n });\n });\n});\n\ntest(\"snapshot.get() returns belongsTo\", function() {\n expect(3);\n\n run(function() {\n var comment = env.store.push(\'comment\', { id: 1, body: \'This is a comment\', post: 2 });\n var snapshot = comment._createSnapshot();\n var relationship;\n\n expectDeprecation(function() {\n relationship = snapshot.get(\'post\');\n });\n\n ok(relationship instanceof DS.Snapshot, \'relationship is an instance of DS.Snapshot\');\n equal(relationship.id, \'2\', \'relationship id is correct\');\n });\n});\n\ntest(\"snapshot.get() returns hasMany\", function() {\n expect(3);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\', comments: [2, 3] });\n var snapshot = post._createSnapshot();\n var relationship;\n\n expectDeprecation(function() {\n relationship = snapshot.get(\'comments\');\n });\n\n ok(relationship instanceof Array, \'relationship is an instance of Array\');\n equal(relationship.length, 2, \'relationship has two items\');\n });\n});\n\ntest(\"snapshot.get() proxies property to record unless identified as id, attribute or relationship\", function() {\n expect(2);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n post.set(\'category\', \'Ember.js\'); // category is not defined as an DS.attr()\n\n expectDeprecation(function() {\n equal(snapshot.get(\'category\'), \'Ember.js\', \'snapshot proxies unknown property correctly\');\n });\n });\n});\n\ntest(\'snapshot.typeKey is deprecated\', function() {\n expect(1);\n\n run(function() {\n var post = env.store.push(\'post\', { id: 1, title: \'Hello World\' });\n var snapshot = post._createSnapshot();\n\n expectDeprecation(function() {\n return snapshot.typeKey;\n });\n });\n\n});\n})();//# sourceURL=ember-data/integration/snapshot-test.js");
354
370
 
355
371
  eval("(function() {var store, env;\n\nvar Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n cars: DS.hasMany(\'car\')\n});\n\nvar run = Ember.run;\n\nPerson.toString = function() { return \"Person\"; };\n\nvar Car = DS.Model.extend({\n make: DS.attr(\'string\'),\n model: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n});\n\nCar.toString = function() { return \"Car\"; };\n\nfunction initializeStore(adapter) {\n env = setupStore({\n adapter: adapter\n });\n store = env.store;\n\n env.registry.register(\'model:car\', Car);\n env.registry.register(\'model:person\', Person);\n}\n\nmodule(\"integration/store - destroy\", {\n setup: function() {\n initializeStore(DS.FixtureAdapter.extend());\n }\n});\n\nfunction tap(obj, methodName, callback) {\n var old = obj[methodName];\n\n var summary = { called: [] };\n\n obj[methodName] = function() {\n var result = old.apply(obj, arguments);\n if (callback) {\n callback.apply(obj, arguments);\n }\n summary.called.push(arguments);\n return result;\n };\n\n return summary;\n}\n\nasyncTest(\"destroying record during find doesn\'t cause error\", function() {\n expect(0);\n\n var TestAdapter = DS.FixtureAdapter.extend({\n find: function(store, type, id, snapshot) {\n return new Ember.RSVP.Promise(function(resolve, reject) {\n Ember.run.next(function() {\n store.unloadAll(type);\n reject();\n });\n });\n }\n });\n\n initializeStore(TestAdapter);\n\n var type = \"car\";\n var id = 1;\n\n function done() {\n start();\n }\n\n run(function() {\n store.find(type, id).then(done, done);\n });\n});\n\nasyncTest(\"find calls do not resolve when the store is destroyed\", function() {\n expect(0);\n\n var TestAdapter = DS.FixtureAdapter.extend({\n find: function(store, type, id, snapshot) {\n store.destroy();\n Ember.RSVP.resolve(null);\n }\n });\n\n initializeStore(TestAdapter);\n\n\n var type = \"car\";\n var id = 1;\n\n store.push = function() {\n Ember.assert(\"The test should have destroyed the store by now\", store.get(\"isDestroyed\"));\n\n throw new Error(\"We shouldn\'t be pushing data into the store when it is destroyed\");\n };\n\n run(function() {\n store.find(type, id);\n });\n\n setTimeout(function() {\n start();\n }, 500);\n});\n\n\ntest(\"destroying the store correctly cleans everything up\", function() {\n var car, person;\n run(function() {\n car = store.push(\'car\', {\n id: 1,\n make: \'BMC\',\n model: \'Mini\',\n person: 1\n });\n\n person = store.push(\'person\', {\n id: 1,\n name: \'Tom Dale\',\n cars: [1]\n });\n });\n\n var personWillDestroy = tap(person, \'willDestroy\');\n var carWillDestroy = tap(car, \'willDestroy\');\n var carsWillDestroy = tap(car.get(\'person.cars\'), \'willDestroy\');\n\n env.adapter.findQuery = function() {\n return [{\n id: 2,\n name: \'Yehuda\'\n }];\n };\n var adapterPopulatedPeople, filterdPeople;\n\n run(function() {\n adapterPopulatedPeople = store.find(\'person\', {\n someCrazy: \'query\'\n });\n });\n\n run(function() {\n filterdPeople = store.filter(\'person\', function() { return true; });\n });\n\n var filterdPeopleWillDestroy = tap(filterdPeople.content, \'willDestroy\');\n var adapterPopulatedPeopleWillDestroy = tap(adapterPopulatedPeople.content, \'willDestroy\');\n\n run(function() {\n store.find(\'person\', 2);\n });\n\n equal(personWillDestroy.called.length, 0, \'expected person.willDestroy to not have been called\');\n equal(carWillDestroy.called.length, 0, \'expected car.willDestroy to not have been called\');\n equal(carsWillDestroy.called.length, 0, \'expected cars.willDestroy to not have been called\');\n equal(adapterPopulatedPeopleWillDestroy.called.length, 0, \'expected adapterPopulatedPeople.willDestroy to not have been called\');\n equal(filterdPeopleWillDestroy.called.length, 0, \'expected filterdPeople.willDestroy to not have been called\');\n\n equal(filterdPeople.get(\'length\'), 2, \'expected filterdPeople to have 2 entries\');\n\n equal(car.get(\'person\'), person, \"expected car\'s person to be the correct person\");\n equal(person.get(\'cars.firstObject\'), car, \" expected persons cars\'s firstRecord to be the correct car\");\n\n Ember.run(person, person.destroy);\n Ember.run(store, \'destroy\');\n\n equal(car.get(\'person\'), null, \"expected car.person to no longer be present\");\n\n equal(personWillDestroy.called.length, 1, \'expected person to have recieved willDestroy once\');\n equal(carWillDestroy.called.length, 1, \'expected car to recieve willDestroy once\');\n equal(carsWillDestroy.called.length, 1, \'expected cars to recieve willDestroy once\');\n equal(adapterPopulatedPeopleWillDestroy.called.length, 1, \'expected adapterPopulatedPeople to recieve willDestroy once\');\n equal(filterdPeopleWillDestroy.called.length, 1, \'expected filterdPeople.willDestroy to have been called once\');\n});\n\nmodule(\"integration/store - fetch\", {\n setup: function() {\n initializeStore(DS.RESTAdapter.extend());\n }\n});\n\nfunction ajaxResponse(value) {\n var passedUrl, passedVerb, passedHash;\n env.adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n passedVerb = verb;\n passedHash = hash;\n\n return Ember.RSVP.resolve(value);\n };\n}\n\ntest(\"Using store#fetch is deprecated\", function() {\n ajaxResponse({\n cars: [\n { id: 1, make: \'BMW\', model: \'Mini\' }\n ]\n });\n\n expectDeprecation(\n function() {\n run(function() {\n store.fetch(\'car\', 1);\n });\n },\n \'Using store.fetch() has been deprecated. Use store.fetchById for fetching individual records or store.fetchAll for collections\'\n );\n});\n\nmodule(\"integration/store - fetchById\", {\n setup: function() {\n initializeStore(DS.RESTAdapter.extend());\n }\n});\n\ntest(\"Using store#fetchById on non existing record fetches it from the server\", function() {\n expect(2);\n\n ajaxResponse({\n cars: [{\n id: 20,\n make: \'BMCW\',\n model: \'Mini\'\n }]\n });\n\n var car = store.hasRecordForId(\'car\', 20);\n ok(!car, \'Car with id=20 should not exist\');\n\n run(function() {\n store.fetchById(\'car\', 20).then(function (car) {\n equal(car.get(\'make\'), \'BMCW\', \'Car with id=20 is now loaded\');\n });\n });\n});\n\ntest(\"Using store#fetchById on existing record reloads it\", function() {\n expect(2);\n var car;\n\n run(function() {\n car = store.push(\'car\', {\n id: 1,\n make: \'BMC\',\n model: \'Mini\'\n });\n\n });\n ajaxResponse({\n cars: [{\n id: 1,\n make: \'BMCW\',\n model: \'Mini\'\n }]\n });\n\n equal(car.get(\'make\'), \'BMC\');\n\n run(function() {\n store.fetchById(\'car\', 1).then(function(car) {\n equal(car.get(\'make\'), \'BMCW\');\n });\n });\n});\n\nmodule(\"integration/store - fetchAll\", {\n setup: function() {\n initializeStore(DS.RESTAdapter.extend());\n }\n});\n\ntest(\"Using store#fetchAll with no records triggers a query\", function() {\n expect(2);\n\n ajaxResponse({\n cars: [{\n id: 1,\n make: \'BMC\',\n model: \'Mini\'\n },\n {\n id: 2,\n make: \'BMCW\',\n model: \'Isetta\'\n }]\n });\n\n var cars = store.all(\'car\');\n ok(!cars.get(\'length\'), \'There is no cars in the store\');\n\n run(function() {\n store.fetchAll(\'car\').then(function(cars) {\n equal(cars.get(\'length\'), 2, \'Two car were fetched\');\n });\n });\n});\n\ntest(\"Using store#fetchAll with existing records performs a query, updating existing records and returning new ones\", function() {\n expect(3);\n\n run(function() {\n store.push(\'car\', {\n id: 1,\n make: \'BMC\',\n model: \'Mini\'\n });\n });\n\n ajaxResponse({\n cars: [{\n id: 1,\n make: \'BMC\',\n model: \'New Mini\'\n },\n {\n id: 2,\n make: \'BMCW\',\n model: \'Isetta\'\n }]\n });\n\n var cars = store.all(\'car\');\n equal(cars.get(\'length\'), 1, \'There is one car in the store\');\n\n run(function() {\n store.fetchAll(\'car\').then(function(cars) {\n equal(cars.get(\'length\'), 2, \'There is 2 cars in the store now\');\n var mini = cars.findBy(\'id\', \'1\');\n equal(mini.get(\'model\'), \'New Mini\', \'Existing records have been updated\');\n });\n });\n});\n\ntest(\"store#fetchAll should return all known records even if they are not in the adapter response\", function() {\n expect(4);\n\n run(function() {\n store.push(\'car\', { id: 1, make: \'BMC\', model: \'Mini\' });\n store.push(\'car\', { id: 2, make: \'BMCW\', model: \'Isetta\' });\n });\n\n ajaxResponse({\n cars: [{\n id: 1,\n make: \'BMC\',\n model: \'New Mini\'\n }]\n });\n\n var cars = store.all(\'car\');\n equal(cars.get(\'length\'), 2, \'There is two cars in the store\');\n\n run(function() {\n store.fetchAll(\'car\').then(function(cars) {\n equal(cars.get(\'length\'), 2, \'It returns all cars\');\n var mini = cars.findBy(\'id\', \'1\');\n equal(mini.get(\'model\'), \'New Mini\', \'Existing records have been updated\');\n\n var carsInStore = store.all(\'car\');\n equal(carsInStore.get(\'length\'), 2, \'There is 2 cars in the store\');\n });\n });\n});\n\ntest(\"Using store#fetch on an empty record calls find\", function() {\n expect(2);\n\n ajaxResponse({\n cars: [{\n id: 20,\n make: \'BMCW\',\n model: \'Mini\'\n }]\n });\n\n run(function() {\n store.push(\'person\', {\n id: 1,\n name: \'Tom Dale\',\n cars: [20]\n });\n });\n\n var car = store.recordForId(\'car\', 20);\n ok(car.get(\'isEmpty\'), \'Car with id=20 should be empty\');\n\n run(function() {\n store.fetchById(\'car\', 20).then(function (car) {\n equal(car.get(\'make\'), \'BMCW\', \'Car with id=20 is now loaded\');\n });\n });\n});\n\ntest(\"Using store#adapterFor should not throw an error when looking up the application adapter\", function() {\n expect(1);\n\n run(function() {\n var applicationAdapter = store.adapterFor(\'application\');\n ok(applicationAdapter);\n });\n});\n\n\ntest(\"Using store#serializerFor should not throw an error when looking up the application serializer\", function() {\n expect(1);\n\n run(function() {\n var applicationSerializer = store.serializerFor(\'application\');\n ok(applicationSerializer);\n });\n});\n})();//# sourceURL=ember-data/integration/store-test.js");
356
372
 
357
373
  eval("(function() {var Person, array, store;\nvar run = Ember.run;\n\nvar adapter = DS.Adapter.extend({\n deleteRecord: function() {\n return Ember.RSVP.Promise.resolve();\n }\n});\n\nmodule(\"unit/adapter_populated_record_array - DS.AdapterPopulatedRecordArray\", {\n setup: function() {\n\n store = createStore({\n adapter: adapter\n });\n\n array = [{ id: \'1\', name: \"Scumbag Dale\" },\n { id: \'2\', name: \"Scumbag Katz\" },\n { id: \'3\', name: \"Scumbag Bryn\" }];\n\n Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n }\n});\n\ntest(\"when a record is deleted in an adapter populated record array, it should be removed\", function() {\n var recordArray = store.recordArrayManager\n .createAdapterPopulatedRecordArray(Person, null);\n\n run(function() {\n recordArray.load(array);\n });\n\n equal(recordArray.get(\'length\'), 3, \"expected recordArray to contain exactly 3 records\");\n\n run(function() {\n recordArray.get(\'firstObject\').destroyRecord();\n });\n\n equal(recordArray.get(\'length\'), 2, \"expected recordArray to contain exactly 2 records\");\n});\n})();//# sourceURL=ember-data/unit/adapter-populated-record-array-test.js");
358
374
 
359
- eval("(function() {var env, adapter;\n\nmodule(\"unit/adapters/build-url-mixin/path-for-type - DS.BuildURLMixin#pathForType\", {\n setup: function() {\n\n // test for overriden pathForType methods which return null path values\n var customPathForType = {\n pathForType: function(type) {\n if (type === \'rootModel\') { return \'\'; }\n return this._super(type);\n }\n };\n\n var Adapter = DS.Adapter.extend(DS.BuildURLMixin, customPathForType);\n\n env = setupStore({\n adapter: Adapter\n });\n\n adapter = env.adapter;\n }\n});\n\ntest(\'pathForType - works with camelized types\', function() {\n equal(adapter.pathForType(\'superUser\'), \"superUsers\");\n});\n\ntest(\'pathForType - works with dasherized types\', function() {\n equal(adapter.pathForType(\'super-user\'), \"superUsers\");\n});\n\ntest(\'pathForType - works with underscored types\', function() {\n equal(adapter.pathForType(\'super_user\'), \"superUsers\");\n});\n\ntest(\'buildURL - works with empty paths\', function() {\n equal(adapter.buildURL(\'rootModel\', 1), \"/1\");\n});\n\ntest(\'buildURL - find requestType delegates to urlForFind\', function() {\n expect(4);\n var snapshotStub = { snapshot: true };\n var originalMethod = adapter.urlForFind;\n adapter.urlForFind = function(id, type, snapshot) {\n equal(id, 1);\n equal(type, \'super-user\');\n equal(snapshot, snapshotStub);\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', 1, snapshotStub, \'find\'), \'/superUsers/1\');\n});\n\ntest(\'buildURL - findAll requestType delegates to urlForFindAll\', function() {\n expect(2);\n var originalMethod = adapter.urlForFindAll;\n adapter.urlForFindAll = function(type) {\n equal(type, \'super-user\');\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', null, null, \'findAll\'), \'/superUsers\');\n});\n\ntest(\'buildURL - findQuery requestType delegates to urlForFindQuery\', function() {\n expect(3);\n var originalMethod = adapter.urlForFindQuery;\n var queryStub = { limit: 10 };\n adapter.urlForFindQuery = function(query, type) {\n equal(query, queryStub);\n equal(type, \'super-user\');\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', queryStub, null, \'findQuery\'), \'/superUsers\');\n});\n\ntest(\'buildURL - findMany requestType delegates to urlForFindMany\', function() {\n expect(3);\n var originalMethod = adapter.urlForFindMany;\n var idsStub = [1, 2, 3];\n adapter.urlForFindMany = function(ids, type) {\n equal(ids, idsStub);\n equal(type, \'super-user\');\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', idsStub, null, \'findMany\'), \'/superUsers\');\n});\n\ntest(\'buildURL - findHasMany requestType delegates to urlForFindHasMany\', function() {\n expect(3);\n var originalMethod = adapter.urlForFindHasMany;\n adapter.urlForFindHasMany = function(id, type) {\n equal(id, 1);\n equal(type, \'super-user\');\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', 1, null, \'findHasMany\'), \'/superUsers/1\');\n});\n\ntest(\'buildURL - findBelongsTo requestType delegates to urlForFindBelongsTo\', function() {\n expect(3);\n var originalMethod = adapter.urlForFindBelongsTo;\n adapter.urlForFindBelongsTo = function(id, type) {\n equal(id, 1);\n equal(type, \'super-user\');\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', 1, null, \'findBelongsTo\'), \'/superUsers/1\');\n});\n\ntest(\'buildURL - createRecord requestType delegates to urlForCreateRecord\', function() {\n expect(3);\n var snapshotStub = { snapshot: true };\n var originalMethod = adapter.urlForCreateRecord;\n adapter.urlForCreateRecord = function(type, snapshot) {\n equal(type, \'super-user\');\n equal(snapshot, snapshotStub);\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', null, snapshotStub, \'createRecord\'), \'/superUsers\');\n});\n\ntest(\'buildURL - updateRecord requestType delegates to urlForUpdateRecord\', function() {\n expect(4);\n var snapshotStub = { snapshot: true };\n var originalMethod = adapter.urlForUpdateRecord;\n adapter.urlForUpdateRecord = function(id, type, snapshot) {\n equal(id, 1);\n equal(type, \'super-user\');\n equal(snapshot, snapshotStub);\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', 1, snapshotStub, \'updateRecord\'), \'/superUsers/1\');\n});\n\ntest(\'buildURL - deleteRecord requestType delegates to urlForDeleteRecord\', function() {\n expect(4);\n var snapshotStub = { snapshot: true };\n var originalMethod = adapter.urlForDeleteRecord;\n adapter.urlForDeleteRecord = function(id, type, snapshot) {\n equal(id, 1);\n equal(type, \'super-user\');\n equal(snapshot, snapshotStub);\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', 1, snapshotStub, \'deleteRecord\'), \'/superUsers/1\');\n});\n\ntest(\'buildURL - unknown requestType\', function() {\n equal(adapter.buildURL(\'super-user\', 1, null, \'unknown\'), \'/superUsers/1\');\n equal(adapter.buildURL(\'super-user\', null, null, \'unknown\'), \'/superUsers\');\n});\n})();//# sourceURL=ember-data/unit/adapters/build-url-mixin/path-for-type-test.js");
375
+ eval("(function() {var env, adapter;\n\nmodule(\"unit/adapters/build-url-mixin/path-for-type - DS.BuildURLMixin#pathForType\", {\n setup: function() {\n\n // test for overriden pathForType methods which return null path values\n var customPathForType = {\n pathForType: function(type) {\n if (type === \'rootModel\') { return \'\'; }\n return this._super(type);\n }\n };\n\n var Adapter = DS.Adapter.extend(DS.BuildURLMixin, customPathForType);\n\n env = setupStore({\n adapter: Adapter\n });\n\n adapter = env.adapter;\n }\n});\n\ntest(\'pathForType - works with camelized types\', function() {\n equal(adapter.pathForType(\'superUser\'), \"superUsers\");\n});\n\ntest(\'pathForType - works with dasherized types\', function() {\n equal(adapter.pathForType(\'super-user\'), \"superUsers\");\n});\n\ntest(\'pathForType - works with underscored types\', function() {\n equal(adapter.pathForType(\'super_user\'), \"superUsers\");\n});\n\ntest(\'buildURL - works with empty paths\', function() {\n equal(adapter.buildURL(\'rootModel\', 1), \"/1\");\n});\n\ntest(\'buildURL - find requestType delegates to urlForFind\', function() {\n expect(4);\n var snapshotStub = { snapshot: true };\n var originalMethod = adapter.urlForFind;\n adapter.urlForFind = function(id, type, snapshot) {\n equal(id, 1);\n equal(type, \'super-user\');\n equal(snapshot, snapshotStub);\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', 1, snapshotStub, \'find\'), \'/superUsers/1\');\n});\n\ntest(\'buildURL - findAll requestType delegates to urlForFindAll\', function() {\n expect(2);\n var originalMethod = adapter.urlForFindAll;\n adapter.urlForFindAll = function(type) {\n equal(type, \'super-user\');\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', null, null, \'findAll\'), \'/superUsers\');\n});\n\ntest(\'buildURL - findQuery requestType delegates to urlForFindQuery\', function() {\n expect(3);\n var originalMethod = adapter.urlForFindQuery;\n var queryStub = { limit: 10 };\n adapter.urlForFindQuery = function(query, type) {\n equal(query, queryStub);\n equal(type, \'super-user\');\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', null, null, \'findQuery\', queryStub), \'/superUsers\');\n});\n\ntest(\'buildURL - findMany requestType delegates to urlForFindMany\', function() {\n expect(3);\n var originalMethod = adapter.urlForFindMany;\n var idsStub = [1, 2, 3];\n adapter.urlForFindMany = function(ids, type) {\n equal(ids, idsStub);\n equal(type, \'super-user\');\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', idsStub, null, \'findMany\'), \'/superUsers\');\n});\n\ntest(\'buildURL - findHasMany requestType delegates to urlForFindHasMany\', function() {\n expect(3);\n var originalMethod = adapter.urlForFindHasMany;\n adapter.urlForFindHasMany = function(id, type) {\n equal(id, 1);\n equal(type, \'super-user\');\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', 1, null, \'findHasMany\'), \'/superUsers/1\');\n});\n\ntest(\'buildURL - findBelongsTo requestType delegates to urlForFindBelongsTo\', function() {\n expect(3);\n var originalMethod = adapter.urlForFindBelongsTo;\n adapter.urlForFindBelongsTo = function(id, type) {\n equal(id, 1);\n equal(type, \'super-user\');\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', 1, null, \'findBelongsTo\'), \'/superUsers/1\');\n});\n\ntest(\'buildURL - createRecord requestType delegates to urlForCreateRecord\', function() {\n expect(3);\n var snapshotStub = { snapshot: true };\n var originalMethod = adapter.urlForCreateRecord;\n adapter.urlForCreateRecord = function(type, snapshot) {\n equal(type, \'super-user\');\n equal(snapshot, snapshotStub);\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', null, snapshotStub, \'createRecord\'), \'/superUsers\');\n});\n\ntest(\'buildURL - updateRecord requestType delegates to urlForUpdateRecord\', function() {\n expect(4);\n var snapshotStub = { snapshot: true };\n var originalMethod = adapter.urlForUpdateRecord;\n adapter.urlForUpdateRecord = function(id, type, snapshot) {\n equal(id, 1);\n equal(type, \'super-user\');\n equal(snapshot, snapshotStub);\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', 1, snapshotStub, \'updateRecord\'), \'/superUsers/1\');\n});\n\ntest(\'buildURL - deleteRecord requestType delegates to urlForDeleteRecord\', function() {\n expect(4);\n var snapshotStub = { snapshot: true };\n var originalMethod = adapter.urlForDeleteRecord;\n adapter.urlForDeleteRecord = function(id, type, snapshot) {\n equal(id, 1);\n equal(type, \'super-user\');\n equal(snapshot, snapshotStub);\n return originalMethod.apply(this, arguments);\n };\n equal(adapter.buildURL(\'super-user\', 1, snapshotStub, \'deleteRecord\'), \'/superUsers/1\');\n});\n\ntest(\'buildURL - unknown requestType\', function() {\n equal(adapter.buildURL(\'super-user\', 1, null, \'unknown\'), \'/superUsers/1\');\n equal(adapter.buildURL(\'super-user\', null, null, \'unknown\'), \'/superUsers\');\n});\n})();//# sourceURL=ember-data/unit/adapters/build-url-mixin/path-for-type-test.js");
360
376
 
361
- eval("(function() {var Person, Place, store, adapter, env;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/ajax - building requests\", {\n setup: function() {\n Person = { typeKey: \'person\' };\n Place = { typeKey: \'place\' };\n env = setupStore({ adapter: DS.RESTAdapter, person: Person, place: Place });\n store = env.store;\n adapter = env.adapter;\n },\n\n teardown: function() {\n run(function() {\n store.destroy();\n env.container.destroy();\n });\n }\n});\n\ntest(\"When an id is searched, the correct url should be generated\", function() {\n expect(2);\n var count = 0;\n adapter.ajax = function(url, method) {\n if (count === 0) { equal(url, \'/people/1\', \"should create the correct url\"); }\n if (count === 1) { equal(url, \'/places/1\', \"should create the correct url\"); }\n count++;\n return Ember.RSVP.resolve();\n };\n run(function() {\n adapter.find(store, Person, 1);\n adapter.find(store, Place, 1);\n });\n});\ntest(\"id\'s should be sanatized\", function() {\n expect(1);\n adapter.ajax= function(url, method) {\n equal(url, \'/people/..%2Fplace%2F1\', \"should create the correct url\");\n return Ember.RSVP.resolve();\n };\n run(function() {\n adapter.find(store, Person, \'../place/1\');\n });\n});\n})();//# sourceURL=ember-data/unit/adapters/rest-adapter/ajax.js");
377
+ eval("(function() {var Person, Place, store, adapter, env;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/ajax - building requests\", {\n setup: function() {\n Person = { modelName: \'person\' };\n Place = { modelName: \'place\' };\n env = setupStore({ adapter: DS.RESTAdapter, person: Person, place: Place });\n store = env.store;\n adapter = env.adapter;\n },\n\n teardown: function() {\n run(function() {\n store.destroy();\n env.container.destroy();\n });\n }\n});\n\ntest(\"When an id is searched, the correct url should be generated\", function() {\n expect(2);\n var count = 0;\n adapter.ajax = function(url, method) {\n if (count === 0) { equal(url, \'/people/1\', \"should create the correct url\"); }\n if (count === 1) { equal(url, \'/places/1\', \"should create the correct url\"); }\n count++;\n return Ember.RSVP.resolve();\n };\n run(function() {\n adapter.find(store, Person, 1);\n adapter.find(store, Place, 1);\n });\n});\ntest(\"id\'s should be sanatized\", function() {\n expect(1);\n adapter.ajax= function(url, method) {\n equal(url, \'/people/..%2Fplace%2F1\', \"should create the correct url\");\n return Ember.RSVP.resolve();\n };\n run(function() {\n adapter.find(store, Person, \'../place/1\');\n });\n});\n})();//# sourceURL=ember-data/unit/adapters/rest-adapter/ajax.js");
362
378
 
363
379
  eval("(function() {var GroupsAdapter, Store;\nvar maxLength = -1;\nvar lengths = Ember.A([]);\n\nmodule(\"unit/adapters/rest_adapter/group_records_for_find_many_test - DS.RESTAdapter#groupRecordsForFindMany\", {\n setup: function() {\n GroupsAdapter = DS.RESTAdapter.extend({\n\n coalesceFindRequests: true,\n\n find: function(store, type, id, snapshot) {\n return Ember.RSVP.Promise.resolve({ id: id });\n },\n\n ajax: function(url, type, options) {\n var queryString = options.data.ids.map(function(i) {\n return encodeURIComponent(\'ids[]\') + \'=\' + encodeURIComponent(i);\n }).join(\'&\');\n var fullUrl = url + \'?\' + queryString;\n\n maxLength = this.get(\'maxUrlLength\');\n lengths.push(fullUrl.length);\n\n var testRecords = options.data.ids.map(function(id) {\n return { id: id };\n });\n return Ember.RSVP.Promise.resolve({ \'testRecords\' : testRecords });\n }\n\n });\n\n Store = createStore({\n adapter: GroupsAdapter,\n testRecord: DS.Model.extend()\n });\n\n }\n});\n\ntest(\'groupRecordsForFindMany - findMany\', function() {\n\n Ember.run(function() {\n for (var i = 1; i <= 1024; i++) {\n Store.find(\'testRecord\', i);\n }\n });\n\n ok(lengths.every(function(len) {\n return len <= maxLength;\n }), \"Some URLs are longer than \" + maxLength + \" chars\");\n\n});\n})();//# sourceURL=ember-data/unit/adapters/rest-adapter/group-records-for-find-many-test.js");
364
380
 
@@ -366,7 +382,7 @@ eval("(function() {var run = Ember.run;\n\nvar TestAdapter = DS.Adapter.extend()
366
382
 
367
383
  eval("(function() {var env, store;\nvar attr = DS.attr;\nvar hasMany = DS.hasMany;\nvar belongsTo = DS.belongsTo;\nvar run = Ember.run;\n\nvar Post, Tag;\n\nmodule(\"unit/many_array - DS.ManyArray\", {\n setup: function() {\n Post = DS.Model.extend({\n title: attr(\'string\'),\n tags: hasMany(\'tag\')\n });\n Post.toString = function() {\n return \'Post\';\n };\n\n Tag = DS.Model.extend({\n name: attr(\'string\'),\n post: belongsTo(\'post\')\n });\n Tag.toString = function() {\n return \'Tag\';\n };\n\n env = setupStore({\n post: Post,\n tag: Tag\n });\n store = env.store;\n },\n\n teardown: function() {\n run(function() {\n store.destroy();\n });\n }\n});\n\ntest(\"manyArray.save() calls save() on all records\", function() {\n expect(3);\n\n run(function() {\n Tag.reopen({\n save: function() {\n ok(true, \'record.save() was called\');\n return Ember.RSVP.resolve();\n }\n });\n\n store.push(\'tag\', { id: 1, name: \'Ember.js\' });\n store.push(\'tag\', { id: 2, name: \'Tomster\' });\n\n var post = store.push(\'post\', { id: 3, title: \'A framework for creating ambitious web applications\', tags: [1, 2] });\n post.get(\'tags\').save().then(function() {\n ok(true, \'manyArray.save() promise resolved\');\n });\n });\n});\n\ntest(\"manyArray.addRecord() has been deprecated\", function() {\n expect(3);\n\n run(function() {\n var tag = store.push(\'tag\', { id: 1, name: \'Ember.js\' });\n var post = store.push(\'post\', { id: 2, title: \'A framework for creating ambitious web applications\' });\n var tags = post.get(\'tags\');\n\n equal(tags.length, 0, \'there should not be any tags\');\n expectDeprecation(function() {\n tags.addRecord(tag);\n });\n equal(tags.length, 1, \'there should be 1 tag\');\n });\n});\n\ntest(\"manyArray.removeRecord() has been deprecated\", function() {\n expect(3);\n run(function() {\n var tag = store.push(\'tag\', { id: 1, name: \'Ember.js\' });\n var post = store.push(\'post\', { id: 2, title: \'A framework for creating ambitious web applications\', tags: [1] });\n var tags = post.get(\'tags\');\n\n equal(tags.length, 1, \'there should be 1 tag\');\n expectDeprecation(function() {\n tags.removeRecord(tag);\n });\n equal(tags.length, 0, \'there should not be any tags\');\n });\n});\n\n\ntest(\"manyArray trigger arrayContentChange functions with the correct values\", function() {\n expect(12);\n var willChangeStartIdx;\n var willChangeRemoveAmt;\n var willChangeAddAmt;\n var originalArrayContentWillChange = DS.ManyArray.prototype.arrayContentWillChange;\n var originalArrayContentDidChange = DS.ManyArray.prototype.arrayContentDidChange;\n DS.ManyArray.reopen({\n arrayContentWillChange: function(startIdx, removeAmt, addAmt) {\n willChangeStartIdx = startIdx;\n willChangeRemoveAmt = removeAmt;\n willChangeAddAmt = addAmt;\n return this._super.apply(arguments);\n },\n arrayContentDidChange: function(startIdx, removeAmt, addAmt) {\n equal(startIdx, willChangeStartIdx, \'WillChange and DidChange startIdx should match\');\n equal(removeAmt, willChangeRemoveAmt, \'WillChange and DidChange removeAmt should match\');\n equal(addAmt, willChangeAddAmt, \'WillChange and DidChange addAmt should match\');\n return this._super.apply(arguments);\n }\n });\n run(function() {\n store.push(\'tag\', { id: 1, name: \'Ember.js\' });\n store.push(\'tag\', { id: 2, name: \'Ember Data\' });\n var post = store.push(\'post\', { id: 2, title: \'A framework for creating ambitious web applications\', tags: [1] });\n post = store.push(\'post\', { id: 2, title: \'A framework for creating ambitious web applications\', tags: [1, 2] });\n });\n DS.ManyArray.reopen({\n arrayContentWillChange: originalArrayContentWillChange,\n arrayContentDidChange: originalArrayContentDidChange\n });\n});\n})();//# sourceURL=ember-data/unit/many-array-test.js");
368
384
 
369
- eval("(function() {var get = Ember.get;\nvar set = Ember.set;\nvar run = Ember.run;\n\nvar Person, store, array;\n\nmodule(\"unit/model - DS.Model\", {\n setup: function() {\n store = createStore();\n\n Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n isDrugAddict: DS.attr(\'boolean\')\n });\n },\n\n teardown: function() {\n run(function() {\n store.destroy();\n });\n Person = null;\n store = null;\n }\n});\n\ntest(\"can have a property set on it\", function() {\n var record;\n run(function() {\n record = store.createRecord(Person);\n set(record, \'name\', \'bar\');\n });\n\n equal(get(record, \'name\'), \'bar\', \"property was set on the record\");\n});\n\ntest(\"setting a property on a record that has not changed does not cause it to become dirty\", function() {\n expect(2);\n\n run(function() {\n store.push(Person, { id: 1, name: \"Peter\", isDrugAddict: true });\n store.find(Person, 1).then(function(person) {\n equal(person.get(\'isDirty\'), false, \"precond - person record should not be dirty\");\n\n person.set(\'name\', \"Peter\");\n person.set(\'isDrugAddict\', true);\n\n equal(person.get(\'isDirty\'), false, \"record does not become dirty after setting property to old value\");\n });\n });\n});\n\ntest(\"resetting a property on a record cause it to become clean again\", function() {\n expect(3);\n\n run(function() {\n store.push(Person, { id: 1, name: \"Peter\", isDrugAddict: true });\n store.find(Person, 1).then(function(person) {\n equal(person.get(\'isDirty\'), false, \"precond - person record should not be dirty\");\n person.set(\'isDrugAddict\', false);\n equal(person.get(\'isDirty\'), true, \"record becomes dirty after setting property to a new value\");\n person.set(\'isDrugAddict\', true);\n equal(person.get(\'isDirty\'), false, \"record becomes clean after resetting property to the old value\");\n });\n });\n});\n\ntest(\"a record becomes clean again only if all changed properties are reset\", function() {\n expect(5);\n\n run(function() {\n store.push(Person, { id: 1, name: \"Peter\", isDrugAddict: true });\n store.find(Person, 1).then(function(person) {\n equal(person.get(\'isDirty\'), false, \"precond - person record should not be dirty\");\n person.set(\'isDrugAddict\', false);\n equal(person.get(\'isDirty\'), true, \"record becomes dirty after setting one property to a new value\");\n person.set(\'name\', \'Mark\');\n equal(person.get(\'isDirty\'), true, \"record stays dirty after setting another property to a new value\");\n person.set(\'isDrugAddict\', true);\n equal(person.get(\'isDirty\'), true, \"record stays dirty after resetting only one property to the old value\");\n person.set(\'name\', \'Peter\');\n equal(person.get(\'isDirty\'), false, \"record becomes clean after resetting both properties to the old value\");\n });\n });\n});\n\ntest(\"a record reports its unique id via the `id` property\", function() {\n expect(1);\n\n run(function() {\n store.push(Person, { id: 1 });\n store.find(Person, 1).then(function(record) {\n equal(get(record, \'id\'), 1, \"reports id as id by default\");\n });\n });\n});\n\ntest(\"a record\'s id is included in its toString representation\", function() {\n expect(1);\n\n run(function() {\n store.push(Person, { id: 1 });\n store.find(Person, 1).then(function(record) {\n equal(record.toString(), \'<(subclass of DS.Model):\'+Ember.guidFor(record)+\':1>\', \"reports id in toString\");\n });\n });\n});\n\ntest(\"trying to set an `id` attribute should raise\", function() {\n Person = DS.Model.extend({\n id: DS.attr(\'number\'),\n name: DS.attr(\'string\')\n });\n\n expectAssertion(function() {\n run(function() {\n store.push(Person, { id: 1, name: \"Scumdale\" });\n store.find(Person, 1);\n });\n }, /You may not set `id`/);\n});\n\ntest(\"a collision of a record\'s id with object function\'s name\", function() {\n expect(1);\n\n var hasWatchMethod = Object.prototype.watch;\n try {\n if (!hasWatchMethod) {\n Object.prototype.watch = function() {};\n }\n run(function() {\n store.push(Person, { id: \'watch\' });\n store.find(Person, \'watch\').then(function(record) {\n equal(get(record, \'id\'), \'watch\', \"record is successfully created and could be found by its id\");\n });\n });\n } finally {\n if (!hasWatchMethod) {\n delete Object.prototype.watch;\n }\n }\n});\n\ntest(\"it should use `_reference` and not `reference` to store its reference\", function() {\n expect(1);\n\n run(function() {\n store.push(Person, { id: 1 });\n\n store.find(Person, 1).then(function(record) {\n equal(record.get(\'reference\'), undefined, \"doesn\'t shadow reference key\");\n });\n });\n});\n\ntest(\"it should cache attributes\", function() {\n expect(2);\n\n var store = createStore();\n\n var Post = DS.Model.extend({\n updatedAt: DS.attr(\'string\')\n });\n\n var dateString = \"Sat, 31 Dec 2011 00:08:16 GMT\";\n var date = new Date(dateString);\n\n run(function() {\n store.push(Post, { id: 1 });\n store.find(Post, 1).then(function(record) {\n run(function() {\n record.set(\'updatedAt\', date);\n });\n deepEqual(date, get(record, \'updatedAt\'), \"setting a date returns the same date\");\n strictEqual(get(record, \'updatedAt\'), get(record, \'updatedAt\'), \"second get still returns the same object\");\n })[\"finally\"](function() {\n run(store, \'destroy\');\n });\n });\n\n});\n\ntest(\"changedAttributes() return correct values\", function() {\n expect(3);\n\n var Mascot = DS.Model.extend({\n name: DS.attr(\'string\'),\n likes: DS.attr(\'string\'),\n isMascot: DS.attr(\'boolean\')\n });\n var mascot;\n\n\n run(function() {\n mascot = store.push(Mascot, { id: 1, likes: \'JavaScript\', isMascot: true });\n });\n\n deepEqual({}, mascot.changedAttributes(), \'there are no initial changes\');\n run(function() {\n mascot.set(\'name\', \'Tomster\'); // new value\n mascot.set(\'likes\', \'Ember.js\'); // changed value\n mascot.set(\'isMascot\', true); // same value\n });\n deepEqual({ name: [undefined, \'Tomster\'], likes: [\'JavaScript\', \'Ember.js\'] }, mascot.changedAttributes(), \'attributes has changed\');\n\n run(function() {\n mascot.rollback();\n });\n deepEqual({}, mascot.changedAttributes(), \'after rollback there are no changes\');\n});\n\ntest(\"a DS.Model does not require an attribute type\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr()\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag, { name: \"test\" });\n });\n\n equal(get(tag, \'name\'), \"test\", \"the value is persisted\");\n});\n\ntest(\"a DS.Model can have a defaultValue without an attribute type\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr({ defaultValue: \"unknown\" })\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag);\n });\n\n equal(get(tag, \'name\'), \"unknown\", \"the default value is found\");\n});\n\ntest(\"Calling attr(), belongsTo() or hasMany() throws a warning\", function() {\n expect(3);\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var store = createStore({ person: Person });\n\n run(function() {\n var person = store.createRecord(\'person\', { id: 1, name: \'TomHuda\' });\n\n throws(function() {\n person.attr();\n }, /The `attr` method is not available on DS.Model, a DS.Snapshot was probably expected/, \"attr() throws a warning\");\n\n throws(function() {\n person.belongsTo();\n }, /The `belongsTo` method is not available on DS.Model, a DS.Snapshot was probably expected/, \"belongTo() throws a warning\");\n\n throws(function() {\n person.hasMany();\n }, /The `hasMany` method is not available on DS.Model, a DS.Snapshot was probably expected/, \"hasMany() throws a warning\");\n });\n});\n\nmodule(\"unit/model - DS.Model updating\", {\n setup: function() {\n array = [{ id: 1, name: \"Scumbag Dale\" }, { id: 2, name: \"Scumbag Katz\" }, { id: 3, name: \"Scumbag Bryn\" }];\n Person = DS.Model.extend({ name: DS.attr(\'string\') });\n store = createStore();\n run(function() {\n store.pushMany(Person, array);\n });\n },\n teardown: function() {\n run(function() {\n store.destroy();\n Person = null;\n store = null;\n array = null;\n });\n }\n});\n\ntest(\"a DS.Model can update its attributes\", function() {\n expect(1);\n\n run(function() {\n store.find(Person, 2).then(function(person) {\n set(person, \'name\', \"Brohuda Katz\");\n equal(get(person, \'name\'), \"Brohuda Katz\", \"setting took hold\");\n });\n });\n});\n\ntest(\"a DS.Model can have a defaultValue\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\', { defaultValue: \"unknown\" })\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag);\n });\n\n equal(get(tag, \'name\'), \"unknown\", \"the default value is found\");\n\n run(function() {\n set(tag, \'name\', null);\n });\n\n equal(get(tag, \'name\'), null, \"null doesn\'t shadow defaultValue\");\n});\n\ntest(\"a DS.model can define \'setUnknownProperty\'\", function() {\n var tag;\n var Tag = DS.Model.extend({\n name: DS.attr(\"string\"),\n\n setUnknownProperty: function(key, value) {\n if (key === \"title\") {\n this.set(\"name\", value);\n }\n }\n });\n\n run(function() {\n tag = store.createRecord(Tag, { name: \"old\" });\n set(tag, \"title\", \"new\");\n });\n\n equal(get(tag, \"name\"), \"new\", \"setUnknownProperty not triggered\");\n});\n\ntest(\"a defaultValue for an attribute can be a function\", function() {\n var Tag = DS.Model.extend({\n createdAt: DS.attr(\'string\', {\n defaultValue: function() {\n return \"le default value\";\n }\n })\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag);\n });\n equal(get(tag, \'createdAt\'), \"le default value\", \"the defaultValue function is evaluated\");\n});\n\ntest(\"a defaultValue function gets the record, options, and key\", function() {\n expect(2);\n\n var Tag = DS.Model.extend({\n createdAt: DS.attr(\'string\', {\n defaultValue: function(record, options, key) {\n deepEqual(record, tag, \"the record is passed in properly\");\n equal(key, \'createdAt\', \"the attribute being defaulted is passed in properly\");\n return \"le default value\";\n }\n })\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag);\n });\n\n get(tag, \'createdAt\');\n});\n\ntest(\"setting a property to undefined on a newly created record should not impact the current state\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag);\n set(tag, \'name\', \'testing\');\n set(tag, \'name\', undefined);\n });\n\n equal(get(tag, \'currentState.stateName\'), \"root.loaded.created.uncommitted\");\n\n run(function() {\n tag = store.createRecord(Tag, { name: undefined });\n });\n\n equal(get(tag, \'currentState.stateName\'), \"root.loaded.created.uncommitted\");\n});\n\n// NOTE: this is a \'backdoor\' test that ensures internal consistency, and should be\n// thrown out if/when the current `_attributes` hash logic is removed.\ntest(\"setting a property back to its original value removes the property from the `_attributes` hash\", function() {\n expect(3);\n\n run(function() {\n store.find(Person, 1).then(function(person) {\n equal(person._attributes.name, undefined, \"the `_attributes` hash is clean\");\n\n set(person, \'name\', \"Niceguy Dale\");\n\n equal(person._attributes.name, \"Niceguy Dale\", \"the `_attributes` hash contains the changed value\");\n\n set(person, \'name\', \"Scumbag Dale\");\n\n equal(person._attributes.name, undefined, \"the `_attributes` hash is reset\");\n });\n });\n});\n\nmodule(\"unit/model - with a simple Person model\", {\n setup: function() {\n array = [\n { id: 1, name: \"Scumbag Dale\" },\n { id: 2, name: \"Scumbag Katz\" },\n { id: 3, name: \"Scumbag Bryn\" }\n ];\n Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n store = createStore({\n person: Person\n });\n run(function() {\n store.pushMany(Person, array);\n });\n },\n teardown: function() {\n run(function() {\n store.destroy();\n Person = null;\n store = null;\n array = null;\n });\n }\n});\n\ntest(\"can ask if record with a given id is loaded\", function() {\n equal(store.recordIsLoaded(Person, 1), true, \'should have person with id 1\');\n equal(store.recordIsLoaded(\'person\', 1), true, \'should have person with id 1\');\n equal(store.recordIsLoaded(Person, 4), false, \'should not have person with id 4\');\n equal(store.recordIsLoaded(\'person\', 4), false, \'should not have person with id 4\');\n});\n\ntest(\"a listener can be added to a record\", function() {\n var count = 0;\n var F = function() { count++; };\n var record;\n\n run(function() {\n record = store.createRecord(Person);\n });\n\n record.on(\'event!\', F);\n run(function() {\n record.trigger(\'event!\');\n });\n\n equal(count, 1, \"the event was triggered\");\n\n run(function() {\n record.trigger(\'event!\');\n });\n\n equal(count, 2, \"the event was triggered\");\n});\n\ntest(\"when an event is triggered on a record the method with the same name is invoked with arguments\", function() {\n var count = 0;\n var F = function() { count++; };\n var record;\n\n run(function() {\n record = store.createRecord(Person);\n });\n\n record.eventNamedMethod = F;\n\n run(function() {\n record.trigger(\'eventNamedMethod\');\n });\n\n equal(count, 1, \"the corresponding method was called\");\n});\n\ntest(\"when a method is invoked from an event with the same name the arguments are passed through\", function() {\n var eventMethodArgs = null;\n var F = function() {\n eventMethodArgs = arguments;\n };\n var record;\n\n run(function() {\n record = store.createRecord(Person);\n });\n\n record.eventThatTriggersMethod = F;\n\n run(function() {\n record.trigger(\'eventThatTriggersMethod\', 1, 2);\n });\n\n equal(eventMethodArgs[0], 1);\n equal(eventMethodArgs[1], 2);\n});\n\nvar converts = function(type, provided, expected) {\n var Model = DS.Model.extend({\n name: DS.attr(type)\n });\n\n var registry, container;\n if (Ember.Registry) {\n registry = new Ember.Registry();\n container = registry.container();\n } else {\n container = new Ember.Container();\n registry = container;\n }\n var testStore = createStore({ model: Model });\n var serializer = DS.JSONSerializer.create({\n store: testStore,\n container: container\n });\n\n run(function() {\n testStore.push(Model, serializer.normalize(Model, { id: 1, name: provided }));\n testStore.push(Model, serializer.normalize(Model, { id: 2 }));\n testStore.find(\'model\', 1).then(function(record) {\n deepEqual(get(record, \'name\'), expected, type + \" coerces \" + provided + \" to \" + expected);\n });\n });\n\n // See: Github issue #421\n // record = testStore.find(Model, 2);\n // set(record, \'name\', provided);\n // deepEqual(get(record, \'name\'), expected, type + \" coerces \" + provided + \" to \" + expected);\n};\n\nvar convertsFromServer = function(type, provided, expected) {\n var Model = DS.Model.extend({\n name: DS.attr(type)\n });\n\n var registry, container;\n if (Ember.Registry) {\n registry = new Ember.Registry();\n container = registry.container();\n } else {\n container = new Ember.Container();\n registry = container;\n }\n var testStore = createStore({ model: Model });\n var serializer = DS.JSONSerializer.create({\n store: testStore,\n container: container\n });\n\n run(function() {\n testStore.push(Model, serializer.normalize(Model, { id: \"1\", name: provided }));\n testStore.find(\'model\', 1).then(function(record) {\n deepEqual(get(record, \'name\'), expected, type + \" coerces \" + provided + \" to \" + expected);\n });\n });\n};\n\nvar convertsWhenSet = function(type, provided, expected) {\n var Model = DS.Model.extend({\n name: DS.attr(type)\n });\n\n var testStore = createStore({ model: Model });\n\n run(function() {\n testStore.push(Model, { id: 2 });\n testStore.find(\'model\', 2).then(function(record) {\n set(record, \'name\', provided);\n deepEqual(record.serialize().name, expected, type + \" saves \" + provided + \" as \" + expected);\n });\n });\n};\n\ntest(\"a DS.Model can describe String attributes\", function() {\n expect(6);\n\n converts(\'string\', \"Scumbag Tom\", \"Scumbag Tom\");\n converts(\'string\', 1, \"1\");\n converts(\'string\', \"\", \"\");\n converts(\'string\', null, null);\n converts(\'string\', undefined, null);\n convertsFromServer(\'string\', undefined, null);\n});\n\ntest(\"a DS.Model can describe Number attributes\", function() {\n expect(9);\n\n converts(\'number\', \"1\", 1);\n converts(\'number\', \"0\", 0);\n converts(\'number\', 1, 1);\n converts(\'number\', 0, 0);\n converts(\'number\', \"\", null);\n converts(\'number\', null, null);\n converts(\'number\', undefined, null);\n converts(\'number\', true, 1);\n converts(\'number\', false, 0);\n});\n\ntest(\"a DS.Model can describe Boolean attributes\", function() {\n expect(7);\n\n converts(\'boolean\', \"1\", true);\n converts(\'boolean\', \"\", false);\n converts(\'boolean\', 1, true);\n converts(\'boolean\', 0, false);\n converts(\'boolean\', null, false);\n converts(\'boolean\', true, true);\n converts(\'boolean\', false, false);\n});\n\ntest(\"a DS.Model can describe Date attributes\", function() {\n expect(5);\n\n converts(\'date\', null, null);\n converts(\'date\', undefined, undefined);\n\n var dateString = \"2011-12-31T00:08:16.000Z\";\n var date = new Date(Ember.Date.parse(dateString));\n\n var store = createStore();\n\n var Person = DS.Model.extend({\n updatedAt: DS.attr(\'date\')\n });\n\n run(function() {\n store.push(Person, { id: 1 });\n store.find(Person, 1).then(function(record) {\n run(function() {\n record.set(\'updatedAt\', date);\n });\n deepEqual(date, get(record, \'updatedAt\'), \"setting a date returns the same date\");\n });\n });\n convertsFromServer(\'date\', dateString, date);\n convertsWhenSet(\'date\', date, dateString);\n});\n\ntest(\"don\'t allow setting\", function() {\n var store = createStore();\n\n var Person = DS.Model.extend();\n var record;\n\n run(function() {\n record = store.createRecord(Person);\n });\n\n raises(function() {\n run(function() {\n record.set(\'isLoaded\', true);\n });\n }, \"raised error when trying to set an unsettable record\");\n});\n\ntest(\"ensure model exits loading state, materializes data and fulfills promise only after data is available\", function () {\n expect(2);\n\n var store = createStore({\n adapter: DS.Adapter.extend({\n find: function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, name: \"John\" });\n }\n })\n });\n\n run(function() {\n store.find(Person, 1).then(function(person) {\n equal(get(person, \'currentState.stateName\'), \'root.loaded.saved\', \'model is in loaded state\');\n equal(get(person, \'isLoaded\'), true, \'model is loaded\');\n });\n });\n});\n\ntest(\"A DS.Model can be JSONified\", function() {\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var store = createStore({ person: Person });\n var record;\n\n run(function() {\n record = store.createRecord(\'person\', { name: \"TomHuda\" });\n });\n deepEqual(record.toJSON(), { name: \"TomHuda\" });\n});\n\ntest(\"A subclass of DS.Model can not use the `data` property\", function() {\n var Person = DS.Model.extend({\n data: DS.attr(\'string\'),\n name: DS.attr(\'string\')\n });\n\n var store = createStore({ person: Person });\n\n expectAssertion(function() {\n run(function() {\n store.createRecord(\'person\', { name: \"TomHuda\" });\n });\n }, /`data` is a reserved property name on DS.Model objects/);\n});\n\ntest(\"A subclass of DS.Model can not use the `store` property\", function() {\n var Retailer = DS.Model.extend({\n store: DS.attr(),\n name: DS.attr()\n });\n\n var store = createStore({ retailer: Retailer });\n\n expectAssertion(function() {\n run(function() {\n store.createRecord(\'retailer\', { name: \"Buy n Large\" });\n });\n }, /`store` is a reserved property name on DS.Model objects/);\n});\n\ntest(\"A subclass of DS.Model can not use reserved properties\", function() {\n expect(3);\n [\n \'currentState\', \'data\', \'store\'\n ].forEach(function(reservedProperty) {\n var invalidExtendObject = {};\n invalidExtendObject[reservedProperty] = DS.attr();\n var Post = DS.Model.extend(invalidExtendObject);\n\n var store = createStore({ post: Post });\n\n expectAssertion(function() {\n run(function() {\n store.createRecord(\'post\', {});\n });\n }, /is a reserved property name on DS.Model objects/);\n });\n});\n\ntest(\"Pushing a record into the store should transition it to the loaded state\", function() {\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var store = createStore({ person: Person });\n\n run(function() {\n var person = store.createRecord(\'person\', { id: 1, name: \'TomHuda\' });\n equal(person.get(\'isNew\'), true, \'createRecord should put records into the new state\');\n store.push(\'person\', { id: 1, name: \'TomHuda\' });\n equal(person.get(\'isNew\'), false, \'push should put records into the loaded state\');\n });\n});\n})();//# sourceURL=ember-data/unit/model-test.js");
385
+ eval("(function() {var get = Ember.get;\nvar set = Ember.set;\nvar run = Ember.run;\n\nvar Person, store, array;\n\nmodule(\"unit/model - DS.Model\", {\n setup: function() {\n store = createStore();\n\n Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n isDrugAddict: DS.attr(\'boolean\')\n });\n },\n\n teardown: function() {\n run(function() {\n store.destroy();\n });\n Person = null;\n store = null;\n }\n});\n\ntest(\"can have a property set on it\", function() {\n var record;\n run(function() {\n record = store.createRecord(Person);\n set(record, \'name\', \'bar\');\n });\n\n equal(get(record, \'name\'), \'bar\', \"property was set on the record\");\n});\n\ntest(\"setting a property on a record that has not changed does not cause it to become dirty\", function() {\n expect(2);\n\n run(function() {\n store.push(Person, { id: 1, name: \"Peter\", isDrugAddict: true });\n store.find(Person, 1).then(function(person) {\n equal(person.get(\'isDirty\'), false, \"precond - person record should not be dirty\");\n\n person.set(\'name\', \"Peter\");\n person.set(\'isDrugAddict\', true);\n\n equal(person.get(\'isDirty\'), false, \"record does not become dirty after setting property to old value\");\n });\n });\n});\n\ntest(\"resetting a property on a record cause it to become clean again\", function() {\n expect(3);\n\n run(function() {\n store.push(Person, { id: 1, name: \"Peter\", isDrugAddict: true });\n store.find(Person, 1).then(function(person) {\n equal(person.get(\'isDirty\'), false, \"precond - person record should not be dirty\");\n person.set(\'isDrugAddict\', false);\n equal(person.get(\'isDirty\'), true, \"record becomes dirty after setting property to a new value\");\n person.set(\'isDrugAddict\', true);\n equal(person.get(\'isDirty\'), false, \"record becomes clean after resetting property to the old value\");\n });\n });\n});\n\ntest(\"a record becomes clean again only if all changed properties are reset\", function() {\n expect(5);\n\n run(function() {\n store.push(Person, { id: 1, name: \"Peter\", isDrugAddict: true });\n store.find(Person, 1).then(function(person) {\n equal(person.get(\'isDirty\'), false, \"precond - person record should not be dirty\");\n person.set(\'isDrugAddict\', false);\n equal(person.get(\'isDirty\'), true, \"record becomes dirty after setting one property to a new value\");\n person.set(\'name\', \'Mark\');\n equal(person.get(\'isDirty\'), true, \"record stays dirty after setting another property to a new value\");\n person.set(\'isDrugAddict\', true);\n equal(person.get(\'isDirty\'), true, \"record stays dirty after resetting only one property to the old value\");\n person.set(\'name\', \'Peter\');\n equal(person.get(\'isDirty\'), false, \"record becomes clean after resetting both properties to the old value\");\n });\n });\n});\n\ntest(\"a record reports its unique id via the `id` property\", function() {\n expect(1);\n\n run(function() {\n store.push(Person, { id: 1 });\n store.find(Person, 1).then(function(record) {\n equal(get(record, \'id\'), 1, \"reports id as id by default\");\n });\n });\n});\n\ntest(\"a record\'s id is included in its toString representation\", function() {\n expect(1);\n\n run(function() {\n store.push(Person, { id: 1 });\n store.find(Person, 1).then(function(record) {\n equal(record.toString(), \'<(subclass of DS.Model):\'+Ember.guidFor(record)+\':1>\', \"reports id in toString\");\n });\n });\n});\n\ntest(\"trying to set an `id` attribute should raise\", function() {\n Person = DS.Model.extend({\n id: DS.attr(\'number\'),\n name: DS.attr(\'string\')\n });\n\n expectAssertion(function() {\n run(function() {\n store.push(Person, { id: 1, name: \"Scumdale\" });\n store.find(Person, 1);\n });\n }, /You may not set `id`/);\n});\n\ntest(\"a collision of a record\'s id with object function\'s name\", function() {\n expect(1);\n\n var hasWatchMethod = Object.prototype.watch;\n try {\n if (!hasWatchMethod) {\n Object.prototype.watch = function() {};\n }\n run(function() {\n store.push(Person, { id: \'watch\' });\n store.find(Person, \'watch\').then(function(record) {\n equal(get(record, \'id\'), \'watch\', \"record is successfully created and could be found by its id\");\n });\n });\n } finally {\n if (!hasWatchMethod) {\n delete Object.prototype.watch;\n }\n }\n});\n\ntest(\"it should use `_reference` and not `reference` to store its reference\", function() {\n expect(1);\n\n run(function() {\n store.push(Person, { id: 1 });\n\n store.find(Person, 1).then(function(record) {\n equal(record.get(\'reference\'), undefined, \"doesn\'t shadow reference key\");\n });\n });\n});\n\ntest(\"it should cache attributes\", function() {\n expect(2);\n\n var store = createStore();\n\n var Post = DS.Model.extend({\n updatedAt: DS.attr(\'string\')\n });\n\n var dateString = \"Sat, 31 Dec 2011 00:08:16 GMT\";\n var date = new Date(dateString);\n\n run(function() {\n store.push(Post, { id: 1 });\n store.find(Post, 1).then(function(record) {\n run(function() {\n record.set(\'updatedAt\', date);\n });\n deepEqual(date, get(record, \'updatedAt\'), \"setting a date returns the same date\");\n strictEqual(get(record, \'updatedAt\'), get(record, \'updatedAt\'), \"second get still returns the same object\");\n })[\"finally\"](function() {\n run(store, \'destroy\');\n });\n });\n\n});\n\ntest(\"changedAttributes() return correct values\", function() {\n expect(3);\n\n var Mascot = DS.Model.extend({\n name: DS.attr(\'string\'),\n likes: DS.attr(\'string\'),\n isMascot: DS.attr(\'boolean\')\n });\n var mascot;\n\n\n run(function() {\n mascot = store.push(Mascot, { id: 1, likes: \'JavaScript\', isMascot: true });\n });\n\n deepEqual({}, mascot.changedAttributes(), \'there are no initial changes\');\n run(function() {\n mascot.set(\'name\', \'Tomster\'); // new value\n mascot.set(\'likes\', \'Ember.js\'); // changed value\n mascot.set(\'isMascot\', true); // same value\n });\n deepEqual({ name: [undefined, \'Tomster\'], likes: [\'JavaScript\', \'Ember.js\'] }, mascot.changedAttributes(), \'attributes has changed\');\n\n run(function() {\n mascot.rollback();\n });\n deepEqual({}, mascot.changedAttributes(), \'after rollback there are no changes\');\n});\n\ntest(\"a DS.Model does not require an attribute type\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr()\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag, { name: \"test\" });\n });\n\n equal(get(tag, \'name\'), \"test\", \"the value is persisted\");\n});\n\ntest(\"a DS.Model can have a defaultValue without an attribute type\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr({ defaultValue: \"unknown\" })\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag);\n });\n\n equal(get(tag, \'name\'), \"unknown\", \"the default value is found\");\n});\n\ntest(\"Calling attr(), belongsTo() or hasMany() throws a warning\", function() {\n expect(3);\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var store = createStore({ person: Person });\n\n run(function() {\n var person = store.createRecord(\'person\', { id: 1, name: \'TomHuda\' });\n\n throws(function() {\n person.attr();\n }, /The `attr` method is not available on DS.Model, a DS.Snapshot was probably expected/, \"attr() throws a warning\");\n\n throws(function() {\n person.belongsTo();\n }, /The `belongsTo` method is not available on DS.Model, a DS.Snapshot was probably expected/, \"belongTo() throws a warning\");\n\n throws(function() {\n person.hasMany();\n }, /The `hasMany` method is not available on DS.Model, a DS.Snapshot was probably expected/, \"hasMany() throws a warning\");\n });\n});\n\ntest(\"supports pushedData in root.deleted.uncommitted\", function() {\n var record;\n var hash = { id: 1 };\n run(function() {\n record = store.push(Person, hash);\n record.deleteRecord();\n store.push(Person, hash);\n equal(get(record, \'currentState.stateName\'), \'root.deleted.uncommitted\',\n \'record accepts pushedData is in root.deleted.uncommitted state\');\n });\n});\n\n\nmodule(\"unit/model - DS.Model updating\", {\n setup: function() {\n array = [{ id: 1, name: \"Scumbag Dale\" }, { id: 2, name: \"Scumbag Katz\" }, { id: 3, name: \"Scumbag Bryn\" }];\n Person = DS.Model.extend({ name: DS.attr(\'string\') });\n store = createStore();\n run(function() {\n store.pushMany(Person, array);\n });\n },\n teardown: function() {\n run(function() {\n store.destroy();\n Person = null;\n store = null;\n array = null;\n });\n }\n});\n\ntest(\"a DS.Model can update its attributes\", function() {\n expect(1);\n\n run(function() {\n store.find(Person, 2).then(function(person) {\n set(person, \'name\', \"Brohuda Katz\");\n equal(get(person, \'name\'), \"Brohuda Katz\", \"setting took hold\");\n });\n });\n});\n\ntest(\"a DS.Model can have a defaultValue\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\', { defaultValue: \"unknown\" })\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag);\n });\n\n equal(get(tag, \'name\'), \"unknown\", \"the default value is found\");\n\n run(function() {\n set(tag, \'name\', null);\n });\n\n equal(get(tag, \'name\'), null, \"null doesn\'t shadow defaultValue\");\n});\n\ntest(\"a DS.model can define \'setUnknownProperty\'\", function() {\n var tag;\n var Tag = DS.Model.extend({\n name: DS.attr(\"string\"),\n\n setUnknownProperty: function(key, value) {\n if (key === \"title\") {\n this.set(\"name\", value);\n }\n }\n });\n\n run(function() {\n tag = store.createRecord(Tag, { name: \"old\" });\n set(tag, \"title\", \"new\");\n });\n\n equal(get(tag, \"name\"), \"new\", \"setUnknownProperty not triggered\");\n});\n\ntest(\"a defaultValue for an attribute can be a function\", function() {\n var Tag = DS.Model.extend({\n createdAt: DS.attr(\'string\', {\n defaultValue: function() {\n return \"le default value\";\n }\n })\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag);\n });\n equal(get(tag, \'createdAt\'), \"le default value\", \"the defaultValue function is evaluated\");\n});\n\ntest(\"a defaultValue function gets the record, options, and key\", function() {\n expect(2);\n\n var Tag = DS.Model.extend({\n createdAt: DS.attr(\'string\', {\n defaultValue: function(record, options, key) {\n deepEqual(record, tag, \"the record is passed in properly\");\n equal(key, \'createdAt\', \"the attribute being defaulted is passed in properly\");\n return \"le default value\";\n }\n })\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag);\n });\n\n get(tag, \'createdAt\');\n});\n\ntest(\"setting a property to undefined on a newly created record should not impact the current state\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var tag;\n\n run(function() {\n tag = store.createRecord(Tag);\n set(tag, \'name\', \'testing\');\n set(tag, \'name\', undefined);\n });\n\n equal(get(tag, \'currentState.stateName\'), \"root.loaded.created.uncommitted\");\n\n run(function() {\n tag = store.createRecord(Tag, { name: undefined });\n });\n\n equal(get(tag, \'currentState.stateName\'), \"root.loaded.created.uncommitted\");\n});\n\n// NOTE: this is a \'backdoor\' test that ensures internal consistency, and should be\n// thrown out if/when the current `_attributes` hash logic is removed.\ntest(\"setting a property back to its original value removes the property from the `_attributes` hash\", function() {\n expect(3);\n\n run(function() {\n store.find(Person, 1).then(function(person) {\n equal(person._attributes.name, undefined, \"the `_attributes` hash is clean\");\n\n set(person, \'name\', \"Niceguy Dale\");\n\n equal(person._attributes.name, \"Niceguy Dale\", \"the `_attributes` hash contains the changed value\");\n\n set(person, \'name\', \"Scumbag Dale\");\n\n equal(person._attributes.name, undefined, \"the `_attributes` hash is reset\");\n });\n });\n});\n\nmodule(\"unit/model - with a simple Person model\", {\n setup: function() {\n array = [\n { id: 1, name: \"Scumbag Dale\" },\n { id: 2, name: \"Scumbag Katz\" },\n { id: 3, name: \"Scumbag Bryn\" }\n ];\n Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n store = createStore({\n person: Person\n });\n run(function() {\n store.pushMany(Person, array);\n });\n },\n teardown: function() {\n run(function() {\n store.destroy();\n Person = null;\n store = null;\n array = null;\n });\n }\n});\n\ntest(\"can ask if record with a given id is loaded\", function() {\n equal(store.recordIsLoaded(Person, 1), true, \'should have person with id 1\');\n equal(store.recordIsLoaded(\'person\', 1), true, \'should have person with id 1\');\n equal(store.recordIsLoaded(Person, 4), false, \'should not have person with id 4\');\n equal(store.recordIsLoaded(\'person\', 4), false, \'should not have person with id 4\');\n});\n\ntest(\"a listener can be added to a record\", function() {\n var count = 0;\n var F = function() { count++; };\n var record;\n\n run(function() {\n record = store.createRecord(Person);\n });\n\n record.on(\'event!\', F);\n run(function() {\n record.trigger(\'event!\');\n });\n\n equal(count, 1, \"the event was triggered\");\n\n run(function() {\n record.trigger(\'event!\');\n });\n\n equal(count, 2, \"the event was triggered\");\n});\n\ntest(\"when an event is triggered on a record the method with the same name is invoked with arguments\", function() {\n var count = 0;\n var F = function() { count++; };\n var record;\n\n run(function() {\n record = store.createRecord(Person);\n });\n\n record.eventNamedMethod = F;\n\n run(function() {\n record.trigger(\'eventNamedMethod\');\n });\n\n equal(count, 1, \"the corresponding method was called\");\n});\n\ntest(\"when a method is invoked from an event with the same name the arguments are passed through\", function() {\n var eventMethodArgs = null;\n var F = function() {\n eventMethodArgs = arguments;\n };\n var record;\n\n run(function() {\n record = store.createRecord(Person);\n });\n\n record.eventThatTriggersMethod = F;\n\n run(function() {\n record.trigger(\'eventThatTriggersMethod\', 1, 2);\n });\n\n equal(eventMethodArgs[0], 1);\n equal(eventMethodArgs[1], 2);\n});\n\nvar converts = function(type, provided, expected) {\n var Model = DS.Model.extend({\n name: DS.attr(type)\n });\n\n var registry, container;\n if (Ember.Registry) {\n registry = new Ember.Registry();\n container = registry.container();\n } else {\n container = new Ember.Container();\n registry = container;\n }\n var testStore = createStore({ model: Model });\n var serializer = DS.JSONSerializer.create({\n store: testStore,\n container: container\n });\n\n run(function() {\n testStore.push(Model, serializer.normalize(Model, { id: 1, name: provided }));\n testStore.push(Model, serializer.normalize(Model, { id: 2 }));\n testStore.find(\'model\', 1).then(function(record) {\n deepEqual(get(record, \'name\'), expected, type + \" coerces \" + provided + \" to \" + expected);\n });\n });\n\n // See: Github issue #421\n // record = testStore.find(Model, 2);\n // set(record, \'name\', provided);\n // deepEqual(get(record, \'name\'), expected, type + \" coerces \" + provided + \" to \" + expected);\n};\n\nvar convertsFromServer = function(type, provided, expected) {\n var Model = DS.Model.extend({\n name: DS.attr(type)\n });\n\n var registry, container;\n if (Ember.Registry) {\n registry = new Ember.Registry();\n container = registry.container();\n } else {\n container = new Ember.Container();\n registry = container;\n }\n var testStore = createStore({ model: Model });\n var serializer = DS.JSONSerializer.create({\n store: testStore,\n container: container\n });\n\n run(function() {\n testStore.push(Model, serializer.normalize(Model, { id: \"1\", name: provided }));\n testStore.find(\'model\', 1).then(function(record) {\n deepEqual(get(record, \'name\'), expected, type + \" coerces \" + provided + \" to \" + expected);\n });\n });\n};\n\nvar convertsWhenSet = function(type, provided, expected) {\n var Model = DS.Model.extend({\n name: DS.attr(type)\n });\n\n var testStore = createStore({ model: Model });\n\n run(function() {\n testStore.push(Model, { id: 2 });\n testStore.find(\'model\', 2).then(function(record) {\n set(record, \'name\', provided);\n deepEqual(record.serialize().name, expected, type + \" saves \" + provided + \" as \" + expected);\n });\n });\n};\n\ntest(\"a DS.Model can describe String attributes\", function() {\n expect(6);\n\n converts(\'string\', \"Scumbag Tom\", \"Scumbag Tom\");\n converts(\'string\', 1, \"1\");\n converts(\'string\', \"\", \"\");\n converts(\'string\', null, null);\n converts(\'string\', undefined, null);\n convertsFromServer(\'string\', undefined, null);\n});\n\ntest(\"a DS.Model can describe Number attributes\", function() {\n expect(9);\n\n converts(\'number\', \"1\", 1);\n converts(\'number\', \"0\", 0);\n converts(\'number\', 1, 1);\n converts(\'number\', 0, 0);\n converts(\'number\', \"\", null);\n converts(\'number\', null, null);\n converts(\'number\', undefined, null);\n converts(\'number\', true, 1);\n converts(\'number\', false, 0);\n});\n\ntest(\"a DS.Model can describe Boolean attributes\", function() {\n expect(7);\n\n converts(\'boolean\', \"1\", true);\n converts(\'boolean\', \"\", false);\n converts(\'boolean\', 1, true);\n converts(\'boolean\', 0, false);\n converts(\'boolean\', null, false);\n converts(\'boolean\', true, true);\n converts(\'boolean\', false, false);\n});\n\ntest(\"a DS.Model can describe Date attributes\", function() {\n expect(5);\n\n converts(\'date\', null, null);\n converts(\'date\', undefined, undefined);\n\n var dateString = \"2011-12-31T00:08:16.000Z\";\n var date = new Date(Ember.Date.parse(dateString));\n\n var store = createStore();\n\n var Person = DS.Model.extend({\n updatedAt: DS.attr(\'date\')\n });\n\n run(function() {\n store.push(Person, { id: 1 });\n store.find(Person, 1).then(function(record) {\n run(function() {\n record.set(\'updatedAt\', date);\n });\n deepEqual(date, get(record, \'updatedAt\'), \"setting a date returns the same date\");\n });\n });\n convertsFromServer(\'date\', dateString, date);\n convertsWhenSet(\'date\', date, dateString);\n});\n\ntest(\"don\'t allow setting\", function() {\n var store = createStore();\n\n var Person = DS.Model.extend();\n var record;\n\n run(function() {\n record = store.createRecord(Person);\n });\n\n raises(function() {\n run(function() {\n record.set(\'isLoaded\', true);\n });\n }, \"raised error when trying to set an unsettable record\");\n});\n\ntest(\"ensure model exits loading state, materializes data and fulfills promise only after data is available\", function () {\n expect(2);\n\n var store = createStore({\n adapter: DS.Adapter.extend({\n find: function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: 1, name: \"John\" });\n }\n })\n });\n\n run(function() {\n store.find(Person, 1).then(function(person) {\n equal(get(person, \'currentState.stateName\'), \'root.loaded.saved\', \'model is in loaded state\');\n equal(get(person, \'isLoaded\'), true, \'model is loaded\');\n });\n });\n});\n\ntest(\"A DS.Model can be JSONified\", function() {\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var store = createStore({ person: Person });\n var record;\n\n run(function() {\n record = store.createRecord(\'person\', { name: \"TomHuda\" });\n });\n deepEqual(record.toJSON(), { name: \"TomHuda\" });\n});\n\ntest(\"A subclass of DS.Model can not use the `data` property\", function() {\n var Person = DS.Model.extend({\n data: DS.attr(\'string\'),\n name: DS.attr(\'string\')\n });\n\n var store = createStore({ person: Person });\n\n expectAssertion(function() {\n run(function() {\n store.createRecord(\'person\', { name: \"TomHuda\" });\n });\n }, /`data` is a reserved property name on DS.Model objects/);\n});\n\ntest(\"A subclass of DS.Model can not use the `store` property\", function() {\n var Retailer = DS.Model.extend({\n store: DS.attr(),\n name: DS.attr()\n });\n\n var store = createStore({ retailer: Retailer });\n\n expectAssertion(function() {\n run(function() {\n store.createRecord(\'retailer\', { name: \"Buy n Large\" });\n });\n }, /`store` is a reserved property name on DS.Model objects/);\n});\n\ntest(\"A subclass of DS.Model can not use reserved properties\", function() {\n expect(3);\n [\n \'currentState\', \'data\', \'store\'\n ].forEach(function(reservedProperty) {\n var invalidExtendObject = {};\n invalidExtendObject[reservedProperty] = DS.attr();\n var Post = DS.Model.extend(invalidExtendObject);\n\n var store = createStore({ post: Post });\n\n expectAssertion(function() {\n run(function() {\n store.createRecord(\'post\', {});\n });\n }, /is a reserved property name on DS.Model objects/);\n });\n});\n\ntest(\"Pushing a record into the store should transition it to the loaded state\", function() {\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var store = createStore({ person: Person });\n\n run(function() {\n var person = store.createRecord(\'person\', { id: 1, name: \'TomHuda\' });\n equal(person.get(\'isNew\'), true, \'createRecord should put records into the new state\');\n store.push(\'person\', { id: 1, name: \'TomHuda\' });\n equal(person.get(\'isNew\'), false, \'push should put records into the loaded state\');\n });\n});\n})();//# sourceURL=ember-data/unit/model-test.js");
370
386
 
371
387
  eval("(function() {var errors;\n\nmodule(\"unit/model/errors\", {\n setup: function() {\n errors = DS.Errors.create();\n },\n\n teardown: function() {\n }\n});\n\nfunction becameInvalid(eventName) {\n if (eventName === \'becameInvalid\') {\n ok(true, \'becameInvalid send\');\n } else {\n ok(false, eventName + \' is send instead of becameInvalid\');\n }\n}\n\nfunction becameValid(eventName) {\n if (eventName === \'becameValid\') {\n ok(true, \'becameValid send\');\n } else {\n ok(false, eventName + \' is send instead of becameValid\');\n }\n}\n\nfunction unexpectedSend(eventName) {\n ok(false, \'unexpected send : \' + eventName);\n}\n\ntest(\"add error\", function() {\n expect(6);\n errors.trigger = becameInvalid;\n errors.add(\'firstName\', \'error\');\n errors.trigger = unexpectedSend;\n ok(errors.has(\'firstName\'), \'it has firstName errors\');\n equal(errors.get(\'length\'), 1, \'it has 1 error\');\n errors.add(\'firstName\', [\'error1\', \'error2\']);\n equal(errors.get(\'length\'), 3, \'it has 3 errors\');\n ok(!errors.get(\'isEmpty\'), \'it is not empty\');\n errors.add(\'lastName\', \'error\');\n errors.add(\'lastName\', \'error\');\n equal(errors.get(\'length\'), 4, \'it has 4 errors\');\n});\n\ntest(\"get error\", function() {\n expect(8);\n ok(errors.get(\'firstObject\') === undefined, \'returns undefined\');\n errors.trigger = becameInvalid;\n errors.add(\'firstName\', \'error\');\n errors.trigger = unexpectedSend;\n ok(errors.get(\'firstName\').length === 1, \'returns errors\');\n deepEqual(errors.get(\'firstObject\'), { attribute: \'firstName\', message: \'error\' });\n errors.add(\'firstName\', \'error2\');\n ok(errors.get(\'firstName\').length === 2, \'returns errors\');\n errors.add(\'lastName\', \'error3\');\n deepEqual(errors.toArray(), [\n { attribute: \'firstName\', message: \'error\' },\n { attribute: \'firstName\', message: \'error2\' },\n { attribute: \'lastName\', message: \'error3\' }\n ]);\n deepEqual(errors.get(\'firstName\'), [\n { attribute: \'firstName\', message: \'error\' },\n { attribute: \'firstName\', message: \'error2\' }\n ]);\n deepEqual(errors.get(\'messages\'), [\'error\', \'error2\', \'error3\']);\n});\n\ntest(\"remove error\", function() {\n expect(5);\n errors.trigger = becameInvalid;\n errors.add(\'firstName\', \'error\');\n errors.trigger = becameValid;\n errors.remove(\'firstName\');\n errors.trigger = unexpectedSend;\n ok(!errors.has(\'firstName\'), \'it has no firstName errors\');\n equal(errors.get(\'length\'), 0, \'it has 0 error\');\n ok(errors.get(\'isEmpty\'), \'it is empty\');\n errors.remove(\'firstName\');\n});\n\ntest(\"remove same errors from different attributes\", function() {\n expect(5);\n errors.trigger = becameInvalid;\n errors.add(\'firstName\', \'error\');\n errors.add(\'lastName\', \'error\');\n errors.trigger = unexpectedSend;\n equal(errors.get(\'length\'), 2, \'it has 2 error\');\n errors.remove(\'firstName\');\n equal(errors.get(\'length\'), 1, \'it has 1 error\');\n errors.trigger = becameValid;\n errors.remove(\'lastName\');\n ok(errors.get(\'isEmpty\'), \'it is empty\');\n});\n\ntest(\"clear errors\", function() {\n expect(5);\n errors.trigger = becameInvalid;\n errors.add(\'firstName\', [\'error\', \'error1\']);\n equal(errors.get(\'length\'), 2, \'it has 2 errors\');\n errors.trigger = becameValid;\n errors.clear();\n errors.trigger = unexpectedSend;\n ok(!errors.has(\'firstName\'), \'it has no firstName errors\');\n equal(errors.get(\'length\'), 0, \'it has 0 error\');\n errors.clear();\n});\n})();//# sourceURL=ember-data/unit/model/errors-test.js");
372
388
 
@@ -384,21 +400,23 @@ eval("(function() {var get = Ember.get;\nvar set = Ember.set;\nvar run = Ember.r
384
400
 
385
401
  eval("(function() {var env, store, Person, Dog;\nvar run = Ember.run;\n\nmodule(\"unit/model/rollback - model.rollback()\", {\n setup: function() {\n Person = DS.Model.extend({\n firstName: DS.attr(),\n lastName: DS.attr()\n });\n\n env = setupStore({ person: Person });\n store = env.store;\n }\n});\n\ntest(\"changes to attributes can be rolled back\", function() {\n var person;\n run(function() {\n person = store.push(\'person\', { id: 1, firstName: \"Tom\", lastName: \"Dale\" });\n person.set(\'firstName\', \"Thomas\");\n });\n\n equal(person.get(\'firstName\'), \"Thomas\");\n\n run(function() {\n person.rollback();\n });\n\n equal(person.get(\'firstName\'), \"Tom\");\n equal(person.get(\'isDirty\'), false);\n});\n\ntest(\"changes to unassigned attributes can be rolled back\", function() {\n var person;\n run(function() {\n person = store.push(\'person\', { id: 1, lastName: \"Dale\" });\n person.set(\'firstName\', \"Thomas\");\n });\n\n equal(person.get(\'firstName\'), \"Thomas\");\n\n run(function() {\n person.rollback();\n });\n\n equal(person.get(\'firstName\'), undefined);\n equal(person.get(\'isDirty\'), false);\n});\n\ntest(\"changes to attributes made after a record is in-flight only rolls back the local changes\", function() {\n env.adapter.updateRecord = function(store, type, snapshot) {\n // Make sure the save is async\n return new Ember.RSVP.Promise(function(resolve, reject) {\n Ember.run.later(null, resolve, 15);\n });\n };\n var person;\n\n run(function() {\n person = store.push(\'person\', { id: 1, firstName: \"Tom\", lastName: \"Dale\" });\n person.set(\'firstName\', \"Thomas\");\n });\n\n Ember.run(function() {\n var saving = person.save();\n\n equal(person.get(\'firstName\'), \"Thomas\");\n\n person.set(\'lastName\', \"Dolly\");\n\n equal(person.get(\'lastName\'), \"Dolly\");\n\n person.rollback();\n\n equal(person.get(\'firstName\'), \"Thomas\");\n equal(person.get(\'lastName\'), \"Dale\");\n equal(person.get(\'isSaving\'), true);\n\n saving.then(async(function() {\n equal(person.get(\'isDirty\'), false, \"The person is now clean\");\n }));\n });\n});\n\ntest(\"a record\'s changes can be made if it fails to save\", function() {\n env.adapter.updateRecord = function(store, type, snapshot) {\n return Ember.RSVP.reject();\n };\n var person;\n\n run(function() {\n person = store.push(\'person\', { id: 1, firstName: \"Tom\", lastName: \"Dale\" });\n person.set(\'firstName\', \"Thomas\");\n });\n\n deepEqual(person.changedAttributes(), { firstName: [\"Tom\", \"Thomas\"] });\n\n run(function() {\n person.save().then(null, function() {\n equal(person.get(\'isError\'), true);\n deepEqual(person.changedAttributes(), { firstName: [\"Tom\", \"Thomas\"] });\n\n person.rollback();\n\n equal(person.get(\'firstName\'), \"Tom\");\n equal(person.get(\'isError\'), false);\n deepEqual(person.changedAttributes(), {});\n });\n });\n});\n\ntest(\"a deleted record can be rollbacked if it fails to save, record arrays are updated accordingly\", function() {\n expect(7);\n env.adapter.deleteRecord = function(store, type, snapshot) {\n return Ember.RSVP.reject();\n };\n var person, people;\n\n run(function() {\n person = store.push(\'person\', { id: 1, firstName: \"Tom\", lastName: \"Dale\" });\n people = store.all(\'person\');\n });\n\n run(function() {\n person.deleteRecord();\n });\n equal(people.get(\'length\'), 0, \"a deleted record does not appear in record array anymore\");\n equal(people.objectAt(0), null, \"a deleted record does not appear in record array anymore\");\n\n run(function() {\n person.save().then(null, function() {\n equal(person.get(\'isError\'), true);\n equal(person.get(\'isDeleted\'), true);\n run(function() {\n person.rollback();\n });\n equal(person.get(\'isDeleted\'), false);\n equal(person.get(\'isError\'), false);\n }).then(function() {\n equal(people.get(\'length\'), 1, \"the underlying record array is updated accordingly in an asynchronous way\");\n });\n });\n});\n\ntest(\"new record can be rollbacked\", function() {\n var person;\n\n run(function() {\n person = store.createRecord(\'person\', { id: 1 });\n });\n\n equal(person.get(\'isNew\'), true, \"must be new\");\n equal(person.get(\'isDirty\'), true, \"must be dirty\");\n\n Ember.run(person, \'rollback\');\n\n equal(person.get(\'isNew\'), false, \"must not be new\");\n equal(person.get(\'isDirty\'), false, \"must not be dirty\");\n equal(person.get(\'isDeleted\'), true, \"must be deleted\");\n});\n\ntest(\"deleted record can be rollbacked\", function() {\n var person, people;\n\n run(function() {\n person = store.push(\'person\', { id: 1 });\n people = store.all(\'person\');\n person.deleteRecord();\n });\n\n equal(people.get(\'length\'), 0, \"a deleted record does not appear in record array anymore\");\n equal(people.objectAt(0), null, \"a deleted record does not appear in record array anymore\");\n\n equal(person.get(\'isDeleted\'), true, \"must be deleted\");\n\n run(function() {\n person.rollback();\n });\n equal(people.get(\'length\'), 1, \"the rollbacked record should appear again in the record array\");\n equal(person.get(\'isDeleted\'), false, \"must not be deleted\");\n equal(person.get(\'isDirty\'), false, \"must not be dirty\");\n});\n\ntest(\"invalid record can be rollbacked\", function() {\n Dog = DS.Model.extend({\n name: DS.attr()\n });\n\n var adapter = DS.RESTAdapter.extend({\n ajax: function(url, type, hash) {\n var adapter = this;\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n /* If InvalidError is passed back in the reject it will throw the\n exception which will bubble up the call stack (crashing the test)\n instead of hitting the failure route of the promise.\n So wrapping the reject in an Ember.run.next makes it so save\n completes without failure and the failure hits the failure route\n of the promise instead of crashing the save. */\n Ember.run.next(function() {\n reject(adapter.ajaxError({ name: \'is invalid\' }));\n });\n });\n },\n\n ajaxError: function(jqXHR) {\n return new DS.InvalidError(jqXHR);\n }\n });\n\n env = setupStore({ dog: Dog, adapter: adapter });\n var dog;\n run(function() {\n dog = env.store.push(\'dog\', { id: 1, name: \"Pluto\" });\n dog.set(\'name\', \"is a dwarf planet\");\n });\n\n run(function() {\n dog.save().then(null, async(function() {\n dog.rollback();\n\n equal(dog.get(\'name\'), \"Pluto\");\n ok(dog.get(\'isValid\'));\n }));\n });\n});\n\ntest(\"invalid record is rolled back to correct state after set\", function() {\n Dog = DS.Model.extend({\n name: DS.attr(),\n breed: DS.attr()\n });\n\n var adapter = DS.RESTAdapter.extend({\n ajax: function(url, type, hash) {\n var adapter = this;\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n /* If InvalidError is passed back in the reject it will throw the\n exception which will bubble up the call stack (crashing the test)\n instead of hitting the failure route of the promise.\n So wrapping the reject in an Ember.run.next makes it so save\n completes without failure and the failure hits the failure route\n of the promise instead of crashing the save. */\n Ember.run.next(function() {\n reject(adapter.ajaxError({ name: \'is invalid\' }));\n });\n });\n },\n\n ajaxError: function(jqXHR) {\n return new Error(jqXHR);\n }\n });\n\n env = setupStore({ dog: Dog, adapter: adapter });\n var dog;\n run(function() {\n dog = env.store.push(\'dog\', { id: 1, name: \"Pluto\", breed: \"Disney\" });\n dog.set(\'name\', \"is a dwarf planet\");\n dog.set(\'breed\', \'planet\');\n });\n\n run(function() {\n dog.save().then(null, async(function() {\n equal(dog.get(\'name\'), \"is a dwarf planet\");\n equal(dog.get(\'breed\'), \"planet\");\n\n run(function() {\n dog.set(\'name\', \'Seymour Asses\');\n });\n\n equal(dog.get(\'name\'), \"Seymour Asses\");\n equal(dog.get(\'breed\'), \"planet\");\n\n run(function() {\n dog.rollback();\n });\n\n equal(dog.get(\'name\'), \"Pluto\");\n equal(dog.get(\'breed\'), \"Disney\");\n ok(dog.get(\'isValid\'));\n }));\n });\n});\n\ntest(\"when destroying a record setup the record state to invalid, the record can be rollbacked\", function() {\n Dog = DS.Model.extend({\n name: DS.attr()\n });\n\n var adapter = DS.RESTAdapter.extend({\n ajax: function(url, type, hash) {\n var adapter = this;\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n Ember.run.next(function() {\n reject(adapter.ajaxError({ name: \'is invalid\' }));\n });\n });\n },\n\n ajaxError: function(jqXHR) {\n return new DS.InvalidError(jqXHR);\n }\n });\n\n env = setupStore({ dog: Dog, adapter: adapter });\n var dog;\n run(function() {\n dog = env.store.push(\'dog\', { id: 1, name: \"Pluto\" });\n });\n\n run(function() {\n dog.destroyRecord().then(null, async(function() {\n\n\n equal(dog.get(\'isError\'), false, \"must not be error\");\n equal(dog.get(\'isDeleted\'), true, \"must be deleted\");\n equal(dog.get(\'isValid\'), false, \"must not be valid\");\n ok(dog.get(\'errors.length\') > 0, \"must have errors\");\n\n dog.rollback();\n\n equal(dog.get(\'isError\'), false, \"must not be error after `rollback`\");\n equal(dog.get(\'isDeleted\'), false, \"must not be deleted after `rollback`\");\n equal(dog.get(\'isValid\'), true, \"must be valid after `rollback`\");\n ok(dog.get(\'errors.length\') === 0, \"must not have errors\");\n }));\n });\n});\n})();//# sourceURL=ember-data/unit/model/rollback-test.js");
386
402
 
403
+ eval("(function() {})();//# sourceURL=ember-data/unit/normalize-type-key-test.js");
404
+
387
405
  eval("(function() {module(\'PromiseManyArray\');\n\ntest(\'.reload should NOT leak the internal promise, rather return another promiseArray\', function() {\n expect(2);\n\n var content = Ember.A();\n\n content.reload = function() {\n return Ember.RSVP.Promise.resolve(content);\n };\n\n var array = DS.PromiseManyArray.create({\n content: content\n });\n\n Ember.run(function() {\n var reloaded = array.reload();\n\n ok(reloaded instanceof DS.PromiseManyArray);\n\n reloaded.then(function(value) {\n equal(content, value);\n });\n });\n});\n})();//# sourceURL=ember-data/unit/promise-proxies-test.js");
388
406
 
389
407
  eval("(function() {var get = Ember.get;\n\nvar Person, array;\nvar run = Ember.run;\n\nmodule(\"unit/record_array - DS.RecordArray\", {\n setup: function() {\n array = [{ id: \'1\', name: \"Scumbag Dale\" }, { id: \'2\', name: \"Scumbag Katz\" }, { id: \'3\', name: \"Scumbag Bryn\" }];\n\n Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n }\n});\n\ntest(\"a record array is backed by records\", function() {\n expect(3);\n\n var store = createStore();\n run(function() {\n store.pushMany(Person, array);\n });\n\n run(function() {\n store.findByIds(Person, [1,2,3]).then(function(records) {\n for (var i=0, l=get(array, \'length\'); i<l; i++) {\n deepEqual(records[i].getProperties(\'id\', \'name\'), array[i], \"a record array materializes objects on demand\");\n }\n });\n });\n});\n\ntest(\"acts as a live query\", function() {\n var store = createStore();\n\n var recordArray = store.all(Person);\n run(function() {\n store.push(Person, { id: 1, name: \'wycats\' });\n });\n equal(get(recordArray, \'lastObject.name\'), \'wycats\');\n\n run(function() {\n store.push(Person, { id: 2, name: \'brohuda\' });\n });\n equal(get(recordArray, \'lastObject.name\'), \'brohuda\');\n});\n\ntest(\"stops updating when destroyed\", function() {\n expect(3);\n var store = createStore();\n\n // TODO remove once\n // https://github.com/emberjs/ember.js/commit/c3f13e85a62069295965dd49ca487fe6ddba1188\n // is on the release branch\n var emptyLength = Ember.meta(store).descs ? undefined : 0;\n\n var recordArray = store.all(Person);\n run(function() {\n store.push(Person, { id: 1, name: \'wycats\' });\n });\n\n run(function() {\n recordArray.destroy();\n });\n\n run(function() {\n equal(recordArray.get(\'length\'), emptyLength, \"Has no more records\");\n store.push(Person, { id: 2, name: \'brohuda\' });\n });\n\n equal(recordArray.get(\'length\'), emptyLength, \"Has not been updated\");\n equal(recordArray.get(\'content\'), undefined, \"Has not been updated\");\n});\n\n\ntest(\"a loaded record is removed from a record array when it is deleted\", function() {\n expect(4);\n\n var Tag = DS.Model.extend({\n people: DS.hasMany(\'person\')\n });\n\n Person.reopen({\n tag: DS.belongsTo(\'tag\')\n });\n\n var env = setupStore({ tag: Tag, person: Person });\n var store = env.store;\n\n run(function() {\n store.pushMany(\'person\', array);\n store.push(\'tag\', { id: 1 });\n });\n\n run(function() {\n var asyncRecords = Ember.RSVP.hash({\n scumbag: store.find(\'person\', 1),\n tag: store.find(\'tag\', 1)\n });\n\n asyncRecords.then(function(records) {\n var scumbag = records.scumbag;\n var tag = records.tag;\n\n run(function() {\n tag.get(\'people\').addObject(scumbag);\n });\n equal(get(scumbag, \'tag\'), tag, \"precond - the scumbag\'s tag has been set\");\n\n var recordArray = tag.get(\'people\');\n\n equal(get(recordArray, \'length\'), 1, \"precond - record array has one item\");\n equal(get(recordArray.objectAt(0), \'name\'), \"Scumbag Dale\", \"item at index 0 is record with id 1\");\n\n scumbag.deleteRecord();\n\n equal(get(recordArray, \'length\'), 0, \"record is removed from the record array\");\n });\n });\n});\n\ntest(\"a loaded record is removed from a record array when it is deleted even if the belongsTo side isn\'t defined\", function() {\n var Tag = DS.Model.extend({\n people: DS.hasMany(\'person\')\n });\n\n var env = setupStore({ tag: Tag, person: Person });\n var store = env.store;\n var scumbag, tag;\n\n run(function() {\n scumbag = store.push(\'person\', { id: 1, name: \'Scumbag Tom\' });\n tag = store.push(\'tag\', { id: 1, people: [1] });\n scumbag.deleteRecord();\n });\n\n equal(tag.get(\'people.length\'), 0, \"record is removed from the record array\");\n});\n\ntest(\"a loaded record is removed both from the record array and from the belongs to, even if the belongsTo side isn\'t defined\", function() {\n var Tag = DS.Model.extend({\n people: DS.hasMany(\'person\')\n });\n\n var Tool = DS.Model.extend({\n person: DS.belongsTo(\'person\')\n });\n\n var env = setupStore({ tag: Tag, person: Person, tool: Tool });\n var store = env.store;\n var scumbag, tag, tool;\n\n run(function() {\n scumbag = store.push(\'person\', { id: 1, name: \'Scumbag Tom\' });\n tag = store.push(\'tag\', { id: 1, people: [1] });\n tool = store.push(\'tool\', { id: 1, person: 1 });\n });\n\n equal(tag.get(\'people.length\'), 1, \"record is in the record array\");\n equal(tool.get(\'person\'), scumbag, \"the tool belongs to the record\");\n\n run(function() {\n scumbag.deleteRecord();\n });\n\n equal(tag.get(\'people.length\'), 0, \"record is removed from the record array\");\n equal(tool.get(\'person\'), null, \"the tool is now orphan\");\n});\n\n// GitHub Issue #168\ntest(\"a newly created record is removed from a record array when it is deleted\", function() {\n var store = createStore();\n var recordArray = store.all(Person);\n var scumbag;\n\n run(function() {\n scumbag = store.createRecord(Person, {\n name: \"Scumbag Dale\"\n });\n });\n\n equal(get(recordArray, \'length\'), 1, \"precond - record array already has the first created item\");\n\n // guarantee coalescence\n Ember.run(function() {\n store.createRecord(Person, { name: \'p1\' });\n store.createRecord(Person, { name: \'p2\' });\n store.createRecord(Person, { name: \'p3\' });\n });\n\n equal(get(recordArray, \'length\'), 4, \"precond - record array has the created item\");\n equal(get(recordArray.objectAt(0), \'name\'), \"Scumbag Dale\", \"item at index 0 is record with id 1\");\n\n run(function() {\n scumbag.deleteRecord();\n });\n\n equal(get(recordArray, \'length\'), 3, \"record is removed from the record array\");\n\n run(function() {\n recordArray.objectAt(0).set(\'name\', \'toto\');\n });\n\n equal(get(recordArray, \'length\'), 3, \"record is still removed from the record array\");\n});\n\ntest(\"a record array returns undefined when asking for a member outside of its content Array\'s range\", function() {\n var store = createStore();\n\n run(function() {\n store.pushMany(Person, array);\n });\n\n var recordArray = store.all(Person);\n\n strictEqual(recordArray.objectAt(20), undefined, \"objects outside of the range just return undefined\");\n});\n\n// This tests for a bug in the recordCache, where the records were being cached in the incorrect order.\ntest(\"a record array should be able to be enumerated in any order\", function() {\n var store = createStore();\n run(function() {\n store.pushMany(Person, array);\n });\n\n var recordArray = store.all(Person);\n\n equal(get(recordArray.objectAt(2), \'id\'), 3, \"should retrieve correct record at index 2\");\n equal(get(recordArray.objectAt(1), \'id\'), 2, \"should retrieve correct record at index 1\");\n equal(get(recordArray.objectAt(0), \'id\'), 1, \"should retrieve correct record at index 0\");\n});\n\ntest(\"an AdapterPopulatedRecordArray knows if it\'s loaded or not\", function() {\n expect(1);\n\n var env = setupStore({ person: Person });\n var store = env.store;\n\n env.adapter.findQuery = function(store, type, query, recordArray) {\n return Ember.RSVP.resolve(array);\n };\n\n run(function() {\n store.find(\'person\', { page: 1 }).then(function(people) {\n equal(get(people, \'isLoaded\'), true, \"The array is now loaded\");\n });\n });\n});\n\ntest(\"a record array should return a promise when updating\", function() {\n var recordArray, promise;\n var env = setupStore({ person: Person });\n var store = env.store;\n\n env.adapter.findAll = function(store, type, query, recordArray) {\n return Ember.RSVP.resolve(array);\n };\n\n recordArray = store.all(Person);\n run(function() {\n promise = recordArray.update();\n });\n ok(promise.then && typeof promise.then === \"function\", \"#update returns a promise\");\n});\n})();//# sourceURL=ember-data/unit/record-array-test.js");
390
408
 
391
409
  eval("(function() {var get = Ember.get;\n\nvar rootState, stateName;\n\nmodule(\"unit/states - Flags for record states\", {\n setup: function() {\n rootState = DS.RootState;\n }\n});\n\nvar isTrue = function(flag) {\n equal(get(rootState, stateName + \".\" + flag), true, stateName + \".\" + flag + \" should be true\");\n};\n\nvar isFalse = function(flag) {\n equal(get(rootState, stateName + \".\" + flag), false, stateName + \".\" + flag + \" should be false\");\n};\n\ntest(\"the empty state\", function() {\n stateName = \"empty\";\n isFalse(\"isLoading\");\n isFalse(\"isLoaded\");\n isFalse(\"isDirty\");\n isFalse(\"isSaving\");\n isFalse(\"isDeleted\");\n});\n\ntest(\"the loading state\", function() {\n stateName = \"loading\";\n isTrue(\"isLoading\");\n isFalse(\"isLoaded\");\n isFalse(\"isDirty\");\n isFalse(\"isSaving\");\n isFalse(\"isDeleted\");\n});\n\ntest(\"the loaded state\", function() {\n stateName = \"loaded\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isFalse(\"isDirty\");\n isFalse(\"isSaving\");\n isFalse(\"isDeleted\");\n});\n\ntest(\"the updated state\", function() {\n stateName = \"loaded.updated\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isTrue(\"isDirty\");\n isFalse(\"isSaving\");\n isFalse(\"isDeleted\");\n});\n\ntest(\"the saving state\", function() {\n stateName = \"loaded.updated.inFlight\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isTrue(\"isDirty\");\n isTrue(\"isSaving\");\n isFalse(\"isDeleted\");\n});\n\ntest(\"the deleted state\", function() {\n stateName = \"deleted\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isTrue(\"isDirty\");\n isFalse(\"isSaving\");\n isTrue(\"isDeleted\");\n});\n\ntest(\"the deleted.saving state\", function() {\n stateName = \"deleted.inFlight\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isTrue(\"isDirty\");\n isTrue(\"isSaving\");\n isTrue(\"isDeleted\");\n});\n\ntest(\"the deleted.saved state\", function() {\n stateName = \"deleted.saved\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isFalse(\"isDirty\");\n isFalse(\"isSaving\");\n isTrue(\"isDeleted\");\n});\n})();//# sourceURL=ember-data/unit/states-test.js");
392
410
 
393
- eval("(function() {var get = Ember.get;\nvar set = Ember.set;\nvar resolve = Ember.RSVP.resolve;\nvar TestAdapter, store;\nvar run = Ember.run;\n\nmodule(\"unit/store/adapter_interop - DS.Store working with a DS.Adapter\", {\n setup: function() {\n TestAdapter = DS.Adapter.extend();\n },\n teardown: function() {\n run(function() {\n if (store) { store.destroy(); }\n });\n }\n});\n\ntest(\"Adapter can be set as a factory\", function() {\n store = createStore({ adapter: TestAdapter });\n\n ok(store.get(\'defaultAdapter\') instanceof TestAdapter);\n});\n\ntest(\'Adapter can be set as a name\', function() {\n store = createStore({ adapter: \'-rest\' });\n\n ok(store.get(\'defaultAdapter\') instanceof DS.RESTAdapter);\n});\n\ntest(\'Adapter can not be set as an instance\', function() {\n expect(5);\n\n store = DS.Store.create({\n adapter: DS.Adapter.create()\n });\n var assert = Ember.assert;\n Ember.assert = function() { ok(true, \"raises an error when passing in an instance\"); };\n store.get(\'defaultAdapter\');\n Ember.assert = assert;\n});\n\ntest(\"Calling Store#find invokes its adapter#find\", function() {\n expect(5);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n ok(true, \"Adapter#find was called\");\n equal(store, currentStore, \"Adapter#find was called with the right store\");\n equal(type, currentType, \"Adapter#find was called with the type passed into Store#find\");\n equal(id, 1, \"Adapter#find was called with the id passed into Store#find\");\n equal(snapshot.id, \'1\', \"Adapter#find was called with the record created from Store#find\");\n\n return Ember.RSVP.resolve({ id: 1 });\n }\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend();\n\n run(function() {\n currentStore.find(currentType, 1);\n });\n});\n\ntest(\"Calling Store#findById multiple times coalesces the calls into a adapter#findMany call\", function() {\n expect(2);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n ok(false, \"Adapter#find was not called\");\n },\n findMany: function(store, type, ids, snapshots) {\n start();\n ok(true, \"Adapter#findMany was called\");\n deepEqual(ids, [\"1\",\"2\"], \'Correct ids were passed in to findMany\');\n return Ember.RSVP.resolve([{ id: 1 }, { id: 2 }]);\n },\n coalesceFindRequests: true\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend();\n currentType.typeKey = \"test\";\n stop();\n run(function() {\n currentStore.find(currentType, 1);\n currentStore.find(currentType, 2);\n });\n});\n\ntest(\"Returning a promise from `find` asynchronously loads data\", function() {\n expect(1);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n return resolve({ id: 1, name: \"Scumbag Dale\" });\n }\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function() {\n currentStore.find(currentType, 1).then(async(function(object) {\n strictEqual(get(object, \'name\'), \"Scumbag Dale\", \"the data was pushed\");\n }));\n });\n});\n\ntest(\"IDs provided as numbers are coerced to strings\", function() {\n expect(4);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n equal(typeof id, \'string\', \"id has been normalized to a string\");\n return resolve({ id: 1, name: \"Scumbag Sylvain\" });\n }\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function() {\n currentStore.find(currentType, 1).then(async(function(object) {\n equal(typeof object.get(\'id\'), \'string\', \"id was coerced to a string\");\n run(function() {\n currentStore.push(currentType, { id: 2, name: \"Scumbag Sam Saffron\" });\n });\n return currentStore.find(currentType, 2);\n })).then(async(function(object) {\n ok(object, \"object was found\");\n equal(typeof object.get(\'id\'), \'string\', \"id is a string despite being supplied and searched for as a number\");\n }));\n });\n});\n\n\nvar array = [{ id: \"1\", name: \"Scumbag Dale\" }, { id: \"2\", name: \"Scumbag Katz\" }, { id: \"3\", name: \"Scumbag Bryn\" }];\n\ntest(\"can load data for the same record if it is not dirty\", function() {\n expect(3);\n\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function() {\n store.push(Person, { id: 1, name: \"Tom Dale\" });\n\n store.find(Person, 1).then(async(function(tom) {\n equal(get(tom, \'isDirty\'), false, \"precond - record is not dirty\");\n equal(get(tom, \'name\'), \"Tom Dale\", \"returns the correct name\");\n\n store.push(Person, { id: 1, name: \"Captain Underpants\" });\n equal(get(tom, \'name\'), \"Captain Underpants\", \"updated record with new date\");\n }));\n });\n});\n\n/*\ntest(\"DS.Store loads individual records without explicit IDs with a custom primaryKey\", function() {\n var store = DS.Store.create();\n var Person = DS.Model.extend({ name: DS.attr(\'string\'), primaryKey: \'key\' });\n\n store.load(Person, { key: 1, name: \"Tom Dale\" });\n\n var tom = store.find(Person, 1);\n equal(get(tom, \'name\'), \"Tom Dale\", \"the person was successfully loaded for the given ID\");\n});\n*/\n\ntest(\"pushMany extracts ids from an Array of hashes if no ids are specified\", function() {\n expect(1);\n\n var store = createStore();\n\n var Person = DS.Model.extend({ name: DS.attr(\'string\') });\n\n run(function() {\n store.pushMany(Person, array);\n store.find(Person, 1).then(async(function(person) {\n equal(get(person, \'name\'), \"Scumbag Dale\", \"correctly extracted id for loaded data\");\n }));\n });\n});\n\ntest(\"loadMany takes an optional Object and passes it on to the Adapter\", function() {\n expect(2);\n\n var passedQuery = { page: 1 };\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var adapter = TestAdapter.extend({\n findQuery: function(store, type, query) {\n equal(type, Person, \"The type was Person\");\n equal(query, passedQuery, \"The query was passed in\");\n return Ember.RSVP.resolve([]);\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n run(function() {\n store.find(Person, passedQuery);\n });\n});\n\ntest(\"Find with query calls the correct extract\", function() {\n var passedQuery = { page: 1 };\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var adapter = TestAdapter.extend({\n findQuery: function(store, type, query) {\n return Ember.RSVP.resolve([]);\n }\n });\n\n var callCount = 0;\n\n var ApplicationSerializer = DS.JSONSerializer.extend({\n extractFindQuery: function(store, type, payload) {\n callCount++;\n return [];\n }\n });\n\n var env = setupStore({\n adapter: adapter\n });\n var store = env.store;\n\n env.registry.register(\'serializer:application\', ApplicationSerializer);\n\n run(function() {\n store.find(Person, passedQuery);\n });\n equal(callCount, 1, \'extractFindQuery was called\');\n});\n\ntest(\"all(type) returns a record array of all records of a specific type\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function() {\n store.push(Person, { id: 1, name: \"Tom Dale\" });\n });\n\n var results = store.all(Person);\n equal(get(results, \'length\'), 1, \"record array should have the original object\");\n equal(get(results.objectAt(0), \'name\'), \"Tom Dale\", \"record has the correct information\");\n\n run(function() {\n store.push(Person, { id: 2, name: \"Yehuda Katz\" });\n });\n equal(get(results, \'length\'), 2, \"record array should have the new object\");\n equal(get(results.objectAt(1), \'name\'), \"Yehuda Katz\", \"record has the correct information\");\n\n strictEqual(results, store.all(Person), \"subsequent calls to all return the same recordArray)\");\n});\n\ntest(\"a new record of a particular type is created via store.createRecord(type)\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var person;\n\n run(function() {\n person = store.createRecord(Person);\n });\n\n equal(get(person, \'isLoaded\'), true, \"A newly created record is loaded\");\n equal(get(person, \'isNew\'), true, \"A newly created record is new\");\n equal(get(person, \'isDirty\'), true, \"A newly created record is dirty\");\n\n run(function() {\n set(person, \'name\', \"Braaahm Dale\");\n });\n\n equal(get(person, \'name\'), \"Braaahm Dale\", \"Even if no hash is supplied, `set` still worked\");\n});\n\ntest(\"a new record with a specific id can\'t be created if this id is already used in the store\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n Person.reopenClass({\n toString: function() {\n return \'Person\';\n }\n });\n\n run(function() {\n store.createRecord(Person, { id: 5 });\n });\n\n expectAssertion(function() {\n run(function() {\n store.createRecord(Person, { id: 5 });\n });\n }, /The id 5 has already been used with another record of type Person/);\n});\n\ntest(\"an initial data hash can be provided via store.createRecord(type, hash)\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var person;\n\n run(function() {\n person = store.createRecord(Person, { name: \"Brohuda Katz\" });\n });\n\n equal(get(person, \'isLoaded\'), true, \"A newly created record is loaded\");\n equal(get(person, \'isNew\'), true, \"A newly created record is new\");\n equal(get(person, \'isDirty\'), true, \"A newly created record is dirty\");\n\n equal(get(person, \'name\'), \"Brohuda Katz\", \"The initial data hash is provided\");\n});\n\ntest(\"if an id is supplied in the initial data hash, it can be looked up using `store.find`\", function() {\n expect(1);\n\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var person;\n\n run(function() {\n person = store.createRecord(Person, { id: 1, name: \"Brohuda Katz\" });\n store.find(Person, 1).then(async(function(again) {\n strictEqual(person, again, \"the store returns the loaded object\");\n }));\n });\n});\n\ntest(\"initial values of attributes can be passed in as the third argument to find\", function() {\n expect(1);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n equal(snapshot.attr(\'name\'), \'Test\', \'Preloaded attribtue set\');\n return Ember.RSVP.resolve({ id: \'1\', name: \'Test\' });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function() {\n store.find(Person, 1, { name: \'Test\' });\n });\n});\n\ntest(\"initial values of belongsTo can be passed in as the third argument to find as records\", function() {\n expect(1);\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n equal(snapshot.belongsTo(\'friend\').attr(\'name\'), \'Tom\', \'Preloaded belongsTo set\');\n return new Ember.RSVP.Promise(function() {});\n }\n });\n\n var env = setupStore({\n adapter: adapter\n });\n var store = env.store;\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friend: DS.belongsTo(\'person\', { inverse: null })\n });\n\n env.registry.register(\'model:person\', Person);\n var tom;\n\n run(function() {\n tom = store.push(Person, { id: 2, name: \'Tom\' });\n store.find(Person, 1, { friend: tom });\n });\n});\n\ntest(\"initial values of belongsTo can be passed in as the third argument to find as ids\", function() {\n expect(1);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n return Ember.RSVP.Promise.resolve({ id: id });\n }\n });\n\n var env = setupStore({\n adapter: adapter\n });\n var store = env.store;\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friend: DS.belongsTo(\'person\', { async: true, inverse: null })\n });\n\n env.registry.register(\'model:person\', Person);\n\n run(function() {\n store.find(Person, 1, { friend: 2 }).then(async(function() {\n store.getById(Person, 1).get(\'friend\').then(async(function(friend) {\n equal(friend.get(\'id\'), \'2\', \'Preloaded belongsTo set\');\n }));\n }));\n });\n});\n\ntest(\"initial values of hasMany can be passed in as the third argument to find as records\", function() {\n expect(1);\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n equal(snapshot.hasMany(\'friends\')[0].attr(\'name\'), \'Tom\', \'Preloaded hasMany set\');\n return new Ember.RSVP.Promise(function() {});\n }\n });\n\n var env = setupStore({\n adapter: adapter\n });\n var store = env.store;\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friends: DS.hasMany(\'person\', { inverse: null })\n });\n\n env.registry.register(\'model:person\', Person);\n var tom;\n\n run(function() {\n tom = store.push(Person, { id: 2, name: \'Tom\' });\n store.find(Person, 1, { friends: [tom] });\n });\n});\n\ntest(\"initial values of hasMany can be passed in as the third argument to find as ids\", function() {\n expect(1);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n equal(snapshot.hasMany(\'friends\')[0].id, \'2\', \'Preloaded hasMany set\');\n return Ember.RSVP.resolve({ id: id });\n }\n });\n\n var env = setupStore({\n adapter: adapter\n });\n var store = env.store;\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friends: DS.hasMany(\'person\', { async: true, inverse: null })\n });\n\n env.registry.register(\'model:person\', Person);\n\n run(function() {\n store.find(Person, 1, { friends: [2] });\n });\n});\n\ntest(\"records should have their ids updated when the adapter returns the id data\", function() {\n expect(2);\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var idCounter = 1;\n var adapter = TestAdapter.extend({\n createRecord: function(store, type, snapshot) {\n return Ember.RSVP.resolve({ name: snapshot.attr(\'name\'), id: idCounter++ });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var people = store.all(Person);\n var tom, yehuda;\n\n run(function() {\n tom = store.createRecord(Person, { name: \'Tom Dale\' });\n yehuda = store.createRecord(Person, { name: \'Yehuda Katz\' });\n });\n\n run(function() {\n Ember.RSVP.all([tom.save(), yehuda.save()]).then(async(function() {\n people.forEach(function(person, index) {\n equal(person.get(\'id\'), index + 1, \"The record\'s id should be correct.\");\n });\n }));\n });\n});\n\ntest(\"store.fetchMany should always return a promise\", function() {\n expect(3);\n\n var Person = DS.Model.extend();\n var store = createStore({\n adapter: TestAdapter.extend()\n });\n run(function() {\n store.createRecord(Person);\n });\n var records = Ember.A([]);\n var results;\n\n run(function() {\n results = store.scheduleFetchMany(records);\n });\n ok(results, \"A call to store.scheduleFetchMany() should return a result\");\n ok(results.then, \"A call to store.scheduleFetchMany() should return a promise\");\n\n results.then(async(function(returnedRecords) {\n deepEqual(returnedRecords, [], \"The correct records are returned\");\n }));\n});\n\ntest(\"store.scheduleFetchMany should not resolve until all the records are resolved\", function() {\n expect(1);\n\n var Person = DS.Model.extend();\n var Phone = DS.Model.extend();\n\n var adapter = TestAdapter.extend({\n find: function (store, type, id, snapshot) {\n var wait = 5;\n\n var record = { id: id };\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n run.later(function() {\n resolve(record);\n }, wait);\n });\n },\n\n findMany: function(store, type, ids, snapshots) {\n var wait = 15;\n\n var records = ids.map(function(id) {\n return { id: id };\n });\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n run.later(function() {\n resolve(records);\n }, wait);\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n run(function() {\n store.createRecord(Person);\n });\n\n var records = Ember.A([\n store.recordForId(Person, 10),\n store.recordForId(Phone, 20),\n store.recordForId(Phone, 21)\n ]);\n\n run(function() {\n store.scheduleFetchMany(records).then(async(function() {\n var unloadedRecords = records.filterBy(\'isEmpty\');\n equal(get(unloadedRecords, \'length\'), 0, \'All unloaded records should be loaded\');\n }));\n });\n});\n\ntest(\"the store calls adapter.findMany according to groupings returned by adapter.groupRecordsForFindMany\", function() {\n expect(3);\n\n var Person = DS.Model.extend();\n\n var adapter = TestAdapter.extend({\n groupRecordsForFindMany: function(store, snapshots) {\n return [\n [snapshots[0]],\n [snapshots[1], snapshots[2]]\n ];\n },\n\n find: function(store, type, id, snapshot) {\n equal(id, \"10\", \"The first group is passed to find\");\n return Ember.RSVP.resolve({ id: id });\n },\n\n findMany: function(store, type, ids, snapshots) {\n var records = ids.map(function(id) {\n return { id: id };\n });\n\n deepEqual(ids, [\"20\", \"21\"], \"The second group is passed to findMany\");\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n resolve(records);\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var records = Ember.A([\n store.recordForId(Person, 10),\n store.recordForId(Person, 20),\n store.recordForId(Person, 21)\n ]);\n\n run(function() {\n store.scheduleFetchMany(records).then(async(function() {\n var ids = records.mapBy(\'id\');\n deepEqual(ids, [\"10\", \"20\", \"21\"], \"The promise fulfills with the records\");\n }));\n });\n});\n\ntest(\"the promise returned by `scheduleFetch`, when it resolves, does not depend on the promises returned to other calls to `scheduleFetch` that are in the same run loop, but different groups\", function() {\n expect(2);\n\n var Person = DS.Model.extend();\n var davidResolved = false;\n\n var adapter = TestAdapter.extend({\n groupRecordsForFindMany: function (store, snapshots) {\n return [\n [snapshots[0]],\n [snapshots[1]]\n ];\n },\n\n find: function(store, type, id, snapshot) {\n var record = { id: id };\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n if (id === \'igor\') {\n resolve(record);\n } else {\n run.later(function () {\n davidResolved = true;\n resolve(record);\n }, 5);\n }\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n run(function () {\n var davidPromise = store.find(Person, \'david\');\n var igorPromise = store.find(Person, \'igor\');\n\n igorPromise.then(async(function () {\n equal(davidResolved, false, \"Igor did not need to wait for David\");\n }));\n\n davidPromise.then(async(function () {\n equal(davidResolved, true, \"David resolved\");\n }));\n });\n});\n\ntest(\"the promise returned by `scheduleFetch`, when it rejects, does not depend on the promises returned to other calls to `scheduleFetch` that are in the same run loop, but different groups\", function() {\n expect(2);\n\n var Person = DS.Model.extend();\n var davidResolved = false;\n\n var adapter = TestAdapter.extend({\n groupRecordsForFindMany: function(store, snapshots) {\n return [\n [snapshots[0]],\n [snapshots[1]]\n ];\n },\n\n find: function(store, type, id, snapshot) {\n var record = { id: id };\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n if (id === \'igor\') {\n reject(record);\n } else {\n run.later(function () {\n davidResolved = true;\n resolve(record);\n }, 5);\n }\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n run(function () {\n var davidPromise = store.find(Person, \'david\');\n var igorPromise = store.find(Person, \'igor\');\n\n igorPromise.then(null, async(function () {\n equal(davidResolved, false, \"Igor did not need to wait for David\");\n }));\n\n davidPromise.then(async(function () {\n equal(davidResolved, true, \"David resolved\");\n }));\n });\n});\n\ntest(\"store.fetchRecord reject records that were not found, even when those requests were coalesced with records that were found\", function() {\n expect(4);\n\n var Person = DS.Model.extend();\n\n var adapter = TestAdapter.extend({\n findMany: function(store, type, ids, snapshots) {\n var records = ids.map(function(id) {\n return { id: id };\n });\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n resolve([\n records[0]\n ]);\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n warns(function() {\n run(function () {\n var davidPromise = store.find(Person, \'david\');\n var igorPromise = store.find(Person, \'igor\');\n\n davidPromise.then(async(function () {\n ok(true, \"David resolved\");\n }));\n\n igorPromise.then(null, async(function () {\n ok(true, \"Igor rejected\");\n }));\n });\n }, /expected to find records with the following ids in the adapter response but they were missing/);\n});\n})();//# sourceURL=ember-data/unit/store/adapter-interop-test.js");
411
+ eval("(function() {var get = Ember.get;\nvar set = Ember.set;\nvar resolve = Ember.RSVP.resolve;\nvar TestAdapter, store;\nvar run = Ember.run;\n\nmodule(\"unit/store/adapter_interop - DS.Store working with a DS.Adapter\", {\n setup: function() {\n TestAdapter = DS.Adapter.extend();\n },\n teardown: function() {\n run(function() {\n if (store) { store.destroy(); }\n });\n }\n});\n\ntest(\"Adapter can be set as a factory\", function() {\n store = createStore({ adapter: TestAdapter });\n\n ok(store.get(\'defaultAdapter\') instanceof TestAdapter);\n});\n\ntest(\'Adapter can be set as a name\', function() {\n store = createStore({ adapter: \'-rest\' });\n\n ok(store.get(\'defaultAdapter\') instanceof DS.RESTAdapter);\n});\n\ntest(\'Adapter can not be set as an instance\', function() {\n expect(5);\n\n store = DS.Store.create({\n adapter: DS.Adapter.create()\n });\n var assert = Ember.assert;\n Ember.assert = function() { ok(true, \"raises an error when passing in an instance\"); };\n store.get(\'defaultAdapter\');\n Ember.assert = assert;\n});\n\ntest(\"Calling Store#find invokes its adapter#find\", function() {\n expect(5);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n ok(true, \"Adapter#find was called\");\n equal(store, currentStore, \"Adapter#find was called with the right store\");\n equal(type, currentType, \"Adapter#find was called with the type passed into Store#find\");\n equal(id, 1, \"Adapter#find was called with the id passed into Store#find\");\n equal(snapshot.id, \'1\', \"Adapter#find was called with the record created from Store#find\");\n\n return Ember.RSVP.resolve({ id: 1 });\n }\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend();\n\n run(function() {\n currentStore.find(currentType, 1);\n });\n});\n\ntest(\"Calling Store#findById multiple times coalesces the calls into a adapter#findMany call\", function() {\n expect(2);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n ok(false, \"Adapter#find was not called\");\n },\n findMany: function(store, type, ids, snapshots) {\n start();\n ok(true, \"Adapter#findMany was called\");\n deepEqual(ids, [\"1\",\"2\"], \'Correct ids were passed in to findMany\');\n return Ember.RSVP.resolve([{ id: 1 }, { id: 2 }]);\n },\n coalesceFindRequests: true\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend();\n currentType.modelName = \"test\";\n stop();\n run(function() {\n currentStore.find(currentType, 1);\n currentStore.find(currentType, 2);\n });\n});\n\ntest(\"Returning a promise from `find` asynchronously loads data\", function() {\n expect(1);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n return resolve({ id: 1, name: \"Scumbag Dale\" });\n }\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function() {\n currentStore.find(currentType, 1).then(async(function(object) {\n strictEqual(get(object, \'name\'), \"Scumbag Dale\", \"the data was pushed\");\n }));\n });\n});\n\ntest(\"IDs provided as numbers are coerced to strings\", function() {\n expect(4);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n equal(typeof id, \'string\', \"id has been normalized to a string\");\n return resolve({ id: 1, name: \"Scumbag Sylvain\" });\n }\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function() {\n currentStore.find(currentType, 1).then(async(function(object) {\n equal(typeof object.get(\'id\'), \'string\', \"id was coerced to a string\");\n run(function() {\n currentStore.push(currentType, { id: 2, name: \"Scumbag Sam Saffron\" });\n });\n return currentStore.find(currentType, 2);\n })).then(async(function(object) {\n ok(object, \"object was found\");\n equal(typeof object.get(\'id\'), \'string\', \"id is a string despite being supplied and searched for as a number\");\n }));\n });\n});\n\n\nvar array = [{ id: \"1\", name: \"Scumbag Dale\" }, { id: \"2\", name: \"Scumbag Katz\" }, { id: \"3\", name: \"Scumbag Bryn\" }];\n\ntest(\"can load data for the same record if it is not dirty\", function() {\n expect(3);\n\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function() {\n store.push(Person, { id: 1, name: \"Tom Dale\" });\n\n store.find(Person, 1).then(async(function(tom) {\n equal(get(tom, \'isDirty\'), false, \"precond - record is not dirty\");\n equal(get(tom, \'name\'), \"Tom Dale\", \"returns the correct name\");\n\n store.push(Person, { id: 1, name: \"Captain Underpants\" });\n equal(get(tom, \'name\'), \"Captain Underpants\", \"updated record with new date\");\n }));\n });\n});\n\n/*\ntest(\"DS.Store loads individual records without explicit IDs with a custom primaryKey\", function() {\n var store = DS.Store.create();\n var Person = DS.Model.extend({ name: DS.attr(\'string\'), primaryKey: \'key\' });\n\n store.load(Person, { key: 1, name: \"Tom Dale\" });\n\n var tom = store.find(Person, 1);\n equal(get(tom, \'name\'), \"Tom Dale\", \"the person was successfully loaded for the given ID\");\n});\n*/\n\ntest(\"pushMany extracts ids from an Array of hashes if no ids are specified\", function() {\n expect(1);\n\n var store = createStore();\n\n var Person = DS.Model.extend({ name: DS.attr(\'string\') });\n\n run(function() {\n store.pushMany(Person, array);\n store.find(Person, 1).then(async(function(person) {\n equal(get(person, \'name\'), \"Scumbag Dale\", \"correctly extracted id for loaded data\");\n }));\n });\n});\n\ntest(\"loadMany takes an optional Object and passes it on to the Adapter\", function() {\n expect(2);\n\n var passedQuery = { page: 1 };\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var adapter = TestAdapter.extend({\n findQuery: function(store, type, query) {\n equal(type, Person, \"The type was Person\");\n equal(query, passedQuery, \"The query was passed in\");\n return Ember.RSVP.resolve([]);\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n run(function() {\n store.find(Person, passedQuery);\n });\n});\n\ntest(\"Find with query calls the correct extract\", function() {\n var passedQuery = { page: 1 };\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var adapter = TestAdapter.extend({\n findQuery: function(store, type, query) {\n return Ember.RSVP.resolve([]);\n }\n });\n\n var callCount = 0;\n\n var ApplicationSerializer = DS.JSONSerializer.extend({\n extractFindQuery: function(store, type, payload) {\n callCount++;\n return [];\n }\n });\n\n var env = setupStore({\n adapter: adapter\n });\n var store = env.store;\n\n env.registry.register(\'serializer:application\', ApplicationSerializer);\n\n run(function() {\n store.find(Person, passedQuery);\n });\n equal(callCount, 1, \'extractFindQuery was called\');\n});\n\ntest(\"all(type) returns a record array of all records of a specific type\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function() {\n store.push(Person, { id: 1, name: \"Tom Dale\" });\n });\n\n var results = store.all(Person);\n equal(get(results, \'length\'), 1, \"record array should have the original object\");\n equal(get(results.objectAt(0), \'name\'), \"Tom Dale\", \"record has the correct information\");\n\n run(function() {\n store.push(Person, { id: 2, name: \"Yehuda Katz\" });\n });\n equal(get(results, \'length\'), 2, \"record array should have the new object\");\n equal(get(results.objectAt(1), \'name\'), \"Yehuda Katz\", \"record has the correct information\");\n\n strictEqual(results, store.all(Person), \"subsequent calls to all return the same recordArray)\");\n});\n\ntest(\"a new record of a particular type is created via store.createRecord(type)\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var person;\n\n run(function() {\n person = store.createRecord(Person);\n });\n\n equal(get(person, \'isLoaded\'), true, \"A newly created record is loaded\");\n equal(get(person, \'isNew\'), true, \"A newly created record is new\");\n equal(get(person, \'isDirty\'), true, \"A newly created record is dirty\");\n\n run(function() {\n set(person, \'name\', \"Braaahm Dale\");\n });\n\n equal(get(person, \'name\'), \"Braaahm Dale\", \"Even if no hash is supplied, `set` still worked\");\n});\n\ntest(\"a new record with a specific id can\'t be created if this id is already used in the store\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n Person.reopenClass({\n toString: function() {\n return \'Person\';\n }\n });\n\n run(function() {\n store.createRecord(Person, { id: 5 });\n });\n\n expectAssertion(function() {\n run(function() {\n store.createRecord(Person, { id: 5 });\n });\n }, /The id 5 has already been used with another record of type Person/);\n});\n\ntest(\"an initial data hash can be provided via store.createRecord(type, hash)\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var person;\n\n run(function() {\n person = store.createRecord(Person, { name: \"Brohuda Katz\" });\n });\n\n equal(get(person, \'isLoaded\'), true, \"A newly created record is loaded\");\n equal(get(person, \'isNew\'), true, \"A newly created record is new\");\n equal(get(person, \'isDirty\'), true, \"A newly created record is dirty\");\n\n equal(get(person, \'name\'), \"Brohuda Katz\", \"The initial data hash is provided\");\n});\n\ntest(\"if an id is supplied in the initial data hash, it can be looked up using `store.find`\", function() {\n expect(1);\n\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var person;\n\n run(function() {\n person = store.createRecord(Person, { id: 1, name: \"Brohuda Katz\" });\n store.find(Person, 1).then(async(function(again) {\n strictEqual(person, again, \"the store returns the loaded object\");\n }));\n });\n});\n\ntest(\"initial values of attributes can be passed in as the third argument to find\", function() {\n expect(1);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n equal(snapshot.attr(\'name\'), \'Test\', \'Preloaded attribtue set\');\n return Ember.RSVP.resolve({ id: \'1\', name: \'Test\' });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function() {\n store.find(Person, 1, { name: \'Test\' });\n });\n});\n\ntest(\"initial values of belongsTo can be passed in as the third argument to find as records\", function() {\n expect(1);\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n equal(snapshot.belongsTo(\'friend\').attr(\'name\'), \'Tom\', \'Preloaded belongsTo set\');\n return new Ember.RSVP.Promise(function() {});\n }\n });\n\n var env = setupStore({\n adapter: adapter\n });\n var store = env.store;\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friend: DS.belongsTo(\'person\', { inverse: null })\n });\n\n env.registry.register(\'model:person\', Person);\n var tom;\n\n run(function() {\n tom = store.push(Person, { id: 2, name: \'Tom\' });\n store.find(Person, 1, { friend: tom });\n });\n});\n\ntest(\"initial values of belongsTo can be passed in as the third argument to find as ids\", function() {\n expect(1);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n return Ember.RSVP.Promise.resolve({ id: id });\n }\n });\n\n var env = setupStore({\n adapter: adapter\n });\n var store = env.store;\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friend: DS.belongsTo(\'person\', { async: true, inverse: null })\n });\n\n env.registry.register(\'model:person\', Person);\n\n run(function() {\n store.find(Person, 1, { friend: 2 }).then(async(function() {\n store.getById(Person, 1).get(\'friend\').then(async(function(friend) {\n equal(friend.get(\'id\'), \'2\', \'Preloaded belongsTo set\');\n }));\n }));\n });\n});\n\ntest(\"initial values of hasMany can be passed in as the third argument to find as records\", function() {\n expect(1);\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n equal(snapshot.hasMany(\'friends\')[0].attr(\'name\'), \'Tom\', \'Preloaded hasMany set\');\n return new Ember.RSVP.Promise(function() {});\n }\n });\n\n var env = setupStore({\n adapter: adapter\n });\n var store = env.store;\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friends: DS.hasMany(\'person\', { inverse: null })\n });\n\n env.registry.register(\'model:person\', Person);\n var tom;\n\n run(function() {\n tom = store.push(Person, { id: 2, name: \'Tom\' });\n store.find(Person, 1, { friends: [tom] });\n });\n});\n\ntest(\"initial values of hasMany can be passed in as the third argument to find as ids\", function() {\n expect(1);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, snapshot) {\n equal(snapshot.hasMany(\'friends\')[0].id, \'2\', \'Preloaded hasMany set\');\n return Ember.RSVP.resolve({ id: id });\n }\n });\n\n var env = setupStore({\n adapter: adapter\n });\n var store = env.store;\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friends: DS.hasMany(\'person\', { async: true, inverse: null })\n });\n\n env.registry.register(\'model:person\', Person);\n\n run(function() {\n store.find(Person, 1, { friends: [2] });\n });\n});\n\ntest(\"records should have their ids updated when the adapter returns the id data\", function() {\n expect(2);\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var idCounter = 1;\n var adapter = TestAdapter.extend({\n createRecord: function(store, type, snapshot) {\n return Ember.RSVP.resolve({ name: snapshot.attr(\'name\'), id: idCounter++ });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var people = store.all(Person);\n var tom, yehuda;\n\n run(function() {\n tom = store.createRecord(Person, { name: \'Tom Dale\' });\n yehuda = store.createRecord(Person, { name: \'Yehuda Katz\' });\n });\n\n run(function() {\n Ember.RSVP.all([tom.save(), yehuda.save()]).then(async(function() {\n people.forEach(function(person, index) {\n equal(person.get(\'id\'), index + 1, \"The record\'s id should be correct.\");\n });\n }));\n });\n});\n\ntest(\"store.fetchMany should always return a promise\", function() {\n expect(3);\n\n var Person = DS.Model.extend();\n var store = createStore({\n adapter: TestAdapter.extend()\n });\n run(function() {\n store.createRecord(Person);\n });\n var records = Ember.A([]);\n var results;\n\n run(function() {\n results = store.scheduleFetchMany(records);\n });\n ok(results, \"A call to store.scheduleFetchMany() should return a result\");\n ok(results.then, \"A call to store.scheduleFetchMany() should return a promise\");\n\n results.then(async(function(returnedRecords) {\n deepEqual(returnedRecords, [], \"The correct records are returned\");\n }));\n});\n\ntest(\"store.scheduleFetchMany should not resolve until all the records are resolved\", function() {\n expect(1);\n\n var Person = DS.Model.extend();\n var Phone = DS.Model.extend();\n\n var adapter = TestAdapter.extend({\n find: function (store, type, id, snapshot) {\n var wait = 5;\n\n var record = { id: id };\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n run.later(function() {\n resolve(record);\n }, wait);\n });\n },\n\n findMany: function(store, type, ids, snapshots) {\n var wait = 15;\n\n var records = ids.map(function(id) {\n return { id: id };\n });\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n run.later(function() {\n resolve(records);\n }, wait);\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n run(function() {\n store.createRecord(Person);\n });\n\n var records = Ember.A([\n store.recordForId(Person, 10),\n store.recordForId(Phone, 20),\n store.recordForId(Phone, 21)\n ]);\n\n run(function() {\n store.scheduleFetchMany(records).then(async(function() {\n var unloadedRecords = records.filterBy(\'isEmpty\');\n equal(get(unloadedRecords, \'length\'), 0, \'All unloaded records should be loaded\');\n }));\n });\n});\n\ntest(\"the store calls adapter.findMany according to groupings returned by adapter.groupRecordsForFindMany\", function() {\n expect(3);\n\n var Person = DS.Model.extend();\n\n var adapter = TestAdapter.extend({\n groupRecordsForFindMany: function(store, snapshots) {\n return [\n [snapshots[0]],\n [snapshots[1], snapshots[2]]\n ];\n },\n\n find: function(store, type, id, snapshot) {\n equal(id, \"10\", \"The first group is passed to find\");\n return Ember.RSVP.resolve({ id: id });\n },\n\n findMany: function(store, type, ids, snapshots) {\n var records = ids.map(function(id) {\n return { id: id };\n });\n\n deepEqual(ids, [\"20\", \"21\"], \"The second group is passed to findMany\");\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n resolve(records);\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var records = Ember.A([\n store.recordForId(Person, 10),\n store.recordForId(Person, 20),\n store.recordForId(Person, 21)\n ]);\n\n run(function() {\n store.scheduleFetchMany(records).then(async(function() {\n var ids = records.mapBy(\'id\');\n deepEqual(ids, [\"10\", \"20\", \"21\"], \"The promise fulfills with the records\");\n }));\n });\n});\n\ntest(\"the promise returned by `scheduleFetch`, when it resolves, does not depend on the promises returned to other calls to `scheduleFetch` that are in the same run loop, but different groups\", function() {\n expect(2);\n\n var Person = DS.Model.extend();\n var davidResolved = false;\n\n var adapter = TestAdapter.extend({\n groupRecordsForFindMany: function (store, snapshots) {\n return [\n [snapshots[0]],\n [snapshots[1]]\n ];\n },\n\n find: function(store, type, id, snapshot) {\n var record = { id: id };\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n if (id === \'igor\') {\n resolve(record);\n } else {\n run.later(function () {\n davidResolved = true;\n resolve(record);\n }, 5);\n }\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n run(function () {\n var davidPromise = store.find(Person, \'david\');\n var igorPromise = store.find(Person, \'igor\');\n\n igorPromise.then(async(function () {\n equal(davidResolved, false, \"Igor did not need to wait for David\");\n }));\n\n davidPromise.then(async(function () {\n equal(davidResolved, true, \"David resolved\");\n }));\n });\n});\n\ntest(\"the promise returned by `scheduleFetch`, when it rejects, does not depend on the promises returned to other calls to `scheduleFetch` that are in the same run loop, but different groups\", function() {\n expect(2);\n\n var Person = DS.Model.extend();\n var davidResolved = false;\n\n var adapter = TestAdapter.extend({\n groupRecordsForFindMany: function(store, snapshots) {\n return [\n [snapshots[0]],\n [snapshots[1]]\n ];\n },\n\n find: function(store, type, id, snapshot) {\n var record = { id: id };\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n if (id === \'igor\') {\n reject(record);\n } else {\n run.later(function () {\n davidResolved = true;\n resolve(record);\n }, 5);\n }\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n run(function () {\n var davidPromise = store.find(Person, \'david\');\n var igorPromise = store.find(Person, \'igor\');\n\n igorPromise.then(null, async(function () {\n equal(davidResolved, false, \"Igor did not need to wait for David\");\n }));\n\n davidPromise.then(async(function () {\n equal(davidResolved, true, \"David resolved\");\n }));\n });\n});\n\ntest(\"store.fetchRecord reject records that were not found, even when those requests were coalesced with records that were found\", function() {\n expect(4);\n\n var Person = DS.Model.extend();\n\n var adapter = TestAdapter.extend({\n findMany: function(store, type, ids, snapshots) {\n var records = ids.map(function(id) {\n return { id: id };\n });\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n resolve([\n records[0]\n ]);\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n warns(function() {\n run(function () {\n var davidPromise = store.find(Person, \'david\');\n var igorPromise = store.find(Person, \'igor\');\n\n davidPromise.then(async(function () {\n ok(true, \"David resolved\");\n }));\n\n igorPromise.then(null, async(function () {\n ok(true, \"Igor rejected\");\n }));\n });\n }, /expected to find records with the following ids in the adapter response but they were missing/);\n});\n})();//# sourceURL=ember-data/unit/store/adapter-interop-test.js");
394
412
 
395
- eval("(function() {var store, container, Record;\nvar run = Ember.run;\n\nmodule(\"unit/store/createRecord - Store creating records\", {\n setup: function() {\n store = createStore({ adapter: DS.Adapter.extend() });\n\n Record = DS.Model.extend({\n title: DS.attr(\'string\')\n });\n }\n});\n\ntest(\"doesn\'t modify passed in properties hash\", function() {\n var attributes = { foo: \'bar\' };\n run(function() {\n store.createRecord(Record, attributes);\n store.createRecord(Record, attributes);\n });\n\n deepEqual(attributes, { foo: \'bar\' }, \"The properties hash is not modified\");\n});\n\nmodule(\"unit/store/createRecord - Store with models by dash\", {\n setup: function() {\n var env = setupStore({\n \'some-thing\': DS.Model.extend({ foo: DS.attr(\'string\') })\n });\n store = env.store;\n container = env.container;\n env.replaceContainerNormalize(function(key) {\n return Ember.String.dasherize(key);\n });\n }\n});\ntest(\"creating a record by camel-case string finds the model\", function() {\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function() {\n record = store.createRecord(\'someThing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'someThing\').typeKey, \'someThing\');\n});\n\ntest(\"creating a record by dasherize string finds the model\", function() {\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function() {\n record = store.createRecord(\'some-thing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'some-thing\').typeKey, \'someThing\');\n});\n\nmodule(\"unit/store/createRecord - Store with models by camelCase\", {\n setup: function() {\n var env = setupStore({\n someThing: DS.Model.extend({ foo: DS.attr(\'string\') })\n });\n store = env.store;\n container = env.container;\n env.replaceContainerNormalize(Ember.String.camelize);\n }\n});\n\ntest(\"creating a record by camel-case string finds the model\", function() {\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function() {\n record = store.createRecord(\'someThing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'someThing\').typeKey, \'someThing\');\n});\n\ntest(\"creating a record by dasherize string finds the model\", function() {\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function() {\n record = store.createRecord(\'some-thing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'some-thing\').typeKey, \'someThing\');\n});\n})();//# sourceURL=ember-data/unit/store/create-record-test.js");
413
+ eval("(function() {var store, container, Record, Storage;\nvar run = Ember.run;\n\nmodule(\"unit/store/createRecord - Store creating records\", {\n setup: function() {\n\n Record = DS.Model.extend({\n title: DS.attr(\'string\')\n });\n\n Storage = DS.Model.extend({\n name: DS.attr(\'name\'),\n records: DS.hasMany(\'record\')\n });\n\n store = createStore({\n adapter: DS.Adapter.extend(),\n record: Record,\n storage: Storage\n });\n }\n});\n\ntest(\"doesn\'t modify passed in properties hash\", function() {\n var attributes = { foo: \'bar\' };\n run(function() {\n store.createRecord(Record, attributes);\n store.createRecord(Record, attributes);\n });\n\n deepEqual(attributes, { foo: \'bar\' }, \"The properties hash is not modified\");\n});\n\ntest(\"allow passing relationships as well as attributes\", function() {\n var records, storage;\n run(function() {\n records = store.pushMany(Record, [{ id: 1, title: \"it\'s a beautiful day\" }, { id: 2, title: \"it\'s a beautiful day\" }]);\n storage = store.createRecord(Storage, { name: \'Great store\', records: records });\n });\n\n equal(storage.get(\'name\'), \'Great store\', \"The attribute is well defined\");\n equal(storage.get(\'records\').findBy(\'id\', \'1\'), Ember.A(records).findBy(\'id\', \'1\'), \"Defined relationships are allowed in createRecord\");\n equal(storage.get(\'records\').findBy(\'id\', \'2\'), Ember.A(records).findBy(\'id\', \'2\'), \"Defined relationships are allowed in createRecord\");\n});\n\nmodule(\"unit/store/createRecord - Store with models by dash\", {\n setup: function() {\n var env = setupStore({\n someThing: DS.Model.extend({ foo: DS.attr(\'string\') })\n });\n store = env.store;\n container = env.container;\n }\n});\ntest(\"creating a record by camel-case string finds the model\", function() {\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function() {\n record = store.createRecord(\'someThing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'someThing\').modelName, \'some-thing\');\n});\n\ntest(\"creating a record by dasherize string finds the model\", function() {\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function() {\n record = store.createRecord(\'some-thing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'some-thing\').modelName, \'some-thing\');\n});\n\nmodule(\"unit/store/createRecord - Store with models by camelCase\", {\n setup: function() {\n var env = setupStore({\n someThing: DS.Model.extend({ foo: DS.attr(\'string\') })\n });\n store = env.store;\n container = env.container;\n }\n});\n\ntest(\"creating a record by camel-case string finds the model\", function() {\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function() {\n record = store.createRecord(\'someThing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'someThing\').modelName, \'some-thing\');\n});\n\ntest(\"creating a record by dasherize string finds the model\", function() {\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function() {\n record = store.createRecord(\'some-thing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'some-thing\').modelName, \'some-thing\');\n});\n})();//# sourceURL=ember-data/unit/store/create-record-test.js");
396
414
 
397
415
  eval("(function() {var env, store, Person, PhoneNumber;\nvar attr = DS.attr;\nvar hasMany = DS.hasMany;\nvar belongsTo = DS.belongsTo;\nvar run = Ember.run;\n\nmodule(\"unit/store/hasRecordForId - Store hasRecordForId\", {\n setup: function() {\n\n Person = DS.Model.extend({\n firstName: attr(\'string\'),\n lastName: attr(\'string\'),\n phoneNumbers: hasMany(\'phone-number\')\n });\n Person.toString = function() {\n return \'Person\';\n };\n\n PhoneNumber = DS.Model.extend({\n number: attr(\'string\'),\n person: belongsTo(\'person\')\n });\n PhoneNumber.toString = function() {\n return \'PhoneNumber\';\n };\n\n env = setupStore({\n person: Person,\n \"phone-number\": PhoneNumber\n });\n\n store = env.store;\n\n },\n\n teardown: function() {\n Ember.run(store, \'destroy\');\n }\n});\n\ntest(\"hasRecordForId should return false for records in the empty state \", function() {\n\n run(function() {\n store.push(Person, {\n id: 1,\n firstName: \"Yehuda\",\n lastName: \"Katz\",\n phoneNumbers: [1]\n });\n\n equal(false, store.hasRecordForId(PhoneNumber, 1), \'hasRecordForId only returns true for loaded records\');\n\n });\n});\n\ntest(\"hasRecordForId should return true for records in the loaded state \", function() {\n run(function() {\n store.push(Person, {\n id: 1,\n firstName: \"Yehuda\",\n lastName: \"Katz\",\n phoneNumbers: [1]\n });\n\n equal(true, store.hasRecordForId(Person, 1), \'hasRecordForId returns true for records loaded into the store\');\n });\n});\n})();//# sourceURL=ember-data/unit/store/has_record_for_id_test.js");
398
416
 
399
417
  eval("(function() {var store;\n\nvar run = Ember.run;\n\nmodule(\"unit/store/metadata_for - DS.Store#metadataFor\", {\n setup: function() {\n store = createStore({\n post: DS.Model.extend(),\n comment: DS.Model.extend()\n });\n },\n\n teardown: function() {\n run(function() {\n store.destroy();\n });\n }\n});\n\ntest(\"metaForType should be deprecated\", function() {\n expect(1);\n\n expectDeprecation(function() {\n store.metaForType(\'post\', { foo: \'bar\' });\n });\n});\n\ntest(\"metadataFor and setMetadataFor should return and set correct metadata\", function() {\n expect(7);\n\n function metadataKeys(type) {\n return Ember.keys(store.metadataFor(type));\n }\n\n // Currently not using QUnit.deepEqual due to the way deepEqual\n // comparing __proto__. In its check to see if an object has\n // no proto, it checks strict equality on null instead of null or undefined.\n\n deepEqual(metadataKeys(\'post\'), [], \'Metadata for post is initially empty\');\n\n store.setMetadataFor(\'post\', { foo: \'bar\' });\n\n deepEqual(metadataKeys(\'post\'), [\'foo\'], \'metadata for post contains foo:bar\');\n equal(store.metadataFor(\'post\').foo, \'bar\');\n\n store.setMetadataFor(\'post\', { hello: \'world\' });\n\n deepEqual(metadataKeys(\'post\'), [\'foo\', \'hello\']);\n equal(store.metadataFor(\'post\').foo, \'bar\', \'keeps original metadata\');\n equal(store.metadataFor(\'post\').hello, \'world\', \'merges new metadata\');\n\n deepEqual(metadataKeys(\'comment\'), [], \'metadata for comment is empty\');\n});\n})();//# sourceURL=ember-data/unit/store/metadata-for-test.js");
400
418
 
401
- eval("(function() {var container, store, registry;\n\nvar camelize = Ember.String.camelize;\nvar dasherize = Ember.String.dasherize;\n\nvar run = Ember.run;\nvar env;\n\nmodule(\"unit/store/model_for - DS.Store#modelFor\", {\n setup: function() {\n env = setupStore({\n blogPost: DS.Model.extend(),\n \"blog-post\": DS.Model.extend()\n });\n store = env.store;\n container = store.container;\n registry = env.registry;\n },\n\n teardown: function() {\n run(function() {\n container.destroy();\n store.destroy();\n });\n }\n});\n\ntest(\"when fetching factory from string, sets a normalized key as typeKey\", function() {\n env.replaceContainerNormalize(camelize);\n\n equal(registry.normalize(\'some.post\'), \'somePost\', \'precond - container camelizes\');\n equal(store.modelFor(\"blog.post\").typeKey, \"blogPost\", \"typeKey is normalized to camelCase\");\n});\n\ntest(\"when fetching factory from string and dashing normalizer, sets a normalized key as typeKey\", function() {\n env.replaceContainerNormalize(function(fullName) {\n return dasherize(camelize(fullName));\n });\n\n equal(registry.normalize(\'some.post\'), \'some-post\', \'precond - container dasherizes\');\n equal(store.modelFor(\"blog.post\").typeKey, \"blogPost\", \"typeKey is normalized to camelCase\");\n});\n\ntest(\"when returning passed factory, sets a normalized key as typeKey\", function() {\n var factory = { typeKey: \'some-thing\' };\n equal(store.modelFor(factory).typeKey, \"someThing\", \"typeKey is normalized to camelCase\");\n});\n\ntest(\"when returning passed factory without typeKey, allows it\", function() {\n var factory = { typeKey: undefined };\n equal(store.modelFor(factory).typeKey, undefined, \"typeKey is undefined\");\n});\n\ntest(\"when fetching something that doesn\'t exist, throws error\", function() {\n throws(function() {\n store.modelFor(\'wild-stuff\');\n }, /No model was found/);\n});\n})();//# sourceURL=ember-data/unit/store/model-for-test.js");
419
+ eval("(function() {var container, store, registry;\n\nvar camelize = Ember.String.camelize;\nvar dasherize = Ember.String.dasherize;\n\nvar run = Ember.run;\nvar env;\n\nmodule(\"unit/store/model_for - DS.Store#modelFor\", {\n setup: function() {\n env = setupStore({\n blogPost: DS.Model.extend(),\n \"blog.post\": DS.Model.extend()\n });\n store = env.store;\n container = store.container;\n registry = env.registry;\n },\n\n teardown: function() {\n run(function() {\n container.destroy();\n store.destroy();\n });\n }\n});\n\ntest(\"when fetching factory from string, sets a normalized key as modelName\", function() {\n env.replaceContainerNormalize(function(key) {\n return dasherize(camelize(key));\n });\n\n equal(registry.normalize(\'some.post\'), \'some-post\', \'precond - container camelizes\');\n equal(store.modelFor(\"blog.post\").modelName, \"blog.post\", \"modelName is normalized to dasherized\");\n});\n\ntest(\"when fetching factory from string and dashing normalizer, sets a normalized key as modelName\", function() {\n env.replaceContainerNormalize(function(key) {\n return dasherize(camelize(key));\n });\n equal(registry.normalize(\'some.post\'), \'some-post\', \'precond - container dasherizes\');\n equal(store.modelFor(\"blog.post\").modelName, \"blog.post\", \"modelName is normalized to dasherized\");\n});\n\ntest(\"when returning passed factory, sets a normalized key as modelName\", function() {\n var factory = { modelName: \'some-thing\' };\n equal(store.modelFor(factory).modelName, \"some-thing\", \"modelName is normalized to dasherized\");\n});\n\ntest(\"when returning passed factory without modelName, allows it\", function() {\n var factory = { modelName: undefined };\n equal(store.modelFor(factory).modelName, undefined, \"modelName is undefined\");\n});\n\ntest(\"when fetching something that doesn\'t exist, throws error\", function() {\n throws(function() {\n store.modelFor(\'wild-stuff\');\n }, /No model was found/);\n});\n})();//# sourceURL=ember-data/unit/store/model-for-test.js");
402
420
 
403
421
  eval("(function() {var env, store, Person, PhoneNumber, Post;\nvar attr = DS.attr;\nvar hasMany = DS.hasMany;\nvar belongsTo = DS.belongsTo;\nvar run = Ember.run;\n\nmodule(\"unit/store/push - DS.Store#push\", {\n setup: function() {\n Person = DS.Model.extend({\n firstName: attr(\'string\'),\n lastName: attr(\'string\'),\n phoneNumbers: hasMany(\'phone-number\')\n });\n Person.toString = function() {\n return \'Person\';\n };\n\n PhoneNumber = DS.Model.extend({\n number: attr(\'string\'),\n person: belongsTo(\'person\')\n });\n PhoneNumber.toString = function() {\n return \'PhoneNumber\';\n };\n\n Post = DS.Model.extend({\n postTitle: attr(\'string\')\n });\n Post.toString = function() {\n return \'Post\';\n };\n\n env = setupStore({\n post: Post,\n person: Person,\n \"phone-number\": PhoneNumber\n });\n\n store = env.store;\n\n env.registry.register(\'serializer:post\', DS.ActiveModelSerializer);\n },\n\n teardown: function() {\n run(function() {\n store.destroy();\n });\n }\n});\n\ntest(\"Calling push with a normalized hash returns a record\", function() {\n expect(2);\n\n run(function() {\n var person = store.push(\'person\', {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n store.find(\'person\', \'wat\').then(function(foundPerson) {\n equal(foundPerson, person, \"record returned via load() is the same as the record returned from find()\");\n deepEqual(foundPerson.getProperties(\'id\', \'firstName\', \'lastName\'), {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n });\n });\n});\n\ntest(\"Supplying a model class for `push` is the same as supplying a string\", function () {\n expect(1);\n\n var Programmer = Person.extend();\n env.registry.register(\'model:programmer\', Programmer);\n\n run(function() {\n store.push(Programmer, {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n\n store.find(\'programmer\', \'wat\').then(function(foundProgrammer) {\n deepEqual(foundProgrammer.getProperties(\'id\', \'firstName\', \'lastName\'), {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n });\n });\n});\n\ntest(\"Calling push triggers `didLoad` even if the record hasn\'t been requested from the adapter\", function() {\n expect(1);\n\n Person.reopen({\n didLoad: async(function() {\n ok(true, \"The didLoad callback was called\");\n })\n });\n\n run(function() {\n store.push(\'person\', {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n });\n});\n\ntest(\"Calling update should be deprecated\", function() {\n expectDeprecation(function() {\n run(function() {\n store.update(\'person\', { id: \'1\', firstName: \'Yehuda\', lastName: \'Katz\' });\n });\n });\n});\n\ntest(\"Calling push with partial records updates just those attributes\", function() {\n expect(2);\n\n run(function() {\n var person = store.push(\'person\', {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n\n store.push(\'person\', {\n id: \'wat\',\n lastName: \"Katz!\"\n });\n\n store.find(\'person\', \'wat\').then(function(foundPerson) {\n equal(foundPerson, person, \"record returned via load() is the same as the record returned from find()\");\n deepEqual(foundPerson.getProperties(\'id\', \'firstName\', \'lastName\'), {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz!\"\n });\n });\n });\n});\n\ntest(\"Calling push on normalize allows partial updates with raw JSON\", function () {\n env.registry.register(\'serializer:person\', DS.RESTSerializer);\n var person;\n\n run(function() {\n person = store.push(\'person\', {\n id: \'1\',\n firstName: \"Robert\",\n lastName: \"Jackson\"\n });\n\n store.push(\'person\', store.normalize(\'person\', {\n id: \'1\',\n firstName: \"Jacquie\"\n }));\n });\n\n equal(person.get(\'firstName\'), \"Jacquie\", \"you can push raw JSON into the store\");\n equal(person.get(\'lastName\'), \"Jackson\", \"existing fields are untouched\");\n});\n\ntest(\"Calling push with partial records triggers observers for just those attributes that changed\", function() {\n expect(1);\n var person;\n\n run(function() {\n person = store.push(\'person\', {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n });\n\n person.addObserver(\'firstName\', function() {\n ok(false, \'firstName observer should not be triggered\');\n });\n\n person.addObserver(\'lastName\', function() {\n ok(true, \'lastName observer should be triggered\');\n });\n\n run(function() {\n store.push(\'person\', {\n id: \'wat\',\n firstName: \'Yehuda\',\n lastName: \'Katz!\'\n });\n });\n});\n\ntest(\"Calling push with a normalized hash containing related records returns a record\", function() {\n var number1, number2, person;\n run(function() {\n number1 = store.push(\'phone-number\', {\n id: 1,\n number: \'5551212\',\n person: \'wat\'\n });\n\n number2 = store.push(\'phone-number\', {\n id: 2,\n number: \'5552121\',\n person: \'wat\'\n });\n\n person = store.push(\'person\', {\n id: \'wat\',\n firstName: \'John\',\n lastName: \'Smith\',\n phoneNumbers: [number1, number2]\n });\n });\n\n\n deepEqual(person.get(\'phoneNumbers\').toArray(), [number1, number2], \"phoneNumbers array is correct\");\n});\n\ntest(\"Calling push with a normalized hash containing IDs of related records returns a record\", function() {\n expect(1);\n\n Person.reopen({\n phoneNumbers: hasMany(\'phone-number\', { async: true })\n });\n\n env.adapter.find = function(store, type, id) {\n if (id === \"1\") {\n return Ember.RSVP.resolve({\n id: 1,\n number: \'5551212\',\n person: \'wat\'\n });\n }\n\n if (id === \"2\") {\n return Ember.RSVP.resolve({\n id: 2,\n number: \'5552121\',\n person: \'wat\'\n });\n }\n };\n var person;\n\n run(function() {\n person = store.push(\'person\', {\n id: \'wat\',\n firstName: \'John\',\n lastName: \'Smith\',\n phoneNumbers: [\"1\", \"2\"]\n });\n person.get(\'phoneNumbers\').then(function(phoneNumbers) {\n deepEqual(phoneNumbers.map(function(item) {\n return item.getProperties(\'id\', \'number\', \'person\');\n }), [{\n id: \"1\",\n number: \'5551212\',\n person: person\n }, {\n id: \"2\",\n number: \'5552121\',\n person: person\n }]);\n });\n });\n});\n\ntest(\"Calling pushPayload allows pushing raw JSON\", function () {\n run(function() {\n store.pushPayload(\'post\', {\n posts: [{\n id: \'1\',\n post_title: \"Ember rocks\"\n }]\n });\n });\n\n var post = store.getById(\'post\', 1);\n\n equal(post.get(\'postTitle\'), \"Ember rocks\", \"you can push raw JSON into the store\");\n\n run(function() {\n store.pushPayload(\'post\', {\n posts: [{\n id: \'1\',\n post_title: \"Ember rocks (updated)\"\n }]\n });\n });\n\n equal(post.get(\'postTitle\'), \"Ember rocks (updated)\", \"You can update data in the store\");\n});\n\ntest(\"Calling pushPayload allows pushing singular payload properties\", function () {\n run(function() {\n store.pushPayload(\'post\', {\n post: {\n id: \'1\',\n post_title: \"Ember rocks\"\n }\n });\n });\n\n var post = store.getById(\'post\', 1);\n\n equal(post.get(\'postTitle\'), \"Ember rocks\", \"you can push raw JSON into the store\");\n\n run(function() {\n store.pushPayload(\'post\', {\n post: {\n id: \'1\',\n post_title: \"Ember rocks (updated)\"\n }\n });\n });\n\n equal(post.get(\'postTitle\'), \"Ember rocks (updated)\", \"You can update data in the store\");\n});\n\ntest(\"Calling pushPayload should use the type\'s serializer for normalizing\", function () {\n expect(4);\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n normalize: function(store, payload) {\n ok(true, \"normalized is called on Post serializer\");\n return this._super(store, payload);\n }\n }));\n env.registry.register(\'serializer:person\', DS.RESTSerializer.extend({\n normalize: function(store, payload) {\n ok(true, \"normalized is called on Person serializer\");\n return this._super(store, payload);\n }\n }));\n\n run(function() {\n store.pushPayload(\'post\', {\n posts: [{\n id: 1,\n postTitle: \"Ember rocks\"\n }],\n people: [{\n id: 2,\n firstName: \"Yehuda\"\n }]\n });\n });\n\n var post = store.getById(\'post\', 1);\n\n equal(post.get(\'postTitle\'), \"Ember rocks\", \"you can push raw JSON into the store\");\n\n var person = store.getById(\'person\', 2);\n\n equal(person.get(\'firstName\'), \"Yehuda\", \"you can push raw JSON into the store\");\n});\n\ntest(\"Calling pushPayload without a type uses application serializer\'s pushPayload method\", function () {\n expect(1);\n\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n pushPayload: function(store, payload) {\n ok(true, \"pushPayload is called on Application serializer\");\n return this._super(store, payload);\n }\n }));\n\n run(function() {\n store.pushPayload({\n posts: [{ id: \'1\', postTitle: \"Ember rocks\" }]\n });\n });\n});\n\ntest(\"Calling pushPayload without a type should use a model\'s serializer when normalizing\", function () {\n expect(4);\n\n env.registry.register(\'serializer:post\', DS.RESTSerializer.extend({\n normalize: function(store, payload) {\n ok(true, \"normalized is called on Post serializer\");\n return this._super(store, payload);\n }\n }));\n\n env.registry.register(\'serializer:application\', DS.RESTSerializer.extend({\n normalize: function(store, payload) {\n ok(true, \"normalized is called on Application serializer\");\n return this._super(store, payload);\n }\n }));\n\n run(function() {\n store.pushPayload({\n posts: [{\n id: \'1\',\n postTitle: \"Ember rocks\"\n }],\n people: [{\n id: \'2\',\n firstName: \'Yehuda\'\n }]\n });\n });\n\n var post = store.getById(\'post\', 1);\n\n equal(post.get(\'postTitle\'), \"Ember rocks\", \"you can push raw JSON into the store\");\n\n var person = store.getById(\'person\', 2);\n\n equal(person.get(\'firstName\'), \"Yehuda\", \"you can push raw JSON into the store\");\n});\n\ntest(\"Calling pushPayload allows partial updates with raw JSON\", function () {\n env.registry.register(\'serializer:person\', DS.RESTSerializer);\n\n var person;\n\n run(function() {\n store.pushPayload(\'person\', {\n people: [{\n id: \'1\',\n firstName: \"Robert\",\n lastName: \"Jackson\"\n }]\n });\n });\n\n person = store.getById(\'person\', 1);\n\n equal(person.get(\'firstName\'), \"Robert\", \"you can push raw JSON into the store\");\n equal(person.get(\'lastName\'), \"Jackson\", \"you can push raw JSON into the store\");\n\n run(function() {\n store.pushPayload(\'person\', {\n people: [{\n id: \'1\',\n firstName: \"Jacquie\"\n }]\n });\n });\n\n equal(person.get(\'firstName\'), \"Jacquie\", \"you can push raw JSON into the store\");\n equal(person.get(\'lastName\'), \"Jackson\", \"existing fields are untouched\");\n});\n\ntest(\'calling push without data argument as an object raises an error\', function() {\n var invalidValues = [\n undefined,\n null,\n 1,\n \'string\',\n Ember.Object.create(),\n Ember.Object.extend(),\n true\n ];\n\n expect(invalidValues.length);\n\n Ember.EnumerableUtils.forEach(invalidValues, function(invalidValue) {\n throws(function() {\n run(function() {\n store.push(\'person\', invalidValue);\n });\n }, /object/);\n });\n});\n\ntest(\'Calling push with a link for a non async relationship should warn\', function() {\n Person.reopen({\n phoneNumbers: hasMany(\'phone-number\', { async: false })\n });\n\n warns(function() {\n run(function() {\n store.push(\'person\', {\n id: \'1\',\n links: {\n phoneNumbers: \'/api/people/1/phone-numbers\'\n }\n });\n });\n }, /You have pushed a record of type \'person\' with \'phoneNumbers\' as a link, but the association is not an async relationship./);\n});\n\ntest(\'Calling push with a link containing an object throws an assertion error\', function() {\n Person.reopen({\n phoneNumbers: hasMany(\'phone-number\', { async: true })\n });\n\n expectAssertion(function() {\n run(function() {\n store.push(\'person\', {\n id: \'1\',\n links: {\n phoneNumbers: {\n href: \'/api/people/1/phone-numbers\'\n }\n }\n });\n });\n }, \"You have pushed a record of type \'person\' with \'phoneNumbers\' as a link, but the value of that link is not a string.\");\n});\n\ntest(\'Calling push with a link containing the value null\', function() {\n run(function() {\n store.push(\'person\', {\n id: \'1\',\n firstName: \'Tan\',\n links: {\n phoneNumbers: null\n }\n });\n });\n\n var person = store.getById(\'person\', 1);\n\n equal(person.get(\'firstName\'), \"Tan\", \"you can use links that contain null as a value\");\n});\n\ntest(\'calling push with hasMany relationship the value must be an array\', function() {\n var invalidValues = [\n 1,\n \'string\',\n Ember.Object.create(),\n Ember.Object.extend(),\n true\n ];\n\n expect(invalidValues.length);\n\n Ember.EnumerableUtils.forEach(invalidValues, function(invalidValue) {\n throws(function() {\n run(function() {\n store.push(\'person\', { id: 1, phoneNumbers: invalidValue });\n });\n }, /must be an array/);\n });\n});\n\ntest(\'calling push with missing or invalid `id` throws assertion error\', function() {\n var invalidValues = [\n {},\n { id: null },\n { id: \'\' }\n ];\n\n expect(invalidValues.length);\n\n Ember.EnumerableUtils.forEach(invalidValues, function(invalidValue) {\n throws(function() {\n run(function() {\n store.push(\'person\', invalidValue);\n });\n }, /You must include an `id`/);\n });\n});\n\ntest(\'calling push with belongsTo relationship the value must not be an array\', function() {\n throws(function() {\n run(function() {\n store.push(\'phone-number\', { id: 1, person: [1] });\n });\n }, /must not be an array/);\n});\n\ntest(\'calling push with an embedded relationship throws a useful error\', function() {\n throws(function() {\n run(function() {\n store.push(\'person\', {\n id: 1,\n firstName: \'Ada\',\n lastName: \'Lovelace\',\n phoneNumbers: [\n { number: \'5551212\', person: 1 }\n ]\n });\n });\n }, /If this is an embedded relationship/);\n});\n\ntest(\"Enabling Ember.ENV.DS_WARN_ON_UNKNOWN_KEYS should warn on unknown keys\", function() {\n run(function() {\n var originalFlagValue = Ember.ENV.DS_WARN_ON_UNKNOWN_KEYS;\n try {\n Ember.ENV.DS_WARN_ON_UNKNOWN_KEYS = true;\n warns(function() {\n store.push(\'person\', {\n id: \'1\',\n firstName: \'Tomster\',\n emailAddress: \'tomster@emberjs.com\',\n isMascot: true\n });\n });\n } finally {\n Ember.ENV.DS_WARN_ON_UNKNOWN_KEYS = originalFlagValue;\n }\n });\n});\n\ntest(\"Calling push with unknown keys should not warn by default\", function() {\n noWarns(function() {\n run(function() {\n store.push(\'person\', {\n id: \'1\',\n firstName: \'Tomster\',\n emailAddress: \'tomster@emberjs.com\',\n isMascot: true\n });\n });\n }, /The payload for \'person\' contains these unknown keys: \\[emailAddress,isMascot\\]. Make sure they\'ve been defined in your model./);\n});\n})();//# sourceURL=ember-data/unit/store/push-test.js");
404
422
 
@@ -175,7 +175,7 @@
175
175
  ```javascript
176
176
  App.ApplicationAdapter = DS.Adapter.extend({
177
177
  find: function(store, type, id, snapshot) {
178
- var url = [type.typeKey, id].join('/');
178
+ var url = [type.modelName, id].join('/');
179
179
 
180
180
  return new Ember.RSVP.Promise(function(resolve, reject) {
181
181
  jQuery.getJSON(url).then(function(data) {
@@ -286,6 +286,7 @@
286
286
 
287
287
  @method generateIdForRecord
288
288
  @param {DS.Store} store
289
+ @param {subclass of DS.Model} type the DS.Model class of the record
289
290
  @param {Object} inputProperties a hash of properties to set on the
290
291
  newly created record.
291
292
  @return {String|Number} id
@@ -314,7 +315,7 @@
314
315
  @return {Object} serialized snapshot
315
316
  */
316
317
  serialize: function(snapshot, options) {
317
- return ember$data$lib$system$adapter$$get(snapshot.record, 'store').serializerFor(snapshot.typeKey).serialize(snapshot, options);
318
+ return ember$data$lib$system$adapter$$get(snapshot.record, 'store').serializerFor(snapshot.modelName).serialize(snapshot, options);
318
319
  },
319
320
 
320
321
  /**
@@ -576,7 +577,7 @@
576
577
  @param {DS.Snapshot} snapshot
577
578
  */
578
579
  mockJSON: function(store, typeClass, snapshot) {
579
- return store.serializerFor(snapshot.typeKey).serialize(snapshot, { includeId: true });
580
+ return store.serializerFor(snapshot.modelName).serialize(snapshot, { includeId: true });
580
581
  },
581
582
 
582
583
  /**
@@ -823,52 +824,53 @@
823
824
  will be arrays of ids and snapshots.
824
825
 
825
826
  @method buildURL
826
- @param {String} typeKey
827
+ @param {String} modelName
827
828
  @param {String|Array|Object} id single id or array of ids or query
828
829
  @param {DS.Snapshot|Array} snapshot single snapshot or array of snapshots
829
830
  @param {String} requestType
831
+ @param {Object} query object of query parameters to send for findQuery requests.
830
832
  @return {String} url
831
833
  */
832
- buildURL: function(typeKey, id, snapshot, requestType) {
834
+ buildURL: function(modelName, id, snapshot, requestType, query) {
833
835
  switch (requestType) {
834
836
  case 'find':
835
- return this.urlForFind(id, typeKey, snapshot);
837
+ return this.urlForFind(id, modelName, snapshot);
836
838
  case 'findAll':
837
- return this.urlForFindAll(typeKey);
839
+ return this.urlForFindAll(modelName);
838
840
  case 'findQuery':
839
- return this.urlForFindQuery(id, typeKey);
841
+ return this.urlForFindQuery(query, modelName);
840
842
  case 'findMany':
841
- return this.urlForFindMany(id, typeKey, snapshot);
843
+ return this.urlForFindMany(id, modelName, snapshot);
842
844
  case 'findHasMany':
843
- return this.urlForFindHasMany(id, typeKey);
845
+ return this.urlForFindHasMany(id, modelName);
844
846
  case 'findBelongsTo':
845
- return this.urlForFindBelongsTo(id, typeKey);
847
+ return this.urlForFindBelongsTo(id, modelName);
846
848
  case 'createRecord':
847
- return this.urlForCreateRecord(typeKey, snapshot);
849
+ return this.urlForCreateRecord(modelName, snapshot);
848
850
  case 'updateRecord':
849
- return this.urlForUpdateRecord(id, typeKey, snapshot);
851
+ return this.urlForUpdateRecord(id, modelName, snapshot);
850
852
  case 'deleteRecord':
851
- return this.urlForDeleteRecord(id, typeKey, snapshot);
853
+ return this.urlForDeleteRecord(id, modelName, snapshot);
852
854
  default:
853
- return this._buildURL(typeKey, id);
855
+ return this._buildURL(modelName, id);
854
856
  }
855
857
  },
856
858
 
857
859
  /**
858
860
  @method _buildURL
859
861
  @private
860
- @param {String} typeKey
862
+ @param {String} modelName
861
863
  @param {String} id
862
864
  @return {String} url
863
865
  */
864
- _buildURL: function(typeKey, id) {
866
+ _buildURL: function(modelName, id) {
865
867
  var url = [];
866
868
  var host = ember$data$lib$adapters$build$url$mixin$$get(this, 'host');
867
869
  var prefix = this.urlPrefix();
868
870
  var path;
869
871
 
870
- if (typeKey) {
871
- path = this.pathForType(typeKey);
872
+ if (modelName) {
873
+ path = this.pathForType(modelName);
872
874
  if (path) { url.push(path); }
873
875
  }
874
876
 
@@ -886,31 +888,31 @@
886
888
  /**
887
889
  * @method urlForFind
888
890
  * @param {String} id
889
- * @param {String} typeKey
891
+ * @param {String} modelName
890
892
  * @param {DS.Snapshot} snapshot
891
893
  * @return {String} url
892
894
  */
893
- urlForFind: function(id, typeKey, snapshot) {
894
- return this._buildURL(typeKey, id);
895
+ urlForFind: function(id, modelName, snapshot) {
896
+ return this._buildURL(modelName, id);
895
897
  },
896
898
 
897
899
  /**
898
900
  * @method urlForFindAll
899
- * @param {String} typeKey
901
+ * @param {String} modelName
900
902
  * @return {String} url
901
903
  */
902
- urlForFindAll: function(typeKey) {
903
- return this._buildURL(typeKey);
904
+ urlForFindAll: function(modelName) {
905
+ return this._buildURL(modelName);
904
906
  },
905
907
 
906
908
  /**
907
909
  * @method urlForFindQuery
908
910
  * @param {Object} query
909
- * @param {String} typeKey
911
+ * @param {String} modelName
910
912
  * @return {String} url
911
913
  */
912
- urlForFindQuery: function(query, typeKey) {
913
- return this._buildURL(typeKey);
914
+ urlForFindQuery: function(query, modelName) {
915
+ return this._buildURL(modelName);
914
916
  },
915
917
 
916
918
  /**
@@ -920,60 +922,60 @@
920
922
  * @param {Array} snapshots
921
923
  * @return {String} url
922
924
  */
923
- urlForFindMany: function(ids, typeKey, snapshots) {
924
- return this._buildURL(typeKey);
925
+ urlForFindMany: function(ids, modelName, snapshots) {
926
+ return this._buildURL(modelName);
925
927
  },
926
928
 
927
929
  /**
928
930
  * @method urlForFindHasMany
929
931
  * @param {String} id
930
- * @param {String} typeKey
932
+ * @param {String} modelName
931
933
  * @return {String} url
932
934
  */
933
- urlForFindHasMany: function(id, typeKey) {
934
- return this._buildURL(typeKey, id);
935
+ urlForFindHasMany: function(id, modelName) {
936
+ return this._buildURL(modelName, id);
935
937
  },
936
938
 
937
939
  /**
938
940
  * @method urlForFindBelongTo
939
941
  * @param {String} id
940
- * @param {String} typeKey
942
+ * @param {String} modelName
941
943
  * @return {String} url
942
944
  */
943
- urlForFindBelongsTo: function(id, typeKey) {
944
- return this._buildURL(typeKey, id);
945
+ urlForFindBelongsTo: function(id, modelName) {
946
+ return this._buildURL(modelName, id);
945
947
  },
946
948
 
947
949
  /**
948
950
  * @method urlForCreateRecord
949
- * @param {String} typeKey
951
+ * @param {String} modelName
950
952
  * @param {DS.Snapshot} snapshot
951
953
  * @return {String} url
952
954
  */
953
- urlForCreateRecord: function(typeKey, snapshot) {
954
- return this._buildURL(typeKey);
955
+ urlForCreateRecord: function(modelName, snapshot) {
956
+ return this._buildURL(modelName);
955
957
  },
956
958
 
957
959
  /**
958
960
  * @method urlForUpdateRecord
959
961
  * @param {String} id
960
- * @param {String} typeKey
962
+ * @param {String} modelName
961
963
  * @param {DS.Snapshot} snapshot
962
964
  * @return {String} url
963
965
  */
964
- urlForUpdateRecord: function(id, typeKey, snapshot) {
965
- return this._buildURL(typeKey, id);
966
+ urlForUpdateRecord: function(id, modelName, snapshot) {
967
+ return this._buildURL(modelName, id);
966
968
  },
967
969
 
968
970
  /**
969
971
  * @method urlForDeleteRecord
970
972
  * @param {String} id
971
- * @param {String} typeKey
973
+ * @param {String} modelName
972
974
  * @param {DS.Snapshot} snapshot
973
975
  * @return {String} url
974
976
  */
975
- urlForDeleteRecord: function(id, typeKey, snapshot) {
976
- return this._buildURL(typeKey, id);
977
+ urlForDeleteRecord: function(id, modelName, snapshot) {
978
+ return this._buildURL(modelName, id);
977
979
  },
978
980
 
979
981
  /**
@@ -1032,19 +1034,19 @@
1032
1034
 
1033
1035
  ```js
1034
1036
  App.ApplicationAdapter = DS.RESTAdapter.extend({
1035
- pathForType: function(typeKey) {
1036
- var decamelized = Ember.String.decamelize(typeKey);
1037
+ pathForType: function(modelName) {
1038
+ var decamelized = Ember.String.decamelize(modelName);
1037
1039
  return Ember.String.pluralize(decamelized);
1038
1040
  }
1039
1041
  });
1040
1042
  ```
1041
1043
 
1042
1044
  @method pathForType
1043
- @param {String} typeKey
1045
+ @param {String} modelName
1044
1046
  @return {String} path
1045
1047
  **/
1046
- pathForType: function(typeKey) {
1047
- var camelized = Ember.String.camelize(typeKey);
1048
+ pathForType: function(modelName) {
1049
+ var camelized = Ember.String.camelize(modelName);
1048
1050
  return Ember.String.pluralize(camelized);
1049
1051
  }
1050
1052
  });
@@ -1226,7 +1228,7 @@
1226
1228
  @return {Promise} promise
1227
1229
  */
1228
1230
  find: function(store, type, id, snapshot) {
1229
- return this.ajax(this.buildURL(type.typeKey, id, snapshot, 'find'), 'GET');
1231
+ return this.ajax(this.buildURL(type.modelName, id, snapshot, 'find'), 'GET');
1230
1232
  },
1231
1233
 
1232
1234
  /**
@@ -1250,7 +1252,7 @@
1250
1252
  query = { since: sinceToken };
1251
1253
  }
1252
1254
 
1253
- url = this.buildURL(type.typeKey, null, null, 'findAll');
1255
+ url = this.buildURL(type.modelName, null, null, 'findAll');
1254
1256
 
1255
1257
  return this.ajax(url, 'GET', { data: query });
1256
1258
  },
@@ -1273,7 +1275,7 @@
1273
1275
  @return {Promise} promise
1274
1276
  */
1275
1277
  findQuery: function(store, type, query) {
1276
- var url = this.buildURL(type.typeKey, query, null, 'findQuery');
1278
+ var url = this.buildURL(type.modelName, null, null, 'findQuery', query);
1277
1279
 
1278
1280
  if (this.sortQueryParams) {
1279
1281
  query = this.sortQueryParams(query);
@@ -1316,7 +1318,7 @@
1316
1318
  @return {Promise} promise
1317
1319
  */
1318
1320
  findMany: function(store, type, ids, snapshots) {
1319
- var url = this.buildURL(type.typeKey, ids, snapshots, 'findMany');
1321
+ var url = this.buildURL(type.modelName, ids, snapshots, 'findMany');
1320
1322
  return this.ajax(url, 'GET', { data: { ids: ids } });
1321
1323
  },
1322
1324
 
@@ -1349,7 +1351,7 @@
1349
1351
  */
1350
1352
  findHasMany: function(store, snapshot, url, relationship) {
1351
1353
  var id = snapshot.id;
1352
- var type = snapshot.typeKey;
1354
+ var type = snapshot.modelName;
1353
1355
 
1354
1356
  url = this.urlPrefix(url, this.buildURL(type, id, null, 'findHasMany'));
1355
1357
 
@@ -1385,7 +1387,7 @@
1385
1387
  */
1386
1388
  findBelongsTo: function(store, snapshot, url, relationship) {
1387
1389
  var id = snapshot.id;
1388
- var type = snapshot.typeKey;
1390
+ var type = snapshot.modelName;
1389
1391
 
1390
1392
  url = this.urlPrefix(url, this.buildURL(type, id, null, 'findBelongsTo'));
1391
1393
  return this.ajax(url, 'GET');
@@ -1409,8 +1411,8 @@
1409
1411
  */
1410
1412
  createRecord: function(store, type, snapshot) {
1411
1413
  var data = {};
1412
- var serializer = store.serializerFor(type.typeKey);
1413
- var url = this.buildURL(type.typeKey, null, snapshot, 'createRecord');
1414
+ var serializer = store.serializerFor(type.modelName);
1415
+ var url = this.buildURL(type.modelName, null, snapshot, 'createRecord');
1414
1416
 
1415
1417
  serializer.serializeIntoHash(data, type, snapshot, { includeId: true });
1416
1418
 
@@ -1435,12 +1437,12 @@
1435
1437
  */
1436
1438
  updateRecord: function(store, type, snapshot) {
1437
1439
  var data = {};
1438
- var serializer = store.serializerFor(type.typeKey);
1440
+ var serializer = store.serializerFor(type.modelName);
1439
1441
 
1440
1442
  serializer.serializeIntoHash(data, type, snapshot);
1441
1443
 
1442
1444
  var id = snapshot.id;
1443
- var url = this.buildURL(type.typeKey, id, snapshot, 'updateRecord');
1445
+ var url = this.buildURL(type.modelName, id, snapshot, 'updateRecord');
1444
1446
 
1445
1447
  return this.ajax(url, "PUT", { data: data });
1446
1448
  },
@@ -1459,11 +1461,11 @@
1459
1461
  deleteRecord: function(store, type, snapshot) {
1460
1462
  var id = snapshot.id;
1461
1463
 
1462
- return this.ajax(this.buildURL(type.typeKey, id, snapshot, 'deleteRecord'), "DELETE");
1464
+ return this.ajax(this.buildURL(type.modelName, id, snapshot, 'deleteRecord'), "DELETE");
1463
1465
  },
1464
1466
 
1465
1467
  _stripIDFromURL: function(store, snapshot) {
1466
- var url = this.buildURL(snapshot.typeKey, snapshot.id, snapshot);
1468
+ var url = this.buildURL(snapshot.modelName, snapshot.id, snapshot);
1467
1469
 
1468
1470
  var expandedURL = url.split('/');
1469
1471
  //Case when the url is of the format ...something/:id
@@ -1725,8 +1727,8 @@
1725
1727
  var ember$inflector$lib$lib$system$inflector$$capitalize = ember$lib$main$$default.String.capitalize;
1726
1728
 
1727
1729
  var ember$inflector$lib$lib$system$inflector$$BLANK_REGEX = /^\s*$/;
1728
- var ember$inflector$lib$lib$system$inflector$$LAST_WORD_DASHED_REGEX = /([\w/-]+[_/-])([a-z\d]+$)/;
1729
- var ember$inflector$lib$lib$system$inflector$$LAST_WORD_CAMELIZED_REGEX = /([\w/-]+)([A-Z][a-z\d]*$)/;
1730
+ var ember$inflector$lib$lib$system$inflector$$LAST_WORD_DASHED_REGEX = /(\w+[_-])([a-z\d]+$)/;
1731
+ var ember$inflector$lib$lib$system$inflector$$LAST_WORD_CAMELIZED_REGEX = /(\w+)([A-Z][a-z\d]*$)/;
1730
1732
  var ember$inflector$lib$lib$system$inflector$$CAMELIZED_REGEX = /[A-Z][a-z\d]*$/;
1731
1733
 
1732
1734
  function ember$inflector$lib$lib$system$inflector$$loadUncountable(rules, uncountable) {
@@ -2347,11 +2349,11 @@
2347
2349
  ```
2348
2350
 
2349
2351
  @method pathForType
2350
- @param {String} typeKey
2352
+ @param {String} modelName
2351
2353
  @return String
2352
2354
  */
2353
- pathForType: function(typeKey) {
2354
- var decamelized = activemodel$adapter$lib$system$active$model$adapter$$decamelize(typeKey);
2355
+ pathForType: function(modelName) {
2356
+ var decamelized = activemodel$adapter$lib$system$active$model$adapter$$decamelize(modelName);
2355
2357
  var underscored = activemodel$adapter$lib$system$active$model$adapter$$underscore(decamelized);
2356
2358
  return ember$inflector$lib$lib$system$string$$pluralize(underscored);
2357
2359
  },
@@ -2377,9 +2379,7 @@
2377
2379
 
2378
2380
  if (jqXHR && jqXHR.status === 422) {
2379
2381
  var response = Ember.$.parseJSON(jqXHR.responseText);
2380
- var errors = response.errors ? response.errors : response;
2381
-
2382
- return new ember$data$lib$system$model$errors$invalid$$default(errors);
2382
+ return new ember$data$lib$system$model$errors$invalid$$default(response);
2383
2383
  } else {
2384
2384
  return error;
2385
2385
  }
@@ -2935,7 +2935,7 @@
2935
2935
  ```js
2936
2936
  App.ApplicationSerializer = DS.RESTSerializer.extend({
2937
2937
  serializeIntoHash: function(data, type, snapshot, options) {
2938
- var root = Ember.String.decamelize(type.typeKey);
2938
+ var root = Ember.String.decamelize(type.modelName);
2939
2939
  data[root] = this.serialize(snapshot, options);
2940
2940
  }
2941
2941
  });
@@ -3111,7 +3111,7 @@
3111
3111
  if (Ember.isNone(belongsTo)) {
3112
3112
  json[key + "_type"] = null;
3113
3113
  } else {
3114
- json[key + "_type"] = belongsTo.typeKey;
3114
+ json[key + "_type"] = belongsTo.modelName;
3115
3115
  }
3116
3116
  }
3117
3117
  });
@@ -3146,7 +3146,7 @@
3146
3146
  socket.on('message', function(message) {
3147
3147
  var data = message.data;
3148
3148
  var typeClass = store.modelFor(message.modelName);
3149
- var serializer = store.serializerFor(typeClass.typeKey);
3149
+ var serializer = store.serializerFor(typeClass.modelName);
3150
3150
  var record = serializer.extract(store, typeClass, data, data.id, 'single');
3151
3151
 
3152
3152
  store.push(message.modelName, record);
@@ -3524,6 +3524,11 @@
3524
3524
  }
3525
3525
  });
3526
3526
 
3527
+ function ember$data$lib$system$normalize$model$name$$normalizeModelName(modelName) {
3528
+ return Ember.String.dasherize(modelName);
3529
+ }
3530
+ var ember$data$lib$system$normalize$model$name$$default = ember$data$lib$system$normalize$model$name$$normalizeModelName;
3531
+
3527
3532
  var ember$data$lib$serializers$rest$serializer$$forEach = Ember.ArrayPolyfills.forEach;
3528
3533
  var ember$data$lib$serializers$rest$serializer$$map = Ember.ArrayPolyfills.map;
3529
3534
  var ember$data$lib$serializers$rest$serializer$$camelize = Ember.String.camelize;
@@ -3774,25 +3779,25 @@
3774
3779
 
3775
3780
  @method extractSingle
3776
3781
  @param {DS.Store} store
3777
- @param {subclass of DS.Model} primaryTypeClasss
3782
+ @param {subclass of DS.Model} primaryTypeClass
3778
3783
  @param {Object} payload
3779
3784
  @param {String} recordId
3780
3785
  @return {Object} the primary response to the original request
3781
3786
  */
3782
3787
  extractSingle: function(store, primaryTypeClass, rawPayload, recordId) {
3783
3788
  var payload = this.normalizePayload(rawPayload);
3784
- var primaryTypeClassName = primaryTypeClass.typeKey;
3789
+ var primaryTypeClassName = primaryTypeClass.modelName;
3785
3790
  var primaryRecord;
3786
3791
 
3787
3792
  for (var prop in payload) {
3788
- var typeName = this.typeForRoot(prop);
3793
+ var typeName = this.modelNameFromPayloadKey(prop);
3789
3794
 
3790
3795
  if (!store.modelFactoryFor(typeName)) {
3791
3796
  Ember.warn(this.warnMessageNoModelForKey(prop, typeName), false);
3792
3797
  continue;
3793
3798
  }
3794
3799
  var type = store.modelFor(typeName);
3795
- var isPrimary = type.typeKey === primaryTypeClassName;
3800
+ var isPrimary = type.modelName === primaryTypeClassName;
3796
3801
  var value = payload[prop];
3797
3802
 
3798
3803
  if (value === null) {
@@ -3807,7 +3812,7 @@
3807
3812
 
3808
3813
  /*jshint loopfunc:true*/
3809
3814
  ember$data$lib$serializers$rest$serializer$$forEach.call(value, function(hash) {
3810
- var typeName = this.typeForRoot(prop);
3815
+ var typeName = this.modelNameFromPayloadKey(prop);
3811
3816
  var type = store.modelFor(typeName);
3812
3817
  var typeSerializer = store.serializerFor(type);
3813
3818
 
@@ -3935,26 +3940,26 @@
3935
3940
  */
3936
3941
  extractArray: function(store, primaryTypeClass, rawPayload) {
3937
3942
  var payload = this.normalizePayload(rawPayload);
3938
- var primaryTypeClassName = primaryTypeClass.typeKey;
3943
+ var primaryTypeClassName = primaryTypeClass.modelName;
3939
3944
  var primaryArray;
3940
3945
 
3941
3946
  for (var prop in payload) {
3942
- var typeKey = prop;
3947
+ var modelName = prop;
3943
3948
  var forcedSecondary = false;
3944
3949
 
3945
3950
  if (prop.charAt(0) === '_') {
3946
3951
  forcedSecondary = true;
3947
- typeKey = prop.substr(1);
3952
+ modelName = prop.substr(1);
3948
3953
  }
3949
3954
 
3950
- var typeName = this.typeForRoot(typeKey);
3955
+ var typeName = this.modelNameFromPayloadKey(modelName);
3951
3956
  if (!store.modelFactoryFor(typeName)) {
3952
3957
  Ember.warn(this.warnMessageNoModelForKey(prop, typeName), false);
3953
3958
  continue;
3954
3959
  }
3955
3960
  var type = store.modelFor(typeName);
3956
3961
  var typeSerializer = store.serializerFor(type);
3957
- var isPrimary = (!forcedSecondary && (type.typeKey === primaryTypeClassName));
3962
+ var isPrimary = (!forcedSecondary && (type.modelName === primaryTypeClassName));
3958
3963
 
3959
3964
  /*jshint loopfunc:true*/
3960
3965
  var normalizedArray = ember$data$lib$serializers$rest$serializer$$map.call(payload[prop], function(hash) {
@@ -4006,12 +4011,12 @@
4006
4011
  var payload = this.normalizePayload(rawPayload);
4007
4012
 
4008
4013
  for (var prop in payload) {
4009
- var typeKey = this.typeForRoot(prop);
4010
- if (!store.modelFactoryFor(typeKey, prop)) {
4011
- Ember.warn(this.warnMessageNoModelForKey(prop, typeKey), false);
4014
+ var modelName = this.modelNameFromPayloadKey(prop);
4015
+ if (!store.modelFactoryFor(modelName)) {
4016
+ Ember.warn(this.warnMessageNoModelForKey(prop, modelName), false);
4012
4017
  continue;
4013
4018
  }
4014
- var type = store.modelFor(typeKey);
4019
+ var type = store.modelFor(modelName);
4015
4020
  var typeSerializer = store.serializerFor(type);
4016
4021
 
4017
4022
  /*jshint loopfunc:true*/
@@ -4019,55 +4024,70 @@
4019
4024
  return typeSerializer.normalize(type, hash, prop);
4020
4025
  }, this);
4021
4026
 
4022
- store.pushMany(typeKey, normalizedArray);
4027
+ store.pushMany(modelName, normalizedArray);
4023
4028
  }
4024
4029
  },
4025
4030
 
4026
4031
  /**
4027
4032
  This method is used to convert each JSON root key in the payload
4028
- into a typeKey that it can use to look up the appropriate model for
4029
- that part of the payload. By default the typeKey for a model is its
4030
- name in camelCase, so if your JSON root key is 'fast-car' you would
4031
- use typeForRoot to convert it to 'fastCar' so that Ember Data finds
4032
- the `FastCar` model.
4033
+ into a modelName that it can use to look up the appropriate model for
4034
+ that part of the payload.
4033
4035
 
4034
- If you diverge from this norm you should also consider changes to
4035
- store._normalizeTypeKey as well.
4036
+ For example, your server may send a model name that does not correspond with
4037
+ the name of the model in your app. Let's take a look at an example model,
4038
+ and an example payload:
4036
4039
 
4037
- For example, your server may return prefixed root keys like so:
4040
+ ```javascript
4041
+ // Located in the file app/models/post.js
4042
+ import DS from 'ember-data';
4043
+ export default var Post = DS.Model.extend();
4044
+ ```
4038
4045
 
4039
- ```js
4040
- {
4041
- "response-fast-car": {
4042
- "id": "1",
4043
- "name": "corvette"
4046
+ ```javascript
4047
+ {
4048
+ "blog/post": {
4049
+ "id": "1
4050
+ }
4044
4051
  }
4045
- }
4046
4052
  ```
4047
4053
 
4048
- In order for Ember Data to know that the model corresponding to
4049
- the 'response-fast-car' hash is `FastCar` (typeKey: 'fastCar'),
4050
- you can override typeForRoot to convert 'response-fast-car' to
4051
- 'fastCar' like so:
4054
+ Ember Data is going to normalize the payload's root key for the modelName. As a result,
4055
+ it will try to look up the "blog/post" model. Since we don't have a model called "blog/post"
4056
+ (or a file called app/models/blog/post.js in ember-cli), Ember Data will throw an error
4057
+ because it cannot find the "blog/post" model.
4052
4058
 
4053
- ```js
4054
- App.ApplicationSerializer = DS.RESTSerializer.extend({
4055
- typeForRoot: function(root) {
4056
- // 'response-fast-car' should become 'fast-car'
4057
- var subRoot = root.substring(9);
4059
+ Since we want to remove this namespace, we can define a serializer for the application that will
4060
+ remove "blog/" from the payload key whenver it's encountered by Ember Data:
4058
4061
 
4059
- // _super normalizes 'fast-car' to 'fastCar'
4060
- return this._super(subRoot);
4062
+ ```javascript
4063
+ // located in app/serializers/application.js
4064
+ import DS from 'ember-data';
4065
+
4066
+ export default DS.RESTSerializer.extend({
4067
+ modelNameFromPayloadKey: function(payloadKey) {
4068
+ if (payloadKey === 'blog/post') {
4069
+ return this._super(payloadKey.replace('blog/', ''));
4070
+ } else {
4071
+ return this._super(payloadKey);
4072
+ }
4061
4073
  }
4062
4074
  });
4063
4075
  ```
4064
4076
 
4065
- @method typeForRoot
4077
+ After refreshing, Ember Data will appropriately look up the "post" model.
4078
+
4079
+ By default the modelName for a model is its
4080
+ name in dasherized form. This means that a payload key like "blogPost" would be
4081
+ normalized to "blog-post" when Ember Data looks up the model. Usually, Ember Data
4082
+ can use the correct inflection to do this for you. Most of the time, you won't
4083
+ need to override `modelNameFromPayloadKey` for this purpose.
4084
+
4085
+ @method modelNameFromPayloadKey
4066
4086
  @param {String} key
4067
- @return {String} the model's typeKey
4087
+ @return {String} the model's modelName
4068
4088
  */
4069
- typeForRoot: function(key) {
4070
- return ember$data$lib$serializers$rest$serializer$$camelize(ember$inflector$lib$lib$system$string$$singularize(key));
4089
+ modelNameFromPayloadKey: function(key) {
4090
+ return ember$inflector$lib$lib$system$string$$singularize(ember$data$lib$system$normalize$model$name$$default(key));
4071
4091
  },
4072
4092
 
4073
4093
  // SERIALIZE
@@ -4221,7 +4241,7 @@
4221
4241
 
4222
4242
  /**
4223
4243
  You can use this method to customize the root keys serialized into the JSON.
4224
- By default the REST Serializer sends the typeKey of a model, which is a camelized
4244
+ By default the REST Serializer sends the modelName of a model, which is a camelized
4225
4245
  version of the name.
4226
4246
 
4227
4247
  For example, your server may expect underscored root objects.
@@ -4229,7 +4249,7 @@
4229
4249
  ```js
4230
4250
  App.ApplicationSerializer = DS.RESTSerializer.extend({
4231
4251
  serializeIntoHash: function(data, type, record, options) {
4232
- var root = Ember.String.decamelize(type.typeKey);
4252
+ var root = Ember.String.decamelize(type.modelName);
4233
4253
  data[root] = this.serialize(record, options);
4234
4254
  }
4235
4255
  });
@@ -4242,7 +4262,68 @@
4242
4262
  @param {Object} options
4243
4263
  */
4244
4264
  serializeIntoHash: function(hash, typeClass, snapshot, options) {
4245
- hash[typeClass.typeKey] = this.serialize(snapshot, options);
4265
+ var normalizedRootKey = this.payloadKeyFromModelName(typeClass.modelName);
4266
+ hash[normalizedRootKey] = this.serialize(snapshot, options);
4267
+ },
4268
+
4269
+ /**
4270
+ You can use `payloadKeyFromModelName` to override the root key for an outgoing
4271
+ request. By default, the RESTSerializer returns a camelized version of the
4272
+ model's name.
4273
+
4274
+ For a model called TacoParty, its `modelName` would be the string `taco-party`. The RESTSerializer
4275
+ will send it to the server with `tacoParty` as the root key in the JSON payload:
4276
+
4277
+ ```js
4278
+ {
4279
+ "tacoParty": {
4280
+ "id": "1",
4281
+ "location": "Matthew Beale's House"
4282
+ }
4283
+ }
4284
+ ```
4285
+
4286
+ For example, your server may expect dasherized root objects:
4287
+
4288
+ ```js
4289
+ App.ApplicationSerializer = DS.RESTSerializer.extend({
4290
+ payloadKeyFromModelName: function(modelName) {
4291
+ return Ember.String.dasherize(modelName);
4292
+ }
4293
+ });
4294
+ ```
4295
+
4296
+ Given a `TacoParty' model, calling `save` on a tacoModel would produce an outgoing
4297
+ request like:
4298
+
4299
+ ```js
4300
+ {
4301
+ "taco-party": {
4302
+ "id": "1",
4303
+ "location": "Matthew Beale's House"
4304
+ }
4305
+ }
4306
+ ```
4307
+
4308
+ @method payloadKeyFromModelName
4309
+ @param {String} modelName
4310
+ @returns {String}
4311
+ */
4312
+ payloadKeyFromModelName: function(modelName) {
4313
+ return ember$data$lib$serializers$rest$serializer$$camelize(modelName);
4314
+ },
4315
+
4316
+ /**
4317
+ Deprecated. Use payloadKeyFromModelName instead
4318
+
4319
+ @method typeForRoot
4320
+ @param {String} modelName
4321
+ @returns {String}
4322
+ @deprecated
4323
+ */
4324
+ typeForRoot: function(modelName) {
4325
+ Ember.deprecate("typeForRoot is deprecated. Use modelNameFromPayloadKey instead.");
4326
+ return this.modelNameFromPayloadKey(modelName);
4246
4327
  },
4247
4328
 
4248
4329
  /**
@@ -4262,15 +4343,15 @@
4262
4343
  if (Ember.isNone(belongsTo)) {
4263
4344
  json[key + "Type"] = null;
4264
4345
  } else {
4265
- json[key + "Type"] = Ember.String.camelize(belongsTo.typeKey);
4346
+ json[key + "Type"] = Ember.String.camelize(belongsTo.modelName);
4266
4347
  }
4267
4348
  }
4268
4349
  });
4269
4350
 
4270
4351
  Ember.runInDebug(function() {
4271
4352
  ember$data$lib$serializers$rest$serializer$$RESTSerializer.reopen({
4272
- warnMessageNoModelForKey: function(prop, typeKey) {
4273
- return 'Encountered "' + prop + '" in payload, but no model was found for model name "' + typeKey + '" (resolved model name using ' + this.constructor.toString() + '.typeForRoot("' + prop + '"))';
4353
+ warnMessageNoModelForKey: function(prop, modelName) {
4354
+ return 'Encountered "' + prop + '" in payload, but no model was found for model name "' + modelName + '" (resolved model name using ' + this.constructor.toString() + '.typeForRoot("' + prop + '"))';
4274
4355
  }
4275
4356
  });
4276
4357
  });
@@ -4413,17 +4494,14 @@
4413
4494
  serializeHasMany: Ember.K,
4414
4495
 
4415
4496
  /**
4416
- Underscores the JSON root keys when serializing.
4497
+ Underscores the JSON root keys when serializing.
4417
4498
 
4418
- @method serializeIntoHash
4419
- @param {Object} hash
4420
- @param {subclass of DS.Model} typeClass
4421
- @param {DS.Snapshot} snapshot
4422
- @param {Object} options
4499
+ @method payloadKeyFromModelName
4500
+ @param {String} modelName
4501
+ @returns {String}
4423
4502
  */
4424
- serializeIntoHash: function(data, typeClass, snapshot, options) {
4425
- var root = activemodel$adapter$lib$system$active$model$serializer$$underscore(activemodel$adapter$lib$system$active$model$serializer$$decamelize(typeClass.typeKey));
4426
- data[root] = this.serialize(snapshot, options);
4503
+ payloadKeyFromModelName: function(modelName) {
4504
+ return activemodel$adapter$lib$system$active$model$serializer$$underscore(activemodel$adapter$lib$system$active$model$serializer$$decamelize(modelName));
4427
4505
  },
4428
4506
 
4429
4507
  /**
@@ -4442,7 +4520,7 @@
4442
4520
  if (Ember.isNone(belongsTo)) {
4443
4521
  json[jsonKey] = null;
4444
4522
  } else {
4445
- json[jsonKey] = activemodel$adapter$lib$system$active$model$serializer$$classify(belongsTo.typeKey).replace(/(\/)([a-z])/g, function(match, separator, chr) {
4523
+ json[jsonKey] = activemodel$adapter$lib$system$active$model$serializer$$classify(belongsTo.modelName).replace(/(\/)([a-z])/g, function(match, separator, chr) {
4446
4524
  return match.toUpperCase();
4447
4525
  }).replace('/', '::');
4448
4526
  }
@@ -4544,11 +4622,11 @@
4544
4622
  payloadKey = this.keyForAttribute(key, "deserialize");
4545
4623
  payload = hash[payloadKey];
4546
4624
  if (payload && payload.type) {
4547
- payload.type = this.typeForRoot(payload.type);
4625
+ payload.type = this.modelNameFromPayloadKey(payload.type);
4548
4626
  } else if (payload && relationship.kind === "hasMany") {
4549
4627
  var self = this;
4550
4628
  activemodel$adapter$lib$system$active$model$serializer$$forEach(payload, function(single) {
4551
- single.type = self.typeForRoot(single.type);
4629
+ single.type = self.modelNameFromPayloadKey(single.type);
4552
4630
  });
4553
4631
  }
4554
4632
  } else {
@@ -4565,10 +4643,11 @@
4565
4643
  }, this);
4566
4644
  }
4567
4645
  },
4568
- typeForRoot: function(key) {
4569
- return activemodel$adapter$lib$system$active$model$serializer$$camelize(ember$inflector$lib$lib$system$string$$singularize(key)).replace(/(^|\:)([A-Z])/g, function(match, separator, chr) {
4646
+ modelNameFromPayloadKey: function(key) {
4647
+ var convertedFromRubyModule = activemodel$adapter$lib$system$active$model$serializer$$camelize(ember$inflector$lib$lib$system$string$$singularize(key)).replace(/(^|\:)([A-Z])/g, function(match, separator, chr) {
4570
4648
  return match.toLowerCase();
4571
4649
  }).replace('::', '/');
4650
+ return ember$data$lib$system$normalize$model$name$$default(convertedFromRubyModule);
4572
4651
  }
4573
4652
  });
4574
4653
 
@@ -4629,7 +4708,7 @@
4629
4708
  }
4630
4709
  var activemodel$adapter$lib$setup$container$$default = activemodel$adapter$lib$setup$container$$setupActiveModelAdapter;
4631
4710
  var ember$data$lib$core$$DS = Ember.Namespace.create({
4632
- VERSION: '1.0.0-beta.17'
4711
+ VERSION: '1.0.0-beta.18'
4633
4712
  });
4634
4713
 
4635
4714
  if (Ember.libraries) {
@@ -4976,7 +5055,7 @@
4976
5055
  content: null,
4977
5056
 
4978
5057
  /**
4979
- The flag to signal a `RecordArray` is currently loading data.
5058
+ The flag to signal a `RecordArray` is finished loading data.
4980
5059
 
4981
5060
  Example
4982
5061
 
@@ -5422,11 +5501,11 @@
5422
5501
 
5423
5502
  @method updateFilter
5424
5503
  @param {Array} array
5425
- @param {String} typeKey
5504
+ @param {String} modelName
5426
5505
  @param {Function} filter
5427
5506
  */
5428
- updateFilter: function(array, typeKey, filter) {
5429
- var typeMap = this.store.typeMapFor(typeKey);
5507
+ updateFilter: function(array, modelName, filter) {
5508
+ var typeMap = this.store.typeMapFor(modelName);
5430
5509
  var records = typeMap.records;
5431
5510
  var record;
5432
5511
 
@@ -5434,7 +5513,7 @@
5434
5513
  record = records[i];
5435
5514
 
5436
5515
  if (!ember$data$lib$system$record$array$manager$$get(record, 'isDeleted') && !ember$data$lib$system$record$array$manager$$get(record, 'isEmpty')) {
5437
- this.updateRecordArray(array, filter, typeKey, record);
5516
+ this.updateRecordArray(array, filter, modelName, record);
5438
5517
  }
5439
5518
  }
5440
5519
  },
@@ -6193,6 +6272,7 @@
6193
6272
  record.triggerLater('ready');
6194
6273
  },
6195
6274
 
6275
+ pushedData: Ember.K,
6196
6276
  becomeDirty: Ember.K,
6197
6277
  deleteRecord: Ember.K,
6198
6278
 
@@ -6611,8 +6691,8 @@
6611
6691
  this.isAsync = relationshipMeta.options.async;
6612
6692
  this.relationshipMeta = relationshipMeta;
6613
6693
  //This probably breaks for polymorphic relationship in complex scenarios, due to
6614
- //multiple possible typeKeys
6615
- this.inverseKeyForImplicit = this.store.modelFor(this.record.constructor).typeKey + this.key;
6694
+ //multiple possible modelNames
6695
+ this.inverseKeyForImplicit = this.store.modelFor(this.record.constructor).modelName + this.key;
6616
6696
  this.linkPromise = null;
6617
6697
  this.hasData = false;
6618
6698
  };
@@ -6803,8 +6883,8 @@
6803
6883
  },
6804
6884
 
6805
6885
  updateLink: function(link) {
6806
- Ember.warn("You have pushed a record of type '" + this.record.constructor.typeKey + "' with '" + this.key + "' as a link, but the association is not an async relationship.", this.isAsync);
6807
- Ember.assert("You have pushed a record of type '" + this.record.constructor.typeKey + "' with '" + this.key + "' as a link, but the value of that link is not a string.", typeof link === 'string' || link === null);
6886
+ Ember.warn("You have pushed a record of type '" + this.record.constructor.modelName + "' with '" + this.key + "' as a link, but the association is not an async relationship.", this.isAsync);
6887
+ Ember.assert("You have pushed a record of type '" + this.record.constructor.modelName + "' with '" + this.key + "' as a link, but the value of that link is not a string.", typeof link === 'string' || link === null);
6808
6888
  if (link !== this.link) {
6809
6889
  this.link = link;
6810
6890
  this.linkPromise = null;
@@ -7031,7 +7111,7 @@
7031
7111
  var type = ember$data$lib$system$many$array$$get(this, 'type');
7032
7112
  var record;
7033
7113
 
7034
- Ember.assert("You cannot add '" + type.typeKey + "' records to this polymorphic relationship.", !ember$data$lib$system$many$array$$get(this, 'isPolymorphic'));
7114
+ Ember.assert("You cannot add '" + type.modelName + "' records to this polymorphic relationship.", !ember$data$lib$system$many$array$$get(this, 'isPolymorphic'));
7035
7115
 
7036
7116
  record = store.createRecord(type, hash);
7037
7117
  this.pushObject(record);
@@ -7142,7 +7222,7 @@
7142
7222
 
7143
7223
  ember$data$lib$system$relationships$state$has$many$$ManyRelationship.prototype.notifyRecordRelationshipAdded = function(record, idx) {
7144
7224
  var type = this.relationshipMeta.type;
7145
- Ember.assert("You cannot add '" + record.constructor.typeKey + "' records to the " + this.record.constructor.typeKey + "." + this.key + " relationship (only '" + this.belongsToType.typeKey + "' allowed)", (function () {
7225
+ Ember.assert("You cannot add '" + record.constructor.modelName + "' records to the " + this.record.constructor.modelName + "." + this.key + " relationship (only '" + this.belongsToType.modelName + "' allowed)", (function () {
7146
7226
  if (type.__isMixin) {
7147
7227
  return type.__mixin.detect(record);
7148
7228
  }
@@ -7237,7 +7317,7 @@
7237
7317
  promise: promise
7238
7318
  });
7239
7319
  } else {
7240
- Ember.assert("You looked up the '" + this.key + "' relationship on a '" + this.record.constructor.typeKey + "' with id " + this.record.get('id') + " but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.hasMany({ async: true })`)", this.manyArray.isEvery('isEmpty', false));
7320
+ Ember.assert("You looked up the '" + this.key + "' relationship on a '" + this.record.constructor.modelName + "' with id " + this.record.get('id') + " but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.hasMany({ async: true })`)", this.manyArray.isEvery('isEmpty', false));
7241
7321
 
7242
7322
  //TODO(Igor) WTF DO I DO HERE?
7243
7323
  if (!this.manyArray.get('isDestroyed')) {
@@ -7319,7 +7399,7 @@
7319
7399
  ember$data$lib$system$relationships$state$belongs$to$$BelongsToRelationship.prototype.addRecord = function(newRecord) {
7320
7400
  if (this.members.has(newRecord)) { return;}
7321
7401
  var type = this.relationshipMeta.type;
7322
- Ember.assert("You cannot add a '" + newRecord.constructor.typeKey + "' record to the '" + this.record.constructor.typeKey + "." + this.key +"'. " + "You can only add a '" + type.typeKey + "' record to this relationship.", (function () {
7402
+ Ember.assert("You cannot add a '" + newRecord.constructor.modelName + "' record to the '" + this.record.constructor.modelName + "." + this.key +"'. " + "You can only add a '" + type.modelName + "' record to this relationship.", (function () {
7323
7403
  if (type.__isMixin) {
7324
7404
  return type.__mixin.detect(newRecord);
7325
7405
  }
@@ -7395,7 +7475,7 @@
7395
7475
  content: this.inverseRecord
7396
7476
  });
7397
7477
  } else {
7398
- Ember.assert("You looked up the '" + this.key + "' relationship on a '" + this.record.constructor.typeKey + "' with id " + this.record.get('id') + " but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.belongsTo({ async: true })`)", this.inverseRecord === null || !this.inverseRecord.get('isEmpty'));
7478
+ Ember.assert("You looked up the '" + this.key + "' relationship on a '" + this.record.constructor.modelName + "' with id " + this.record.get('id') + " but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (`DS.belongsTo({ async: true })`)", this.inverseRecord === null || !this.inverseRecord.get('isEmpty'));
7399
7479
  return this.inverseRecord;
7400
7480
  }
7401
7481
  };
@@ -7442,7 +7522,7 @@
7442
7522
  this.id = ember$data$lib$system$snapshot$$get(record, 'id');
7443
7523
  this.record = record;
7444
7524
  this.type = record.constructor;
7445
- this.typeKey = record.constructor.typeKey;
7525
+ this.modelName = record.constructor.modelName;
7446
7526
 
7447
7527
  // The following code is here to keep backwards compatibility when accessing
7448
7528
  // `constructor` directly.
@@ -7517,10 +7597,10 @@
7517
7597
  /**
7518
7598
  The name of the type of the underlying record for this snapshot, as a string.
7519
7599
 
7520
- @property typeKey
7600
+ @property modelName
7521
7601
  @type {String}
7522
7602
  */
7523
- typeKey: null,
7603
+ modelName: null,
7524
7604
 
7525
7605
  /**
7526
7606
  Returns the value of an attribute.
@@ -7799,6 +7879,17 @@
7799
7879
  }
7800
7880
  };
7801
7881
 
7882
+ Ember.defineProperty(ember$data$lib$system$snapshot$$Snapshot.prototype, 'typeKey', {
7883
+ enumerable: false,
7884
+ get: function() {
7885
+ Ember.deprecate('Snapshot.typeKey is deprecated. Use snapshot.modelName instead.');
7886
+ return this.modelName;
7887
+ },
7888
+ set: function() {
7889
+ Ember.assert('Setting snapshot.typeKey is not supported. In addition, Snapshot.typeKey has been deprecated for Snapshot.modelName.');
7890
+ }
7891
+ });
7892
+
7802
7893
  var ember$data$lib$system$snapshot$$default = ember$data$lib$system$snapshot$$Snapshot;
7803
7894
 
7804
7895
  /**
@@ -8666,14 +8757,15 @@
8666
8757
  Example
8667
8758
 
8668
8759
  ```javascript
8760
+ var attr = DS.attr;
8669
8761
  App.Mascot = DS.Model.extend({
8670
8762
  name: attr('string')
8671
8763
  });
8672
8764
 
8673
- var person = store.createRecord('person');
8674
- person.changedAttributes(); // {}
8675
- person.set('name', 'Tomster');
8676
- person.changedAttributes(); // {name: [undefined, 'Tomster']}
8765
+ var mascot = store.createRecord('mascot');
8766
+ mascot.changedAttributes(); // {}
8767
+ mascot.set('name', 'Tomster');
8768
+ mascot.changedAttributes(); // {name: [undefined, 'Tomster']}
8677
8769
  ```
8678
8770
 
8679
8771
  @method changedAttributes
@@ -9046,7 +9138,35 @@
9046
9138
  */
9047
9139
  create: function() {
9048
9140
  throw new Ember.Error("You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.");
9049
- }
9141
+ },
9142
+
9143
+ /**
9144
+ Represents the model's class name as a string. This can be used to look up the model through
9145
+ DS.Store's modelFor method.
9146
+
9147
+ `modelName` is generated for you by Ember Data. It will be a lowercased, dasherized string.
9148
+ For example:
9149
+
9150
+ ```javascript
9151
+ store.modelFor('post').modelName; // 'post'
9152
+ store.modelFor('blog-post').modelName; // 'blog-post'
9153
+ ```
9154
+
9155
+ The most common place you'll want to access `modelName` is in your serializer's `payloadKeyFromModelName` method. For example, to change payload
9156
+ keys to underscore (instead of dasherized), you might use the following code:
9157
+
9158
+ ```javascript
9159
+ export default var PostSerializer = DS.RESTSerializer.extend({
9160
+ payloadKeyFromModelName: function(modelName) {
9161
+ return Ember.String.underscore(modelName);
9162
+ }
9163
+ });
9164
+ ```
9165
+ @property
9166
+ @type String
9167
+ @readonly
9168
+ */
9169
+ modelName: null
9050
9170
  });
9051
9171
 
9052
9172
  var ember$data$lib$system$model$model$$default = ember$data$lib$system$model$model$$Model;
@@ -9371,6 +9491,7 @@
9371
9491
  }
9372
9492
  var ember$data$lib$system$model$attributes$$default = ember$data$lib$system$model$attributes$$attr;
9373
9493
  var ember$data$lib$system$model$$default = ember$data$lib$system$model$model$$default;
9494
+
9374
9495
  //Stanley told me to do this
9375
9496
  var ember$data$lib$system$store$$Backburner = Ember.__loader.require('backburner')['default'] || Ember.__loader.require('backburner')['Backburner'];
9376
9497
 
@@ -9426,8 +9547,6 @@
9426
9547
  var ember$data$lib$system$store$$copy = Ember.copy;
9427
9548
  var ember$data$lib$system$store$$Store;
9428
9549
 
9429
- var ember$data$lib$system$store$$camelize = Ember.String.camelize;
9430
-
9431
9550
  var ember$data$lib$system$store$$Service = Ember.Service;
9432
9551
  if (!ember$data$lib$system$store$$Service) {
9433
9552
  ember$data$lib$system$store$$Service = Ember.Object;
@@ -9577,7 +9696,7 @@
9577
9696
  */
9578
9697
  serialize: function(record, options) {
9579
9698
  var snapshot = record._createSnapshot();
9580
- return this.serializerFor(snapshot.typeKey).serialize(snapshot, options);
9699
+ return this.serializerFor(snapshot.modelName).serialize(snapshot, options);
9581
9700
  },
9582
9701
 
9583
9702
  /**
@@ -9631,13 +9750,13 @@
9631
9750
  ```
9632
9751
 
9633
9752
  @method createRecord
9634
- @param {String} typeKey
9753
+ @param {String} modelName
9635
9754
  @param {Object} properties a hash of properties to set on the
9636
9755
  newly created record.
9637
9756
  @return {DS.Model} record
9638
9757
  */
9639
- createRecord: function(typeKey, inputProperties) {
9640
- var typeClass = this.modelFor(typeKey);
9758
+ createRecord: function(modelName, inputProperties) {
9759
+ var typeClass = this.modelFor(modelName);
9641
9760
  var properties = ember$data$lib$system$store$$copy(inputProperties) || {};
9642
9761
 
9643
9762
  // If the passed properties do not include a primary key,
@@ -9674,15 +9793,15 @@
9674
9793
 
9675
9794
  @method _generateId
9676
9795
  @private
9677
- @param {String} typeKey
9796
+ @param {String} modelName
9678
9797
  @param {Object} properties from the new record
9679
9798
  @return {String} if the adapter can generate one, an ID
9680
9799
  */
9681
- _generateId: function(typeKey, properties) {
9682
- var adapter = this.adapterFor(typeKey);
9800
+ _generateId: function(modelName, properties) {
9801
+ var adapter = this.adapterFor(modelName);
9683
9802
 
9684
9803
  if (adapter && adapter.generateIdForRecord) {
9685
- return adapter.generateIdForRecord(this, typeKey, properties);
9804
+ return adapter.generateIdForRecord(this, modelName, properties);
9686
9805
  }
9687
9806
 
9688
9807
  return null;
@@ -9835,25 +9954,25 @@
9835
9954
  ```
9836
9955
 
9837
9956
  @method find
9838
- @param {String} typeKey
9957
+ @param {String} modelName
9839
9958
  @param {Object|String|Integer|null} id
9840
9959
  @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
9841
9960
  @return {Promise} promise
9842
9961
  */
9843
- find: function(typeKey, id, preload) {
9962
+ find: function(modelName, id, preload) {
9844
9963
  Ember.assert("You need to pass a type to the store's find method", arguments.length >= 1);
9845
9964
  Ember.assert("You may not pass `" + id + "` as id to the store's find method", arguments.length === 1 || !Ember.isNone(id));
9846
9965
 
9847
9966
  if (arguments.length === 1) {
9848
- return this.findAll(typeKey);
9967
+ return this.findAll(modelName);
9849
9968
  }
9850
9969
 
9851
9970
  // We are passed a query instead of an id.
9852
9971
  if (Ember.typeOf(id) === 'object') {
9853
- return this.findQuery(typeKey, id);
9972
+ return this.findQuery(modelName, id);
9854
9973
  }
9855
9974
 
9856
- return this.findById(typeKey, ember$data$lib$system$store$$coerceId(id), preload);
9975
+ return this.findById(modelName, ember$data$lib$system$store$$coerceId(id), preload);
9857
9976
  },
9858
9977
 
9859
9978
  /**
@@ -9877,16 +9996,16 @@
9877
9996
  ```
9878
9997
 
9879
9998
  @method fetchById
9880
- @param {String} typeKey
9999
+ @param {String} modelName
9881
10000
  @param {String|Integer} id
9882
10001
  @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
9883
10002
  @return {Promise} promise
9884
10003
  */
9885
- fetchById: function(typeKey, id, preload) {
9886
- if (this.hasRecordForId(typeKey, id)) {
9887
- return this.getById(typeKey, id).reload();
10004
+ fetchById: function(modelName, id, preload) {
10005
+ if (this.hasRecordForId(modelName, id)) {
10006
+ return this.getById(modelName, id).reload();
9888
10007
  } else {
9889
- return this.find(typeKey, id, preload);
10008
+ return this.find(modelName, id, preload);
9890
10009
  }
9891
10010
  },
9892
10011
 
@@ -9895,26 +10014,26 @@
9895
10014
  in the store or not.
9896
10015
 
9897
10016
  @method fetchAll
9898
- @param {String} typeKey
10017
+ @param {String} modelName
9899
10018
  @return {Promise} promise
9900
10019
  */
9901
- fetchAll: function(typeKey) {
9902
- var typeClass = this.modelFor(typeKey);
10020
+ fetchAll: function(modelName) {
10021
+ var typeClass = this.modelFor(modelName);
9903
10022
 
9904
- return this._fetchAll(typeClass, this.all(typeKey));
10023
+ return this._fetchAll(typeClass, this.all(modelName));
9905
10024
  },
9906
10025
 
9907
10026
  /**
9908
10027
  @method fetch
9909
- @param {String} typeKey
10028
+ @param {String} modelName
9910
10029
  @param {String|Integer} id
9911
10030
  @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
9912
10031
  @return {Promise} promise
9913
10032
  @deprecated Use [fetchById](#method_fetchById) instead
9914
10033
  */
9915
- fetch: function(typeKey, id, preload) {
10034
+ fetch: function(modelName, id, preload) {
9916
10035
  Ember.deprecate('Using store.fetch() has been deprecated. Use store.fetchById for fetching individual records or store.fetchAll for collections');
9917
- return this.fetchById(typeKey, id, preload);
10036
+ return this.fetchById(modelName, id, preload);
9918
10037
  },
9919
10038
 
9920
10039
  /**
@@ -9922,14 +10041,14 @@
9922
10041
 
9923
10042
  @method findById
9924
10043
  @private
9925
- @param {String} typeKey
10044
+ @param {String} modelName
9926
10045
  @param {String|Integer} id
9927
10046
  @param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
9928
10047
  @return {Promise} promise
9929
10048
  */
9930
- findById: function(typeKey, id, preload) {
10049
+ findById: function(modelName, id, preload) {
9931
10050
 
9932
- var typeClass = this.modelFor(typeKey);
10051
+ var typeClass = this.modelFor(modelName);
9933
10052
  var record = this.recordForId(typeClass, id);
9934
10053
 
9935
10054
  return this._findByRecord(record, preload);
@@ -9949,7 +10068,7 @@
9949
10068
  fetchedRecord = record._loadingPromise;
9950
10069
  }
9951
10070
 
9952
- return ember$data$lib$system$promise$proxies$$promiseObject(fetchedRecord || record, "DS: Store#findByRecord " + record.typeKey + " with id: " + ember$data$lib$system$store$$get(record, 'id'));
10071
+ return ember$data$lib$system$promise$proxies$$promiseObject(fetchedRecord || record, "DS: Store#findByRecord " + record.modelName + " with id: " + ember$data$lib$system$store$$get(record, 'id'));
9953
10072
  },
9954
10073
 
9955
10074
  /**
@@ -9958,16 +10077,16 @@
9958
10077
 
9959
10078
  @private
9960
10079
  @method findByIds
9961
- @param {String} typeKey
10080
+ @param {String} modelName
9962
10081
  @param {Array} ids
9963
10082
  @return {Promise} promise
9964
10083
  */
9965
- findByIds: function(typeKey, ids) {
10084
+ findByIds: function(modelName, ids) {
9966
10085
  var store = this;
9967
10086
 
9968
10087
  return ember$data$lib$system$promise$proxies$$promiseArray(Ember.RSVP.all(ember$data$lib$system$store$$map(ids, function(id) {
9969
- return store.findById(typeKey, id);
9970
- })).then(Ember.A, null, "DS: Store#findByIds of " + typeKey + " complete"));
10088
+ return store.findById(modelName, id);
10089
+ })).then(Ember.A, null, "DS: Store#findByIds of " + modelName + " complete"));
9971
10090
  },
9972
10091
 
9973
10092
  /**
@@ -10177,8 +10296,8 @@
10177
10296
  @param {String|Integer} id
10178
10297
  @return {Boolean}
10179
10298
  */
10180
- hasRecordForId: function(typeKey, inputId) {
10181
- var typeClass = this.modelFor(typeKey);
10299
+ hasRecordForId: function(modelName, inputId) {
10300
+ var typeClass = this.modelFor(modelName);
10182
10301
  var id = ember$data$lib$system$store$$coerceId(inputId);
10183
10302
  var record = this.typeMapFor(typeClass).idToRecord[id];
10184
10303
  return !!record && ember$data$lib$system$store$$get(record, 'isLoaded');
@@ -10190,12 +10309,12 @@
10190
10309
 
10191
10310
  @method recordForId
10192
10311
  @private
10193
- @param {String} typeKey
10312
+ @param {String} modelName
10194
10313
  @param {String|Integer} id
10195
10314
  @return {DS.Model} record
10196
10315
  */
10197
- recordForId: function(typeKey, inputId) {
10198
- var typeClass = this.modelFor(typeKey);
10316
+ recordForId: function(modelName, inputId) {
10317
+ var typeClass = this.modelFor(modelName);
10199
10318
  var id = ember$data$lib$system$store$$coerceId(inputId);
10200
10319
  var idToRecord = this.typeMapFor(typeClass).idToRecord;
10201
10320
  var record = idToRecord[id];
@@ -10305,11 +10424,11 @@
10305
10424
 
10306
10425
  @method findAll
10307
10426
  @private
10308
- @param {String} typeKey
10427
+ @param {String} modelName
10309
10428
  @return {DS.AdapterPopulatedRecordArray}
10310
10429
  */
10311
- findAll: function(typeKey) {
10312
- return this.fetchAll(typeKey);
10430
+ findAll: function(modelName) {
10431
+ return this.fetchAll(modelName);
10313
10432
  },
10314
10433
 
10315
10434
  /**
@@ -10360,11 +10479,11 @@
10360
10479
  ```
10361
10480
 
10362
10481
  @method all
10363
- @param {String} typeKey
10482
+ @param {String} modelName
10364
10483
  @return {DS.RecordArray}
10365
10484
  */
10366
- all: function(typeKey) {
10367
- var typeClass = this.modelFor(typeKey);
10485
+ all: function(modelName) {
10486
+ var typeClass = this.modelFor(modelName);
10368
10487
  var typeMap = this.typeMapFor(typeClass);
10369
10488
  var findAllCache = typeMap.findAllCache;
10370
10489
 
@@ -10390,9 +10509,9 @@
10390
10509
  ```
10391
10510
 
10392
10511
  @method unloadAll
10393
- @param {String} optional typeKey
10512
+ @param {String} optional modelName
10394
10513
  */
10395
- unloadAll: function(typeKey) {
10514
+ unloadAll: function(modelName) {
10396
10515
  if (arguments.length === 0) {
10397
10516
  var typeMaps = this.typeMaps;
10398
10517
  var keys = Ember.keys(typeMaps);
@@ -10401,7 +10520,7 @@
10401
10520
 
10402
10521
  ember$data$lib$system$store$$forEach(types, this.unloadAll, this);
10403
10522
  } else {
10404
- var typeClass = this.modelFor(typeKey);
10523
+ var typeClass = this.modelFor(modelName);
10405
10524
  var typeMap = this.typeMapFor(typeClass);
10406
10525
  var records = typeMap.records.slice();
10407
10526
  var record;
@@ -10759,14 +10878,15 @@
10759
10878
  in this case
10760
10879
  */
10761
10880
 
10762
- _modelForMixin: function(key) {
10881
+ _modelForMixin: function(modelName) {
10882
+ var normalizedTypeKey = ember$data$lib$system$normalize$model$name$$default(modelName);
10763
10883
  var registry = this.container._registry ? this.container._registry : this.container;
10764
- var mixin = registry.resolve('mixin:' + key);
10884
+ var mixin = registry.resolve('mixin:' + normalizedTypeKey);
10765
10885
  if (mixin) {
10766
10886
  //Cache the class as a model
10767
- registry.register('model:' + key, DS.Model.extend(mixin));
10887
+ registry.register('model:' + normalizedTypeKey, DS.Model.extend(mixin));
10768
10888
  }
10769
- var factory = this.modelFactoryFor(key);
10889
+ var factory = this.modelFactoryFor(normalizedTypeKey);
10770
10890
  if (factory) {
10771
10891
  factory.__isMixin = true;
10772
10892
  factory.__mixin = mixin;
@@ -10796,21 +10916,37 @@
10796
10916
  if (!factory) {
10797
10917
  throw new Ember.Error("No model was found for '" + key + "'");
10798
10918
  }
10799
- factory.typeKey = factory.typeKey || this._normalizeTypeKey(key);
10919
+ factory.modelName = factory.modelName || ember$data$lib$system$normalize$model$name$$default(key);
10800
10920
  } else {
10801
10921
  // A factory already supplied. Ensure it has a normalized key.
10802
10922
  factory = key;
10803
- if (factory.typeKey) {
10804
- factory.typeKey = this._normalizeTypeKey(factory.typeKey);
10923
+ if (factory.modelName) {
10924
+ factory.modelName = ember$data$lib$system$normalize$model$name$$default(factory.modelName);
10805
10925
  }
10806
10926
  }
10807
10927
 
10928
+ // deprecate typeKey
10929
+ if (!('typeKey' in factory)) {
10930
+ Ember.defineProperty(factory, 'typeKey', {
10931
+ enumerable: true,
10932
+ configurable: false,
10933
+ get: function() {
10934
+ Ember.deprecate('Usage of `typeKey` has been deprecated and will be removed in Ember Data 1.0. It has been replaced by `modelName` on the model class.');
10935
+ return Ember.String.camelize(this.modelName);
10936
+ },
10937
+ set: function() {
10938
+ Ember.assert('Setting typeKey is not supported. In addition, typeKey has also been deprecated in favor of modelName. Setting modelName is also not supported.');
10939
+ }
10940
+ });
10941
+ }
10942
+
10808
10943
  factory.store = this;
10809
10944
  return factory;
10810
10945
  },
10811
10946
 
10812
10947
  modelFactoryFor: function(key) {
10813
- return this.container.lookupFactory('model:' + key);
10948
+ var normalizedKey = ember$data$lib$system$normalize$model$name$$default(key);
10949
+ return this.container.lookupFactory('model:' + normalizedKey);
10814
10950
  },
10815
10951
 
10816
10952
  /**
@@ -10875,22 +11011,22 @@
10875
11011
  records, as well as to update existing records.
10876
11012
 
10877
11013
  @method push
10878
- @param {String or subclass of DS.Model} type
11014
+ @param {String or subclass of DS.Model} modelName
10879
11015
  @param {Object} data
10880
11016
  @return {DS.Model} the record that was created or
10881
11017
  updated.
10882
11018
  */
10883
- push: function(typeName, data) {
10884
- Ember.assert("Expected an object as `data` in a call to `push` for " + typeName + " , but was " + data, Ember.typeOf(data) === 'object');
10885
- Ember.assert("You must include an `id` for " + typeName + " in an object passed to `push`", data.id != null && data.id !== '');
11019
+ push: function(modelName, data) {
11020
+ Ember.assert("Expected an object as `data` in a call to `push` for " + modelName + " , but was " + data, Ember.typeOf(data) === 'object');
11021
+ Ember.assert("You must include an `id` for " + modelName + " in an object passed to `push`", data.id != null && data.id !== '');
10886
11022
 
10887
- var type = this.modelFor(typeName);
11023
+ var type = this.modelFor(modelName);
10888
11024
  var filter = Ember.EnumerableUtils.filter;
10889
11025
 
10890
11026
  // If Ember.ENV.DS_WARN_ON_UNKNOWN_KEYS is set to true and the payload
10891
11027
  // contains unknown keys, log a warning.
10892
11028
  if (Ember.ENV.DS_WARN_ON_UNKNOWN_KEYS) {
10893
- Ember.warn("The payload for '" + type.typeKey + "' contains these unknown keys: " +
11029
+ Ember.warn("The payload for '" + type.modelName + "' contains these unknown keys: " +
10894
11030
  Ember.inspect(filter(Ember.keys(data), function(key) {
10895
11031
  return !(key === 'id' || key === 'links' || ember$data$lib$system$store$$get(type, 'fields').has(key) || key.match(/Type$/));
10896
11032
  })) + ". Make sure they've been defined in your model.",
@@ -11169,7 +11305,7 @@
11169
11305
  type = this.modelFor(type);
11170
11306
  }
11171
11307
 
11172
- var adapter = this.lookupAdapter(type.typeKey) || this.lookupAdapter('application');
11308
+ var adapter = this.lookupAdapter(type.modelName) || this.lookupAdapter('application');
11173
11309
 
11174
11310
  return adapter || ember$data$lib$system$store$$get(this, 'defaultAdapter');
11175
11311
  },
@@ -11208,7 +11344,7 @@
11208
11344
  type = this.modelFor(type);
11209
11345
  }
11210
11346
 
11211
- var serializer = this.lookupSerializer(type.typeKey) || this.lookupSerializer('application');
11347
+ var serializer = this.lookupSerializer(type.modelName) || this.lookupSerializer('application');
11212
11348
 
11213
11349
  if (!serializer) {
11214
11350
  var adapter = this.adapterFor(type);
@@ -11232,12 +11368,13 @@
11232
11368
 
11233
11369
  @method retrieveManagedInstance
11234
11370
  @private
11235
- @param {String} type the object type
11371
+ @param {String} type the object modelName
11236
11372
  @param {String} type the object name
11237
11373
  @return {Ember.Object}
11238
11374
  */
11239
- retrieveManagedInstance: function(type, name) {
11240
- var key = type+":"+name;
11375
+ retrieveManagedInstance: function(modelName, name) {
11376
+ var normalizedTypeKey = ember$data$lib$system$normalize$model$name$$default(modelName);
11377
+ var key = normalizedTypeKey + ":" +name;
11241
11378
 
11242
11379
  if (!this._containerCache[key]) {
11243
11380
  var instance = this.container.lookup(key);
@@ -11270,20 +11407,8 @@
11270
11407
  }
11271
11408
 
11272
11409
  delete this._containerCache;
11273
- },
11274
-
11275
- /**
11276
- All typeKeys are camelCase internally. Changing this function may
11277
- require changes to other normalization hooks (such as typeForRoot).
11278
-
11279
- @method _normalizeTypeKey
11280
- @private
11281
- @param {String} type
11282
- @return {String} if the adapter can generate one, an ID
11283
- */
11284
- _normalizeTypeKey: function(key) {
11285
- return ember$data$lib$system$store$$camelize(ember$inflector$lib$lib$system$string$$singularize(key));
11286
11410
  }
11411
+
11287
11412
  });
11288
11413
 
11289
11414
 
@@ -11635,8 +11760,8 @@
11635
11760
  return columns;
11636
11761
  },
11637
11762
 
11638
- getRecords: function(typeKey) {
11639
- return this.get('store').all(typeKey);
11763
+ getRecords: function(modelName) {
11764
+ return this.get('store').all(modelName);
11640
11765
  },
11641
11766
 
11642
11767
  getRecordColumnValues: function(record) {
@@ -12315,7 +12440,7 @@
12315
12440
 
12316
12441
  typeClass.eachRelationship(function(key, relationship) {
12317
12442
  if (serializer.hasDeserializeRecordsOption(key)) {
12318
- var embeddedTypeClass = store.modelFor(relationship.type.typeKey);
12443
+ var embeddedTypeClass = store.modelFor(relationship.type.modelName);
12319
12444
  if (relationship.kind === "hasMany") {
12320
12445
  if (relationship.options.polymorphic) {
12321
12446
  ember$data$lib$serializers$embedded$records$mixin$$extractEmbeddedHasManyPolymorphic(store, key, partial);
@@ -12344,7 +12469,7 @@
12344
12469
 
12345
12470
  var ids = [];
12346
12471
 
12347
- var embeddedSerializer = store.serializerFor(embeddedTypeClass.typeKey);
12472
+ var embeddedSerializer = store.serializerFor(embeddedTypeClass.modelName);
12348
12473
  ember$data$lib$serializers$embedded$records$mixin$$forEach(hash[key], function(data) {
12349
12474
  var embeddedRecord = embeddedSerializer.normalize(embeddedTypeClass, data, null);
12350
12475
  store.push(embeddedTypeClass, embeddedRecord);
@@ -12363,14 +12488,14 @@
12363
12488
  var ids = [];
12364
12489
 
12365
12490
  ember$data$lib$serializers$embedded$records$mixin$$forEach(hash[key], function(data) {
12366
- var typeKey = data.type;
12367
- var embeddedSerializer = store.serializerFor(typeKey);
12368
- var embeddedTypeClass = store.modelFor(typeKey);
12491
+ var modelName = data.type;
12492
+ var embeddedSerializer = store.serializerFor(modelName);
12493
+ var embeddedTypeClass = store.modelFor(modelName);
12369
12494
  var primaryKey = ember$data$lib$serializers$embedded$records$mixin$$get(embeddedSerializer, 'primaryKey');
12370
12495
 
12371
12496
  var embeddedRecord = embeddedSerializer.normalize(embeddedTypeClass, data, null);
12372
12497
  store.push(embeddedTypeClass, embeddedRecord);
12373
- ids.push({ id: embeddedRecord[primaryKey], type: typeKey });
12498
+ ids.push({ id: embeddedRecord[primaryKey], type: modelName });
12374
12499
  });
12375
12500
 
12376
12501
  hash[key] = ids;
@@ -12382,7 +12507,7 @@
12382
12507
  return hash;
12383
12508
  }
12384
12509
 
12385
- var embeddedSerializer = store.serializerFor(embeddedTypeClass.typeKey);
12510
+ var embeddedSerializer = store.serializerFor(embeddedTypeClass.modelName);
12386
12511
  var embeddedRecord = embeddedSerializer.normalize(embeddedTypeClass, hash[key], null);
12387
12512
  store.push(embeddedTypeClass, embeddedRecord);
12388
12513
 
@@ -12397,16 +12522,16 @@
12397
12522
  }
12398
12523
 
12399
12524
  var data = hash[key];
12400
- var typeKey = data.type;
12401
- var embeddedSerializer = store.serializerFor(typeKey);
12402
- var embeddedTypeClass = store.modelFor(typeKey);
12525
+ var modelName = data.type;
12526
+ var embeddedSerializer = store.serializerFor(modelName);
12527
+ var embeddedTypeClass = store.modelFor(modelName);
12403
12528
  var primaryKey = ember$data$lib$serializers$embedded$records$mixin$$get(embeddedSerializer, 'primaryKey');
12404
12529
 
12405
12530
  var embeddedRecord = embeddedSerializer.normalize(embeddedTypeClass, data, null);
12406
12531
  store.push(embeddedTypeClass, embeddedRecord);
12407
12532
 
12408
12533
  hash[key] = embeddedRecord[primaryKey];
12409
- hash[key + 'Type'] = typeKey;
12534
+ hash[key + 'Type'] = modelName;
12410
12535
  return hash;
12411
12536
  }
12412
12537
 
@@ -12466,24 +12591,32 @@
12466
12591
  @namespace
12467
12592
  @method belongsTo
12468
12593
  @for DS
12469
- @param {String} type (optional) type of the relationship
12594
+ @param {String} modelName (optional) type of the relationship
12470
12595
  @param {Object} options (optional) a hash of options
12471
12596
  @return {Ember.computed} relationship
12472
12597
  */
12473
- function ember$data$lib$system$relationships$belongs$to$$belongsTo(type, options) {
12474
- if (typeof type === 'object') {
12475
- options = type;
12476
- type = undefined;
12598
+ function ember$data$lib$system$relationships$belongs$to$$belongsTo(modelName, options) {
12599
+ var opts, userEnteredModelName;
12600
+ if (typeof modelName === 'object') {
12601
+ opts = modelName;
12602
+ userEnteredModelName = undefined;
12603
+ } else {
12604
+ opts = options;
12605
+ userEnteredModelName = modelName;
12606
+ }
12607
+
12608
+ if (typeof userEnteredModelName === 'string') {
12609
+ userEnteredModelName = ember$data$lib$system$normalize$model$name$$default(userEnteredModelName);
12477
12610
  }
12478
12611
 
12479
- Ember.assert("The first argument to DS.belongsTo must be a string representing a model type key, not an instance of " + Ember.inspect(type) + ". E.g., to define a relation to the Person model, use DS.belongsTo('person')", typeof type === 'string' || typeof type === 'undefined');
12612
+ Ember.assert("The first argument to DS.belongsTo must be a string representing a model type key, not an instance of " + Ember.inspect(userEnteredModelName) + ". E.g., to define a relation to the Person model, use DS.belongsTo('person')", typeof userEnteredModelName === 'string' || typeof userEnteredModelName === 'undefined');
12480
12613
 
12481
- options = options || {};
12614
+ opts = opts || {};
12482
12615
 
12483
12616
  var meta = {
12484
- type: type,
12617
+ type: userEnteredModelName,
12485
12618
  isRelationship: true,
12486
- options: options,
12619
+ options: opts,
12487
12620
  kind: 'belongsTo',
12488
12621
  key: null
12489
12622
  };
@@ -12618,6 +12751,10 @@
12618
12751
 
12619
12752
  options = options || {};
12620
12753
 
12754
+ if (typeof type === 'string') {
12755
+ type = ember$data$lib$system$normalize$model$name$$default(type);
12756
+ }
12757
+
12621
12758
  // Metadata about relationships is stored on the meta of
12622
12759
  // the relationship. This is used for introspection and
12623
12760
  // serialization. Note that `key` is populated lazily
@@ -12630,10 +12767,18 @@
12630
12767
  key: null
12631
12768
  };
12632
12769
 
12633
- return Ember.computed(function(key) {
12634
- var relationship = this._relationships[key];
12635
- return relationship.getRecords();
12636
- }).meta(meta).readOnly();
12770
+ return ember$data$lib$utils$computed$polyfill$$default({
12771
+ get: function(key) {
12772
+ var relationship = this._relationships[key];
12773
+ return relationship.getRecords();
12774
+ },
12775
+ set: function(key, records) {
12776
+ var relationship = this._relationships[key];
12777
+ relationship.clear();
12778
+ relationship.addRecords(records);
12779
+ return relationship.getRecords();
12780
+ }
12781
+ }).meta(meta);
12637
12782
  }
12638
12783
 
12639
12784
  ember$data$lib$system$model$$default.reopen({
@@ -12650,14 +12795,14 @@
12650
12795
 
12651
12796
  var ember$data$lib$system$relationships$has$many$$default = ember$data$lib$system$relationships$has$many$$hasMany;
12652
12797
  function ember$data$lib$system$relationship$meta$$typeForRelationshipMeta(store, meta) {
12653
- var typeKey, typeClass;
12798
+ var modelName, typeClass;
12654
12799
 
12655
- typeKey = meta.type || meta.key;
12656
- if (typeof typeKey === 'string') {
12800
+ modelName = meta.type || meta.key;
12801
+ if (typeof modelName === 'string') {
12657
12802
  if (meta.kind === 'hasMany') {
12658
- typeKey = ember$inflector$lib$lib$system$string$$singularize(typeKey);
12803
+ modelName = ember$inflector$lib$lib$system$string$$singularize(modelName);
12659
12804
  }
12660
- typeClass = store.modelFor(typeKey);
12805
+ typeClass = store.modelFor(modelName);
12661
12806
  } else {
12662
12807
  typeClass = meta.type;
12663
12808
  }
@@ -12711,7 +12856,7 @@
12711
12856
  ember$data$lib$system$relationships$ext$$relatedTypesDescriptor._cacheable = false;
12712
12857
  }
12713
12858
 
12714
- var typeKey;
12859
+ var modelName;
12715
12860
  var types = Ember.A();
12716
12861
 
12717
12862
  // Loop through each computed property on the class,
@@ -12720,13 +12865,13 @@
12720
12865
  this.eachComputedProperty(function(name, meta) {
12721
12866
  if (meta.isRelationship) {
12722
12867
  meta.key = name;
12723
- typeKey = ember$data$lib$system$relationship$meta$$typeForRelationshipMeta(this.store, meta);
12868
+ modelName = ember$data$lib$system$relationship$meta$$typeForRelationshipMeta(this.store, meta);
12724
12869
 
12725
- Ember.assert("You specified a hasMany (" + meta.type + ") on " + meta.parentType + " but " + meta.type + " was not found.", typeKey);
12870
+ Ember.assert("You specified a hasMany (" + meta.type + ") on " + meta.parentType + " but " + meta.type + " was not found.", modelName);
12726
12871
 
12727
- if (!types.contains(typeKey)) {
12728
- Ember.assert("Trying to sideload " + name + " on " + this.toString() + " but the type doesn't exist.", !!typeKey);
12729
- types.push(typeKey);
12872
+ if (!types.contains(modelName)) {
12873
+ Ember.assert("Trying to sideload " + name + " on " + this.toString() + " but the type doesn't exist.", !!modelName);
12874
+ types.push(modelName);
12730
12875
  }
12731
12876
  }
12732
12877
  });
@@ -12903,14 +13048,14 @@
12903
13048
 
12904
13049
  var inverseName, inverseKind, inverse;
12905
13050
 
12906
- Ember.warn("Detected a reflexive relationship by the name of '" + name + "' without an inverse option. Look at http://emberjs.com/guides/models/defining-models/#toc_reflexive-relation for how to explicitly specify inverses.", options.inverse || propertyMeta.type !== propertyMeta.parentType.typeKey);
13051
+ Ember.warn("Detected a reflexive relationship by the name of '" + name + "' without an inverse option. Look at http://emberjs.com/guides/models/defining-models/#toc_reflexive-relation for how to explicitly specify inverses.", options.inverse || propertyMeta.type !== propertyMeta.parentType.modelName);
12907
13052
 
12908
13053
  //If inverse is specified manually, return the inverse
12909
13054
  if (options.inverse) {
12910
13055
  inverseName = options.inverse;
12911
13056
  inverse = Ember.get(inverseType, 'relationshipsByName').get(inverseName);
12912
13057
 
12913
- Ember.assert("We found no inverse relationships by the name of '" + inverseName + "' on the '" + inverseType.typeKey +
13058
+ Ember.assert("We found no inverse relationships by the name of '" + inverseName + "' on the '" + inverseType.modelName +
12914
13059
  "' model. This is most likely due to a missing attribute on your model definition.", !Ember.isNone(inverse));
12915
13060
 
12916
13061
  inverseKind = inverse.kind;
@@ -13352,6 +13497,13 @@
13352
13497
 
13353
13498
  ember$data$lib$core$$default._setupContainer = ember$data$lib$setup$container$$default;
13354
13499
 
13500
+ Ember.defineProperty(ember$data$lib$core$$default, 'normalizeModelName', {
13501
+ enumerable: true,
13502
+ writable: false,
13503
+ configurable: false,
13504
+ value: ember$data$lib$system$normalize$model$name$$default
13505
+ });
13506
+
13355
13507
  Ember.lookup.DS = ember$data$lib$core$$default;
13356
13508
 
13357
13509
  var ember$data$lib$main$$default = ember$data$lib$core$$default;