ember-data-source 1.0.0.beta.15 → 1.0.0.beta.16

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: f454694e6a4f24335ba2eb4470bfdee2ae4c1643
4
- data.tar.gz: ccdd5d271e9efc9c55ced61325d0553483467d37
3
+ metadata.gz: 86672a74c26bba0f8ff7b9d088d78b1624dc3f1a
4
+ data.tar.gz: a1d8145d74098e849a470b9632c2f774d824fb96
5
5
  SHA512:
6
- metadata.gz: 76a46634a6571f4a2edd4de26dac3daeca1365207c20d3016233f22eac87a7733939e13ff64df46f3e6ab637f1f0ddc7d1e70003a75b71743a298b1ec65f8957
7
- data.tar.gz: 515d4756d871c67c1b13442c8ae744d1af5330f2918842663d7dbfebb79f822fadf591330765abbdab31c80e81bdf6540839ef4ba4c73369e03e12ead4d51fc6
6
+ metadata.gz: 4a29bce761345b48ccf2bb5a1fc3819bae1caae400ef7ff7261ce226fe43821991888607a9933fff025de8cc091e5d00ee4588f7052f9bd481ae2f66ea3e39a7
7
+ data.tar.gz: 60d1335f6f35a47d72b7aa9442bddd9f85102af5a1fbf37bfcdf797038e5ae60cdc96f800d2165badbe89f7c4ea97e9715a181ea1bd86fc94e24ce7d9c36ecdf
@@ -4,27 +4,29 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib\');\n
4
4
 
5
5
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib\');\ntest(\'lib/system.js should pass jshint\', function() { \n ok(true, \'lib/system.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/lib/system.jshint.js");
6
6
 
7
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/active_model_adapter.js should pass jshint\', function() { \n ok(true, \'lib/system/active_model_adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/lib/system/active_model_adapter.jshint.js");
7
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/active-model-adapter.js should pass jshint\', function() { \n ok(true, \'lib/system/active-model-adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/lib/system/active-model-adapter.jshint.js");
8
8
 
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");
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_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");
11
+ 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
12
 
13
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/active_model_serializer_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/active_model_serializer_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/tests/integration/active_model_serializer_test.jshint.js");
13
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/active-model-serializer-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/active-model-serializer-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/tests/integration/active-model-serializer-test.jshint.js");
14
14
 
15
- 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");
15
+ 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");
16
16
 
17
- 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({ errors: { 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 - invalid error has camelized keys\', function() {\n var error = new DS.InvalidError({ errors: { firstName: \"can\'t be blank\" } });\n\n var jqXHR = {\n status: 422,\n responseText: JSON.stringify({ errors: { first_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");
17
+ 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({ errors: { 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 - invalid error has camelized keys\', function() {\n var error = new DS.InvalidError({ errors: { firstName: \"can\'t be blank\" } });\n\n var jqXHR = {\n status: 422,\n responseText: JSON.stringify({ errors: { first_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");
18
18
 
19
- 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})();//# sourceURL=activemodel-adapter/integration/active_model_serializer_test.js");
19
+ 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})();//# sourceURL=activemodel-adapter/integration/active-model-serializer-test.js");
20
20
 
21
- 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");
21
+ 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");
22
22
 
23
23
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib\');\ntest(\'lib/adapters.js should pass jshint\', function() { \n ok(true, \'lib/adapters.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/adapters.jshint.js");
24
24
 
25
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/adapters\');\ntest(\'lib/adapters/fixture_adapter.js should pass jshint\', function() { \n ok(true, \'lib/adapters/fixture_adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/adapters/fixture_adapter.jshint.js");
25
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/adapters\');\ntest(\'lib/adapters/build-url-mixin.js should pass jshint\', function() { \n ok(true, \'lib/adapters/build-url-mixin.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/adapters/build-url-mixin.jshint.js");
26
26
 
27
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/adapters\');\ntest(\'lib/adapters/rest_adapter.js should pass jshint\', function() { \n ok(true, \'lib/adapters/rest_adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/adapters/rest_adapter.jshint.js");
27
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/adapters\');\ntest(\'lib/adapters/fixture-adapter.js should pass jshint\', function() { \n ok(true, \'lib/adapters/fixture-adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/adapters/fixture-adapter.jshint.js");
28
+
29
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/adapters\');\ntest(\'lib/adapters/rest-adapter.js should pass jshint\', function() { \n ok(true, \'lib/adapters/rest-adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/adapters/rest-adapter.jshint.js");
28
30
 
29
31
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib\');\ntest(\'lib/core.js should pass jshint\', function() { \n ok(true, \'lib/core.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/core.jshint.js");
30
32
 
@@ -32,11 +34,11 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib\');\n
32
34
 
33
35
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/ext\');\ntest(\'lib/ext/date.js should pass jshint\', function() { \n ok(true, \'lib/ext/date.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/ext/date.jshint.js");
34
36
 
35
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/initializers\');\ntest(\'lib/initializers/data_adapter.js should pass jshint\', function() { \n ok(true, \'lib/initializers/data_adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/initializers/data_adapter.jshint.js");
37
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/initializers\');\ntest(\'lib/initializers/data-adapter.js should pass jshint\', function() { \n ok(true, \'lib/initializers/data-adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/initializers/data-adapter.jshint.js");
36
38
 
37
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/initializers\');\ntest(\'lib/initializers/store.js should pass jshint\', function() { \n ok(true, \'lib/initializers/store.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/initializers/store.jshint.js");
39
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/initializers\');\ntest(\'lib/initializers/store-injections.js should pass jshint\', function() { \n ok(true, \'lib/initializers/store-injections.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/initializers/store-injections.jshint.js");
38
40
 
39
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/initializers\');\ntest(\'lib/initializers/store_injections.js should pass jshint\', function() { \n ok(true, \'lib/initializers/store_injections.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/initializers/store_injections.jshint.js");
41
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/initializers\');\ntest(\'lib/initializers/store.js should pass jshint\', function() { \n ok(true, \'lib/initializers/store.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/initializers/store.jshint.js");
40
42
 
41
43
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/initializers\');\ntest(\'lib/initializers/transforms.js should pass jshint\', function() { \n ok(true, \'lib/initializers/transforms.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/initializers/transforms.jshint.js");
42
44
 
@@ -44,23 +46,25 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib\');\n
44
46
 
45
47
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib\');\ntest(\'lib/serializers.js should pass jshint\', function() { \n ok(true, \'lib/serializers.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/serializers.jshint.js");
46
48
 
47
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/serializers\');\ntest(\'lib/serializers/embedded_records_mixin.js should pass jshint\', function() { \n ok(true, \'lib/serializers/embedded_records_mixin.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/serializers/embedded_records_mixin.jshint.js");
49
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/serializers\');\ntest(\'lib/serializers/embedded-records-mixin.js should pass jshint\', function() { \n ok(true, \'lib/serializers/embedded-records-mixin.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/serializers/embedded-records-mixin.jshint.js");
48
50
 
49
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/serializers\');\ntest(\'lib/serializers/json_serializer.js should pass jshint\', function() { \n ok(true, \'lib/serializers/json_serializer.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/serializers/json_serializer.jshint.js");
51
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/serializers\');\ntest(\'lib/serializers/json-serializer.js should pass jshint\', function() { \n ok(true, \'lib/serializers/json-serializer.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/serializers/json-serializer.jshint.js");
50
52
 
51
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/serializers\');\ntest(\'lib/serializers/rest_serializer.js should pass jshint\', function() { \n ok(true, \'lib/serializers/rest_serializer.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/serializers/rest_serializer.jshint.js");
53
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/serializers\');\ntest(\'lib/serializers/rest-serializer.js should pass jshint\', function() { \n ok(true, \'lib/serializers/rest-serializer.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/serializers/rest-serializer.jshint.js");
52
54
 
53
55
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib\');\ntest(\'lib/setup-container.js should pass jshint\', function() { \n ok(true, \'lib/setup-container.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/setup-container.jshint.js");
54
56
 
55
57
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/adapter.js should pass jshint\', function() { \n ok(true, \'lib/system/adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/adapter.jshint.js");
56
58
 
57
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/container_proxy.js should pass jshint\', function() { \n ok(true, \'lib/system/container_proxy.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/container_proxy.jshint.js");
59
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/container-proxy.js should pass jshint\', function() { \n ok(true, \'lib/system/container-proxy.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/container-proxy.jshint.js");
58
60
 
59
61
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/debug.js should pass jshint\', function() { \n ok(true, \'lib/system/debug.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/debug.jshint.js");
60
62
 
61
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/debug\');\ntest(\'lib/system/debug/debug_adapter.js should pass jshint\', function() { \n ok(true, \'lib/system/debug/debug_adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/debug/debug_adapter.jshint.js");
63
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/debug\');\ntest(\'lib/system/debug/debug-adapter.js should pass jshint\', function() { \n ok(true, \'lib/system/debug/debug-adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/debug/debug-adapter.jshint.js");
64
+
65
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/debug\');\ntest(\'lib/system/debug/debug-info.js should pass jshint\', function() { \n ok(true, \'lib/system/debug/debug-info.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/debug/debug-info.jshint.js");
62
66
 
63
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/debug\');\ntest(\'lib/system/debug/debug_info.js should pass jshint\', function() { \n ok(true, \'lib/system/debug/debug_info.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/debug/debug_info.jshint.js");
67
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/many-array.js should pass jshint\', function() { \n ok(true, \'lib/system/many-array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/many-array.jshint.js");
64
68
 
65
69
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/map.js should pass jshint\', function() { \n ok(true, \'lib/system/map.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/map.jshint.js");
66
70
 
@@ -76,35 +80,35 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/syste
76
80
 
77
81
  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");
78
82
 
79
- 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");
83
+ 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");
80
84
 
81
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/record_array_manager.js should pass jshint\', function() { \n ok(true, \'lib/system/record_array_manager.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/record_array_manager.jshint.js");
85
+ 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");
82
86
 
83
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/record_arrays.js should pass jshint\', function() { \n ok(true, \'lib/system/record_arrays.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/record_arrays.jshint.js");
87
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/record-array-manager.js should pass jshint\', function() { \n ok(true, \'lib/system/record-array-manager.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/record-array-manager.jshint.js");
84
88
 
85
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/record_arrays\');\ntest(\'lib/system/record_arrays/adapter_populated_record_array.js should pass jshint\', function() { \n ok(true, \'lib/system/record_arrays/adapter_populated_record_array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/record_arrays/adapter_populated_record_array.jshint.js");
89
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/record-arrays.js should pass jshint\', function() { \n ok(true, \'lib/system/record-arrays.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/record-arrays.jshint.js");
86
90
 
87
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/record_arrays\');\ntest(\'lib/system/record_arrays/filtered_record_array.js should pass jshint\', function() { \n ok(true, \'lib/system/record_arrays/filtered_record_array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/record_arrays/filtered_record_array.jshint.js");
91
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/record-arrays\');\ntest(\'lib/system/record-arrays/adapter-populated-record-array.js should pass jshint\', function() { \n ok(true, \'lib/system/record-arrays/adapter-populated-record-array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/record-arrays/adapter-populated-record-array.jshint.js");
88
92
 
89
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/record_arrays\');\ntest(\'lib/system/record_arrays/many_array.js should pass jshint\', function() { \n ok(true, \'lib/system/record_arrays/many_array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/record_arrays/many_array.jshint.js");
93
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/record-arrays\');\ntest(\'lib/system/record-arrays/filtered-record-array.js should pass jshint\', function() { \n ok(true, \'lib/system/record-arrays/filtered-record-array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/record-arrays/filtered-record-array.jshint.js");
90
94
 
91
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/record_arrays\');\ntest(\'lib/system/record_arrays/record_array.js should pass jshint\', function() { \n ok(true, \'lib/system/record_arrays/record_array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/record_arrays/record_array.jshint.js");
95
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/record-arrays\');\ntest(\'lib/system/record-arrays/record-array.js should pass jshint\', function() { \n ok(true, \'lib/system/record-arrays/record-array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/record-arrays/record-array.jshint.js");
92
96
 
93
97
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/relationship-meta.js should pass jshint\', function() { \n ok(true, \'lib/system/relationship-meta.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationship-meta.jshint.js");
94
98
 
95
99
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/relationships.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships.jshint.js");
96
100
 
97
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/relationships\');\ntest(\'lib/system/relationships/belongs_to.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships/belongs_to.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships/belongs_to.jshint.js");
101
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/relationships\');\ntest(\'lib/system/relationships/belongs-to.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships/belongs-to.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships/belongs-to.jshint.js");
98
102
 
99
103
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/relationships\');\ntest(\'lib/system/relationships/ext.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships/ext.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships/ext.jshint.js");
100
104
 
101
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/relationships\');\ntest(\'lib/system/relationships/has_many.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships/has_many.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships/has_many.jshint.js");
105
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/relationships\');\ntest(\'lib/system/relationships/has-many.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships/has-many.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships/has-many.jshint.js");
102
106
 
103
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/relationships/state\');\ntest(\'lib/system/relationships/state/belongs_to.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships/state/belongs_to.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships/state/belongs_to.jshint.js");
107
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/relationships/state\');\ntest(\'lib/system/relationships/state/belongs-to.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships/state/belongs-to.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships/state/belongs-to.jshint.js");
104
108
 
105
109
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/relationships/state\');\ntest(\'lib/system/relationships/state/create.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships/state/create.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships/state/create.jshint.js");
106
110
 
107
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/relationships/state\');\ntest(\'lib/system/relationships/state/has_many.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships/state/has_many.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships/state/has_many.jshint.js");
111
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/relationships/state\');\ntest(\'lib/system/relationships/state/has-many.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships/state/has-many.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships/state/has-many.jshint.js");
108
112
 
109
113
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/relationships/state\');\ntest(\'lib/system/relationships/state/relationship.js should pass jshint\', function() { \n ok(true, \'lib/system/relationships/state/relationship.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/relationships/state/relationship.jshint.js");
110
114
 
@@ -114,6 +118,12 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/syste
114
118
 
115
119
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system\');\ntest(\'lib/system/store.js should pass jshint\', function() { \n ok(true, \'lib/system/store.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/store.jshint.js");
116
120
 
121
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/store\');\ntest(\'lib/system/store/common.js should pass jshint\', function() { \n ok(true, \'lib/system/store/common.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/store/common.jshint.js");
122
+
123
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/store\');\ntest(\'lib/system/store/finders.js should pass jshint\', function() { \n ok(true, \'lib/system/store/finders.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/store/finders.jshint.js");
124
+
125
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/system/store\');\ntest(\'lib/system/store/serializers.js should pass jshint\', function() { \n ok(true, \'lib/system/store/serializers.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/system/store/serializers.jshint.js");
126
+
117
127
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib\');\ntest(\'lib/transforms.js should pass jshint\', function() { \n ok(true, \'lib/transforms.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/transforms.jshint.js");
118
128
 
119
129
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/transforms\');\ntest(\'lib/transforms/base.js should pass jshint\', function() { \n ok(true, \'lib/transforms/base.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/transforms/base.jshint.js");
@@ -126,246 +136,262 @@ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/trans
126
136
 
127
137
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - lib/transforms\');\ntest(\'lib/transforms/string.js should pass jshint\', function() { \n ok(true, \'lib/transforms/string.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/lib/transforms/string.jshint.js");
128
138
 
129
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/find_all_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/find_all_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/find_all_test.jshint.js");
139
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/find-all-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/find-all-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/find-all-test.jshint.js");
140
+
141
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/find-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/find-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/find-test.jshint.js");
130
142
 
131
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/find_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/find_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/find_test.jshint.js");
143
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/fixture-adapter-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/fixture-adapter-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/fixture-adapter-test.jshint.js");
132
144
 
133
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/fixture_adapter_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/fixture_adapter_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/fixture_adapter_test.jshint.js");
145
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/queries-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/queries-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/queries-test.jshint.js");
134
146
 
135
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/queries_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/queries_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/queries_test.jshint.js");
147
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/record-persistence-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/record-persistence-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/record-persistence-test.jshint.js");
136
148
 
137
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/record_persistence_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/record_persistence_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/record_persistence_test.jshint.js");
149
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/rest-adapter-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/rest-adapter-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/rest-adapter-test.jshint.js");
138
150
 
139
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/rest_adapter_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/rest_adapter_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/rest_adapter_test.jshint.js");
151
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/store-adapter-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/store-adapter-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/store-adapter-test.jshint.js");
140
152
 
141
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/adapter\');\ntest(\'tests/integration/adapter/store_adapter_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/adapter/store_adapter_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/adapter/store_adapter_test.jshint.js");
153
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/all-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/all-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/all-test.jshint.js");
142
154
 
143
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/all_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/all_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/all_test.jshint.js");
155
+ 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");
144
156
 
145
- 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");
157
+ 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");
146
158
 
147
- 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");
159
+ 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");
148
160
 
149
- 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");
161
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/filter-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/filter-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/filter-test.jshint.js");
150
162
 
151
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/filter_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/filter_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/filter_test.jshint.js");
163
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/inverse-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/inverse-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/inverse-test.jshint.js");
152
164
 
153
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/inverse_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/inverse_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/inverse_test.jshint.js");
165
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/lifecycle-hooks-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/lifecycle-hooks-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/lifecycle-hooks-test.jshint.js");
154
166
 
155
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/lifecycle_hooks_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/lifecycle_hooks_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/lifecycle_hooks_test.jshint.js");
167
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/multiple_stores_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/multiple_stores_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/multiple_stores_test.jshint.js");
156
168
 
157
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/record_array_manager_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/record_array_manager_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/record_array_manager_test.jshint.js");
169
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/record-array-manager-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/record-array-manager-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/record-array-manager-test.jshint.js");
158
170
 
159
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/records\');\ntest(\'tests/integration/records/collection_save_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/records/collection_save_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/records/collection_save_test.jshint.js");
171
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/records\');\ntest(\'tests/integration/records/collection-save-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/records/collection-save-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/records/collection-save-test.jshint.js");
160
172
 
161
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/records\');\ntest(\'tests/integration/records/delete_record_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/records/delete_record_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/records/delete_record_test.jshint.js");
173
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/records\');\ntest(\'tests/integration/records/delete-record-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/records/delete-record-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/records/delete-record-test.jshint.js");
162
174
 
163
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/records\');\ntest(\'tests/integration/records/reload_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/records/reload_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/records/reload_test.jshint.js");
175
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/records\');\ntest(\'tests/integration/records/reload-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/records/reload-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/records/reload-test.jshint.js");
164
176
 
165
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/records\');\ntest(\'tests/integration/records/save_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/records/save_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/records/save_test.jshint.js");
177
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/records\');\ntest(\'tests/integration/records/save-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/records/save-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/records/save-test.jshint.js");
166
178
 
167
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/records\');\ntest(\'tests/integration/records/unload_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/records/unload_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/records/unload_test.jshint.js");
179
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/records\');\ntest(\'tests/integration/records/unload-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/records/unload-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/records/unload-test.jshint.js");
168
180
 
169
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/belongs_to_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/belongs_to_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/belongs_to_test.jshint.js");
181
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/belongs-to-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/belongs-to-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/belongs-to-test.jshint.js");
170
182
 
171
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/has_many_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/has_many_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/has_many_test.jshint.js");
183
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/has-many-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/has-many-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/has-many-test.jshint.js");
172
184
 
173
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/inverse_relationships_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/inverse_relationships_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/inverse_relationships_test.jshint.js");
185
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/inverse-relationships-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/inverse-relationships-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/inverse-relationships-test.jshint.js");
174
186
 
175
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/many_to_many_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/many_to_many_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/many_to_many_test.jshint.js");
187
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/many-to-many-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/many-to-many-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/many-to-many-test.jshint.js");
176
188
 
177
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/one_to_many_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/one_to_many_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/one_to_many_test.jshint.js");
189
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/one-to-many-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/one-to-many-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/one-to-many-test.jshint.js");
178
190
 
179
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/one_to_one_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/one_to_one_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/one_to_one_test.jshint.js");
191
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/one-to-one-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/one-to-one-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/one-to-one-test.jshint.js");
180
192
 
181
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/serializers\');\ntest(\'tests/integration/serializers/embedded_records_mixin_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/serializers/embedded_records_mixin_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/serializers/embedded_records_mixin_test.jshint.js");
193
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/polymorphic-mixins-belongs-to-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/polymorphic-mixins-belongs-to-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/polymorphic-mixins-belongs-to-test.jshint.js");
182
194
 
183
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/serializers\');\ntest(\'tests/integration/serializers/json_serializer_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/serializers/json_serializer_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/serializers/json_serializer_test.jshint.js");
195
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/relationships\');\ntest(\'tests/integration/relationships/polymorphic-mixins-has-many-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/relationships/polymorphic-mixins-has-many-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/relationships/polymorphic-mixins-has-many-test.jshint.js");
184
196
 
185
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/serializers\');\ntest(\'tests/integration/serializers/rest_serializer_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/serializers/rest_serializer_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/serializers/rest_serializer_test.jshint.js");
197
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/serializers\');\ntest(\'tests/integration/serializers/embedded-records-mixin-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/serializers/embedded-records-mixin-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/serializers/embedded-records-mixin-test.jshint.js");
198
+
199
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/serializers\');\ntest(\'tests/integration/serializers/json-serializer-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/serializers/json-serializer-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/serializers/json-serializer-test.jshint.js");
200
+
201
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration/serializers\');\ntest(\'tests/integration/serializers/rest-serializer-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/serializers/rest-serializer-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/serializers/rest-serializer-test.jshint.js");
186
202
 
187
203
  eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/setup-container-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/setup-container-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/setup-container-test.jshint.js");
188
204
 
189
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/snapshot_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/snapshot_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/snapshot_test.jshint.js");
205
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/snapshot-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/snapshot-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/snapshot-test.jshint.js");
206
+
207
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/store-test.js should pass jshint\', function() { \n ok(true, \'tests/integration/store-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/store-test.jshint.js");
208
+
209
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/adapter-populated-record-array-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/adapter-populated-record-array-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/adapter-populated-record-array-test.jshint.js");
210
+
211
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/adapters/rest-adapter\');\ntest(\'tests/unit/adapters/rest-adapter/ajax.js should pass jshint\', function() { \n ok(true, \'tests/unit/adapters/rest-adapter/ajax.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/adapters/rest-adapter/ajax.jshint.js");
212
+
213
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/adapters/rest-adapter\');\ntest(\'tests/unit/adapters/rest-adapter/group-records-for-find-many-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/adapters/rest-adapter/group-records-for-find-many-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/adapters/rest-adapter/group-records-for-find-many-test.jshint.js");
214
+
215
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/adapters/rest-adapter\');\ntest(\'tests/unit/adapters/rest-adapter/path-for-type-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/adapters/rest-adapter/path-for-type-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/adapters/rest-adapter/path-for-type-test.jshint.js");
190
216
 
191
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/integration\');\ntest(\'tests/integration/store_test.js should pass jshint\', function() { \n ok(true, \'tests/integration/store_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/integration/store_test.jshint.js");
217
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/debug-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/debug-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/debug-test.jshint.js");
192
218
 
193
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/adapter_populated_record_array_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/adapter_populated_record_array_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/adapter_populated_record_array_test.jshint.js");
219
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/many-array-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/many-array-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/many-array-test.jshint.js");
194
220
 
195
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/adapters/rest_adapter\');\ntest(\'tests/unit/adapters/rest_adapter/ajax.js should pass jshint\', function() { \n ok(true, \'tests/unit/adapters/rest_adapter/ajax.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/adapters/rest_adapter/ajax.jshint.js");
221
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/model-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model-test.jshint.js");
196
222
 
197
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/adapters/rest_adapter\');\ntest(\'tests/unit/adapters/rest_adapter/group_records_for_find_many_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/adapters/rest_adapter/group_records_for_find_many_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/adapters/rest_adapter/group_records_for_find_many_test.jshint.js");
223
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model\');\ntest(\'tests/unit/model/errors-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/errors-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/errors-test.jshint.js");
198
224
 
199
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/adapters/rest_adapter\');\ntest(\'tests/unit/adapters/rest_adapter/path_for_type_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/adapters/rest_adapter/path_for_type_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/adapters/rest_adapter/path_for_type_test.jshint.js");
225
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model\');\ntest(\'tests/unit/model/lifecycle-callbacks-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/lifecycle-callbacks-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/lifecycle-callbacks-test.jshint.js");
200
226
 
201
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/debug_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/debug_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/debug_test.jshint.js");
227
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model\');\ntest(\'tests/unit/model/merge-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/merge-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/merge-test.jshint.js");
202
228
 
203
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/many_array_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/many_array_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/many_array_test.jshint.js");
229
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model\');\ntest(\'tests/unit/model/relationships-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/relationships-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/relationships-test.jshint.js");
204
230
 
205
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model\');\ntest(\'tests/unit/model/errors_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/errors_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/errors_test.jshint.js");
231
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model/relationships\');\ntest(\'tests/unit/model/relationships/belongs-to-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/relationships/belongs-to-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/relationships/belongs-to-test.jshint.js");
206
232
 
207
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model\');\ntest(\'tests/unit/model/lifecycle_callbacks_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/lifecycle_callbacks_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/lifecycle_callbacks_test.jshint.js");
233
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model/relationships\');\ntest(\'tests/unit/model/relationships/has-many-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/relationships/has-many-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/relationships/has-many-test.jshint.js");
208
234
 
209
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model\');\ntest(\'tests/unit/model/merge_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/merge_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/merge_test.jshint.js");
235
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model/relationships\');\ntest(\'tests/unit/model/relationships/record-array-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/relationships/record-array-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/relationships/record-array-test.jshint.js");
210
236
 
211
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model/relationships\');\ntest(\'tests/unit/model/relationships/belongs_to_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/relationships/belongs_to_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/relationships/belongs_to_test.jshint.js");
237
+ 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");
212
238
 
213
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model/relationships\');\ntest(\'tests/unit/model/relationships/has_many_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/relationships/has_many_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/relationships/has_many_test.jshint.js");
239
+ 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");
214
240
 
215
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model/relationships\');\ntest(\'tests/unit/model/relationships/record_array_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/relationships/record_array_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/relationships/record_array_test.jshint.js");
241
+ 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");
216
242
 
217
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/model\');\ntest(\'tests/unit/model/relationships_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model/relationships_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model/relationships_test.jshint.js");
243
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/states-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/states-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/states-test.jshint.js");
218
244
 
219
- 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");
245
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/adapter-interop-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/adapter-interop-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/adapter-interop-test.jshint.js");
220
246
 
221
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/model_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/model_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/model_test.jshint.js");
247
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/create-record-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/create-record-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/create-record-test.jshint.js");
222
248
 
223
- 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");
249
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/has_record_for_id_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/has_record_for_id_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/has_record_for_id_test.jshint.js");
224
250
 
225
- 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");
251
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/metadata-for-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/metadata-for-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/metadata-for-test.jshint.js");
226
252
 
227
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit\');\ntest(\'tests/unit/states_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/states_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/states_test.jshint.js");
253
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/model-for-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/model-for-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/model-for-test.jshint.js");
228
254
 
229
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/adapter_interop_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/adapter_interop_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/adapter_interop_test.jshint.js");
255
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/push-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/push-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/push-test.jshint.js");
230
256
 
231
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/create_record_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/create_record_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/create_record_test.jshint.js");
257
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/serializer-for-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/serializer-for-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/serializer-for-test.jshint.js");
232
258
 
233
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/metadata_for_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/metadata_for_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/metadata_for_test.jshint.js");
259
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/unload-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/unload-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/unload-test.jshint.js");
234
260
 
235
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/model_for_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/model_for_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/model_for_test.jshint.js");
261
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/transform\');\ntest(\'tests/unit/transform/boolean-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/transform/boolean-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/transform/boolean-test.jshint.js");
236
262
 
237
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/push_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/push_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/push_test.jshint.js");
263
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/transform\');\ntest(\'tests/unit/transform/date-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/transform/date-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/transform/date-test.jshint.js");
238
264
 
239
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/serializer_for_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/serializer_for_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/serializer_for_test.jshint.js");
265
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/transform\');\ntest(\'tests/unit/transform/number-test.js should pass jshint\', function() { \n ok(true, \'tests/unit/transform/number-test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/transform/number-test.jshint.js");
240
266
 
241
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/store\');\ntest(\'tests/unit/store/unload_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/store/unload_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/store/unload_test.jshint.js");
267
+ 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");
242
268
 
243
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/transform\');\ntest(\'tests/unit/transform/boolean_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/transform/boolean_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/transform/boolean_test.jshint.js");
269
+ 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({ 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");
244
270
 
245
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/transform\');\ntest(\'tests/unit/transform/date_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/transform/date_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/transform/date_test.jshint.js");
271
+ eval("(function() {var Person, store;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/find - Finding Records\", {\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\n teardown: function() {\n run(store, \'destroy\');\n }\n});\n\ntest(\"It raises an assertion when no type is passed\", function() {\n store = createStore();\n\n expectAssertion(function() {\n store.find();\n }, \"You need to pass a type to the store\'s find method\");\n});\n\ntest(\"It raises an assertion when `undefined` is passed as id (#1705)\", function() {\n store = createStore();\n\n expectAssertion(function() {\n store.find(Person, undefined);\n }, \"You may not pass `undefined` as id to the store\'s find method\");\n\n expectAssertion(function() {\n store.find(Person, null);\n }, \"You may not pass `null` as id to the store\'s find method\");\n});\n\ntest(\"When a single record is requested, the adapter\'s find method should be called unless it\'s loaded.\", function() {\n expect(2);\n\n var count = 0;\n\n store = createStore({ adapter: DS.Adapter.extend({\n find: function(store, type, id, snapshot) {\n equal(type, Person, \"the find method is called with the correct type\");\n equal(count, 0, \"the find method is only called once\");\n\n count++;\n return { id: 1, name: \"Braaaahm Dale\" };\n }\n })\n });\n\n run(function() {\n store.find(Person, 1);\n store.find(Person, 1);\n });\n});\n\ntest(\"When a single record is requested multiple times, all .find() calls are resolved after the promise is resolved\", function() {\n var deferred = Ember.RSVP.defer();\n\n store = createStore({ adapter: DS.Adapter.extend({\n find: function(store, type, id, snapshot) {\n return deferred.promise;\n }\n })\n });\n\n run(function() {\n store.find(Person, 1).then(async(function(person) {\n equal(person.get(\'id\'), \"1\");\n equal(person.get(\'name\'), \"Braaaahm Dale\");\n\n stop();\n deferred.promise.then(function(value) {\n start();\n ok(true, \'expected deferred.promise to fulfill\');\n }, function(reason) {\n start();\n ok(false, \'expected deferred.promise to fulfill, but rejected\');\n });\n }));\n });\n\n run(function() {\n store.find(Person, 1).then(async(function(post) {\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Braaaahm Dale\");\n\n stop();\n deferred.promise.then(function(value) {\n start();\n ok(true, \'expected deferred.promise to fulfill\');\n }, function(reason) {\n start();\n ok(false, \'expected deferred.promise to fulfill, but rejected\');\n });\n\n }));\n });\n\n Ember.run(function() {\n deferred.resolve({ id: 1, name: \"Braaaahm Dale\" });\n });\n});\n\ntest(\"When a single record is requested, and the promise is rejected, .find() is rejected.\", function() {\n store = createStore({ adapter: DS.Adapter.extend({\n find: function(store, type, id, snapshot) {\n return Ember.RSVP.reject();\n }\n })\n });\n\n run(function() {\n store.find(Person, 1).then(null, async(function(reason) {\n ok(true, \"The rejection handler was called\");\n }));\n });\n});\n\ntest(\"When a single record is requested, and the promise is rejected, the record should be unloaded.\", function() {\n expect(2);\n\n store = createStore({ adapter: DS.Adapter.extend({\n find: function(store, type, id, snapshot) {\n return Ember.RSVP.reject();\n }\n })\n });\n\n run(function() {\n store.find(Person, 1).then(null, async(function(reason) {\n ok(true, \"The rejection handler was called\");\n }));\n });\n\n ok(!store.hasRecordForId(Person, 1), \"The record has been unloaded\");\n});\n})();//# sourceURL=ember-data/integration/adapter/find-test.js");
246
272
 
247
- eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - tests/unit/transform\');\ntest(\'tests/unit/transform/number_test.js should pass jshint\', function() { \n ok(true, \'tests/unit/transform/number_test.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/tests/unit/transform/number_test.jshint.js");
273
+ eval("(function() {var get = Ember.get;\nvar env, Person, Phone;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/fixture_adapter - DS.FixtureAdapter\", {\n setup: function() {\n Person = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n\n height: DS.attr(\'number\'),\n\n phones: DS.hasMany(\'phone\', { async: true })\n });\n\n Phone = DS.Model.extend({\n person: DS.belongsTo(\'person\', { async: true })\n });\n\n env = setupStore({ person: Person, phone: Phone, adapter: DS.FixtureAdapter });\n env.adapter.simulateRemoteResponse = true;\n env.adapter.latency = 50;\n\n // Enable setTimeout.\n Ember.testing = false;\n\n Person.FIXTURES = [];\n Phone.FIXTURES = [];\n },\n teardown: function() {\n Ember.testing = true;\n\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"should load data for a type asynchronously when it is requested\", function() {\n Person.FIXTURES = [{\n id: \'wycats\',\n firstName: \"Yehuda\",\n lastName: \"Katz\",\n\n height: 65\n },\n\n {\n id: \'ebryn\',\n firstName: \"Erik\",\n lastName: \"Brynjolffsosysdfon\",\n\n height: 70,\n phones: [1, 2]\n }];\n\n Phone.FIXTURES = [{\n id: 1,\n person: \'ebryn\'\n }, {\n id: 2,\n person: \'ebryn\'\n }];\n\n run(env.store, \'find\', \'person\', \'ebryn\').then(async(function(ebryn) {\n equal(get(ebryn, \'isLoaded\'), true, \"data loads asynchronously\");\n equal(get(ebryn, \'height\'), 70, \"data from fixtures is loaded correctly\");\n\n return Ember.RSVP.hash({ ebryn: ebryn, wycats: env.store.find(\'person\', \'wycats\') });\n }, 1000)).then(async(function(records) {\n equal(get(records.wycats, \'isLoaded\'), true, \"subsequent requests for records are returned asynchronously\");\n equal(get(records.wycats, \'height\'), 65, \"subsequent requested records contain correct information\");\n\n return get(records.ebryn, \'phones\');\n }, 1000)).then(async(function(phones) {\n equal(get(phones, \'length\'), 2, \"relationships from fixtures is loaded correctly\");\n }, 1000));\n});\n\ntest(\"should load data asynchronously at the end of the runloop when simulateRemoteResponse is false\", function() {\n Person.FIXTURES = [{\n id: \'wycats\',\n firstName: \"Yehuda\"\n }];\n\n env.adapter.simulateRemoteResponse = false;\n\n var wycats;\n\n Ember.run(function() {\n env.store.find(\'person\', \'wycats\').then(function(person) {\n wycats = person;\n });\n });\n\n ok(get(wycats, \'isLoaded\'), \'isLoaded is true after runloop finishes\');\n equal(get(wycats, \'firstName\'), \'Yehuda\', \'record properties are defined after runloop finishes\');\n});\n\ntest(\"should create record asynchronously when it is committed\", function() {\n var paul;\n equal(Person.FIXTURES.length, 0, \"Fixtures is empty\");\n\n run(function() {\n paul = env.store.createRecord(\'person\', { firstName: \'Paul\', lastName: \'Chavard\', height: 70 });\n });\n\n paul.on(\'didCreate\', async(function() {\n equal(get(paul, \'isNew\'), false, \"data loads asynchronously\");\n equal(get(paul, \'isDirty\'), false, \"data loads asynchronously\");\n equal(get(paul, \'height\'), 70, \"data from fixtures is saved correctly\");\n\n equal(Person.FIXTURES.length, 1, \"Record added to FIXTURES\");\n\n var fixture = Person.FIXTURES[0];\n\n ok(typeof fixture.id === \'string\', \"The fixture has an ID generated for it\");\n equal(fixture.firstName, \'Paul\');\n equal(fixture.lastName, \'Chavard\');\n equal(fixture.height, 70);\n }));\n\n paul.save();\n});\n\ntest(\"should update record asynchronously when it is committed\", function() {\n equal(Person.FIXTURES.length, 0, \"Fixtures is empty\");\n\n var paul = env.store.push(\'person\', { id: 1, firstName: \'Paul\', lastName: \'Chavard\', height: 70 });\n\n paul.set(\'height\', 80);\n\n paul.on(\'didUpdate\', async(function() {\n equal(get(paul, \'isDirty\'), false, \"data loads asynchronously\");\n equal(get(paul, \'height\'), 80, \"data from fixtures is saved correctly\");\n\n equal(Person.FIXTURES.length, 1, \"Record FIXTURES updated\");\n\n var fixture = Person.FIXTURES[0];\n\n equal(fixture.firstName, \'Paul\');\n equal(fixture.lastName, \'Chavard\');\n equal(fixture.height, 80);\n }, 1000));\n\n paul.save();\n});\n\ntest(\"should delete record asynchronously when it is committed\", function() {\n stop();\n\n var timer = setTimeout(function() {\n start();\n ok(false, \"timeout exceeded waiting for fixture data\");\n }, 1000);\n\n equal(Person.FIXTURES.length, 0, \"Fixtures empty\");\n\n var paul = env.store.push(\'person\', { id: \'paul\', firstName: \'Paul\', lastName: \'Chavard\', height: 70 });\n\n paul.save().then(function() {\n paul.deleteRecord();\n paul.save();\n });\n\n paul.on(\'didDelete\', function() {\n clearTimeout(timer);\n start();\n\n equal(get(paul, \'isDeleted\'), true, \"data deleted asynchronously\");\n equal(get(paul, \'isDirty\'), false, \"data deleted asynchronously\");\n\n equal(Person.FIXTURES.length, 0, \"Record removed from FIXTURES\");\n });\n\n});\n\ntest(\"should follow isUpdating semantics\", function() {\n var timer = setTimeout(function() {\n start();\n ok(false, \"timeout exceeded waiting for fixture data\");\n }, 1000);\n\n stop();\n\n Person.FIXTURES = [{\n id: \"twinturbo\",\n firstName: \"Adam\",\n lastName: \"Hawkins\",\n height: 65\n }];\n\n var result = env.store.findAll(\'person\');\n\n result.then(function(all) {\n clearTimeout(timer);\n start();\n equal(get(all, \'isUpdating\'), false, \"isUpdating is set when it shouldn\'t be\");\n });\n});\n\ntest(\"should coerce integer ids into string\", function() {\n Person.FIXTURES = [{\n id: 1,\n firstName: \"Adam\",\n lastName: \"Hawkins\",\n height: 65\n }];\n\n env.store.find(\'person\', 1).then(async(function(result) {\n strictEqual(get(result, \'id\'), \"1\", \"should load integer model id as string\");\n }));\n});\n\ntest(\"should coerce belongsTo ids into string\", function() {\n Person.FIXTURES = [{\n id: 1,\n firstName: \"Adam\",\n lastName: \"Hawkins\",\n\n phones: [1]\n }];\n\n Phone.FIXTURES = [{\n id: 1,\n person: 1\n }];\n\n env.store.find(\'phone\', 1).then(async(function(result) {\n get(result, \'person\').then(async(function(person) {\n strictEqual(get(person, \'id\'), \"1\", \"should load integer belongsTo id as string\");\n strictEqual(get(person, \'firstName\'), \"Adam\", \"resolved relationship with an integer belongsTo id\");\n }));\n }));\n});\n\ntest(\"only coerce belongsTo ids to string if id is defined and not null\", function() {\n Person.FIXTURES = [];\n\n Phone.FIXTURES = [{\n id: 1\n }];\n\n env.store.find(\'phone\', 1).then(async(function(phone) {\n phone.get(\'person\').then(async(function(person) {\n equal(person, null);\n }));\n }));\n});\n\ntest(\"should throw if ids are not defined in the FIXTURES\", function() {\n Person.FIXTURES = [{\n firstName: \"Adam\",\n lastName: \"Hawkins\",\n height: 65\n }];\n\n raises(function() {\n run(function() {\n env.store.find(\'person\', 1);\n });\n }, /the id property must be defined as a number or string for fixture/);\n});\n\ntest(\"0 is an acceptable ID in FIXTURES\", function() {\n Person.FIXTURES = [{\n id: 0\n }];\n\n env.store.find(\'person\', 0).then(async(function() {\n ok(true, \"0 is an acceptable ID, so no exception was thrown\");\n }), function() {\n ok(false, \"should not get here\");\n });\n});\n\nasyncTest(\"copies fixtures instead of passing the direct reference\", function() {\n var returnedFixture;\n\n expect(2);\n\n Person.FIXTURES = [{\n id: \'1\',\n firstName: \'Katie\',\n lastName: \'Gengler\'\n }];\n\n var PersonAdapter = DS.FixtureAdapter.extend({\n find: function(store, type, id, snapshot) {\n return this._super(store, type, id).then(function(fixture) {\n return returnedFixture = fixture;\n });\n }\n });\n\n Ember.run(function() {\n env.registry.register(\'adapter:person\', PersonAdapter);\n });\n\n env.store.find(\'person\', 1).then(function() {\n start();\n ok(Person.FIXTURES[0] !== returnedFixture, \'returnedFixture does not have object identity with defined fixture\');\n deepEqual(Person.FIXTURES[0], returnedFixture);\n }, function(err) {\n ok(false, \'got error\' + err);\n });\n});\n\ntest(\"should save hasMany records\", function() {\n var createPhone, savePerson, assertPersonPhones;\n\n expect(3);\n\n Person.FIXTURES = [{ id: \'tomjerry\', firstName: \"Tom\", lastName: \"Jerry\", height: 3 }];\n\n createPhone = async(function(tom) {\n env.store.createRecord(\'phone\', { person: tom });\n\n return tom.get(\'phones\').then(async(function(p) {\n equal(p.get(\'length\'), 1, \"hasMany relationships are created in the store\");\n return tom;\n }));\n });\n\n savePerson = async(function(tom) {\n return tom.save();\n });\n\n assertPersonPhones = async(function(record) {\n var phonesPromise = record.get(\'phones\');\n\n return phonesPromise.then(async(function(phones) {\n equal(phones.get(\'length\'), 1, \"hasMany relationship saved correctly\");\n }));\n });\n\n var ensureFixtureAdapterDoesNotLeak = async(function() {\n env.store.destroy();\n env = setupStore({ person: Person, phone: Phone, adapter: DS.FixtureAdapter });\n return env.store.find(\'phone\').then(async(function(phones) {\n equal(phones.get(\'length\'), 0, \"the fixture adapter should not leak after destroying the store\");\n }));\n });\n env.store.find(\'person\', \'tomjerry\').then(createPhone)\n .then(savePerson)\n .then(assertPersonPhones)\n .then(ensureFixtureAdapterDoesNotLeak);\n\n});\n})();//# sourceURL=ember-data/integration/adapter/fixture-adapter-test.js");
248
274
 
249
- 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");
275
+ eval("(function() {var get = Ember.get;\nvar Person, env, store, adapter;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/queries - Queries\", {\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 env = setupStore({ person: Person });\n store = env.store;\n adapter = env.adapter;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"When a query is made, the adapter should receive a record array it can populate with the results of the query.\", function() {\n adapter.findQuery = function(store, type, query, recordArray) {\n equal(type, Person, \"the find method is called with the correct type\");\n\n return Ember.RSVP.resolve([{ id: 1, name: \"Peter Wagenet\" }, { id: 2, name: \"Brohuda Katz\" }]);\n };\n\n store.find(\'person\', { page: 1 }).then(async(function(queryResults) {\n equal(get(queryResults, \'length\'), 2, \"the record array has a length of 2 after the results are loaded\");\n equal(get(queryResults, \'isLoaded\'), true, \"the record array\'s `isLoaded` property should be true\");\n\n equal(queryResults.objectAt(0).get(\'name\'), \"Peter Wagenet\", \"the first record is \'Peter Wagenet\'\");\n equal(queryResults.objectAt(1).get(\'name\'), \"Brohuda Katz\", \"the second record is \'Brohuda Katz\'\");\n }));\n});\n})();//# sourceURL=ember-data/integration/adapter/queries-test.js");
250
276
 
251
- 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({ 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");
277
+ 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");
252
278
 
253
- eval("(function() {var Person, store;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/find - Finding Records\", {\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\n teardown: function() {\n run(store, \'destroy\');\n }\n});\n\ntest(\"It raises an assertion when no type is passed\", function() {\n store = createStore();\n\n expectAssertion(function() {\n store.find();\n }, \"You need to pass a type to the store\'s find method\");\n});\n\ntest(\"It raises an assertion when `undefined` is passed as id (#1705)\", function() {\n store = createStore();\n\n expectAssertion(function() {\n store.find(Person, undefined);\n }, \"You may not pass `undefined` as id to the store\'s find method\");\n\n expectAssertion(function() {\n store.find(Person, null);\n }, \"You may not pass `null` as id to the store\'s find method\");\n});\n\ntest(\"When a single record is requested, the adapter\'s find method should be called unless it\'s loaded.\", function() {\n expect(2);\n\n var count = 0;\n\n store = createStore({ adapter: DS.Adapter.extend({\n find: function(store, type, id) {\n equal(type, Person, \"the find method is called with the correct type\");\n equal(count, 0, \"the find method is only called once\");\n\n count++;\n return { id: 1, name: \"Braaaahm Dale\" };\n }\n })\n });\n\n run(function() {\n store.find(Person, 1);\n store.find(Person, 1);\n });\n});\n\ntest(\"When a single record is requested multiple times, all .find() calls are resolved after the promise is resolved\", function() {\n var deferred = Ember.RSVP.defer();\n\n store = createStore({ adapter: DS.Adapter.extend({\n find: function(store, type, id) {\n return deferred.promise;\n }\n })\n });\n\n run(function() {\n store.find(Person, 1).then(async(function(person) {\n equal(person.get(\'id\'), \"1\");\n equal(person.get(\'name\'), \"Braaaahm Dale\");\n\n stop();\n deferred.promise.then(function(value) {\n start();\n ok(true, \'expected deferred.promise to fulfill\');\n }, function(reason) {\n start();\n ok(false, \'expected deferred.promise to fulfill, but rejected\');\n });\n }));\n });\n\n run(function() {\n store.find(Person, 1).then(async(function(post) {\n equal(post.get(\'id\'), \"1\");\n equal(post.get(\'name\'), \"Braaaahm Dale\");\n\n stop();\n deferred.promise.then(function(value) {\n start();\n ok(true, \'expected deferred.promise to fulfill\');\n }, function(reason) {\n start();\n ok(false, \'expected deferred.promise to fulfill, but rejected\');\n });\n\n }));\n });\n\n Ember.run(function() {\n deferred.resolve({ id: 1, name: \"Braaaahm Dale\" });\n });\n});\n\ntest(\"When a single record is requested, and the promise is rejected, .find() is rejected.\", function() {\n store = createStore({ adapter: DS.Adapter.extend({\n find: function(store, type, id) {\n return Ember.RSVP.reject();\n }\n })\n });\n\n run(function() {\n store.find(Person, 1).then(null, async(function(reason) {\n ok(true, \"The rejection handler was called\");\n }));\n });\n});\n\ntest(\"When a single record is requested, and the promise is rejected, the record should be unloaded.\", function() {\n expect(2);\n\n store = createStore({ adapter: DS.Adapter.extend({\n find: function(store, type, id) {\n return Ember.RSVP.reject();\n }\n })\n });\n\n run(function() {\n store.find(Person, 1).then(null, async(function(reason) {\n ok(true, \"The rejection handler was called\");\n }));\n });\n\n ok(!store.hasRecordForId(Person, 1), \"The record has been unloaded\");\n});\n})();//# sourceURL=ember-data/integration/adapter/find_test.js");
279
+ 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\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});\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 - 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 - 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 - 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\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 - 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 - 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(\"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(\'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\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(\'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(\'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");
254
280
 
255
- eval("(function() {var get = Ember.get;\nvar env, Person, Phone;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/fixture_adapter - DS.FixtureAdapter\", {\n setup: function() {\n Person = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n\n height: DS.attr(\'number\'),\n\n phones: DS.hasMany(\'phone\', { async: true })\n });\n\n Phone = DS.Model.extend({\n person: DS.belongsTo(\'person\', { async: true })\n });\n\n env = setupStore({ person: Person, phone: Phone, adapter: DS.FixtureAdapter });\n env.adapter.simulateRemoteResponse = true;\n env.adapter.latency = 50;\n\n // Enable setTimeout.\n Ember.testing = false;\n\n Person.FIXTURES = [];\n Phone.FIXTURES = [];\n },\n teardown: function() {\n Ember.testing = true;\n\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"should load data for a type asynchronously when it is requested\", function() {\n Person.FIXTURES = [{\n id: \'wycats\',\n firstName: \"Yehuda\",\n lastName: \"Katz\",\n\n height: 65\n },\n\n {\n id: \'ebryn\',\n firstName: \"Erik\",\n lastName: \"Brynjolffsosysdfon\",\n\n height: 70,\n phones: [1, 2]\n }];\n\n Phone.FIXTURES = [{\n id: 1,\n person: \'ebryn\'\n }, {\n id: 2,\n person: \'ebryn\'\n }];\n\n run(env.store, \'find\', \'person\', \'ebryn\').then(async(function(ebryn) {\n equal(get(ebryn, \'isLoaded\'), true, \"data loads asynchronously\");\n equal(get(ebryn, \'height\'), 70, \"data from fixtures is loaded correctly\");\n\n return Ember.RSVP.hash({ ebryn: ebryn, wycats: env.store.find(\'person\', \'wycats\') });\n }, 1000)).then(async(function(records) {\n equal(get(records.wycats, \'isLoaded\'), true, \"subsequent requests for records are returned asynchronously\");\n equal(get(records.wycats, \'height\'), 65, \"subsequent requested records contain correct information\");\n\n return get(records.ebryn, \'phones\');\n }, 1000)).then(async(function(phones) {\n equal(get(phones, \'length\'), 2, \"relationships from fixtures is loaded correctly\");\n }, 1000));\n});\n\ntest(\"should load data asynchronously at the end of the runloop when simulateRemoteResponse is false\", function() {\n Person.FIXTURES = [{\n id: \'wycats\',\n firstName: \"Yehuda\"\n }];\n\n env.adapter.simulateRemoteResponse = false;\n\n var wycats;\n\n Ember.run(function() {\n env.store.find(\'person\', \'wycats\').then(function(person) {\n wycats = person;\n });\n });\n\n ok(get(wycats, \'isLoaded\'), \'isLoaded is true after runloop finishes\');\n equal(get(wycats, \'firstName\'), \'Yehuda\', \'record properties are defined after runloop finishes\');\n});\n\ntest(\"should create record asynchronously when it is committed\", function() {\n var paul;\n equal(Person.FIXTURES.length, 0, \"Fixtures is empty\");\n\n run(function() {\n paul = env.store.createRecord(\'person\', { firstName: \'Paul\', lastName: \'Chavard\', height: 70 });\n });\n\n paul.on(\'didCreate\', async(function() {\n equal(get(paul, \'isNew\'), false, \"data loads asynchronously\");\n equal(get(paul, \'isDirty\'), false, \"data loads asynchronously\");\n equal(get(paul, \'height\'), 70, \"data from fixtures is saved correctly\");\n\n equal(Person.FIXTURES.length, 1, \"Record added to FIXTURES\");\n\n var fixture = Person.FIXTURES[0];\n\n ok(typeof fixture.id === \'string\', \"The fixture has an ID generated for it\");\n equal(fixture.firstName, \'Paul\');\n equal(fixture.lastName, \'Chavard\');\n equal(fixture.height, 70);\n }));\n\n paul.save();\n});\n\ntest(\"should update record asynchronously when it is committed\", function() {\n equal(Person.FIXTURES.length, 0, \"Fixtures is empty\");\n\n var paul = env.store.push(\'person\', { id: 1, firstName: \'Paul\', lastName: \'Chavard\', height: 70 });\n\n paul.set(\'height\', 80);\n\n paul.on(\'didUpdate\', async(function() {\n equal(get(paul, \'isDirty\'), false, \"data loads asynchronously\");\n equal(get(paul, \'height\'), 80, \"data from fixtures is saved correctly\");\n\n equal(Person.FIXTURES.length, 1, \"Record FIXTURES updated\");\n\n var fixture = Person.FIXTURES[0];\n\n equal(fixture.firstName, \'Paul\');\n equal(fixture.lastName, \'Chavard\');\n equal(fixture.height, 80);\n }, 1000));\n\n paul.save();\n});\n\ntest(\"should delete record asynchronously when it is committed\", function() {\n stop();\n\n var timer = setTimeout(function() {\n start();\n ok(false, \"timeout exceeded waiting for fixture data\");\n }, 1000);\n\n equal(Person.FIXTURES.length, 0, \"Fixtures empty\");\n\n var paul = env.store.push(\'person\', { id: \'paul\', firstName: \'Paul\', lastName: \'Chavard\', height: 70 });\n\n paul.save().then(function() {\n paul.deleteRecord();\n paul.save();\n });\n\n paul.on(\'didDelete\', function() {\n clearTimeout(timer);\n start();\n\n equal(get(paul, \'isDeleted\'), true, \"data deleted asynchronously\");\n equal(get(paul, \'isDirty\'), false, \"data deleted asynchronously\");\n\n equal(Person.FIXTURES.length, 0, \"Record removed from FIXTURES\");\n });\n\n});\n\ntest(\"should follow isUpdating semantics\", function() {\n var timer = setTimeout(function() {\n start();\n ok(false, \"timeout exceeded waiting for fixture data\");\n }, 1000);\n\n stop();\n\n Person.FIXTURES = [{\n id: \"twinturbo\",\n firstName: \"Adam\",\n lastName: \"Hawkins\",\n height: 65\n }];\n\n var result = env.store.findAll(\'person\');\n\n result.then(function(all) {\n clearTimeout(timer);\n start();\n equal(get(all, \'isUpdating\'), false, \"isUpdating is set when it shouldn\'t be\");\n });\n});\n\ntest(\"should coerce integer ids into string\", function() {\n Person.FIXTURES = [{\n id: 1,\n firstName: \"Adam\",\n lastName: \"Hawkins\",\n height: 65\n }];\n\n env.store.find(\'person\', 1).then(async(function(result) {\n strictEqual(get(result, \'id\'), \"1\", \"should load integer model id as string\");\n }));\n});\n\ntest(\"should coerce belongsTo ids into string\", function() {\n Person.FIXTURES = [{\n id: 1,\n firstName: \"Adam\",\n lastName: \"Hawkins\",\n\n phones: [1]\n }];\n\n Phone.FIXTURES = [{\n id: 1,\n person: 1\n }];\n\n env.store.find(\'phone\', 1).then(async(function(result) {\n get(result, \'person\').then(async(function(person) {\n strictEqual(get(person, \'id\'), \"1\", \"should load integer belongsTo id as string\");\n strictEqual(get(person, \'firstName\'), \"Adam\", \"resolved relationship with an integer belongsTo id\");\n }));\n }));\n});\n\ntest(\"only coerce belongsTo ids to string if id is defined and not null\", function() {\n Person.FIXTURES = [];\n\n Phone.FIXTURES = [{\n id: 1\n }];\n\n env.store.find(\'phone\', 1).then(async(function(phone) {\n phone.get(\'person\').then(async(function(person) {\n equal(person, null);\n }));\n }));\n});\n\ntest(\"should throw if ids are not defined in the FIXTURES\", function() {\n Person.FIXTURES = [{\n firstName: \"Adam\",\n lastName: \"Hawkins\",\n height: 65\n }];\n\n raises(function() {\n run(function() {\n env.store.find(\'person\', 1);\n });\n }, /the id property must be defined as a number or string for fixture/);\n\n Person.FIXTURES = [{\n id: 0\n }];\n\n env.store.find(\'person\', 0).then(async(function() {\n ok(true, \"0 is an acceptable ID, so no exception was thrown\");\n }), function() {\n ok(false, \"should not get here\");\n });\n});\n\nasyncTest(\"copies fixtures instead of passing the direct reference\", function() {\n var returnedFixture;\n\n expect(2);\n\n Person.FIXTURES = [{\n id: \'1\',\n firstName: \'Katie\',\n lastName: \'Gengler\'\n }];\n\n var PersonAdapter = DS.FixtureAdapter.extend({\n find: function(store, type, id) {\n return this._super(store, type, id).then(function(fixture) {\n return returnedFixture = fixture;\n });\n }\n });\n\n Ember.run(function() {\n env.registry.register(\'adapter:person\', PersonAdapter);\n });\n\n env.store.find(\'person\', 1).then(function() {\n start();\n ok(Person.FIXTURES[0] !== returnedFixture, \'returnedFixture does not have object identity with defined fixture\');\n deepEqual(Person.FIXTURES[0], returnedFixture);\n }, function(err) {\n ok(false, \'got error\' + err);\n });\n});\n\ntest(\"should save hasMany records\", function() {\n var createPhone, savePerson, assertPersonPhones;\n\n expect(3);\n\n Person.FIXTURES = [{ id: \'tomjerry\', firstName: \"Tom\", lastName: \"Jerry\", height: 3 }];\n\n createPhone = async(function(tom) {\n env.store.createRecord(\'phone\', { person: tom });\n\n return tom.get(\'phones\').then(async(function(p) {\n equal(p.get(\'length\'), 1, \"hasMany relationships are created in the store\");\n return tom;\n }));\n });\n\n savePerson = async(function(tom) {\n return tom.save();\n });\n\n assertPersonPhones = async(function(record) {\n var phonesPromise = record.get(\'phones\');\n\n return phonesPromise.then(async(function(phones) {\n equal(phones.get(\'length\'), 1, \"hasMany relationship saved correctly\");\n }));\n });\n\n var ensureFixtureAdapterDoesNotLeak = async(function() {\n env.store.destroy();\n env = setupStore({ person: Person, phone: Phone, adapter: DS.FixtureAdapter });\n return env.store.find(\'phone\').then(async(function(phones) {\n equal(phones.get(\'length\'), 0, \"the fixture adapter should not leak after destroying the store\");\n }));\n });\n env.store.find(\'person\', \'tomjerry\').then(createPhone)\n .then(savePerson)\n .then(assertPersonPhones)\n .then(ensureFixtureAdapterDoesNotLeak);\n\n});\n})();//# sourceURL=ember-data/integration/adapter/fixture_adapter_test.js");
281
+ 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");
256
282
 
257
- eval("(function() {var get = Ember.get;\nvar Person, env, store, adapter;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/queries - Queries\", {\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 env = setupStore({ person: Person });\n store = env.store;\n adapter = env.adapter;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"When a query is made, the adapter should receive a record array it can populate with the results of the query.\", function() {\n adapter.findQuery = function(store, type, query, recordArray) {\n equal(type, Person, \"the find method is called with the correct type\");\n\n return Ember.RSVP.resolve([{ id: 1, name: \"Peter Wagenet\" }, { id: 2, name: \"Brohuda Katz\" }]);\n };\n\n store.find(\'person\', { page: 1 }).then(async(function(queryResults) {\n equal(get(queryResults, \'length\'), 2, \"the record array has a length of 2 after the results are loaded\");\n equal(get(queryResults, \'isLoaded\'), true, \"the record array\'s `isLoaded` property should be true\");\n\n equal(queryResults.objectAt(0).get(\'name\'), \"Peter Wagenet\", \"the first record is \'Peter Wagenet\'\");\n equal(queryResults.objectAt(1).get(\'name\'), \"Brohuda Katz\", \"the second record is \'Brohuda Katz\'\");\n }));\n});\n})();//# sourceURL=ember-data/integration/adapter/queries_test.js");
283
+ eval("(function() {var get = Ember.get;\nvar run = Ember.run;\n\nvar Person, store, array, moreArray;\n\nmodule(\"integration/all - DS.Store#all()\", {\n setup: function() {\n array = [{ id: 1, name: \"Scumbag Dale\" }, { id: 2, name: \"Scumbag Katz\" }];\n moreArray = [{ id: 3, name: \"Scumbag Bryn\" }];\n Person = DS.Model.extend({ name: DS.attr(\'string\') });\n\n store = createStore({ person: Person });\n },\n teardown: function() {\n run(store, \'destroy\');\n Person = null;\n array = null;\n }\n});\n\ntest(\"store.all(\'person\') should return all records and should update with new ones\", function() {\n run(function() {\n store.pushMany(\'person\', array);\n });\n\n var all = store.all(\'person\');\n equal(get(all, \'length\'), 2);\n\n run(function() {\n store.pushMany(\'person\', moreArray);\n });\n\n equal(get(all, \'length\'), 3);\n});\n\ntest(\"Calling store.all() multiple times should update immediately inside the runloop\", function() {\n expect(3);\n\n Ember.run(function() {\n equal(get(store.all(\'person\'), \'length\'), 0, \'should initially be empty\');\n store.createRecord(\'person\', { name: \"Tomster\" });\n equal(get(store.all(\'person\'), \'length\'), 1, \'should contain one person\');\n store.push(\'person\', { id: 1, name: \"Tomster\'s friend\" });\n equal(get(store.all(\'person\'), \'length\'), 2, \'should contain two people\');\n });\n});\n\ntest(\"Calling store.all() after creating a record should return correct data\", function() {\n expect(1);\n\n Ember.run(function() {\n store.createRecord(\'person\', { name: \"Tomster\" });\n equal(get(store.all(\'person\'), \'length\'), 1, \'should contain one person\');\n });\n});\n})();//# sourceURL=ember-data/integration/all-test.js");
258
284
 
259
- 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, record) {\n equal(type, Person, \"the type is correct\");\n equal(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, record) {\n equal(type, Person, \"the type is correct\");\n equal(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, record) {\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, record) {\n equal(type, Person, \"the type is correct\");\n equal(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, record) {\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, record) {\n if (record.get(\'id\') === \"1\") {\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\", updatedAt: \"now\" });\n } else if (record.get(\'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, record) {\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, record) {\n switch (record.get(\'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, record) {\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");
285
+ 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");
260
286
 
261
- 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\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});\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 - 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 - 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 - 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\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 - 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 - 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(\"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(\'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, record) {\n return \"/posts/\" + record.get(\'post.id\') + \'/comments/\' + record.get(\'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, records) {\n return \"/posts/\" + records.get(\'firstObject.post.id\') + \'/comments/\';\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, record) {\n return \"/posts/\" + record.get(\'post.id\') + \'/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, record) {\n return \"/posts/\" + record.get(\'post.id\') + \'/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, record) {\n return \"/posts/\" + record.get(\'post.id\') + \'/comments/\' + record.get(\'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, record) {\n return \'posts/\' + record.get(\'post.id\') + \'/comments/\' + record.get(\'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(\'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, record) {\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, record ) {\n equal(id, \'1\');\n return Ember.RSVP.resolve({ comments: { id: 1 } });\n };\n\n adapter.findMany = function(store, type, ids, records ) {\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, record) {\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, record ) {\n equal(id, \'1\');\n return Ember.RSVP.resolve({ comments: { id: 1 } });\n };\n\n adapter.findMany = function(store, type, ids, records ) {\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, record) {\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, records) {\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, record) {\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, records) {\n deepEqual(ids, [a100, b100]);\n return Ember.RSVP.resolve({ comments: { id: ids } });\n };\n\n run(function() {\n post.get(\'comments\');\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");
287
+ 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");
262
288
 
263
- 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, record) {\n equal(type, Person, \"the type is correct\");\n\n if (count === 1) {\n equal(get(record, \'name\'), \"Tom Dale\");\n } else if (count === 2) {\n equal(get(record, \'name\'), \"Yehuda Katz\");\n } else {\n ok(false, \"should not have invoked more than 2 times\");\n }\n\n var hash = get(record, \'data\');\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, record) {\n equal(type, Person, \"the type is correct\");\n\n if (count === 0) {\n equal(get(record, \'name\'), \"Tom Dale\");\n } else if (count === 1) {\n equal(get(record, \'name\'), \"Yehuda Katz\");\n } else {\n ok(false, \"should not get here\");\n }\n\n count++;\n\n equal(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, record) {\n equal(type, Person, \"the type is correct\");\n\n count++;\n if (count === 1) {\n equal(get(record, \'name\'), \"Tom Dale\");\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\", updatedAt: \"now\" });\n } else if (count === 2) {\n equal(get(record, \'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, record) {\n equal(type, Person, \"the type is correct\");\n\n if (count === 0) {\n equal(get(record, \'name\'), \"Tom Dale\");\n } else if (count === 1) {\n equal(get(record, \'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, record) {\n equal(type, Person, \"the type is correct\");\n\n if (count === 0) {\n equal(get(record, \'name\'), \"Tom Dale\");\n } else if (count === 1) {\n equal(get(record, \'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, record) {\n count++;\n equal(get(record, \'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, record) {\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, record) {\n equal(type, Person, \"the type is correct\");\n\n if (get(record, \'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, record) {\n if (get(record, \'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, record) {\n equal(type, Person, \"the type is correct\");\n saveCount++;\n\n if (get(record, \'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, record) {\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, record) {\n equal(type, Person, \"the type is correct\");\n\n if (get(record, \'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, record) {\n if (get(record, \'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, record) {\n equal(type, Person, \"the type is correct\");\n saveCount++;\n if (get(record, \'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, record) {\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) {\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) {\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\", dogs: [1] });\n };\n\n adapter.updateRecord = function(store, type, record) {\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) {\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() {\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, record) {\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})();//# sourceURL=ember-data/integration/adapter/store_adapter_test.js");
289
+ 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");
264
290
 
265
- eval("(function() {var get = Ember.get;\nvar run = Ember.run;\n\nvar Person, store, array, moreArray;\n\nmodule(\"integration/all - DS.Store#all()\", {\n setup: function() {\n array = [{ id: 1, name: \"Scumbag Dale\" }, { id: 2, name: \"Scumbag Katz\" }];\n moreArray = [{ id: 3, name: \"Scumbag Bryn\" }];\n Person = DS.Model.extend({ name: DS.attr(\'string\') });\n\n store = createStore({ person: Person });\n },\n teardown: function() {\n run(store, \'destroy\');\n Person = null;\n array = null;\n }\n});\n\ntest(\"store.all(\'person\') should return all records and should update with new ones\", function() {\n run(function() {\n store.pushMany(\'person\', array);\n });\n\n var all = store.all(\'person\');\n equal(get(all, \'length\'), 2);\n\n run(function() {\n store.pushMany(\'person\', moreArray);\n });\n\n equal(get(all, \'length\'), 3);\n});\n\ntest(\"Calling store.all() multiple times should update immediately inside the runloop\", function() {\n expect(3);\n\n Ember.run(function() {\n equal(get(store.all(\'person\'), \'length\'), 0, \'should initially be empty\');\n store.createRecord(\'person\', { name: \"Tomster\" });\n equal(get(store.all(\'person\'), \'length\'), 1, \'should contain one person\');\n store.push(\'person\', { id: 1, name: \"Tomster\'s friend\" });\n equal(get(store.all(\'person\'), \'length\'), 2, \'should contain two people\');\n });\n});\n\ntest(\"Calling store.all() after creating a record should return correct data\", function() {\n expect(1);\n\n Ember.run(function() {\n store.createRecord(\'person\', { name: \"Tomster\" });\n equal(get(store.all(\'person\'), \'length\'), 1, \'should contain one person\');\n });\n});\n})();//# sourceURL=ember-data/integration/all_test.js");
291
+ eval("(function() {var get = Ember.get;\nvar set = Ember.set;\nvar forEach = Ember.EnumerableUtils.forEach;\nvar indexOf = Ember.EnumerableUtils.indexOf;\nvar run = Ember.run;\n\nvar Person, store, env, array, recordArray;\n\nvar shouldContain = function(array, item) {\n ok(indexOf(array, item) !== -1, \"array should contain \"+item.get(\'name\'));\n};\n\nvar shouldNotContain = function(array, item) {\n ok(indexOf(array, item) === -1, \"array should not contain \"+item.get(\'name\'));\n};\n\nmodule(\"integration/filter - DS.Model updating\", {\n setup: function() {\n array = [{ id: 1, name: \"Scumbag Dale\", bestFriend: 2 }, { id: 2, name: \"Scumbag Katz\" }, { id: 3, name: \"Scumbag Bryn\" }];\n Person = DS.Model.extend({ name: DS.attr(\'string\'), bestFriend: DS.belongsTo(\'person\', { inverse: null }) });\n\n env = setupStore({ person: Person });\n store = env.store;\n },\n teardown: function() {\n run(store, \'destroy\');\n Person = null;\n array = null;\n }\n});\n\nfunction tapFn(fn, callback) {\n var old_fn = fn;\n\n var new_fn = function() {\n var result = old_fn.apply(this, arguments);\n if (callback) {\n callback.apply(fn, arguments);\n }\n new_fn.summary.called.push(arguments);\n return result;\n };\n new_fn.summary = { called: [] };\n\n return new_fn;\n}\n\n\ntest(\"when a DS.Model updates its attributes, its changes affect its filtered Array membership\", function() {\n run(function() {\n store.pushMany(\'person\', array);\n });\n var people;\n\n run(function() {\n people = store.filter(\'person\', function(hash) {\n if (hash.get(\'name\').match(/Katz$/)) { return true; }\n });\n });\n\n run(function() {\n equal(get(people, \'length\'), 1, \"precond - one item is in the RecordArray\");\n });\n\n var person = people.objectAt(0);\n\n equal(get(person, \'name\'), \"Scumbag Katz\", \"precond - the item is correct\");\n\n run(function() {\n set(person, \'name\', \"Yehuda Katz\");\n });\n\n equal(get(people, \'length\'), 1, \"there is still one item\");\n equal(get(person, \'name\'), \"Yehuda Katz\", \"it has the updated item\");\n\n run(function() {\n set(person, \'name\', \"Yehuda Katz-Foo\");\n });\n\n equal(get(people, \'query\'), null, \'expected no query object set\');\n equal(get(people, \'length\'), 0, \"there are now no items\");\n});\n\ntest(\"when a DS.Model updates its relationships, its changes affect its filtered Array membership\", function() {\n run(function() {\n store.pushMany(\'person\', array);\n });\n var people;\n\n run(function() {\n people = store.filter(\'person\', function(person) {\n if (person.get(\'bestFriend\') && person.get(\'bestFriend.name\').match(/Katz$/)) { return true; }\n });\n });\n\n run(function() {\n equal(get(people, \'length\'), 1, \"precond - one item is in the RecordArray\");\n });\n\n var person = people.objectAt(0);\n\n equal(get(person, \'name\'), \"Scumbag Dale\", \"precond - the item is correct\");\n\n run(function() {\n set(person, \'bestFriend\', null);\n });\n\n equal(get(people, \'length\'), 0, \"there are now 0 items\");\n\n var erik = store.getById(\'person\', 3);\n var yehuda = store.getById(\'person\', 2);\n run(function() {\n erik.set(\'bestFriend\', yehuda);\n });\n\n person = people.objectAt(0);\n equal(get(people, \'length\'), 1, \"there is now 1 item\");\n equal(get(person, \'name\'), \"Scumbag Bryn\", \"precond - the item is correct\");\n});\n\n\ntest(\"a record array can have a filter on it\", function() {\n run(function() {\n store.pushMany(\'person\', array);\n });\n var recordArray;\n\n run(function() {\n recordArray = store.filter(\'person\', function(hash) {\n if (hash.get(\'name\').match(/Scumbag [KD]/)) { return true; }\n });\n });\n\n equal(get(recordArray, \'length\'), 2, \"The Record Array should have the filtered objects on it\");\n\n run(function() {\n store.push(\'person\', { id: 4, name: \"Scumbag Koz\" });\n });\n\n equal(get(recordArray, \'length\'), 3, \"The Record Array should be updated as new items are added to the store\");\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Scumbag Tom\" });\n });\n\n equal(get(recordArray, \'length\'), 2, \"The Record Array should be updated as existing members are updated\");\n});\n\ntest(\"a filtered record array includes created elements\", function() {\n run(function() {\n store.pushMany(\'person\', array);\n });\n var recordArray;\n\n run(function() {\n recordArray = store.filter(\'person\', function(hash) {\n if (hash.get(\'name\').match(/Scumbag [KD]/)) { return true; }\n });\n });\n\n equal(get(recordArray, \'length\'), 2, \"precond - The Record Array should have the filtered objects on it\");\n\n run(function() {\n store.createRecord(\'person\', { name: \"Scumbag Koz\" });\n });\n\n equal(get(recordArray, \'length\'), 3, \"The record array has the new object on it\");\n});\n\ntest(\"a Record Array can update its filter\", function() {\n run(function() {\n set(store, \'adapter\', DS.Adapter.extend({\n deleteRecord: function(store, type, snapshot) {\n return Ember.RSVP.resolve();\n }\n }));\n });\n\n run(function() {\n store.pushMany(\'person\', array);\n });\n\n var dickens = run(function() {\n var record = store.createRecord(\'person\', { id: 4, name: \"Scumbag Dickens\" });\n record.deleteRecord();\n return record;\n });\n var asyncDale, asyncKatz, asyncBryn;\n\n run(function() {\n asyncDale = store.find(\'person\', 1);\n asyncKatz = store.find(\'person\', 2);\n asyncBryn = store.find(\'person\', 3);\n });\n\n store.filter(Person, function(hash) {\n if (hash.get(\'name\').match(/Scumbag [KD]/)) { return true; }\n }).then(async(function(recordArray) {\n\n Ember.RSVP.hash({ dale: asyncDale, katz: asyncKatz, bryn: asyncBryn }).then(async(function(records) {\n shouldContain(recordArray, records.dale);\n shouldContain(recordArray, records.katz);\n shouldNotContain(recordArray, records.bryn);\n shouldNotContain(recordArray, dickens);\n\n Ember.run(function() {\n recordArray.set(\'filterFunction\', function(hash) {\n if (hash.get(\'name\').match(/Katz/)) { return true; }\n });\n });\n\n equal(get(recordArray, \'length\'), 1, \"The Record Array should have one object on it\");\n\n Ember.run(function() {\n store.push(\'person\', { id: 5, name: \"Other Katz\" });\n });\n\n equal(get(recordArray, \'length\'), 2, \"The Record Array now has the new object matching the filter\");\n\n Ember.run(function() {\n store.push(\'person\', { id: 6, name: \"Scumbag Demon\" });\n });\n\n equal(get(recordArray, \'length\'), 2, \"The Record Array doesn\'t have objects matching the old filter\");\n }));\n }));\n});\n\ntest(\"a Record Array can update its filter and notify array observers\", function() {\n run(function() {\n set(store, \'adapter\', DS.Adapter.extend({\n deleteRecord: function(store, type, snapshot) {\n return Ember.RSVP.resolve();\n }\n }));\n });\n\n run(function() {\n store.pushMany(\'person\', array);\n });\n var dickens;\n\n run(function() {\n dickens = store.createRecord(\'person\', { id: 4, name: \"Scumbag Dickens\" });\n dickens.deleteRecord();\n });\n\n var asyncDale, asyncKatz, asyncBryn;\n\n run(function() {\n asyncDale = store.find(\'person\', 1);\n asyncKatz = store.find(\'person\', 2);\n asyncBryn = store.find(\'person\', 3);\n });\n\n store.filter(Person, function(hash) {\n if (hash.get(\'name\').match(/Scumbag [KD]/)) { return true; }\n }).then(async(function(recordArray) {\n\n var didChangeIdx;\n var didChangeRemoved = 0;\n var didChangeAdded = 0;\n\n var arrayObserver = {\n arrayWillChange: Ember.K,\n\n arrayDidChange: function(array, idx, removed, added) {\n didChangeIdx = idx;\n didChangeRemoved += removed;\n didChangeAdded += added;\n }\n };\n\n recordArray.addArrayObserver(arrayObserver);\n\n Ember.run(function() {\n recordArray.set(\'filterFunction\', function(hash) {\n if (hash.get(\'name\').match(/Katz/)) { return true; }\n });\n });\n\n Ember.RSVP.all([asyncDale, asyncKatz, asyncBryn]).then(async(function() {\n equal(didChangeRemoved, 1, \"removed one item from array\");\n didChangeRemoved = 0;\n\n Ember.run(function() {\n store.push(\'person\', { id: 5, name: \"Other Katz\" });\n });\n\n equal(didChangeAdded, 1, \"one item was added\");\n didChangeAdded = 0;\n\n equal(recordArray.objectAt(didChangeIdx).get(\'name\'), \"Other Katz\");\n\n Ember.run(function() {\n store.push(\'person\', { id: 6, name: \"Scumbag Demon\" });\n });\n\n equal(didChangeAdded, 0, \"did not get called when an object that doesn\'t match is added\");\n\n Ember.run(function() {\n recordArray.set(\'filterFunction\', function(hash) {\n if (hash.get(\'name\').match(/Scumbag [KD]/)) { return true; }\n });\n });\n\n equal(didChangeAdded, 2, \"one item is added when going back\");\n equal(recordArray.objectAt(didChangeIdx).get(\'name\'), \"Scumbag Demon\");\n equal(recordArray.objectAt(didChangeIdx-1).get(\'name\'), \"Scumbag Dale\");\n }));\n }));\n});\n\ntest(\"it is possible to filter by computed properties\", function() {\n Person.reopen({\n name: DS.attr(\'string\'),\n upperName: Ember.computed(function() {\n return this.get(\'name\').toUpperCase();\n }).property(\'name\')\n });\n var filter;\n\n run(function() {\n filter = store.filter(\'person\', function(person) {\n return person.get(\'upperName\') === \"TOM DALE\";\n });\n });\n\n equal(filter.get(\'length\'), 0, \"precond - the filter starts empty\");\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n\n equal(filter.get(\'length\'), 1, \"the filter now has a record in it\");\n\n store.find(\'person\', 1).then(async(function(person) {\n Ember.run(function() {\n person.set(\'name\', \"Yehuda Katz\");\n });\n\n equal(filter.get(\'length\'), 0, \"the filter is empty again\");\n }));\n});\n\ntest(\"a filter created after a record is already loaded works\", function() {\n Person.reopen({\n name: DS.attr(\'string\'),\n upperName: Ember.computed(function() {\n return this.get(\'name\').toUpperCase();\n }).property(\'name\')\n });\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n var filter;\n\n run(function() {\n filter = store.filter(\'person\', function(person) {\n return person.get(\'upperName\') === \"TOM DALE\";\n });\n });\n\n equal(filter.get(\'length\'), 1, \"the filter now has a record in it\");\n asyncEqual(filter.objectAt(0), store.find(\'person\', 1));\n});\n\ntest(\"filter with query persists query on the resulting filteredRecordArray\", function() {\n set(store, \'adapter\', DS.Adapter.extend({\n findQuery: function(store, type, id) {\n return Ember.RSVP.resolve([{\n id: id,\n name: \"Tom Dale\"\n }]);\n }\n }));\n var filter;\n\n run(function() {\n filter = store.filter(Person, { foo: 1 }, function(person) {\n return true;\n });\n });\n\n Ember.run(function() {\n filter.then(function(array) {\n deepEqual(get(array, \'query\'), { foo: 1 }, \'has expected query\');\n });\n });\n});\n\n\ntest(\"it is possible to filter by state flags\", function() {\n var filter;\n run(function() {\n set(store, \'adapter\', DS.Adapter.extend({\n find: function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({ id: id, name: \"Tom Dale\" });\n }\n }));\n\n filter = store.filter(Person, function(person) {\n return person.get(\'isLoaded\');\n });\n });\n\n equal(filter.get(\'length\'), 0, \"precond - there are no records yet\");\n\n Ember.run(function() {\n var asyncPerson = store.find(\'person\', 1);\n\n // Ember.run will block `find` from being synchronously\n // resolved in test mode\n\n equal(filter.get(\'length\'), 0, \"the unloaded record isn\'t in the filter\");\n\n asyncPerson.then(async(function(person) {\n equal(filter.get(\'length\'), 1, \"the now-loaded record is in the filter\");\n asyncEqual(filter.objectAt(0), store.find(\'person\', 1));\n }));\n });\n});\n\ntest(\"it is possible to filter loaded records by dirtiness\", function() {\n set(store, \'adapter\', DS.Adapter.extend({\n updateRecord: function() {\n return Ember.RSVP.resolve();\n }\n }));\n\n var filter = store.filter(\'person\', function(person) {\n return !person.get(\'isDirty\');\n });\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n\n store.find(\'person\', 1).then(async(function(person) {\n equal(filter.get(\'length\'), 1, \"the clean record is in the filter\");\n\n // Force synchronous update of the filter, even though\n // we\'re already inside a run loop\n Ember.run(function() {\n person.set(\'name\', \"Yehuda Katz\");\n });\n\n equal(filter.get(\'length\'), 0, \"the now-dirty record is not in the filter\");\n\n return person.save();\n })).then(async(function(person) {\n equal(filter.get(\'length\'), 1, \"the clean record is back in the filter\");\n }));\n});\n\ntest(\"it is possible to filter created records by dirtiness\", function() {\n run(function() {\n set(store, \'adapter\', DS.Adapter.extend({\n createRecord: function() {\n return Ember.RSVP.resolve();\n }\n }));\n });\n\n var filter;\n\n run(function() {\n filter = store.filter(\'person\', function(person) {\n return !person.get(\'isDirty\');\n });\n });\n\n var person;\n\n run(function() {\n person = store.createRecord(\'person\', {\n id: 1,\n name: \"Tom Dale\"\n });\n });\n\n equal(filter.get(\'length\'), 0, \"the dirty record is not in the filter\");\n\n run(function() {\n person.save().then(function(person) {\n equal(filter.get(\'length\'), 1, \"the clean record is in the filter\");\n });\n });\n});\n\ntest(\"it is possible to filter created records by isReloading\", function() {\n set(store, \'adapter\', DS.Adapter.extend({\n find: function(store, type, id, snapshot) {\n return Ember.RSVP.resolve({\n id: 1,\n name: \"Tom Dalle\"\n });\n }\n }));\n\n var filter = store.filter(\'person\', function(person) {\n return !person.get(\'isReloading\');\n });\n\n var person = store.createRecord(\'person\', {\n id: 1,\n name: \"Tom Dale\"\n });\n\n person.reload().then(async(function(person) {\n equal(filter.get(\'length\'), 1, \"the filter correctly returned a reloaded object\");\n }));\n});\n\n\n// SERVER SIDE TESTS\nvar edited;\n\nvar clientEdits = function(ids) {\n edited = [];\n\n forEach(ids, function(id) {\n // wrap in an Ember.run to guarantee coalescence of the\n // iterated `set` calls and promise resolution.\n Ember.run(function() {\n store.find(\'person\', id).then(function(person) {\n edited.push(person);\n person.set(\'name\', \'Client-side \' + id );\n });\n });\n });\n};\n\nvar clientCreates = function(names) {\n edited = [];\n\n // wrap in an Ember.run to guarantee coalescence of the\n // iterated `set` calls.\n Ember.run(function() {\n forEach(names, function(name) {\n edited.push(store.createRecord(\'person\', { name: \'Client-side \' + name }));\n });\n });\n};\n\nvar serverResponds = function() {\n forEach(edited, function(person) { run(person, \'save\'); });\n};\n\nvar setup = function(serverCallbacks) {\n run(function() {\n set(store, \'adapter\', DS.Adapter.extend(serverCallbacks));\n\n store.pushMany(\'person\', array);\n\n recordArray = store.filter(\'person\', function(hash) {\n if (hash.get(\'name\').match(/Scumbag/)) { return true; }\n });\n });\n\n equal(get(recordArray, \'length\'), 3, \"The filter function should work\");\n};\n\ntest(\"a Record Array can update its filter after server-side updates one record\", function() {\n setup({\n updateRecord: function(store, type, snapshot) {\n return Ember.RSVP.resolve({ id: 1, name: \"Scumbag Server-side Dale\" });\n }\n });\n\n clientEdits([1]);\n equal(get(recordArray, \'length\'), 2, \"The record array updates when the client changes records\");\n\n serverResponds();\n equal(get(recordArray, \'length\'), 3, \"The record array updates when the server changes one record\");\n});\n\ntest(\"a Record Array can update its filter after server-side updates multiple records\", function() {\n setup({\n updateRecord: function(store, type, snapshot) {\n switch (snapshot.id) {\n case \"1\":\n return Ember.RSVP.resolve({ id: 1, name: \"Scumbag Server-side Dale\" });\n case \"2\":\n return Ember.RSVP.resolve({ id: 2, name: \"Scumbag Server-side Katz\" });\n }\n }\n });\n\n clientEdits([1,2]);\n equal(get(recordArray, \'length\'), 1, \"The record array updates when the client changes records\");\n\n serverResponds();\n equal(get(recordArray, \'length\'), 3, \"The record array updates when the server changes multiple records\");\n});\n\ntest(\"a Record Array can update its filter after server-side creates one record\", function() {\n setup({\n createRecord: function(store, type, snapshot) {\n return Ember.RSVP.resolve({ id: 4, name: \"Scumbag Server-side Tim\" });\n }\n });\n\n clientCreates([\"Tim\"]);\n equal(get(recordArray, \'length\'), 3, \"The record array does not include non-matching records\");\n\n serverResponds();\n equal(get(recordArray, \'length\'), 4, \"The record array updates when the server creates a record\");\n});\n\ntest(\"a Record Array can update its filter after server-side creates multiple records\", function() {\n setup({\n createRecord: function(store, type, snapshot) {\n switch (snapshot.attr(\'name\')) {\n case \"Client-side Mike\":\n return Ember.RSVP.resolve({ id: 4, name: \"Scumbag Server-side Mike\" });\n case \"Client-side David\":\n return Ember.RSVP.resolve({ id: 5, name: \"Scumbag Server-side David\" });\n }\n }\n });\n\n clientCreates([\"Mike\", \"David\"]);\n equal(get(recordArray, \'length\'), 3, \"The record array does not include non-matching records\");\n\n serverResponds();\n equal(get(recordArray, \'length\'), 5, \"The record array updates when the server creates multiple records\");\n});\n\ntest(\"a Record Array can update its filter after server-side creates multiple records\", function() {\n setup({\n createRecord: function(store, type, snapshot) {\n switch (snapshot.attr(\'name\')) {\n case \"Client-side Mike\":\n return Ember.RSVP.resolve({ id: 4, name: \"Scumbag Server-side Mike\" });\n case \"Client-side David\":\n return Ember.RSVP.resolve({ id: 5, name: \"Scumbag Server-side David\" });\n }\n }\n });\n\n clientCreates([\"Mike\", \"David\"]);\n equal(get(recordArray, \'length\'), 3, \"The record array does not include non-matching records\");\n\n serverResponds();\n equal(get(recordArray, \'length\'), 5, \"The record array updates when the server creates multiple records\");\n});\n\ntest(\"destroying filteredRecordArray unregisters models from being filtered\", function() {\n var filterFn = tapFn(function() { return true; });\n var person;\n\n run(function() {\n person = store.push(\'person\', {\n id: 1,\n name: \'Tom Dale\'\n });\n });\n\n var recordArray;\n\n run(function() {\n recordArray = store.filter(\'person\', filterFn);\n });\n\n equal(filterFn.summary.called.length, 1);\n\n Ember.run(function() {\n recordArray.then(function(array) {\n array.destroy();\n });\n });\n clientEdits([1]);\n\n equal(filterFn.summary.called.length, 1, \'expected the filter function not being called anymore\');\n});\n})();//# sourceURL=ember-data/integration/filter-test.js");
266
292
 
267
- 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\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");
293
+ eval("(function() {var env, store, User, Job, ReflexiveModel;\n\nvar attr = DS.attr;\nvar belongsTo = DS.belongsTo;\nvar run = Ember.run;\n\nfunction stringify(string) {\n return function() { return string; };\n}\n\nmodule(\'integration/inverse_test - inverseFor\', {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n bestFriend: belongsTo(\'user\', { async: true, inverse: null }),\n job: belongsTo(\'job\')\n });\n\n User.toString = stringify(\'user\');\n\n Job = DS.Model.extend({\n isGood: attr(),\n user: belongsTo(\'user\')\n });\n\n Job.toString = stringify(\'job\');\n\n ReflexiveModel = DS.Model.extend({\n reflexiveProp: belongsTo(\'reflexiveModel\')\n });\n\n ReflexiveModel.toString = stringify(\'reflexiveModel\');\n\n env = setupStore({\n user: User,\n job: Job,\n reflexiveModel: ReflexiveModel\n });\n\n store = env.store;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"Finds the inverse when there is only one possible available\", function () {\n //Maybe store is evaluated lazily, so we need this :(\n run(store, \'push\', \'user\', { id: 1 });\n\n deepEqual(Job.inverseFor(\'user\'), {\n type: User,\n name: \'job\',\n kind: \'belongsTo\'\n }, \'Gets correct type, name and kind\');\n});\n\ntest(\"Finds the inverse when only one side has defined it manually\", function () {\n Job.reopen({\n owner: belongsTo(\'user\', { inverse: \'previousJob\' })\n });\n\n User.reopen({\n previousJob: belongsTo(\'job\')\n });\n\n //Maybe store is evaluated lazily, so we need this :(\n var user, job;\n run(function() {\n user = store.push(\'user\', { id: 1 });\n job = store.push(\'user\', { id: 1 });\n });\n\n deepEqual(Job.inverseFor(\'owner\'), {\n type: User, //the model\'s type\n name: \'previousJob\', //the models relationship key\n kind: \'belongsTo\'\n }, \'Gets correct type, name and kind\');\n\n deepEqual(User.inverseFor(\'previousJob\'), {\n type: Job, //the model\'s type\n name: \'owner\', //the models relationship key\n kind: \'belongsTo\'\n }, \'Gets correct type, name and kind\');\n});\n\ntest(\"Returns null if inverse relationship it is manually set with a different relationship key\", function () {\n Job.reopen({\n user: belongsTo(\'user\', { inverse: \'previousJob\' })\n });\n\n User.reopen({\n job: belongsTo(\'job\')\n });\n //Maybe store is evaluated lazily, so we need this :(\n var user;\n run(function() {\n user = store.push(\'user\', { id: 1 });\n });\n\n equal(User.inverseFor(\'job\'), null, \'There is no inverse\');\n});\n\ntest(\"Errors out if you define 2 inverses to the same model\", function () {\n Job.reopen({\n user: belongsTo(\'user\', { inverse: \'job\' }),\n owner: belongsTo(\'user\', { inverse: \'job\' })\n });\n\n User.reopen({\n job: belongsTo(\'job\')\n });\n\n //Maybe store is evaluated lazily, so we need this :(\n expectAssertion(function() {\n run(function() {\n store.push(\'user\', { id: 1 });\n });\n User.inverseFor(\'job\');\n }, \"You defined the \'job\' relationship on user, but you defined the inverse relationships of type job multiple times. Look at http://emberjs.com/guides/models/defining-models/#toc_explicit-inverses for how to explicitly specify inverses\");\n});\n\n\ntest(\"Caches findInverseFor return value\", function () {\n expect(1);\n //Maybe store is evaluated lazily, so we need this :(\n run(function() {\n store.push(\'user\', { id: 1 });\n });\n\n var inverseForUser = Job.inverseFor(\'user\');\n Job.findInverseFor = function() {\n ok(false, \'Find is not called anymore\');\n };\n\n equal(inverseForUser, Job.inverseFor(\'user\'), \'Inverse cached succesfully\');\n});\n\ntest(\"Errors out if you do not define an inverse for a reflexive relationship\", function () {\n\n //Maybe store is evaluated lazily, so we need this :(\n warns(function() {\n var reflexiveModel;\n run(function() {\n reflexiveModel = store.push(\'reflexiveModel\', { id: 1 });\n });\n }, /Detected a reflexive relationship by the name of \'reflexiveProp\'/);\n});\n})();//# sourceURL=ember-data/integration/inverse-test.js");
268
294
 
269
- 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, record) {\n if (type === Comment) {\n equal(get(record, \'id\'), \'id-1\', \"Comment passed to `createRecord` has \'id-1\' assigned\");\n return Ember.RSVP.resolve();\n } else {\n equal(get(record, \'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");
295
+ 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");
270
296
 
271
- 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, args, record;\n\n Ember.run(function() {\n store.push(\'post\', { id: \'1\', title: \'Clean Post\' });\n });\n\n var callback = function() {\n args = arguments;\n };\n\n debugAdapter.watchRecords(App.Post, callback, callback, callback);\n\n equal(get(args[0], \'length\'), 1);\n record = args[0][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 record = args[0][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 record = args[0][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 var index = args[0];\n var count = args[1];\n equal(index, 1);\n equal(count, 1);\n});\n})();//# sourceURL=ember-data/integration/debug_adapter_test.js");
297
+ 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");
272
298
 
273
- eval("(function() {var get = Ember.get;\nvar set = Ember.set;\nvar forEach = Ember.EnumerableUtils.forEach;\nvar indexOf = Ember.EnumerableUtils.indexOf;\nvar run = Ember.run;\n\nvar Person, store, env, array, recordArray;\n\nvar shouldContain = function(array, item) {\n ok(indexOf(array, item) !== -1, \"array should contain \"+item.get(\'name\'));\n};\n\nvar shouldNotContain = function(array, item) {\n ok(indexOf(array, item) === -1, \"array should not contain \"+item.get(\'name\'));\n};\n\nmodule(\"integration/filter - DS.Model updating\", {\n setup: function() {\n array = [{ id: 1, name: \"Scumbag Dale\", bestFriend: 2 }, { id: 2, name: \"Scumbag Katz\" }, { id: 3, name: \"Scumbag Bryn\" }];\n Person = DS.Model.extend({ name: DS.attr(\'string\'), bestFriend: DS.belongsTo(\'person\', { inverse: null }) });\n\n env = setupStore({ person: Person });\n store = env.store;\n },\n teardown: function() {\n run(store, \'destroy\');\n Person = null;\n array = null;\n }\n});\n\nfunction tapFn(fn, callback) {\n var old_fn = fn;\n\n var new_fn = function() {\n var result = old_fn.apply(this, arguments);\n if (callback) {\n callback.apply(fn, arguments);\n }\n new_fn.summary.called.push(arguments);\n return result;\n };\n new_fn.summary = { called: [] };\n\n return new_fn;\n}\n\n\ntest(\"when a DS.Model updates its attributes, its changes affect its filtered Array membership\", function() {\n run(function() {\n store.pushMany(\'person\', array);\n });\n var people;\n\n run(function() {\n people = store.filter(\'person\', function(hash) {\n if (hash.get(\'name\').match(/Katz$/)) { return true; }\n });\n });\n\n run(function() {\n equal(get(people, \'length\'), 1, \"precond - one item is in the RecordArray\");\n });\n\n var person = people.objectAt(0);\n\n equal(get(person, \'name\'), \"Scumbag Katz\", \"precond - the item is correct\");\n\n run(function() {\n set(person, \'name\', \"Yehuda Katz\");\n });\n\n equal(get(people, \'length\'), 1, \"there is still one item\");\n equal(get(person, \'name\'), \"Yehuda Katz\", \"it has the updated item\");\n\n run(function() {\n set(person, \'name\', \"Yehuda Katz-Foo\");\n });\n\n equal(get(people, \'query\'), null, \'expected no query object set\');\n equal(get(people, \'length\'), 0, \"there are now no items\");\n});\n\ntest(\"when a DS.Model updates its relationships, its changes affect its filtered Array membership\", function() {\n run(function() {\n store.pushMany(\'person\', array);\n });\n var people;\n\n run(function() {\n people = store.filter(\'person\', function(person) {\n if (person.get(\'bestFriend\') && person.get(\'bestFriend.name\').match(/Katz$/)) { return true; }\n });\n });\n\n run(function() {\n equal(get(people, \'length\'), 1, \"precond - one item is in the RecordArray\");\n });\n\n var person = people.objectAt(0);\n\n equal(get(person, \'name\'), \"Scumbag Dale\", \"precond - the item is correct\");\n\n run(function() {\n set(person, \'bestFriend\', null);\n });\n\n equal(get(people, \'length\'), 0, \"there are now 0 items\");\n\n var erik = store.getById(\'person\', 3);\n var yehuda = store.getById(\'person\', 2);\n run(function() {\n erik.set(\'bestFriend\', yehuda);\n });\n\n person = people.objectAt(0);\n equal(get(people, \'length\'), 1, \"there is now 1 item\");\n equal(get(person, \'name\'), \"Scumbag Bryn\", \"precond - the item is correct\");\n});\n\n\ntest(\"a record array can have a filter on it\", function() {\n run(function() {\n store.pushMany(\'person\', array);\n });\n var recordArray;\n\n run(function() {\n recordArray = store.filter(\'person\', function(hash) {\n if (hash.get(\'name\').match(/Scumbag [KD]/)) { return true; }\n });\n });\n\n equal(get(recordArray, \'length\'), 2, \"The Record Array should have the filtered objects on it\");\n\n run(function() {\n store.push(\'person\', { id: 4, name: \"Scumbag Koz\" });\n });\n\n equal(get(recordArray, \'length\'), 3, \"The Record Array should be updated as new items are added to the store\");\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Scumbag Tom\" });\n });\n\n equal(get(recordArray, \'length\'), 2, \"The Record Array should be updated as existing members are updated\");\n});\n\ntest(\"a filtered record array includes created elements\", function() {\n run(function() {\n store.pushMany(\'person\', array);\n });\n var recordArray;\n\n run(function() {\n recordArray = store.filter(\'person\', function(hash) {\n if (hash.get(\'name\').match(/Scumbag [KD]/)) { return true; }\n });\n });\n\n equal(get(recordArray, \'length\'), 2, \"precond - The Record Array should have the filtered objects on it\");\n\n run(function() {\n store.createRecord(\'person\', { name: \"Scumbag Koz\" });\n });\n\n equal(get(recordArray, \'length\'), 3, \"The record array has the new object on it\");\n});\n\ntest(\"a Record Array can update its filter\", function() {\n run(function() {\n set(store, \'adapter\', DS.Adapter.extend({\n deleteRecord: function(store, type, record) {\n return Ember.RSVP.resolve();\n }\n }));\n });\n\n run(function() {\n store.pushMany(\'person\', array);\n });\n\n var dickens = run(function() {\n var record = store.createRecord(\'person\', { id: 4, name: \"Scumbag Dickens\" });\n record.deleteRecord();\n return record;\n });\n var asyncDale, asyncKatz, asyncBryn;\n\n run(function() {\n asyncDale = store.find(\'person\', 1);\n asyncKatz = store.find(\'person\', 2);\n asyncBryn = store.find(\'person\', 3);\n });\n\n store.filter(Person, function(hash) {\n if (hash.get(\'name\').match(/Scumbag [KD]/)) { return true; }\n }).then(async(function(recordArray) {\n\n Ember.RSVP.hash({ dale: asyncDale, katz: asyncKatz, bryn: asyncBryn }).then(async(function(records) {\n shouldContain(recordArray, records.dale);\n shouldContain(recordArray, records.katz);\n shouldNotContain(recordArray, records.bryn);\n shouldNotContain(recordArray, dickens);\n\n Ember.run(function() {\n recordArray.set(\'filterFunction\', function(hash) {\n if (hash.get(\'name\').match(/Katz/)) { return true; }\n });\n });\n\n equal(get(recordArray, \'length\'), 1, \"The Record Array should have one object on it\");\n\n Ember.run(function() {\n store.push(\'person\', { id: 5, name: \"Other Katz\" });\n });\n\n equal(get(recordArray, \'length\'), 2, \"The Record Array now has the new object matching the filter\");\n\n Ember.run(function() {\n store.push(\'person\', { id: 6, name: \"Scumbag Demon\" });\n });\n\n equal(get(recordArray, \'length\'), 2, \"The Record Array doesn\'t have objects matching the old filter\");\n }));\n }));\n});\n\ntest(\"a Record Array can update its filter and notify array observers\", function() {\n run(function() {\n set(store, \'adapter\', DS.Adapter.extend({\n deleteRecord: function(store, type, record) {\n return Ember.RSVP.resolve();\n }\n }));\n });\n\n run(function() {\n store.pushMany(\'person\', array);\n });\n var dickens;\n\n run(function() {\n dickens = store.createRecord(\'person\', { id: 4, name: \"Scumbag Dickens\" });\n dickens.deleteRecord();\n });\n\n var asyncDale, asyncKatz, asyncBryn;\n\n run(function() {\n asyncDale = store.find(\'person\', 1);\n asyncKatz = store.find(\'person\', 2);\n asyncBryn = store.find(\'person\', 3);\n });\n\n store.filter(Person, function(hash) {\n if (hash.get(\'name\').match(/Scumbag [KD]/)) { return true; }\n }).then(async(function(recordArray) {\n\n var didChangeIdx;\n var didChangeRemoved = 0;\n var didChangeAdded = 0;\n\n var arrayObserver = {\n arrayWillChange: Ember.K,\n\n arrayDidChange: function(array, idx, removed, added) {\n didChangeIdx = idx;\n didChangeRemoved += removed;\n didChangeAdded += added;\n }\n };\n\n recordArray.addArrayObserver(arrayObserver);\n\n Ember.run(function() {\n recordArray.set(\'filterFunction\', function(hash) {\n if (hash.get(\'name\').match(/Katz/)) { return true; }\n });\n });\n\n Ember.RSVP.all([asyncDale, asyncKatz, asyncBryn]).then(async(function() {\n equal(didChangeRemoved, 1, \"removed one item from array\");\n didChangeRemoved = 0;\n\n Ember.run(function() {\n store.push(\'person\', { id: 5, name: \"Other Katz\" });\n });\n\n equal(didChangeAdded, 1, \"one item was added\");\n didChangeAdded = 0;\n\n equal(recordArray.objectAt(didChangeIdx).get(\'name\'), \"Other Katz\");\n\n Ember.run(function() {\n store.push(\'person\', { id: 6, name: \"Scumbag Demon\" });\n });\n\n equal(didChangeAdded, 0, \"did not get called when an object that doesn\'t match is added\");\n\n Ember.run(function() {\n recordArray.set(\'filterFunction\', function(hash) {\n if (hash.get(\'name\').match(/Scumbag [KD]/)) { return true; }\n });\n });\n\n equal(didChangeAdded, 2, \"one item is added when going back\");\n equal(recordArray.objectAt(didChangeIdx).get(\'name\'), \"Scumbag Demon\");\n equal(recordArray.objectAt(didChangeIdx-1).get(\'name\'), \"Scumbag Dale\");\n }));\n }));\n});\n\ntest(\"it is possible to filter by computed properties\", function() {\n Person.reopen({\n name: DS.attr(\'string\'),\n upperName: Ember.computed(function() {\n return this.get(\'name\').toUpperCase();\n }).property(\'name\')\n });\n var filter;\n\n run(function() {\n filter = store.filter(\'person\', function(person) {\n return person.get(\'upperName\') === \"TOM DALE\";\n });\n });\n\n equal(filter.get(\'length\'), 0, \"precond - the filter starts empty\");\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n\n equal(filter.get(\'length\'), 1, \"the filter now has a record in it\");\n\n store.find(\'person\', 1).then(async(function(person) {\n Ember.run(function() {\n person.set(\'name\', \"Yehuda Katz\");\n });\n\n equal(filter.get(\'length\'), 0, \"the filter is empty again\");\n }));\n});\n\ntest(\"a filter created after a record is already loaded works\", function() {\n Person.reopen({\n name: DS.attr(\'string\'),\n upperName: Ember.computed(function() {\n return this.get(\'name\').toUpperCase();\n }).property(\'name\')\n });\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n var filter;\n\n run(function() {\n filter = store.filter(\'person\', function(person) {\n return person.get(\'upperName\') === \"TOM DALE\";\n });\n });\n\n equal(filter.get(\'length\'), 1, \"the filter now has a record in it\");\n asyncEqual(filter.objectAt(0), store.find(\'person\', 1));\n});\n\ntest(\"filter with query persists query on the resulting filteredRecordArray\", function() {\n set(store, \'adapter\', DS.Adapter.extend({\n findQuery: function(store, type, id) {\n return Ember.RSVP.resolve([{\n id: id,\n name: \"Tom Dale\"\n }]);\n }\n }));\n var filter;\n\n run(function() {\n filter = store.filter(Person, { foo: 1 }, function(person) {\n return true;\n });\n });\n\n Ember.run(function() {\n filter.then(function(array) {\n deepEqual(get(array, \'query\'), { foo: 1 }, \'has expected query\');\n });\n });\n});\n\n\ntest(\"it is possible to filter by state flags\", function() {\n var filter;\n run(function() {\n set(store, \'adapter\', DS.Adapter.extend({\n find: function(store, type, id) {\n return Ember.RSVP.resolve({ id: id, name: \"Tom Dale\" });\n }\n }));\n\n filter = store.filter(Person, function(person) {\n return person.get(\'isLoaded\');\n });\n });\n\n equal(filter.get(\'length\'), 0, \"precond - there are no records yet\");\n\n Ember.run(function() {\n var asyncPerson = store.find(\'person\', 1);\n\n // Ember.run will block `find` from being synchronously\n // resolved in test mode\n\n equal(filter.get(\'length\'), 0, \"the unloaded record isn\'t in the filter\");\n\n asyncPerson.then(async(function(person) {\n equal(filter.get(\'length\'), 1, \"the now-loaded record is in the filter\");\n asyncEqual(filter.objectAt(0), store.find(\'person\', 1));\n }));\n });\n});\n\ntest(\"it is possible to filter loaded records by dirtiness\", function() {\n set(store, \'adapter\', DS.Adapter.extend({\n updateRecord: function() {\n return Ember.RSVP.resolve();\n }\n }));\n\n var filter = store.filter(\'person\', function(person) {\n return !person.get(\'isDirty\');\n });\n\n run(function() {\n store.push(\'person\', { id: 1, name: \"Tom Dale\" });\n });\n\n store.find(\'person\', 1).then(async(function(person) {\n equal(filter.get(\'length\'), 1, \"the clean record is in the filter\");\n\n // Force synchronous update of the filter, even though\n // we\'re already inside a run loop\n Ember.run(function() {\n person.set(\'name\', \"Yehuda Katz\");\n });\n\n equal(filter.get(\'length\'), 0, \"the now-dirty record is not in the filter\");\n\n return person.save();\n })).then(async(function(person) {\n equal(filter.get(\'length\'), 1, \"the clean record is back in the filter\");\n }));\n});\n\ntest(\"it is possible to filter created records by dirtiness\", function() {\n run(function() {\n set(store, \'adapter\', DS.Adapter.extend({\n createRecord: function() {\n return Ember.RSVP.resolve();\n }\n }));\n });\n\n var filter;\n\n run(function() {\n filter = store.filter(\'person\', function(person) {\n return !person.get(\'isDirty\');\n });\n });\n\n var person;\n\n run(function() {\n person = store.createRecord(\'person\', {\n id: 1,\n name: \"Tom Dale\"\n });\n });\n\n equal(filter.get(\'length\'), 0, \"the dirty record is not in the filter\");\n\n run(function() {\n person.save().then(function(person) {\n equal(filter.get(\'length\'), 1, \"the clean record is in the filter\");\n });\n });\n});\n\ntest(\"it is possible to filter created records by isReloading\", function() {\n set(store, \'adapter\', DS.Adapter.extend({\n find: function() {\n return Ember.RSVP.resolve({\n id: 1,\n name: \"Tom Dalle\"\n });\n }\n }));\n\n var filter = store.filter(\'person\', function(person) {\n return !person.get(\'isReloading\');\n });\n\n var person = store.createRecord(\'person\', {\n id: 1,\n name: \"Tom Dale\"\n });\n\n person.reload().then(async(function(person) {\n equal(filter.get(\'length\'), 1, \"the filter correctly returned a reloaded object\");\n }));\n});\n\n\n// SERVER SIDE TESTS\nvar edited;\n\nvar clientEdits = function(ids) {\n edited = [];\n\n forEach(ids, function(id) {\n // wrap in an Ember.run to guarantee coalescence of the\n // iterated `set` calls and promise resolution.\n Ember.run(function() {\n store.find(\'person\', id).then(function(person) {\n edited.push(person);\n person.set(\'name\', \'Client-side \' + id );\n });\n });\n });\n};\n\nvar clientCreates = function(names) {\n edited = [];\n\n // wrap in an Ember.run to guarantee coalescence of the\n // iterated `set` calls.\n Ember.run(function() {\n forEach(names, function(name) {\n edited.push(store.createRecord(\'person\', { name: \'Client-side \' + name }));\n });\n });\n};\n\nvar serverResponds = function() {\n forEach(edited, function(person) { run(person, \'save\'); });\n};\n\nvar setup = function(serverCallbacks) {\n run(function() {\n set(store, \'adapter\', DS.Adapter.extend(serverCallbacks));\n\n store.pushMany(\'person\', array);\n\n recordArray = store.filter(\'person\', function(hash) {\n if (hash.get(\'name\').match(/Scumbag/)) { return true; }\n });\n });\n\n equal(get(recordArray, \'length\'), 3, \"The filter function should work\");\n};\n\ntest(\"a Record Array can update its filter after server-side updates one record\", function() {\n setup({\n updateRecord: function(store, type, record) {\n return Ember.RSVP.resolve({ id: 1, name: \"Scumbag Server-side Dale\" });\n }\n });\n\n clientEdits([1]);\n equal(get(recordArray, \'length\'), 2, \"The record array updates when the client changes records\");\n\n serverResponds();\n equal(get(recordArray, \'length\'), 3, \"The record array updates when the server changes one record\");\n});\n\ntest(\"a Record Array can update its filter after server-side updates multiple records\", function() {\n setup({\n updateRecord: function(store, type, record) {\n switch (record.get(\'id\')) {\n case \"1\":\n return Ember.RSVP.resolve({ id: 1, name: \"Scumbag Server-side Dale\" });\n case \"2\":\n return Ember.RSVP.resolve({ id: 2, name: \"Scumbag Server-side Katz\" });\n }\n }\n });\n\n clientEdits([1,2]);\n equal(get(recordArray, \'length\'), 1, \"The record array updates when the client changes records\");\n\n serverResponds();\n equal(get(recordArray, \'length\'), 3, \"The record array updates when the server changes multiple records\");\n});\n\ntest(\"a Record Array can update its filter after server-side creates one record\", function() {\n setup({\n createRecord: function(store, type, record) {\n return Ember.RSVP.resolve({ id: 4, name: \"Scumbag Server-side Tim\" });\n }\n });\n\n clientCreates([\"Tim\"]);\n equal(get(recordArray, \'length\'), 3, \"The record array does not include non-matching records\");\n\n serverResponds();\n equal(get(recordArray, \'length\'), 4, \"The record array updates when the server creates a record\");\n});\n\ntest(\"a Record Array can update its filter after server-side creates multiple records\", function() {\n setup({\n createRecord: function(store, type, record) {\n switch (record.get(\'name\')) {\n case \"Client-side Mike\":\n return Ember.RSVP.resolve({ id: 4, name: \"Scumbag Server-side Mike\" });\n case \"Client-side David\":\n return Ember.RSVP.resolve({ id: 5, name: \"Scumbag Server-side David\" });\n }\n }\n });\n\n clientCreates([\"Mike\", \"David\"]);\n equal(get(recordArray, \'length\'), 3, \"The record array does not include non-matching records\");\n\n serverResponds();\n equal(get(recordArray, \'length\'), 5, \"The record array updates when the server creates multiple records\");\n});\n\ntest(\"a Record Array can update its filter after server-side creates multiple records\", function() {\n setup({\n createRecord: function(store, type, record) {\n switch (record.get(\'name\')) {\n case \"Client-side Mike\":\n return Ember.RSVP.resolve({ id: 4, name: \"Scumbag Server-side Mike\" });\n case \"Client-side David\":\n return Ember.RSVP.resolve({ id: 5, name: \"Scumbag Server-side David\" });\n }\n }\n });\n\n clientCreates([\"Mike\", \"David\"]);\n equal(get(recordArray, \'length\'), 3, \"The record array does not include non-matching records\");\n\n serverResponds();\n equal(get(recordArray, \'length\'), 5, \"The record array updates when the server creates multiple records\");\n});\n\ntest(\"destroying filteredRecordArray unregisters models from being filtered\", function() {\n var filterFn = tapFn(function() { return true; });\n var person;\n\n run(function() {\n person = store.push(\'person\', {\n id: 1,\n name: \'Tom Dale\'\n });\n });\n\n var recordArray;\n\n run(function() {\n recordArray = store.filter(\'person\', filterFn);\n });\n\n equal(filterFn.summary.called.length, 1);\n\n Ember.run(function() {\n recordArray.then(function(array) {\n array.destroy();\n });\n });\n clientEdits([1]);\n\n equal(filterFn.summary.called.length, 1, \'expected the filter function not being called anymore\');\n});\n})();//# sourceURL=ember-data/integration/filter_test.js");
299
+ 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");
274
300
 
275
- eval("(function() {var env, store, User, Job, ReflexiveModel;\n\nvar attr = DS.attr;\nvar belongsTo = DS.belongsTo;\nvar run = Ember.run;\n\nfunction stringify(string) {\n return function() { return string; };\n}\n\nmodule(\'integration/inverse_test - inverseFor\', {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n bestFriend: belongsTo(\'user\', { async: true, inverse: null }),\n job: belongsTo(\'job\')\n });\n\n User.toString = stringify(\'user\');\n\n Job = DS.Model.extend({\n isGood: attr(),\n user: belongsTo(\'user\')\n });\n\n Job.toString = stringify(\'job\');\n\n ReflexiveModel = DS.Model.extend({\n reflexiveProp: belongsTo(\'reflexiveModel\')\n });\n\n ReflexiveModel.toString = stringify(\'reflexiveModel\');\n\n env = setupStore({\n user: User,\n job: Job,\n reflexiveModel: ReflexiveModel\n });\n\n store = env.store;\n },\n\n teardown: function() {\n run(env.container, \'destroy\');\n }\n});\n\ntest(\"Finds the inverse when there is only one possible available\", function () {\n //Maybe store is evaluated lazily, so we need this :(\n run(store, \'push\', \'user\', { id: 1 });\n\n deepEqual(Job.inverseFor(\'user\'), {\n type: User,\n name: \'job\',\n kind: \'belongsTo\'\n }, \'Gets correct type, name and kind\');\n});\n\ntest(\"Finds the inverse when only one side has defined it manually\", function () {\n Job.reopen({\n owner: belongsTo(\'user\', { inverse: \'previousJob\' })\n });\n\n User.reopen({\n previousJob: belongsTo(\'job\')\n });\n\n //Maybe store is evaluated lazily, so we need this :(\n var user, job;\n run(function() {\n user = store.push(\'user\', { id: 1 });\n job = store.push(\'user\', { id: 1 });\n });\n\n deepEqual(Job.inverseFor(\'owner\'), {\n type: User, //the model\'s type\n name: \'previousJob\', //the models relationship key\n kind: \'belongsTo\'\n }, \'Gets correct type, name and kind\');\n\n deepEqual(User.inverseFor(\'previousJob\'), {\n type: Job, //the model\'s type\n name: \'owner\', //the models relationship key\n kind: \'belongsTo\'\n }, \'Gets correct type, name and kind\');\n});\n\ntest(\"Returns null if inverse relationship it is manually set with a different relationship key\", function () {\n Job.reopen({\n user: belongsTo(\'user\', { inverse: \'previousJob\' })\n });\n\n User.reopen({\n job: belongsTo(\'job\')\n });\n //Maybe store is evaluated lazily, so we need this :(\n var user;\n run(function() {\n user = store.push(\'user\', { id: 1 });\n });\n\n equal(User.inverseFor(\'job\'), null, \'There is no inverse\');\n});\n\ntest(\"Errors out if you define 2 inverses to the same model\", function () {\n Job.reopen({\n user: belongsTo(\'user\', { inverse: \'job\' }),\n owner: belongsTo(\'user\', { inverse: \'job\' })\n });\n\n User.reopen({\n job: belongsTo(\'job\')\n });\n\n //Maybe store is evaluated lazily, so we need this :(\n expectAssertion(function() {\n run(function() {\n store.push(\'user\', { id: 1 });\n });\n User.inverseFor(\'job\');\n }, \"You defined the \'job\' relationship on user, but you defined the inverse relationships of type job multiple times. Look at http://emberjs.com/guides/models/defining-models/#toc_explicit-inverses for how to explicitly specify inverses\");\n});\n\n\ntest(\"Caches findInverseFor return value\", function () {\n expect(1);\n //Maybe store is evaluated lazily, so we need this :(\n run(function() {\n store.push(\'user\', { id: 1 });\n });\n\n var inverseForUser = Job.inverseFor(\'user\');\n Job.findInverseFor = function() {\n ok(false, \'Find is not called anymore\');\n };\n\n equal(inverseForUser, Job.inverseFor(\'user\'), \'Inverse cached succesfully\');\n});\n\ntest(\"Errors out if you do not define an inverse for a reflexive relationship\", function () {\n\n //Maybe store is evaluated lazily, so we need this :(\n warns(function() {\n var reflexiveModel;\n run(function() {\n reflexiveModel = store.push(\'reflexiveModel\', { id: 1 });\n });\n }, /Detected a reflexive relationship by the name of \'reflexiveProp\'/);\n});\n})();//# sourceURL=ember-data/integration/inverse_test.js");
301
+ eval("(function() {var Post, env;\nvar run = Ember.run;\n\nmodule(\"integration/records/collection_save - Save Collection of Records\", {\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(\"Collection will resolve save on success\", function() {\n expect(1);\n run(function() {\n env.store.createRecord(\'post\', { title: \'Hello\' });\n env.store.createRecord(\'post\', { title: \'World\' });\n });\n\n var posts = env.store.all(\'post\');\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.resolve({ id: 123 });\n };\n\n run(function() {\n posts.save().then(async(function() {\n ok(true, \'save operation was resolved\');\n }));\n });\n});\n\ntest(\"Collection will reject save on error\", function() {\n run(function() {\n env.store.createRecord(\'post\', { title: \'Hello\' });\n env.store.createRecord(\'post\', { title: \'World\' });\n });\n\n var posts = env.store.all(\'post\');\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.reject();\n };\n\n run(function() {\n posts.save().then(function() {}, async(function() {\n ok(true, \'save operation was rejected\');\n }));\n });\n});\n\ntest(\"Retry is allowed in a failure handler\", function() {\n run(function() {\n env.store.createRecord(\'post\', { title: \'Hello\' });\n env.store.createRecord(\'post\', { title: \'World\' });\n });\n\n var posts = env.store.all(\'post\');\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 env.adapter.updateRecord = function(store, type, snapshot) {\n return Ember.RSVP.resolve({ id: 123 });\n };\n\n run(function() {\n posts.save().then(function() {}, async(function() {\n return posts.save();\n })).then(async(function(post) {\n equal(posts.get(\'firstObject.id\'), \'123\', \"The post ID made it through\");\n }));\n });\n});\n\ntest(\"Collection will reject save on invalid\", function() {\n expect(1);\n run(function() {\n env.store.createRecord(\'post\', { title: \'Hello\' });\n env.store.createRecord(\'post\', { title: \'World\' });\n });\n\n var posts = env.store.all(\'post\');\n\n env.adapter.createRecord = function(store, type, snapshot) {\n return Ember.RSVP.reject({ title: \'invalid\' });\n };\n\n Ember.run(function() {\n posts.save().then(function() {}, function() {\n ok(true, \'save operation was rejected\');\n });\n });\n});\n})();//# sourceURL=ember-data/integration/records/collection-save-test.js");
276
302
 
277
- 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, record) {\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, record) {\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");
303
+ eval("(function() {var attr = DS.attr;\nvar Person, env;\nvar run = Ember.run;\n\nmodule(\"integration/deletedRecord - Deleting Records\", {\n setup: function() {\n Person = DS.Model.extend({\n name: attr(\'string\')\n });\n\n Person.toString = function() { return \"Person\"; };\n\n env = setupStore({\n person: Person\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n env.container.destroy();\n });\n }\n});\n\ntest(\"records can be deleted during record array enumeration\", function () {\n var adam, dave;\n run(function() {\n adam = env.store.push(\'person\', { id: 1, name: \"Adam Sunderland\" });\n dave = env.store.push(\'person\', { id: 2, name: \"Dave Sunderland\" });\n });\n var all = env.store.all(\'person\');\n\n // pre-condition\n equal(all.get(\'length\'), 2, \'expected 2 records\');\n\n Ember.run(function() {\n all.forEach(function(record) {\n record.deleteRecord();\n });\n });\n\n equal(all.get(\'length\'), 0, \'expected 0 records\');\n});\n\ntest(\"when deleted records are rolled back, they are still in their previous record arrays\", function () {\n var jaime, cersei;\n run(function() {\n jaime = env.store.push(\'person\', { id: 1, name: \"Jaime Lannister\" });\n cersei = env.store.push(\'person\', { id: 2, name: \"Cersei Lannister\" });\n });\n var all = env.store.all(\'person\');\n var filtered;\n run(function() {\n filtered = env.store.filter(\'person\', function () {\n return true;\n });\n });\n\n equal(all.get(\'length\'), 2, \'precond - we start with two people\');\n equal(filtered.get(\'length\'), 2, \'precond - we start with two people\');\n\n run(function() {\n jaime.deleteRecord();\n jaime.rollback();\n });\n equal(all.get(\'length\'), 2, \'record was not removed\');\n equal(filtered.get(\'length\'), 2, \'record was not removed\');\n});\n})();//# sourceURL=ember-data/integration/records/delete-record-test.js");
278
304
 
279
- 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");
305
+ 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 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 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(\'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");
280
306
 
281
- eval("(function() {var Post, env;\nvar run = Ember.run;\n\nmodule(\"integration/records/collection_save - Save Collection of Records\", {\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(\"Collection will resolve save on success\", function() {\n expect(1);\n run(function() {\n env.store.createRecord(\'post\', { title: \'Hello\' });\n env.store.createRecord(\'post\', { title: \'World\' });\n });\n\n var posts = env.store.all(\'post\');\n\n env.adapter.createRecord = function(store, type, record) {\n return Ember.RSVP.resolve({ id: 123 });\n };\n\n run(function() {\n posts.save().then(async(function() {\n ok(true, \'save operation was resolved\');\n }));\n });\n});\n\ntest(\"Collection will reject save on error\", function() {\n run(function() {\n env.store.createRecord(\'post\', { title: \'Hello\' });\n env.store.createRecord(\'post\', { title: \'World\' });\n });\n\n var posts = env.store.all(\'post\');\n\n env.adapter.createRecord = function(store, type, record) {\n return Ember.RSVP.reject();\n };\n\n run(function() {\n posts.save().then(function() {}, async(function() {\n ok(true, \'save operation was rejected\');\n }));\n });\n});\n\ntest(\"Retry is allowed in a failure handler\", function() {\n run(function() {\n env.store.createRecord(\'post\', { title: \'Hello\' });\n env.store.createRecord(\'post\', { title: \'World\' });\n });\n\n var posts = env.store.all(\'post\');\n\n var count = 0;\n\n env.adapter.createRecord = function(store, type, record) {\n if (count++ === 0) {\n return Ember.RSVP.reject();\n } else {\n return Ember.RSVP.resolve({ id: 123 });\n }\n };\n\n env.adapter.updateRecord = function(store, type, record) {\n return Ember.RSVP.resolve({ id: 123 });\n };\n\n run(function() {\n posts.save().then(function() {}, async(function() {\n return posts.save();\n })).then(async(function(post) {\n equal(posts.get(\'firstObject.id\'), \'123\', \"The post ID made it through\");\n }));\n });\n});\n\ntest(\"Collection will reject save on invalid\", function() {\n expect(1);\n run(function() {\n env.store.createRecord(\'post\', { title: \'Hello\' });\n env.store.createRecord(\'post\', { title: \'World\' });\n });\n\n var posts = env.store.all(\'post\');\n\n env.adapter.createRecord = function(store, type, record) {\n return Ember.RSVP.reject({ title: \'invalid\' });\n };\n\n Ember.run(function() {\n posts.save().then(function() {}, function() {\n ok(true, \'save operation was rejected\');\n });\n });\n});\n})();//# sourceURL=ember-data/integration/records/collection_save_test.js");
307
+ 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");
282
308
 
283
- eval("(function() {var attr = DS.attr;\nvar Person, env;\nvar run = Ember.run;\n\nmodule(\"integration/deletedRecord - Deleting Records\", {\n setup: function() {\n Person = DS.Model.extend({\n name: attr(\'string\')\n });\n\n Person.toString = function() { return \"Person\"; };\n\n env = setupStore({\n person: Person\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n env.container.destroy();\n });\n }\n});\n\ntest(\"records can be deleted during record array enumeration\", function () {\n var adam, dave;\n run(function() {\n adam = env.store.push(\'person\', { id: 1, name: \"Adam Sunderland\" });\n dave = env.store.push(\'person\', { id: 2, name: \"Dave Sunderland\" });\n });\n var all = env.store.all(\'person\');\n\n // pre-condition\n equal(all.get(\'length\'), 2, \'expected 2 records\');\n\n Ember.run(function() {\n all.forEach(function(record) {\n record.deleteRecord();\n });\n });\n\n equal(all.get(\'length\'), 0, \'expected 0 records\');\n});\n\ntest(\"when deleted records are rolled back, they are still in their previous record arrays\", function () {\n var jaime, cersei;\n run(function() {\n jaime = env.store.push(\'person\', { id: 1, name: \"Jaime Lannister\" });\n cersei = env.store.push(\'person\', { id: 2, name: \"Cersei Lannister\" });\n });\n var all = env.store.all(\'person\');\n var filtered;\n run(function() {\n filtered = env.store.filter(\'person\', function () {\n return true;\n });\n });\n\n equal(all.get(\'length\'), 2, \'precond - we start with two people\');\n equal(filtered.get(\'length\'), 2, \'precond - we start with two people\');\n\n run(function() {\n jaime.deleteRecord();\n jaime.rollback();\n });\n equal(all.get(\'length\'), 2, \'record was not removed\');\n equal(filtered.get(\'length\'), 2, \'record was not removed\');\n});\n})();//# sourceURL=ember-data/integration/records/delete_record_test.js");
309
+ eval("(function() {var attr = DS.attr;\nvar belongsTo = DS.belongsTo;\nvar hasMany = DS.hasMany;\nvar run = Ember.run;\nvar env;\n\nvar Person = DS.Model.extend({\n name: attr(\'string\'),\n cars: hasMany(\'car\')\n});\n\nPerson.toString = function() { return \"Person\"; };\n\nvar Group = DS.Model.extend({\n people: hasMany(\'person\')\n});\n\nGroup.toString = function() { return \"Group\"; };\n\nvar Car = DS.Model.extend({\n make: attr(\'string\'),\n model: attr(\'string\'),\n person: belongsTo(\'person\')\n});\n\nCar.toString = function() { return \"Car\"; };\n\nmodule(\"integration/unload - Unloading Records\", {\n setup: function() {\n env = setupStore({\n person: Person,\n car: Car,\n group: Group\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n env.container.destroy();\n });\n }\n});\n\ntest(\"can unload a single record\", function () {\n var adam;\n run(function() {\n adam = env.store.push(\'person\', { id: 1, name: \"Adam Sunderland\" });\n });\n\n Ember.run(function() {\n adam.unloadRecord();\n });\n\n equal(env.store.all(\'person\').get(\'length\'), 0);\n});\n\ntest(\"can unload all records for a given type\", function () {\n var adam, bob;\n run(function() {\n adam = env.store.push(\'person\', { id: 1, name: \"Adam Sunderland\" });\n bob = env.store.push(\'person\', { id: 2, name: \"Bob Bobson\" });\n });\n\n Ember.run(function() {\n env.store.unloadAll(\'person\');\n });\n\n equal(env.store.all(\'person\').get(\'length\'), 0);\n});\n\ntest(\"removes findAllCache after unloading all records\", function () {\n var adam, bob;\n run(function() {\n adam = env.store.push(\'person\', { id: 1, name: \"Adam Sunderland\" });\n bob = env.store.push(\'person\', { id: 2, name: \"Bob Bobson\" });\n });\n\n Ember.run(function() {\n env.store.all(\'person\');\n env.store.unloadAll(\'person\');\n });\n\n equal(env.store.all(\'person\').get(\'length\'), 0);\n});\n\ntest(\"unloading all records also updates record array from all()\", function() {\n var adam, bob;\n run(function() {\n adam = env.store.push(\'person\', { id: 1, name: \"Adam Sunderland\" });\n bob = env.store.push(\'person\', { id: 2, name: \"Bob Bobson\" });\n });\n var all = env.store.all(\'person\');\n\n equal(all.get(\'length\'), 2);\n\n Ember.run(function() {\n env.store.unloadAll(\'person\');\n });\n\n equal(all.get(\'length\'), 0);\n});\n\n\ntest(\"unloading a record also clears its relationship\", function() {\n var adam, bob;\n run(function() {\n adam = env.store.push(\'person\', {\n id: 1,\n name: \"Adam Sunderland\",\n cars: [1]\n });\n });\n\n run(function() {\n bob = env.store.push(\'car\', {\n id: 1,\n make: \"Lotus\",\n model: \"Exige\",\n person: 1\n });\n });\n\n run(function() {\n env.store.find(\'person\', 1).then(function(person) {\n equal(person.get(\'cars.length\'), 1, \'The inital length of cars is correct\');\n\n run(function() {\n person.unloadRecord();\n });\n\n equal(person.get(\'cars.length\'), undefined);\n });\n });\n});\n\ntest(\"unloading a record also clears the implicit inverse relationships\", function() {\n var adam, bob;\n run(function() {\n adam = env.store.push(\'person\', {\n id: 1,\n name: \"Adam Sunderland\"\n });\n });\n\n run(function() {\n bob = env.store.push(\'group\', {\n id: 1,\n people: [1]\n });\n });\n\n run(function() {\n env.store.find(\'group\', 1).then(function(group) {\n equal(group.get(\'people.length\'), 1, \'The inital length of people is correct\');\n var person = env.store.getById(\'person\', 1);\n run(function() {\n person.unloadRecord();\n });\n\n equal(group.get(\'people.length\'), 0, \'Person was removed from the people array\');\n });\n });\n});\n})();//# sourceURL=ember-data/integration/records/unload-test.js");
284
310
 
285
- 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) {\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) {\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 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(\'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) {\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");
311
+ eval("(function() {var env, store, User, Message, Post, Contact, Comment, Book, 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 });\n\n Author = DS.Model.extend({\n name: attr(\'string\')\n });\n\n env = setupStore({\n user: User,\n post: Post,\n comment: Comment,\n message: Message,\n book: Book,\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})();//# sourceURL=ember-data/integration/relationships/belongs-to-test.js");
286
312
 
287
- 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, record) {\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, record) {\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, record) {\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, record) {\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, record) {\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");
313
+ eval("(function() {var env, 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\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(3);\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 });\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})();//# sourceURL=ember-data/integration/relationships/has-many-test.js");
288
314
 
289
- eval("(function() {var attr = DS.attr;\nvar belongsTo = DS.belongsTo;\nvar hasMany = DS.hasMany;\nvar run = Ember.run;\nvar env;\n\nvar Person = DS.Model.extend({\n name: attr(\'string\'),\n cars: hasMany(\'car\')\n});\n\nvar Car = DS.Model.extend({\n make: attr(\'string\'),\n model: attr(\'string\'),\n person: belongsTo(\'person\')\n});\n\nPerson.toString = function() { return \"Person\"; };\n\nmodule(\"integration/unload - Unloading Records\", {\n setup: function() {\n env = setupStore({\n person: Person,\n car: Car\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n env.container.destroy();\n });\n }\n});\n\ntest(\"can unload a single record\", function () {\n var adam;\n run(function() {\n adam = env.store.push(\'person\', { id: 1, name: \"Adam Sunderland\" });\n });\n\n Ember.run(function() {\n adam.unloadRecord();\n });\n\n equal(env.store.all(\'person\').get(\'length\'), 0);\n});\n\ntest(\"can unload all records for a given type\", function () {\n var adam, bob;\n run(function() {\n adam = env.store.push(\'person\', { id: 1, name: \"Adam Sunderland\" });\n bob = env.store.push(\'person\', { id: 2, name: \"Bob Bobson\" });\n });\n\n Ember.run(function() {\n env.store.unloadAll(\'person\');\n });\n\n equal(env.store.all(\'person\').get(\'length\'), 0);\n});\n\ntest(\"removes findAllCache after unloading all records\", function () {\n var adam, bob;\n run(function() {\n adam = env.store.push(\'person\', { id: 1, name: \"Adam Sunderland\" });\n bob = env.store.push(\'person\', { id: 2, name: \"Bob Bobson\" });\n });\n\n Ember.run(function() {\n env.store.all(\'person\');\n env.store.unloadAll(\'person\');\n });\n\n equal(env.store.all(\'person\').get(\'length\'), 0);\n});\n\ntest(\"unloading all records also updates record array from all()\", function() {\n var adam, bob;\n run(function() {\n adam = env.store.push(\'person\', { id: 1, name: \"Adam Sunderland\" });\n bob = env.store.push(\'person\', { id: 2, name: \"Bob Bobson\" });\n });\n var all = env.store.all(\'person\');\n\n equal(all.get(\'length\'), 2);\n\n Ember.run(function() {\n env.store.unloadAll(\'person\');\n });\n\n equal(all.get(\'length\'), 0);\n});\n\n\n//TODO(Igor) think about how this works with ssot and unloading\ntest(\"unloading a record also clears its relationship\", function() {\n var adam, bob;\n run(function() {\n adam = env.store.push(\'person\', {\n id: 1,\n name: \"Adam Sunderland\",\n cars: [1]\n });\n });\n\n run(function() {\n bob = env.store.push(\'car\', {\n id: 1,\n make: \"Lotus\",\n model: \"Exige\",\n person: 1\n });\n });\n\n run(function() {\n env.store.find(\'person\', 1).then(function(person) {\n equal(person.get(\'cars.length\'), 1, \'aaaa\');\n\n run(function() {\n person.unloadRecord();\n });\n\n equal(person.get(\'cars.length\'), undefined);\n });\n });\n});\n})();//# sourceURL=ember-data/integration/records/unload_test.js");
315
+ 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");
290
316
 
291
- eval("(function() {var env, store, User, Message, Post, Contact, Comment, Book, 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 });\n\n Author = DS.Model.extend({\n name: attr(\'string\')\n });\n\n env = setupStore({\n user: User,\n post: Post,\n comment: Comment,\n message: Message,\n book: Book,\n author: Author\n });\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) {\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 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 env.serializer.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() {\n throw new Error(\"Adapter\'s find method should not be called\");\n };\n\n env.adapter.findBelongsTo = async(function(store, record, 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() {\n throw new Error(\"Adapter\'s find method should not be called\");\n };\n\n env.adapter.findBelongsTo = async(function(store, record, 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() {\n throw new Error(\"Adapter\'s find method should not be called\");\n };\n\n env.adapter.findBelongsTo = async(function(store, record, 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, record) {\n ok(record instanceof type);\n equal(record.id, 1, \'should first comment\');\n return record.toJSON({ includeId: true });\n };\n\n env.adapter.findMany = function(store, type, ids, records) {\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() {\n throw new Error(\"Adapter\'s find method should not be called\");\n };\n\n env.adapter.deleteRecord = function(store, type, record) {\n ok(record instanceof type);\n equal(record.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})();//# sourceURL=ember-data/integration/relationships/belongs_to_test.js");
317
+ eval("(function() {var Account, Topic, User, store, env;\nvar run = Ember.run;\n\nvar attr = DS.attr;\nvar hasMany = DS.hasMany;\n\nfunction stringify(string) {\n return function() { return string; };\n}\n\nmodule(\'integration/relationships/many_to_many_test - ManyToMany relationships\', {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n topics: hasMany(\'topic\', { async: true }),\n accounts: hasMany(\'account\')\n });\n\n User.toString = stringify(\'User\');\n\n Account = DS.Model.extend({\n state: attr(),\n users: hasMany(\'user\')\n });\n\n Account.toString = stringify(\'Account\');\n\n Topic = DS.Model.extend({\n title: attr(\'string\'),\n users: hasMany(\'user\', { async: true })\n });\n\n Topic.toString = stringify(\'Topic\');\n\n env = setupStore({\n user: User,\n topic: Topic,\n account: Account\n });\n\n store = env.store;\n },\n\n teardown: function() {\n run(function() {\n env.container.destroy();\n });\n }\n});\n\n/*\n Server loading tests\n*/\n\ntest(\"Loading from one hasMany side reflects on the other hasMany side - async\", function () {\n run(function() {\n store.push(\'user\', { id: 1, name: \'Stanley\', topics: [2, 3] });\n });\n var topic = run(function() {\n return store.push(\'topic\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 1, \'User relationship was set up correctly\');\n }));\n });\n});\n\ntest(\"Relationship is available from the belongsTo side even if only loaded from the hasMany side - sync\", function () {\n var account;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n run(function() {\n equal(account.get(\'users.length\'), 1, \'User relationship was set up correctly\');\n });\n});\n\ntest(\"Fetching a hasMany where a record was removed reflects on the other hasMany side - async\", function () {\n var user, topic;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', topics: [2] });\n topic = store.push(\'topic\', { id: 2, title: \'EmberFest was great\', users: [] });\n });\n run(function() {\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 0, \'Topics were removed correctly\');\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 0, \'Users were removed correctly\');\n }));\n }));\n });\n});\n\ntest(\"Fetching a hasMany where a record was removed reflects on the other hasMany side - async\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n account = store.push(\'account\', { id: 2 , state: \'lonely\', users: [] });\n });\n equal(user.get(\'accounts.length\'), 0, \'Accounts were removed correctly\');\n equal(account.get(\'users.length\'), 0, \'Users were removed correctly\');\n});\n\n/*\n Local edits\n*/\n\ntest(\"Pushing to a hasMany reflects on the other hasMany side - async\", function () {\n expect(1);\n var user, topic;\n\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', topics: [] });\n topic = store.push(\'topic\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n topic.get(\'users\').then(async(function(fetchedUsers) {\n fetchedUsers.pushObject(user);\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 1, \'User relationship was set up correctly\');\n }));\n }));\n });\n});\n\ntest(\"Pushing to a hasMany reflects on the other hasMany side - sync\", function () {\n var account, stanley;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\' });\n stanley.get(\'accounts\').pushObject(account);\n });\n equal(account.get(\'users.length\'), 1, \'User relationship was set up correctly\');\n});\n\ntest(\"Removing a record from a hasMany reflects on the other hasMany side - async\", function () {\n var user, topic;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', topics: [2] });\n topic = store.push(\'topic\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 1, \'Topics were setup correctly\');\n fetchedTopics.removeObject(topic);\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 0, \'Users were removed correctly\');\n }));\n }));\n });\n});\n\ntest(\"Removing a record from a hasMany reflects on the other hasMany side - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n equal(account.get(\'users.length\'), 1, \'Users were setup correctly\');\n run(function() {\n account.get(\'users\').removeObject(user);\n });\n equal(user.get(\'accounts.length\'), 0, \'Accounts were removed correctly\');\n equal(account.get(\'users.length\'), 0, \'Users were removed correctly\');\n});\n\n/*\nDeleting tests\n*/\n\ntest(\"Deleting a record that has a hasMany relationship removes it from the otherMany array but does not remove the other record from itself - async\", function () {\n var user, topic;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', topics: [2] });\n topic = store.push(\'topic\', { id: 2, title: \'EmberFest was great\' });\n });\n run(topic, \'deleteRecord\');\n run(function() {\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 1, \'Users are still there\');\n }));\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 0, \'Topic got removed from the user\');\n }));\n });\n});\n\ntest(\"Deleting a record that has a hasMany relationship removes it from the otherMany array but does not remove the other record from itself - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n run(account, \'deleteRecord\');\n equal(account.get(\'users.length\'), 1, \'Users are still there\');\n equal(user.get(\'accounts.length\'), 0, \'Acocount got removed from the user\');\n});\n\n/*\n Rollback tests\n*/\n\ntest(\"Rollbacking a deleted record that has a ManyToMany relationship works correctly - async\", function () {\n var user, topic;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', topics: [2] });\n topic = store.push(\'topic\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n topic.deleteRecord();\n topic.rollback();\n });\n run(function() {\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 1, \'Users are still there\');\n }));\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 1, \'Topic got rollbacked into the user\');\n }));\n });\n});\n\ntest(\"Deleting a record that has a hasMany relationship removes it from the otherMany array but does not remove the other record from itself - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n run(function() {\n account.deleteRecord();\n account.rollback();\n });\n equal(account.get(\'users.length\'), 1, \'Users are still there\');\n equal(user.get(\'accounts.length\'), 1, \'Account got rolledback correctly into the user\');\n});\n\ntest(\"Rollbacking a created record that has a ManyToMany relationship works correctly - async\", function () {\n var user, topic;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n topic = store.createRecord(\'topic\');\n });\n run(function() {\n user.get(\'topics\').then(async(function(fetchedTopics) {\n fetchedTopics.pushObject(topic);\n topic.rollback();\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 0, \'Users got removed\');\n }));\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 0, \'Topics got removed\');\n }));\n }));\n });\n});\n\ntest(\"Deleting a record that has a hasMany relationship removes it from the otherMany array but does not remove the other record from itself - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.createRecord(\'user\');\n });\n run(function() {\n account.get(\'users\').pushObject(user);\n user.rollback();\n });\n equal(account.get(\'users.length\'), 0, \'Users got removed\');\n equal(user.get(\'accounts.length\'), undefined, \'Accounts got rolledback correctly\');\n});\n\n\ntest(\"Re-loading a removed record should re add it to the relationship when the removed record is the last one in the relationship\", function () {\n var account, ada, byron;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'account 1\' });\n ada = store.push(\'user\', { id: 1, name: \'Ada Lovelace\', accounts: [2] });\n byron = store.push(\'user\', { id: 2, name: \'Lord Byron\', accounts: [2] });\n account.get(\'users\').removeObject(byron);\n account = store.push(\'account\', { id: 2 , state: \'account 1\', users: [1, 2] });\n });\n\n equal(account.get(\'users.length\'), 2, \'Accounts were updated correctly\');\n});\n})();//# sourceURL=ember-data/integration/relationships/many-to-many-test.js");
292
318
 
293
- eval("(function() {var env, 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\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() {\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, records) {\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) {\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() {\n throw new Error(\"Adapter\'s findMany should not be called\");\n };\n\n env.adapter.findHasMany = function(store, record, 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, record, 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, record, 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, record, link, relationship) {\n return Ember.RSVP.resolve([]);\n };\n\n env.adapter.createRecord = function(store, record, 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, record, link, relationship) {\n return Ember.RSVP.resolve([{ id: 5, body: \'hello\' }]);\n };\n\n env.adapter.createRecord = function(store, record, 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) {\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, record, 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, record, 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) {\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, records) {\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) {\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, records) {\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, records) {\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) {\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, records) {\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, record, 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, record, 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, record, 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() {\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) {\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(3);\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 });\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, record) {\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, record) {\n var data = 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() {\n return resolve([{ id: 1, body: \'first\' }, { id: 2, body: \'second\' }]);\n };\n\n env.adapter.find = function() {\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})();//# sourceURL=ember-data/integration/relationships/has_many_test.js");
319
+ eval("(function() {var env, store, User, Message, Account;\nvar get = Ember.get;\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/one_to_many_test - OneToMany relationships\', {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n messages: hasMany(\'message\', { async: true }),\n accounts: hasMany(\'account\')\n });\n User.toString = stringify(\'User\');\n\n Account = DS.Model.extend({\n state: attr(),\n user: belongsTo(\'user\')\n });\n Account.toString = stringify(\'Account\');\n\n Message = DS.Model.extend({\n title: attr(\'string\'),\n user: belongsTo(\'user\', { async: true })\n });\n Message.toString = stringify(\'Message\');\n\n env = setupStore({\n user: User,\n message: Message,\n account: Account\n });\n\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, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [2, 3] });\n message = store.push(\'message\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'User relationship was set up correctly\');\n });\n });\n});\n\ntest(\"Relationship is available from the belongsTo side even if only loaded from the hasMany side - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n equal(account.get(\'user\'), user, \'User relationship was set up correctly\');\n});\n\ntest(\"Relationship is available from the hasMany side even if only loaded from the belongsTo side - async\", function () {\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n message = store.push(\'message\', { id: 2, title: \'EmberFest was great\', user: 1 });\n });\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(fetchedMessages.objectAt(0), message, \'Messages relationship was set up correctly\');\n });\n });\n});\n\ntest(\"Relationship is available from the hasMany side even if only loaded from the belongsTo side - sync\", function () {\n var user, account;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n account = store.push(\'account\', { id: 2 , state: \'lonely\', user: 1 });\n });\n equal(user.get(\'accounts\').objectAt(0), account, \'Accounts relationship was set up correctly\');\n});\n\ntest(\"Fetching a belongsTo that is set to null removes the record from a relationship - async\", function () {\n var user;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1,2] });\n });\n run(function() {\n store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n store.push(\'message\', { id: 2, title: \'EmberConf will be better\', user: null });\n });\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(get(fetchedMessages, \'length\'), 1, \'Messages relationship was set up correctly\');\n });\n });\n});\n\ntest(\"Fetching a belongsTo that is set to null removes the record from a relationship - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n account = store.push(\'account\', { id: 2 , state: \'lonely\', user: null });\n });\n equal(user.get(\'accounts\').objectAt(0), null, \'Account was sucesfully removed\');\n});\n\ntest(\"Fetching a belongsTo that is not defined does not remove the record from a relationship - async\", function () {\n var user;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1,2] });\n });\n run(function() {\n store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n store.push(\'message\', { id: 2, title: \'EmberConf will be better\' });\n });\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(get(fetchedMessages, \'length\'), 2, \'Messages relationship was set up correctly\');\n });\n });\n});\n\ntest(\"Fetching a belongsTo that is not defined does not remove the record from a relationship - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n });\n equal(user.get(\'accounts\').objectAt(0), account, \'Account was sucesfully removed\');\n});\n\ntest(\"Fetching the hasMany that doesn\'t contain the belongsTo, sets the belongsTo to null - async\", function () {\n var user, message, message2;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n message2 = store.push(\'message\', { id: 2, title: \'EmberConf is gonna be better\' });\n });\n run(function() {\n store.push(\'user\', { id: 1, name: \'Stanley\', messages: [2] });\n });\n\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'User was removed correctly\');\n });\n\n message2.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'User was set on the second message\');\n });\n });\n});\n\ntest(\"Fetching the hasMany that doesn\'t contain the belongsTo, sets the belongsTo to null - sync\", function () {\n var account;\n run(function() {\n store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n account = store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n store.push(\'account\', { id: 2, state: \'awesome\' });\n store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n\n equal(account.get(\'user\'), null, \'User was removed correctly\');\n});\n\ntest(\"Fetching the hasMany side where the hasMany is undefined does not change the belongsTo side - async\", function () {\n var message, user;\n run(function() {\n store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n });\n\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'User was not removed\');\n });\n });\n});\n\ntest(\"Fetching the hasMany side where the hasMany is undefined does not change the belongsTo side - sync\", function () {\n var account, user;\n run(function() {\n store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n account = store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n store.push(\'account\', { id: 2, state: \'awesome\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n });\n\n equal(account.get(\'user\'), user, \'User was not removed\');\n});\n\n/*\n Local edits\n*/\n\ntest(\"Pushing to the hasMany reflects the change on the belongsTo side - async\", function () {\n var user, message2;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n store.push(\'message\', { id: 1, title: \'EmberFest was great\' });\n message2 = store.push(\'message\', { id: 2, title: \'EmberFest was great\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n fetchedMessages.pushObject(message2);\n message2.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \"user got set correctly\");\n });\n });\n });\n});\n\ntest(\"Pushing to the hasMany reflects the change on the belongsTo side - sync\", function () {\n var user, account2;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n\n account2 = store.push(\'account\', { id: 2, state: \'awesome\' });\n user.get(\'accounts\').pushObject(account2);\n });\n\n equal(account2.get(\'user\'), user, \'user got set correctly\');\n});\n\ntest(\"Removing from the hasMany side reflects the change on the belongsTo side - async\", function () {\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n fetchedMessages.removeObject(message);\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, null, \"user got removed correctly\");\n });\n });\n });\n});\n\ntest(\"Removing from the hasMany side reflects the change on the belongsTo side - sync\", function () {\n var user, account;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n account = store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n });\n run(function() {\n user.get(\'accounts\').removeObject(account);\n });\n\n equal(account.get(\'user\'), null, \'user got removed correctly\');\n});\n\ntest(\"Pushing to the hasMany side keeps the oneToMany invariant on the belongsTo side - async\", function () {\n expect(2);\n var user, user2, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n user2 = store.push(\'user\', { id: 2, name: \'Tomhuda\' });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\' });\n });\n\n run(function() {\n user2.get(\'messages\').then(function(fetchedMessages) {\n fetchedMessages.pushObject(message);\n\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user2, \"user got set correctly\");\n });\n\n user.get(\'messages\').then(function(newFetchedMessages) {\n equal(get(newFetchedMessages, \'length\'), 0, \'message got removed from the old messages hasMany\');\n });\n });\n });\n});\n\ntest(\"Pushing to the hasMany side keeps the oneToMany invariant - sync\", function () {\n var user, user2, account;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n user2 = store.push(\'user\', { id: 2, name: \'Stanley\' });\n account = store.push(\'account\', { id: 1, state: \'great\' });\n user2.get(\'accounts\').pushObject(account);\n });\n\n equal(account.get(\'user\'), user2, \'user got set correctly\');\n equal(user.get(\'accounts.length\'), 0, \'the account got removed correctly\');\n equal(user2.get(\'accounts.length\'), 1, \'the account got pushed correctly\');\n});\n\ntest(\"Setting the belongsTo side keeps the oneToMany invariant on the hasMany- async\", function () {\n expect(2);\n var user, user2, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n user2 = store.push(\'user\', { id: 2, name: \'Tomhuda\' });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n message.set(\'user\', user2);\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(get(fetchedMessages, \'length\'), 0, \'message got removed from the first user correctly\');\n });\n });\n run(function() {\n user2.get(\'messages\').then(function(fetchedMessages) {\n equal(get(fetchedMessages, \'length\'), 1, \'message got added to the second user correctly\');\n });\n });\n});\n\ntest(\"Setting the belongsTo side keeps the oneToMany invariant on the hasMany- sync\", function () {\n var user, user2, account;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n user2 = store.push(\'user\', { id: 2, name: \'Stanley\' });\n account = store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n account.set(\'user\', user2);\n });\n\n equal(account.get(\'user\'), user2, \'user got set correctly\');\n\n equal(user.get(\'accounts.length\'), 0, \'the account got removed correctly\');\n equal(user2.get(\'accounts.length\'), 1, \'the account got pushed correctly\');\n});\n\n\ntest(\"Setting the belongsTo side to null removes the record from the hasMany side - async\", function () {\n expect(2);\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n message.set(\'user\', null);\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(get(fetchedMessages, \'length\'), 0, \'message got removed from the user correctly\');\n });\n });\n\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'user got set to null correctly\');\n });\n });\n});\n\ntest(\"Setting the belongsTo side to null removes the record from the hasMany side - sync\", function () {\n var user, account;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n account = store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n account.set(\'user\', null);\n });\n\n equal(account.get(\'user\'), null, \'user got set to null correctly\');\n\n equal(user.get(\'accounts.length\'), 0, \'the account got removed correctly\');\n});\n\n/*\nDeleting\n*/\n\ntest(\"When deleting a record that has a belongsTo it is removed from the hasMany side but not the belongsTo side- async\", function () {\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [2] });\n message = store.push(\'message\', { id: 2, title: \'EmberFest was great\' });\n });\n run(message, \'deleteRecord\');\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'Message still has the user\');\n });\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(fetchedMessages.get(\'length\'), 0, \'User was removed from the messages\');\n });\n });\n});\n\ntest(\"When deleting a record that has a belongsTo it is removed from the hasMany side but not the belongsTo side- sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n account.deleteRecord();\n });\n equal(user.get(\'accounts.length\'), 0, \"User was removed from the accounts\");\n equal(account.get(\'user\'), user, \'Account still has the user\');\n});\n\ntest(\"When deleting a record that has a hasMany it is removed from the belongsTo side but not the hasMany side- async\", function () {\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [2] });\n message = store.push(\'message\', { id: 2, title: \'EmberFest was great\' });\n });\n run(user, \'deleteRecord\');\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'Message does not have the user anymore\');\n });\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(fetchedMessages.get(\'length\'), 1, \'User still has the messages\');\n });\n });\n});\n\ntest(\"When deleting a record that has a hasMany it is removed from the belongsTo side but not the hasMany side - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n run(function() {\n user.deleteRecord();\n });\n equal(user.get(\'accounts.length\'), 1, \"User still has the accounts\");\n equal(account.get(\'user\'), null, \'Account no longer has the user\');\n});\n\n/*\nRollback from deleted state\n*/\n\ntest(\"Rollbacking a deleted record works correctly when the hasMany side has been deleted - async\", function () {\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [2] });\n message = store.push(\'message\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n message.deleteRecord();\n message.rollback();\n });\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'Message still has the user\');\n });\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(fetchedMessages.objectAt(0), message, \'User has the message\');\n });\n });\n});\n\ntest(\"Rollbacking a deleted record works correctly when the hasMany side has been deleted - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n run(function() {\n account.deleteRecord();\n account.rollback();\n });\n equal(user.get(\'accounts.length\'), 1, \"Accounts are rolled back\");\n equal(account.get(\'user\'), user, \'Account still has the user\');\n});\n\ntest(\"Rollbacking a deleted record works correctly when the belongsTo side has been deleted - async\", function () {\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [2] });\n message = store.push(\'message\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n user.deleteRecord();\n user.rollback();\n });\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'Message has the user again\');\n });\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(fetchedMessages.get(\'length\'), 1, \'User still has the messages\');\n });\n });\n});\n\ntest(\"Rollbacking a deleted record works correctly when the belongsTo side has been deleted - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n run(function() {\n user.deleteRecord();\n user.rollback();\n });\n equal(user.get(\'accounts.length\'), 1, \"User still has the accounts\");\n equal(account.get(\'user\'), user, \'Account has the user again\');\n});\n\n/*\nRollback from created state\n*/\n\ntest(\"Rollbacking a created record works correctly when the hasMany side has been created - async\", function () {\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n message = store.createRecord(\'message\', { user: user });\n });\n run(message, \'rollback\');\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'Message does not have the user anymore\');\n });\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(fetchedMessages.get(\'length\'), 0, message, \'User does not have the message anymore\');\n });\n });\n});\n\ntest(\"Rollbacking a created record works correctly when the hasMany side has been created - sync\", function () {\n var user, account;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n account = store.createRecord(\'account\', { user: user });\n });\n run(account, \'rollback\');\n equal(user.get(\'accounts.length\'), 0, \"Accounts are rolled back\");\n equal(account.get(\'user\'), null, \'Account does not have the user anymore\');\n});\n\ntest(\"Rollbacking a created record works correctly when the belongsTo side has been created - async\", function () {\n var message, user;\n run(function() {\n message = store.push(\'message\', { id: 2, title: \'EmberFest was great\' });\n user = store.createRecord(\'user\');\n });\n run(function() {\n user.get(\'messages\').then(function(messages) {\n messages.pushObject(message);\n user.rollback();\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'Message does not have the user anymore\');\n });\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(fetchedMessages.get(\'length\'), 0, \'User does not have the message anymore\');\n });\n });\n });\n});\n\ntest(\"Rollbacking a created record works correctly when the belongsTo side has been created - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.createRecord(\'user\');\n });\n run(function() {\n user.get(\'accounts\').pushObject(account);\n });\n run(user, \'rollback\');\n equal(user.get(\'accounts.length\'), undefined, \"User does not have the account anymore\");\n equal(account.get(\'user\'), null, \'Account does not have the user anymore\');\n});\n})();//# sourceURL=ember-data/integration/relationships/one-to-many-test.js");
294
320
 
295
- 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");
321
+ eval("(function() {var env, store, User, Job;\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/one_to_one_test - OneToOne relationships\', {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n bestFriend: belongsTo(\'user\', { async: true, inverse: \'bestFriend\' }),\n job: belongsTo(\'job\')\n });\n User.toString = stringify(\'User\');\n\n Job = DS.Model.extend({\n isGood: attr(),\n user: belongsTo(\'user\')\n });\n Job.toString = stringify(\'Job\');\n\n env = setupStore({\n user: User,\n job: Job\n });\n\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 both sides even if only loaded from one side - async\", function () {\n var stanley, stanleysFriend;\n run(function() {\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\', bestFriend: 2 });\n stanleysFriend = store.push(\'user\', { id: 2, name: \"Stanley\'s friend\" });\n stanleysFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, stanley, \'User relationship was set up correctly\');\n });\n });\n});\n\ntest(\"Relationship is available from both sides even if only loaded from one side - sync\", function () {\n var job, user;\n run(function() {\n job = store.push(\'job\', { id: 2 , isGood: true });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', job: 2 });\n });\n equal(job.get(\'user\'), user, \'User relationship was set up correctly\');\n});\n\ntest(\"Fetching a belongsTo that is set to null removes the record from a relationship - async\", function () {\n var stanleysFriend;\n run(function() {\n stanleysFriend = store.push(\'user\', { id: 2, name: \"Stanley\'s friend\", bestFriend: 1 });\n store.push(\'user\', { id: 1, name: \'Stanley\', bestFriend: null });\n stanleysFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'User relationship was removed correctly\');\n });\n });\n});\n\ntest(\"Fetching a belongsTo that is set to null removes the record from a relationship - sync\", function () {\n var job;\n run(function() {\n job = store.push(\'job\', { id: 2 , isGood: true });\n store.push(\'user\', { id: 1, name: \'Stanley\', job: 2 });\n });\n run(function() {\n job = store.push(\'job\', { id: 2 , isGood: true, user: null });\n });\n equal(job.get(\'user\'), null, \'User relationship was removed correctly\');\n});\n\ntest(\"Fetching a belongsTo that is set to a different record, sets the old relationship to null - async\", function () {\n expect(3);\n var stanley, stanleysFriend;\n run(function() {\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\', bestFriend: 2 });\n stanleysFriend = store.push(\'user\', { id: 2, name: \"Stanley\'s friend\", bestFriend: 1 });\n\n stanleysFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, stanley, \'User relationship was initally setup correctly\');\n var stanleysNewFriend;\n run(function() {\n stanleysNewFriend = store.push(\'user\', { id: 3, name: \"Stanley\'s New friend\", bestFriend: 1 });\n });\n\n stanley.get(\'bestFriend\').then(function(fetchedNewFriend) {\n equal(fetchedNewFriend, stanleysNewFriend, \'User relationship was updated correctly\');\n });\n\n stanleysFriend.get(\'bestFriend\').then(function(fetchedOldFriend) {\n equal(fetchedOldFriend, null, \'The old relationship was set to null correctly\');\n });\n });\n });\n});\n\ntest(\"Fetching a belongsTo that is set to a different record, sets the old relationship to null - sync\", function () {\n var job, user, newBetterJob;\n run(function() {\n job = store.push(\'job\', { id: 2 , isGood: false });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', job: 2 });\n });\n equal(job.get(\'user\'), user, \'Job and user initially setup correctly\');\n run(function() {\n newBetterJob = store.push(\'job\', { id: 3, isGood: true, user: 1 });\n });\n\n equal(user.get(\'job\'), newBetterJob, \'Job updated correctly\');\n equal(job.get(\'user\'), null, \'Old relationship nulled out correctly\');\n equal(newBetterJob.get(\'user\'), user, \'New job setup correctly\');\n});\n\n/*\n Local edits\n*/\n\ntest(\"Setting a OneToOne relationship reflects correctly on the other side- async\", function () {\n var stanley, stanleysFriend;\n run(function() {\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\' });\n stanleysFriend = store.push(\'user\', { id: 2, name: \"Stanley\'s friend\" });\n });\n run(function() {\n stanley.set(\'bestFriend\', stanleysFriend);\n stanleysFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, stanley, \'User relationship was updated correctly\');\n });\n });\n});\n\ntest(\"Setting a OneToOne relationship reflects correctly on the other side- sync\", function () {\n var job, user;\n run(function() {\n job = store.push(\'job\', { id: 2 , isGood: true });\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n });\n run(function() {\n user.set(\'job\', job);\n });\n equal(job.get(\'user\'), user, \'User relationship was set up correctly\');\n});\n\ntest(\"Setting a BelongsTo to a promise unwraps the promise before setting- async\", function () {\n var stanley, stanleysFriend, newFriend;\n run(function() {\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\', bestFriend: 2 });\n stanleysFriend = store.push(\'user\', { id: 2, name: \"Stanley\'s friend\" });\n newFriend = store.push(\'user\', { id: 3, name: \"New friend\" });\n });\n run(function() {\n newFriend.set(\'bestFriend\', stanleysFriend.get(\'bestFriend\'));\n stanley.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, newFriend, \'User relationship was updated correctly\');\n });\n newFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, stanley, \'User relationship was updated correctly\');\n });\n });\n});\n\ntest(\"Setting a BelongsTo to a promise works when the promise returns null- async\", function () {\n var igor, newFriend;\n run(function() {\n store.push(\'user\', { id: 1, name: \'Stanley\' });\n igor = store.push(\'user\', { id: 2, name: \"Igor\" });\n newFriend = store.push(\'user\', { id: 3, name: \"New friend\", bestFriend: 1 });\n });\n run(function() {\n newFriend.set(\'bestFriend\', igor.get(\'bestFriend\'));\n newFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'User relationship was updated correctly\');\n });\n });\n});\n\ntest(\"Setting a BelongsTo to a promise that didn\'t come from a relationship errors out\", function () {\n var stanley, igor;\n run(function() {\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\', bestFriend: 2 });\n igor = store.push(\'user\', { id: 3, name: \'Igor\' });\n });\n expectAssertion(function() {\n run(function() {\n stanley.set(\'bestFriend\', Ember.RSVP.resolve(igor));\n });\n }, /You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo or hasMany relationship to the get call./);\n});\n\ntest(\"Setting a BelongsTo to a promise multiple times is resistant to race conditions- async\", function () {\n expect(1);\n var stanley, igor, newFriend;\n run(function() {\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\', bestFriend: 2 });\n igor = store.push(\'user\', { id: 3, name: \"Igor\", bestFriend: 5 });\n newFriend = store.push(\'user\', { id: 7, name: \"New friend\" });\n });\n env.adapter.find = function(store, type, id, snapshot) {\n if (id === \'5\') {\n return Ember.RSVP.resolve({ id: 5, name: \"Igor\'s friend\" });\n } else if (id === \'2\') {\n stop();\n return new Ember.RSVP.Promise(function(resolve, reject) {\n setTimeout(function() {\n start();\n resolve({ id: 2, name: \"Stanley\'s friend\" });\n }, 1);\n });\n }\n };\n\n run(function() {\n newFriend.set(\'bestFriend\', stanley.get(\'bestFriend\'));\n newFriend.set(\'bestFriend\', igor.get(\'bestFriend\'));\n newFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser.get(\'name\'), \"Igor\'s friend\", \'User relationship was updated correctly\');\n });\n });\n});\n\ntest(\"Setting a OneToOne relationship to null reflects correctly on the other side - async\", function () {\n var stanley, stanleysFriend;\n run(function() {\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\', bestFriend: 2 });\n stanleysFriend = store.push(\'user\', { id: 2, name: \"Stanley\'s friend\", bestFriend: 1 });\n });\n run(function() {\n stanley.set(\'bestFriend\', null); // :(\n stanleysFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'User relationship was removed correctly\');\n });\n });\n});\n\ntest(\"Setting a OneToOne relationship to null reflects correctly on the other side - sync\", function () {\n var job, user;\n run(function() {\n job = store.push(\'job\', { id: 2 , isGood: false, user: 1 });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', job: 2 });\n });\n run(function() {\n user.set(\'job\', null);\n });\n equal(job.get(\'user\'), null, \'User relationship was removed correctly\');\n});\n\ntest(\"Setting a belongsTo to a different record, sets the old relationship to null - async\", function () {\n expect(3);\n\n var stanley, stanleysFriend;\n run(function() {\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\', bestFriend: 2 });\n stanleysFriend = store.push(\'user\', { id: 2, name: \"Stanley\'s friend\", bestFriend: 1 });\n\n stanleysFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, stanley, \'User relationship was initally setup correctly\');\n var stanleysNewFriend = store.push(\'user\', { id: 3, name: \"Stanley\'s New friend\" });\n run(function() {\n stanleysNewFriend.set(\'bestFriend\', stanley);\n });\n\n stanley.get(\'bestFriend\').then(function(fetchedNewFriend) {\n equal(fetchedNewFriend, stanleysNewFriend, \'User relationship was updated correctly\');\n });\n\n stanleysFriend.get(\'bestFriend\').then(function(fetchedOldFriend) {\n equal(fetchedOldFriend, null, \'The old relationship was set to null correctly\');\n });\n });\n });\n});\n\ntest(\"Setting a belongsTo to a different record, sets the old relationship to null - sync\", function () {\n var job, user, newBetterJob;\n run(function() {\n job = store.push(\'job\', { id: 2 , isGood: false });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', job: 2 });\n });\n\n equal(job.get(\'user\'), user, \'Job and user initially setup correctly\');\n\n run(function() {\n newBetterJob = store.push(\'job\', { id: 3, isGood: true });\n newBetterJob.set(\'user\', user);\n });\n\n equal(user.get(\'job\'), newBetterJob, \'Job updated correctly\');\n equal(job.get(\'user\'), null, \'Old relationship nulled out correctly\');\n equal(newBetterJob.get(\'user\'), user, \'New job setup correctly\');\n});\n\n/*\nDeleting tests\n*/\n\ntest(\"When deleting a record that has a belongsTo relationship, the record is removed from the inverse but still has access to its own relationship - async\", function () {\n // This observer is here to make sure that inverseRecord gets cleared, when\n // the record is deleted, before notifyRecordRelationshipRemoved() and in turn\n // notifyPropertyChange() gets called. If not properly cleared observers will\n // trigger with the old value of the relationship.\n User.reopen({\n bestFriendObserver: Ember.observer(\'bestFriend\', function() {\n this.get(\'bestFriend\');\n })\n });\n var stanleysFriend, stanley;\n\n run(function() {\n stanleysFriend = store.push(\'user\', { id: 2, name: \"Stanley\'s friend\" });\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\', bestFriend: 2 });\n });\n run(function() {\n stanley.deleteRecord();\n stanleysFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'Stanley got removed\');\n });\n stanley.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, stanleysFriend, \'Stanleys friend did not get removed\');\n });\n });\n});\n\ntest(\"When deleting a record that has a belongsTo relationship, the record is removed from the inverse but still has access to its own relationship - sync\", function () {\n var job, user;\n run(function() {\n job = store.push(\'job\', { id: 2 , isGood: true });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', job: 2 });\n });\n run(function() {\n job.deleteRecord();\n });\n equal(user.get(\'job\'), null, \'Job got removed from the user\');\n equal(job.get(\'user\'), user, \'Job still has the user\');\n});\n\n/*\nRollback tests\n*/\n\ntest(\"Rollbacking a deleted record restores the relationship on both sides - async\", function () {\n var stanley, stanleysFriend;\n run(function() {\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\', bestFriend: 2 });\n stanleysFriend = store.push(\'user\', { id: 2, name: \"Stanley\'s friend\" });\n });\n run(function() {\n stanley.deleteRecord();\n });\n run(function() {\n stanley.rollback();\n stanleysFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, stanley, \'Stanley got rollbacked correctly\');\n });\n stanley.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, stanleysFriend, \'Stanleys friend did not get removed\');\n });\n });\n});\n\ntest(\"Rollbacking a deleted record restores the relationship on both sides - sync\", function () {\n var job, user;\n run(function() {\n job = store.push(\'job\', { id: 2 , isGood: true });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', job: 2 });\n });\n run(function() {\n job.deleteRecord();\n job.rollback();\n });\n equal(user.get(\'job\'), job, \'Job got rollbacked correctly\');\n equal(job.get(\'user\'), user, \'Job still has the user\');\n});\n\ntest(\"Rollbacking a created record removes the relationship on both sides - async\", function () {\n var stanleysFriend, stanley;\n run(function() {\n stanleysFriend = store.push(\'user\', { id: 2, name: \"Stanley\'s friend\" });\n stanley = store.createRecord(\'user\', { bestFriend: stanleysFriend });\n });\n run(function() {\n stanley.rollback();\n stanleysFriend.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'Stanley got rollbacked correctly\');\n });\n stanley.get(\'bestFriend\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'Stanleys friend did got removed\');\n });\n });\n});\n\ntest(\"Rollbacking a created record removes the relationship on both sides - sync\", function () {\n var user, job;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n job = store.createRecord(\'job\', { user: user });\n });\n run(function() {\n job.rollback();\n });\n equal(user.get(\'job\'), null, \'Job got rollbacked correctly\');\n equal(job.get(\'user\'), null, \'Job does not have user anymore\');\n});\n})();//# sourceURL=ember-data/integration/relationships/one-to-one-test.js");
296
322
 
297
- eval("(function() {var Account, Topic, User, store, env;\nvar run = Ember.run;\n\nvar attr = DS.attr;\nvar hasMany = DS.hasMany;\n\nfunction stringify(string) {\n return function() { return string; };\n}\n\nmodule(\'integration/relationships/many_to_many_test - ManyToMany relationships\', {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n topics: hasMany(\'topic\', { async: true }),\n accounts: hasMany(\'account\')\n });\n\n User.toString = stringify(\'User\');\n\n Account = DS.Model.extend({\n state: attr(),\n users: hasMany(\'user\')\n });\n\n Account.toString = stringify(\'Account\');\n\n Topic = DS.Model.extend({\n title: attr(\'string\'),\n users: hasMany(\'user\', { async: true })\n });\n\n Topic.toString = stringify(\'Topic\');\n\n env = setupStore({\n user: User,\n topic: Topic,\n account: Account\n });\n\n store = env.store;\n },\n\n teardown: function() {\n run(function() {\n env.container.destroy();\n });\n }\n});\n\n/*\n Server loading tests\n*/\n\ntest(\"Loading from one hasMany side reflects on the other hasMany side - async\", function () {\n run(function() {\n store.push(\'user\', { id: 1, name: \'Stanley\', topics: [2, 3] });\n });\n var topic = run(function() {\n return store.push(\'topic\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 1, \'User relationship was set up correctly\');\n }));\n });\n});\n\ntest(\"Relationship is available from the belongsTo side even if only loaded from the hasMany side - sync\", function () {\n var account;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n run(function() {\n equal(account.get(\'users.length\'), 1, \'User relationship was set up correctly\');\n });\n});\n\ntest(\"Fetching a hasMany where a record was removed reflects on the other hasMany side - async\", function () {\n var user, topic;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', topics: [2] });\n topic = store.push(\'topic\', { id: 2, title: \'EmberFest was great\', users: [] });\n });\n run(function() {\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 0, \'Topics were removed correctly\');\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 0, \'Users were removed correctly\');\n }));\n }));\n });\n});\n\ntest(\"Fetching a hasMany where a record was removed reflects on the other hasMany side - async\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n account = store.push(\'account\', { id: 2 , state: \'lonely\', users: [] });\n });\n equal(user.get(\'accounts.length\'), 0, \'Accounts were removed correctly\');\n equal(account.get(\'users.length\'), 0, \'Users were removed correctly\');\n});\n\n/*\n Local edits\n*/\n\ntest(\"Pushing to a hasMany reflects on the other hasMany side - async\", function () {\n expect(1);\n var user, topic;\n\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', topics: [] });\n topic = store.push(\'topic\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n topic.get(\'users\').then(async(function(fetchedUsers) {\n fetchedUsers.pushObject(user);\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 1, \'User relationship was set up correctly\');\n }));\n }));\n });\n});\n\ntest(\"Pushing to a hasMany reflects on the other hasMany side - sync\", function () {\n var account, stanley;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n stanley = store.push(\'user\', { id: 1, name: \'Stanley\' });\n stanley.get(\'accounts\').pushObject(account);\n });\n equal(account.get(\'users.length\'), 1, \'User relationship was set up correctly\');\n});\n\ntest(\"Removing a record from a hasMany reflects on the other hasMany side - async\", function () {\n var user, topic;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', topics: [2] });\n topic = store.push(\'topic\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 1, \'Topics were setup correctly\');\n fetchedTopics.removeObject(topic);\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 0, \'Users were removed correctly\');\n }));\n }));\n });\n});\n\ntest(\"Removing a record from a hasMany reflects on the other hasMany side - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n equal(account.get(\'users.length\'), 1, \'Users were setup correctly\');\n run(function() {\n account.get(\'users\').removeObject(user);\n });\n equal(user.get(\'accounts.length\'), 0, \'Accounts were removed correctly\');\n equal(account.get(\'users.length\'), 0, \'Users were removed correctly\');\n});\n\n/*\nDeleting tests\n*/\n\ntest(\"Deleting a record that has a hasMany relationship removes it from the otherMany array but does not remove the other record from itself - async\", function () {\n var user, topic;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', topics: [2] });\n topic = store.push(\'topic\', { id: 2, title: \'EmberFest was great\' });\n });\n run(topic, \'deleteRecord\');\n run(function() {\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 1, \'Users are still there\');\n }));\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 0, \'Topic got removed from the user\');\n }));\n });\n});\n\ntest(\"Deleting a record that has a hasMany relationship removes it from the otherMany array but does not remove the other record from itself - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n run(account, \'deleteRecord\');\n equal(account.get(\'users.length\'), 1, \'Users are still there\');\n equal(user.get(\'accounts.length\'), 0, \'Acocount got removed from the user\');\n});\n\n/*\n Rollback tests\n*/\n\ntest(\"Rollbacking a deleted record that has a ManyToMany relationship works correctly - async\", function () {\n var user, topic;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', topics: [2] });\n topic = store.push(\'topic\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n topic.deleteRecord();\n topic.rollback();\n });\n run(function() {\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 1, \'Users are still there\');\n }));\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 1, \'Topic got rollbacked into the user\');\n }));\n });\n});\n\ntest(\"Deleting a record that has a hasMany relationship removes it from the otherMany array but does not remove the other record from itself - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n run(function() {\n account.deleteRecord();\n account.rollback();\n });\n equal(account.get(\'users.length\'), 1, \'Users are still there\');\n equal(user.get(\'accounts.length\'), 1, \'Account got rolledback correctly into the user\');\n});\n\ntest(\"Rollbacking a created record that has a ManyToMany relationship works correctly - async\", function () {\n var user, topic;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n topic = store.createRecord(\'topic\');\n });\n run(function() {\n user.get(\'topics\').then(async(function(fetchedTopics) {\n fetchedTopics.pushObject(topic);\n topic.rollback();\n topic.get(\'users\').then(async(function(fetchedUsers) {\n equal(fetchedUsers.get(\'length\'), 0, \'Users got removed\');\n }));\n user.get(\'topics\').then(async(function(fetchedTopics) {\n equal(fetchedTopics.get(\'length\'), 0, \'Topics got removed\');\n }));\n }));\n });\n});\n\ntest(\"Deleting a record that has a hasMany relationship removes it from the otherMany array but does not remove the other record from itself - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.createRecord(\'user\');\n });\n run(function() {\n account.get(\'users\').pushObject(user);\n user.rollback();\n });\n equal(account.get(\'users.length\'), 0, \'Users got removed\');\n equal(user.get(\'accounts.length\'), undefined, \'Accounts got rolledback correctly\');\n});\n\n\ntest(\"Re-loading a removed record should re add it to the relationship when the removed record is the last one in the relationship\", function () {\n var account, ada, byron;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'account 1\' });\n ada = store.push(\'user\', { id: 1, name: \'Ada Lovelace\', accounts: [2] });\n byron = store.push(\'user\', { id: 2, name: \'Lord Byron\', accounts: [2] });\n account.get(\'users\').removeObject(byron);\n account = store.push(\'account\', { id: 2 , state: \'account 1\', users: [1, 2] });\n });\n\n equal(account.get(\'users.length\'), 2, \'Accounts were updated correctly\');\n});\n})();//# sourceURL=ember-data/integration/relationships/many_to_many_test.js");
323
+ 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");
298
324
 
299
- eval("(function() {var env, store, User, Message, Account;\nvar get = Ember.get;\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/one_to_many_test - OneToMany relationships\', {\n setup: function() {\n User = DS.Model.extend({\n name: attr(\'string\'),\n messages: hasMany(\'message\', { async: true }),\n accounts: hasMany(\'account\')\n });\n User.toString = stringify(\'User\');\n\n Account = DS.Model.extend({\n state: attr(),\n user: belongsTo(\'user\')\n });\n Account.toString = stringify(\'Account\');\n\n Message = DS.Model.extend({\n title: attr(\'string\'),\n user: belongsTo(\'user\', { async: true })\n });\n Message.toString = stringify(\'Message\');\n\n env = setupStore({\n user: User,\n message: Message,\n account: Account\n });\n\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, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [2, 3] });\n message = store.push(\'message\', { id: 2, title: \'EmberFest was great\' });\n });\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'User relationship was set up correctly\');\n });\n });\n});\n\ntest(\"Relationship is available from the belongsTo side even if only loaded from the hasMany side - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n equal(account.get(\'user\'), user, \'User relationship was set up correctly\');\n});\n\ntest(\"Relationship is available from the hasMany side even if only loaded from the belongsTo side - async\", function () {\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n message = store.push(\'message\', { id: 2, title: \'EmberFest was great\', user: 1 });\n });\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(fetchedMessages.objectAt(0), message, \'Messages relationship was set up correctly\');\n });\n });\n});\n\ntest(\"Relationship is available from the hasMany side even if only loaded from the belongsTo side - sync\", function () {\n var user, account;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n account = store.push(\'account\', { id: 2 , state: \'lonely\', user: 1 });\n });\n equal(user.get(\'accounts\').objectAt(0), account, \'Accounts relationship was set up correctly\');\n});\n\ntest(\"Fetching a belongsTo that is set to null removes the record from a relationship - async\", function () {\n var user;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1,2] });\n });\n run(function() {\n store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n store.push(\'message\', { id: 2, title: \'EmberConf will be better\', user: null });\n });\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(get(fetchedMessages, \'length\'), 1, \'Messages relationship was set up correctly\');\n });\n });\n});\n\ntest(\"Fetching a belongsTo that is set to null removes the record from a relationship - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n account = store.push(\'account\', { id: 2 , state: \'lonely\', user: null });\n });\n equal(user.get(\'accounts\').objectAt(0), null, \'Account was sucesfully removed\');\n});\n\ntest(\"Fetching a belongsTo that is not defined does not remove the record from a relationship - async\", function () {\n var user;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1,2] });\n });\n run(function() {\n store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n store.push(\'message\', { id: 2, title: \'EmberConf will be better\' });\n });\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(get(fetchedMessages, \'length\'), 2, \'Messages relationship was set up correctly\');\n });\n });\n});\n\ntest(\"Fetching a belongsTo that is not defined does not remove the record from a relationship - sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n });\n equal(user.get(\'accounts\').objectAt(0), account, \'Account was sucesfully removed\');\n});\n\ntest(\"Fetching the hasMany that doesn\'t contain the belongsTo, sets the belongsTo to null - async\", function () {\n var user, message, message2;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n message2 = store.push(\'message\', { id: 2, title: \'EmberConf is gonna be better\' });\n });\n run(function() {\n store.push(\'user\', { id: 1, name: \'Stanley\', messages: [2] });\n });\n\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'User was removed correctly\');\n });\n\n message2.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'User was set on the second message\');\n });\n });\n});\n\ntest(\"Fetching the hasMany that doesn\'t contain the belongsTo, sets the belongsTo to null - sync\", function () {\n var account;\n run(function() {\n store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n account = store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n store.push(\'account\', { id: 2, state: \'awesome\' });\n store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n });\n\n equal(account.get(\'user\'), null, \'User was removed correctly\');\n});\n\ntest(\"Fetching the hasMany side where the hasMany is undefined does not change the belongsTo side - async\", function () {\n var message, user;\n run(function() {\n store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n });\n\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'User was not removed\');\n });\n });\n});\n\ntest(\"Fetching the hasMany side where the hasMany is undefined does not change the belongsTo side - sync\", function () {\n var account, user;\n run(function() {\n store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n account = store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n store.push(\'account\', { id: 2, state: \'awesome\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\' });\n });\n\n equal(account.get(\'user\'), user, \'User was not removed\');\n});\n\n/*\n Local edits\n*/\n\ntest(\"Pushing to the hasMany reflects the change on the belongsTo side - async\", function () {\n var user, message2;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n store.push(\'message\', { id: 1, title: \'EmberFest was great\' });\n message2 = store.push(\'message\', { id: 2, title: \'EmberFest was great\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n fetchedMessages.pushObject(message2);\n message2.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \"user got set correctly\");\n });\n });\n });\n});\n\ntest(\"Pushing to the hasMany reflects the change on the belongsTo side - sync\", function () {\n var user, account2;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n\n account2 = store.push(\'account\', { id: 2, state: \'awesome\' });\n user.get(\'accounts\').pushObject(account2);\n });\n\n equal(account2.get(\'user\'), user, \'user got set correctly\');\n});\n\ntest(\"Removing from the hasMany side reflects the change on the belongsTo side - async\", function () {\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\' });\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n fetchedMessages.removeObject(message);\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, null, \"user got removed correctly\");\n });\n });\n });\n});\n\ntest(\"Removing from the hasMany side reflects the change on the belongsTo side - sync\", function () {\n var user, account;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n account = store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n });\n run(function() {\n user.get(\'accounts\').removeObject(account);\n });\n\n equal(account.get(\'user\'), null, \'user got removed correctly\');\n});\n\ntest(\"Pushing to the hasMany side keeps the oneToMany invariant on the belongsTo side - async\", function () {\n expect(2);\n var user, user2, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n user2 = store.push(\'user\', { id: 2, name: \'Tomhuda\' });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\' });\n });\n\n run(function() {\n user2.get(\'messages\').then(function(fetchedMessages) {\n fetchedMessages.pushObject(message);\n\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user2, \"user got set correctly\");\n });\n\n user.get(\'messages\').then(function(newFetchedMessages) {\n equal(get(newFetchedMessages, \'length\'), 0, \'message got removed from the old messages hasMany\');\n });\n });\n });\n});\n\ntest(\"Pushing to the hasMany side keeps the oneToMany invariant - sync\", function () {\n var user, user2, account;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n user2 = store.push(\'user\', { id: 2, name: \'Stanley\' });\n account = store.push(\'account\', { id: 1, state: \'great\' });\n user2.get(\'accounts\').pushObject(account);\n });\n\n equal(account.get(\'user\'), user2, \'user got set correctly\');\n equal(user.get(\'accounts.length\'), 0, \'the account got removed correctly\');\n equal(user2.get(\'accounts.length\'), 1, \'the account got pushed correctly\');\n});\n\ntest(\"Setting the belongsTo side keeps the oneToMany invariant on the hasMany- async\", function () {\n expect(2);\n var user, user2, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n user2 = store.push(\'user\', { id: 2, name: \'Tomhuda\' });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n message.set(\'user\', user2);\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(get(fetchedMessages, \'length\'), 0, \'message got removed from the first user correctly\');\n });\n });\n run(function() {\n user2.get(\'messages\').then(function(fetchedMessages) {\n equal(get(fetchedMessages, \'length\'), 1, \'message got added to the second user correctly\');\n });\n });\n});\n\ntest(\"Setting the belongsTo side keeps the oneToMany invariant on the hasMany- sync\", function () {\n var user, user2, account;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n user2 = store.push(\'user\', { id: 2, name: \'Stanley\' });\n account = store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n account.set(\'user\', user2);\n });\n\n equal(account.get(\'user\'), user2, \'user got set correctly\');\n\n equal(user.get(\'accounts.length\'), 0, \'the account got removed correctly\');\n equal(user2.get(\'accounts.length\'), 1, \'the account got pushed correctly\');\n});\n\n\ntest(\"Setting the belongsTo side to null removes the record from the hasMany side - async\", function () {\n expect(2);\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [1] });\n message = store.push(\'message\', { id: 1, title: \'EmberFest was great\', user: 1 });\n message.set(\'user\', null);\n });\n\n run(function() {\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(get(fetchedMessages, \'length\'), 0, \'message got removed from the user correctly\');\n });\n });\n\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, null, \'user got set to null correctly\');\n });\n });\n});\n\ntest(\"Setting the belongsTo side to null removes the record from the hasMany side - sync\", function () {\n var user, account;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [1] });\n account = store.push(\'account\', { id: 1, state: \'great\', user: 1 });\n account.set(\'user\', null);\n });\n\n equal(account.get(\'user\'), null, \'user got set to null correctly\');\n\n equal(user.get(\'accounts.length\'), 0, \'the account got removed correctly\');\n});\n\n/*\nDeleting\n*/\n\ntest(\"When deleting a record that has a belongsTo it is removed from the hasMany side but not the belongsTo side- async\", function () {\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [2] });\n message = store.push(\'message\', { id: 2, title: \'EmberFest was great\' });\n });\n run(message, \'deleteRecord\');\n run(function() {\n message.get(\'user\').then(function(fetchedUser) {\n equal(fetchedUser, user, \'Message still has the user\');\n });\n user.get(\'messages\').then(function(fetchedMessages) {\n equal(fetchedMessages.get(\'length\'), 0, \'User was removed from the messages\');\n });\n });\n});\n\ntest(\"When deleting a record that has a belongsTo it is removed from the hasMany side but not the belongsTo side- sync\", function () {\n var account, user;\n run(function() {\n account = store.push(\'account\', { id: 2 , state: \'lonely\' });\n user = store.push(\'user\', { id: 1, name: \'Stanley\', accounts: [2] });\n account.deleteRecord();\n });\n equal(user.get(\'accounts.length\'), 0, \"User was removed from the accounts\");\n equal(account.get(\'user\'), user, \'Account still has the user\');\n});\n\ntest(\"When deleting a record that has a hasMany it is removed from the belongsTo side but not the hasMany side- async\", function () {\n var user, message;\n run(function() {\n user = store.push(\'user\', { id: 1, name: \'Stanley\', messages: [