ember-data-source 1.0.0.beta.12 → 1.0.0.beta.14

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: 1ec7886b169bf196e72745d21481d28febfeab00
4
- data.tar.gz: 2283e331324037b0a97e223b0bb3b5f8e35d66a0
3
+ metadata.gz: e31db634e6afe4aa600daf41f092bebf095847e6
4
+ data.tar.gz: 0ab72e940680f87d7fb82d2004f528779ebac563
5
5
  SHA512:
6
- metadata.gz: 515a3df184db91da5b80694adbdd224ec79ea552c3aaf427c5b9ca46eb65d90b5b76284c569141698f7da5c4161bee0e8010e84af6ebdc1b6b54281c9fb13acf
7
- data.tar.gz: 82f3701fa0b20d55352232f474fe53ece838c5e77e8ebdcd4b6f854bb75209822c3b6517b48d6f76fa5047779c2c0c34decb391a9e66a5262e0e904dab37f26b
6
+ metadata.gz: 737f7dfa6dc8a22e46154bd8a0df002587d105e09d9600c29769d9c4c74ef7674391a719cf4a689510e8d32e130624da54936b48ad5b7783ef7eab31934a970c
7
+ data.tar.gz: 315ba9a8232d6b954923b876d8df8f561fd3f6f5573ea89f3c01025ab1de8902b2f6a1bc49284a84c77a33d18bcc49595456cd222fb73a9089fa36412a4bdf7b
@@ -12,38 +12,6 @@
12
12
  }
13
13
  });
14
14
 
15
- Ember.RSVP.resolve = syncForTest(Ember.RSVP.resolve);
16
-
17
- Ember.View.reopen({
18
- _insertElementLater: syncForTest()
19
- });
20
-
21
- DS.Store.reopen({
22
- save: syncForTest(),
23
- createRecord: syncForTest(),
24
- deleteRecord: syncForTest(),
25
- push: syncForTest(),
26
- pushMany: syncForTest(),
27
- filter: syncForTest(),
28
- find: syncForTest(),
29
- findMany: syncForTest(),
30
- findByIds: syncForTest(),
31
- didSaveRecord: syncForTest(),
32
- didSaveRecords: syncForTest(),
33
- didUpdateAttribute: syncForTest(),
34
- didUpdateAttributes: syncForTest(),
35
- didUpdateRelationship: syncForTest(),
36
- didUpdateRelationships: syncForTest()
37
- });
38
-
39
- DS.Model.reopen({
40
- save: syncForTest(),
41
- reload: syncForTest(),
42
- deleteRecord: syncForTest(),
43
- dataDidChange: Ember.observer(syncForTest(), 'data'),
44
- updateRecordArraysLater: syncForTest()
45
- });
46
-
47
15
  var transforms = {
48
16
  'boolean': DS.BooleanTransform.create(),
49
17
  'date': DS.DateTransform.create(),
@@ -58,5 +26,4 @@
58
26
  }
59
27
  });
60
28
 
61
- Ember.RSVP.Promise.prototype.then = syncForTest(Ember.RSVP.Promise.prototype.then);
62
29
  })();
@@ -0,0 +1,231 @@
1
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - .\');\ntest(\'main.js should pass jshint\', function() { \n ok(true, \'main.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/main.jshint.js");
2
+
3
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - .\');\ntest(\'setup-container.js should pass jshint\', function() { \n ok(true, \'setup-container.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/setup-container.jshint.js");
4
+
5
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - .\');\ntest(\'system.js should pass jshint\', function() { \n ok(true, \'system.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/system.jshint.js");
6
+
7
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/active_model_adapter.js should pass jshint\', function() { \n ok(true, \'system/active_model_adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/system/active_model_adapter.jshint.js");
8
+
9
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/active_model_serializer.js should pass jshint\', function() { \n ok(true, \'system/active_model_serializer.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=activemodel-adapter-jshint/system/active_model_serializer.jshint.js");
10
+
11
+ 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");
12
+
13
+ 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.container.register(\'serializer:application\', DS.ActiveModelSerializer);\n env.container.register(\'serializer:-active-model\', DS.ActiveModelSerializer);\n env.container.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);\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);\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);\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.container.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.container.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);\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);\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);\n });\n\n deepEqual(json[\"evil_minion_type\"], null);\n});\n\ntest(\"extractPolymorphic hasMany\", function() {\n env.container.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.container.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");
14
+
15
+ 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");
16
+
17
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - .\');\ntest(\'adapters.js should pass jshint\', function() { \n ok(true, \'adapters.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/adapters.jshint.js");
18
+
19
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - adapters\');\ntest(\'adapters/fixture_adapter.js should pass jshint\', function() { \n ok(true, \'adapters/fixture_adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/adapters/fixture_adapter.jshint.js");
20
+
21
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - adapters\');\ntest(\'adapters/rest_adapter.js should pass jshint\', function() { \n ok(true, \'adapters/rest_adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/adapters/rest_adapter.jshint.js");
22
+
23
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - .\');\ntest(\'core.js should pass jshint\', function() { \n ok(true, \'core.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/core.jshint.js");
24
+
25
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - .\');\ntest(\'ember-initializer.js should pass jshint\', function() { \n ok(true, \'ember-initializer.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/ember-initializer.jshint.js");
26
+
27
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - ext\');\ntest(\'ext/date.js should pass jshint\', function() { \n ok(true, \'ext/date.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/ext/date.jshint.js");
28
+
29
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - initializers\');\ntest(\'initializers/data_adapter.js should pass jshint\', function() { \n ok(true, \'initializers/data_adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/initializers/data_adapter.jshint.js");
30
+
31
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - initializers\');\ntest(\'initializers/store.js should pass jshint\', function() { \n ok(true, \'initializers/store.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/initializers/store.jshint.js");
32
+
33
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - initializers\');\ntest(\'initializers/store_injections.js should pass jshint\', function() { \n ok(true, \'initializers/store_injections.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/initializers/store_injections.jshint.js");
34
+
35
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - initializers\');\ntest(\'initializers/transforms.js should pass jshint\', function() { \n ok(true, \'initializers/transforms.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/initializers/transforms.jshint.js");
36
+
37
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - .\');\ntest(\'main.js should pass jshint\', function() { \n ok(true, \'main.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/main.jshint.js");
38
+
39
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - .\');\ntest(\'serializers.js should pass jshint\', function() { \n ok(true, \'serializers.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/serializers.jshint.js");
40
+
41
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - serializers\');\ntest(\'serializers/embedded_records_mixin.js should pass jshint\', function() { \n ok(true, \'serializers/embedded_records_mixin.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/serializers/embedded_records_mixin.jshint.js");
42
+
43
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - serializers\');\ntest(\'serializers/json_serializer.js should pass jshint\', function() { \n ok(true, \'serializers/json_serializer.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/serializers/json_serializer.jshint.js");
44
+
45
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - serializers\');\ntest(\'serializers/rest_serializer.js should pass jshint\', function() { \n ok(true, \'serializers/rest_serializer.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/serializers/rest_serializer.jshint.js");
46
+
47
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - .\');\ntest(\'setup-container.js should pass jshint\', function() { \n ok(true, \'setup-container.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/setup-container.jshint.js");
48
+
49
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/adapter.js should pass jshint\', function() { \n ok(true, \'system/adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/adapter.jshint.js");
50
+
51
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/container_proxy.js should pass jshint\', function() { \n ok(true, \'system/container_proxy.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/container_proxy.jshint.js");
52
+
53
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/create.js should pass jshint\', function() { \n ok(true, \'system/create.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/create.jshint.js");
54
+
55
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/debug.js should pass jshint\', function() { \n ok(true, \'system/debug.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/debug.jshint.js");
56
+
57
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/debug\');\ntest(\'system/debug/debug_adapter.js should pass jshint\', function() { \n ok(true, \'system/debug/debug_adapter.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/debug/debug_adapter.jshint.js");
58
+
59
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/debug\');\ntest(\'system/debug/debug_info.js should pass jshint\', function() { \n ok(true, \'system/debug/debug_info.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/debug/debug_info.jshint.js");
60
+
61
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/map.js should pass jshint\', function() { \n ok(true, \'system/map.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/map.jshint.js");
62
+
63
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/merge.js should pass jshint\', function() { \n ok(true, \'system/merge.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/merge.jshint.js");
64
+
65
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/model.js should pass jshint\', function() { \n ok(true, \'system/model.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/model.jshint.js");
66
+
67
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/model\');\ntest(\'system/model/attributes.js should pass jshint\', function() { \n ok(true, \'system/model/attributes.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/model/attributes.jshint.js");
68
+
69
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/model\');\ntest(\'system/model/errors.js should pass jshint\', function() { \n ok(true, \'system/model/errors.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/model/errors.jshint.js");
70
+
71
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/model\');\ntest(\'system/model/model.js should pass jshint\', function() { \n ok(true, \'system/model/model.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/model/model.jshint.js");
72
+
73
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/model\');\ntest(\'system/model/states.js should pass jshint\', function() { \n ok(true, \'system/model/states.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/model/states.jshint.js");
74
+
75
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/promise_proxies.js should pass jshint\', function() { \n ok(true, \'system/promise_proxies.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/promise_proxies.jshint.js");
76
+
77
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/record_array_manager.js should pass jshint\', function() { \n ok(true, \'system/record_array_manager.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/record_array_manager.jshint.js");
78
+
79
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/record_arrays.js should pass jshint\', function() { \n ok(true, \'system/record_arrays.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/record_arrays.jshint.js");
80
+
81
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/record_arrays\');\ntest(\'system/record_arrays/adapter_populated_record_array.js should pass jshint\', function() { \n ok(true, \'system/record_arrays/adapter_populated_record_array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/record_arrays/adapter_populated_record_array.jshint.js");
82
+
83
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/record_arrays\');\ntest(\'system/record_arrays/filtered_record_array.js should pass jshint\', function() { \n ok(true, \'system/record_arrays/filtered_record_array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/record_arrays/filtered_record_array.jshint.js");
84
+
85
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/record_arrays\');\ntest(\'system/record_arrays/many_array.js should pass jshint\', function() { \n ok(true, \'system/record_arrays/many_array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/record_arrays/many_array.jshint.js");
86
+
87
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/record_arrays\');\ntest(\'system/record_arrays/record_array.js should pass jshint\', function() { \n ok(true, \'system/record_arrays/record_array.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/record_arrays/record_array.jshint.js");
88
+
89
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/relationship-meta.js should pass jshint\', function() { \n ok(true, \'system/relationship-meta.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/relationship-meta.jshint.js");
90
+
91
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/relationships.js should pass jshint\', function() { \n ok(true, \'system/relationships.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/relationships.jshint.js");
92
+
93
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/relationships\');\ntest(\'system/relationships/belongs_to.js should pass jshint\', function() { \n ok(true, \'system/relationships/belongs_to.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/relationships/belongs_to.jshint.js");
94
+
95
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/relationships\');\ntest(\'system/relationships/ext.js should pass jshint\', function() { \n ok(true, \'system/relationships/ext.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/relationships/ext.jshint.js");
96
+
97
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/relationships\');\ntest(\'system/relationships/has_many.js should pass jshint\', function() { \n ok(true, \'system/relationships/has_many.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/relationships/has_many.jshint.js");
98
+
99
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/relationships/state\');\ntest(\'system/relationships/state/belongs_to.js should pass jshint\', function() { \n ok(true, \'system/relationships/state/belongs_to.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/relationships/state/belongs_to.jshint.js");
100
+
101
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/relationships/state\');\ntest(\'system/relationships/state/create.js should pass jshint\', function() { \n ok(true, \'system/relationships/state/create.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/relationships/state/create.jshint.js");
102
+
103
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/relationships/state\');\ntest(\'system/relationships/state/has_many.js should pass jshint\', function() { \n ok(true, \'system/relationships/state/has_many.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/relationships/state/has_many.jshint.js");
104
+
105
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system/relationships/state\');\ntest(\'system/relationships/state/relationship.js should pass jshint\', function() { \n ok(true, \'system/relationships/state/relationship.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/relationships/state/relationship.jshint.js");
106
+
107
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - system\');\ntest(\'system/store.js should pass jshint\', function() { \n ok(true, \'system/store.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/system/store.jshint.js");
108
+
109
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - .\');\ntest(\'transforms.js should pass jshint\', function() { \n ok(true, \'transforms.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/transforms.jshint.js");
110
+
111
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - transforms\');\ntest(\'transforms/base.js should pass jshint\', function() { \n ok(true, \'transforms/base.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/transforms/base.jshint.js");
112
+
113
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - transforms\');\ntest(\'transforms/boolean.js should pass jshint\', function() { \n ok(true, \'transforms/boolean.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/transforms/boolean.jshint.js");
114
+
115
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - transforms\');\ntest(\'transforms/date.js should pass jshint\', function() { \n ok(true, \'transforms/date.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/transforms/date.jshint.js");
116
+
117
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - transforms\');\ntest(\'transforms/number.js should pass jshint\', function() { \n ok(true, \'transforms/number.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/transforms/number.jshint.js");
118
+
119
+ eval("(function() {if (!QUnit.urlParams.nojshint) {\nmodule(\'JSHint - transforms\');\ntest(\'transforms/string.js should pass jshint\', function() { \n ok(true, \'transforms/string.js should pass jshint.\'); \n});\n\n}})();//# sourceURL=ember-data-jshint/transforms/string.jshint.js");
120
+
121
+ 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");
122
+
123
+ 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})();//# sourceURL=ember-data/integration/adapter/find_test.js");
124
+
125
+ 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.container.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");
126
+
127
+ 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");
128
+
129
+ eval("(function() {var get = Ember.get, set = Ember.set, attr = DS.attr;\nvar Person, env, store;\nvar run = Ember.run;\n\nvar all = Ember.RSVP.all, 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");
130
+
131
+ 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.container.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.container.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.container.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.container.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.container.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.container.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.container.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.container.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(\"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 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.container.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 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 - 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 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.container.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 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\nreturn post.get(\'comments\');\n })).then(async(function(comments) {\n var comment1 = store.getById(\'comment\', 1),\n comment2 = store.getById(\'comment\', 2),\n 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 comment2 = store.getById(\'comment\', 2),\n comment3 = store.getById(\'comment\', 3),\n comment4 = store.getById(\'comment\', 4),\n 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.container.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n env.container.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 comment2 = store.getById(\'comment\', 2),\n 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 comment2 = store.getById(\'comment\', 2),\n 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 comment2 = store.getById(\'comment\', 2),\n comment3 = store.getById(\'comment\', 3),\n 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.container.register(\'serializer:post\', DS.RESTSerializer.extend({\n primaryKey: \'_ID_\',\n attrs: { name: \'_NAME_\' }\n }));\n\n env.container.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 comment2 = store.getById(\'comment\', 2),\n 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\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.container.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.container.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.container.register(\'model:user\', DS.Model.extend({\n createdAt: DS.attr(),\n name: DS.attr()\n }));\n\n env.container.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})();//# sourceURL=ember-data/integration/adapter/rest_adapter_test.js");
132
+
133
+ 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, set = Ember.set;\nvar Person, Dog, env, store, adapter;\nvar run = Ember.run;\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, 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, 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, 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, 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, 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, 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(\"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(\"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");
134
+
135
+ 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");
136
+
137
+ eval("(function() {var run = Ember.run,\n Application = Ember.Application,\n Controller = Ember.Controller,\n View = Ember.View,\n Store = DS.Store,\n 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");
138
+
139
+ 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");
140
+
141
+ eval("(function() {var App, store, debugAdapter, 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 // Support Ember < 1.5.\n // TODO: Remove this workaround (if statement) when Ember 1.5 is released.\n if (!this.get(\'containerDebugAdapter\')) {\n return Ember.A([App.Post]);\n }\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");
142
+
143
+ eval("(function() {var get = Ember.get, 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\') });\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(obj, 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, didChangeRemoved = 0, 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");
144
+
145
+ eval("(function() {var env, store, User, Job;\n\nvar attr = DS.attr, 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}),\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 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\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})();//# sourceURL=ember-data/integration/inverse_test.js");
146
+
147
+ 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");
148
+
149
+ 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 = DS.RecordArrayManager.create({\n store: store\n });\n\n env.container.register(\'model:car\', Car);\n env.container.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})();//# sourceURL=ember-data/integration/record_array_manager_test.js");
150
+
151
+ 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");
152
+
153
+ 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 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");
154
+
155
+ 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.container.register(\'model:person\', DS.Model.extend({\n name: DS.attr(),\n tags: DS.hasMany(\'tag\', { async: true })\n }));\n\n env.container.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) { 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");
156
+
157
+ 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");
158
+
159
+ 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");
160
+
161
+ eval("(function() {var env, store, User, Message, Post, Comment, Book, Author, NewMessage;\nvar get = Ember.get;\nvar run = Ember.run;\n\nvar attr = DS.attr, hasMany = DS.hasMany, belongsTo = DS.belongsTo;\nvar hash = Ember.RSVP.hash;\n\nfunction stringify(string) {\n return function() { return string; };\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 User.toString = stringify(\'User\');\n\n Message = DS.Model.extend({\n user: belongsTo(\'user\', { inverse: \'messages\' }),\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(\'message\', { polymorphic: true })\n });\n Comment.toString = stringify(\'Comment\');\n\n Book = DS.Model.extend({\n name: attr(\'string\'),\n author: belongsTo(\'author\')\n });\n Book.toString = stringify(\'Book\');\n\n Author = DS.Model.extend({\n name: attr(\'string\')\n });\n Author.toString = stringify(\'Author\');\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.container.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.container.register(\'model:group\', Group);\n env.container.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.container.register(\'model:seat\', Seat);\n env.container.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.container.register(\'model:group\', Group);\n env.container.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(\"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 NewMessage.toString = stringify(\'Message\');\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 relationshipsByName = get(modelViaSecondFactory, \'relationshipsByName\'),\n 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 oldCacheable = Ember.meta(model).descs.relationshipsByName._cacheable;\n Ember.meta(model).descs.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 Ember.meta(model).descs.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 oldCacheable = Ember.meta(model).descs.relatedTypes._cacheable;\n Ember.meta(model).descs.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 Ember.meta(model).descs.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 oldCacheable = Ember.meta(model).descs.relatedTypes._cacheable;\n Ember.meta(model).descs.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 Ember.meta(model).descs.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;\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 record;\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");
162
+
163
+ 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, hasMany = DS.hasMany, 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()\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\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\n Ember.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([ env.store.find(\'post\', 1), env.store.find(\'post\', 2) ]).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 Ember.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 = Ember.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 = Ember.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 = Ember.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 Ember.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 var arr = Ember.A([1,2]);\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 var arr = Ember.A([1,2]);\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 run(function(){\n post = env.store.push(\'post\', { id: 2, title: \'Sailing the Seven Seas\', comments: [1,2] });\n env.store.pushMany(\'comment\', [\n {\n id: 1,\n post: 2\n },\n {\n id: 2,\n post: 2\n },\n {\n id: 3,\n post: 2\n }\n ]);\n });\n\n run(function(){\n post._relationships[\'comments\'].clear();\n var comments = Em.A(env.store.all(\'comment\'));\n deepEqual(comments.mapBy(\'post\'), [undefined, undefined, undefined]);\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 run(function(){\n post = env.store.push(\'post\', { id: 2, title: \'Sailing the Seven Seas\', comments: [1,2] });\n env.store.pushMany(\'comment\', [\n {\n id: 1,\n post: 2\n },\n {\n id: 2,\n post: 2\n }\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");
164
+
165
+ 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 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 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 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 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\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\n run(function(){\n comment = store.createRecord(\'comment\');\n post = store.createRecord(\'post\');\n comment2 = store.createRecord(\'comment\');\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(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 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 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 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 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");
166
+
167
+ eval("(function() {var Account, Topic, User, store, env;\nvar run = Ember.run;\n\nvar attr = DS.attr, 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})();//# sourceURL=ember-data/integration/relationships/many_to_many_test.js");
168
+
169
+ eval("(function() {var env, store, User, Message, Account;\nvar get = Ember.get;\nvar run = Ember.run;\n\nvar attr = DS.attr, hasMany = DS.hasMany, 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");
170
+
171
+ eval("(function() {var env, store, User, Job;\nvar run = Ember.run;\n\nvar attr = DS.attr, 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}),\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) {\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 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");
172
+
173
+ eval("(function() {var get = Ember.get;\nvar HomePlanet, SuperVillain, EvilMinion, SecretLab, SecretWeapon, Comment,\n league, superVillain, evilMinion, secretWeapon, homePlanet, secretLab, env;\nvar indexOf = Ember.EnumerableUtils.indexOf;\nvar run = Ember.run;\nvar LightSaber;\n\nmodule(\"integration/embedded_records_mixin - EmbeddedRecordsMixin\", {\n setup: function() {\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n homePlanet: DS.belongsTo(\"homePlanet\", {inverse: \'villains\'}),\n secretLab: DS.belongsTo(\"secretLab\"),\n secretWeapons: DS.hasMany(\"secretWeapon\"),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n HomePlanet = DS.Model.extend({\n name: DS.attr(\'string\'),\n villains: DS.hasMany(\'superVillain\', {inverse: \'homePlanet\'})\n });\n SecretLab = DS.Model.extend({\n minionCapacity: DS.attr(\'number\'),\n vicinity: DS.attr(\'string\'),\n superVillain: DS.belongsTo(\'superVillain\')\n });\n SecretWeapon = DS.Model.extend({\n name: DS.attr(\'string\'),\n superVillain: DS.belongsTo(\'superVillain\')\n });\n LightSaber = SecretWeapon.extend({\n color: DS.attr(\'string\')\n });\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n Comment = DS.Model.extend({\n body: DS.attr(\'string\'),\n root: DS.attr(\'boolean\'),\n children: DS.hasMany(\'comment\')\n });\n env = setupStore({\n superVillain: SuperVillain,\n homePlanet: HomePlanet,\n secretLab: SecretLab,\n secretWeapon: SecretWeapon,\n lightSaber: LightSaber,\n evilMinion: EvilMinion,\n comment: Comment\n });\n env.store.modelFor(\'superVillain\');\n env.store.modelFor(\'homePlanet\');\n env.store.modelFor(\'secretLab\');\n env.store.modelFor(\'secretWeapon\');\n env.store.modelFor(\'lightSaber\');\n env.store.modelFor(\'evilMinion\');\n env.store.modelFor(\'comment\');\n env.container.register(\'serializer:application\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin));\n env.container.register(\'serializer:-active-model\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin));\n env.container.register(\'adapter:-active-model\', DS.ActiveModelAdapter);\n env.amsSerializer = env.container.lookup(\"serializer:-active-model\");\n env.amsAdapter = env.container.lookup(\"adapter:-active-model\");\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"extractSingle with embedded objects\", function() {\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n var json_hash = {\n home_planet: {\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\"\n }]\n }\n };\n var json;\n\n run(function(){\n json = serializer.extractSingle(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n });\n run(function(){\n env.store.find(\"superVillain\", 1).then(function(minion) {\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"extractSingle with embedded objects inside embedded objects\", function() {\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: {embedded: \'always\'}\n }\n }));\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n var json_hash = {\n home_planet: {\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n evil_minions: [{\n id: \"1\",\n name: \"Alex\"\n }]\n }]\n }\n };\n var json;\n\n run(function(){\n json = serializer.extractSingle(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n });\n run(function(){\n env.store.find(\"superVillain\", 1).then(function(villain) {\n equal(villain.get(\'firstName\'), \"Tom\");\n equal(villain.get(\'evilMinions.length\'), 1, \"Should load the embedded child\");\n equal(villain.get(\'evilMinions.firstObject.name\'), \"Alex\", \"Should load the embedded child\");\n });\n env.store.find(\"evilMinion\", 1).then(function(minion) {\n equal(minion.get(\'name\'), \"Alex\");\n });\n });\n});\n\ntest(\"extractSingle with embedded objects of same type\", function() {\n env.container.register(\'adapter:comment\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:comment\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n children: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:comment\");\n var json_hash = {\n comment: {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [{\n id: \"2\",\n body: \"World\",\n root: false\n },\n {\n id: \"3\",\n body: \"Foo\",\n root: false\n }]\n }\n };\n var json;\n run(function(){\n json = serializer.extractSingle(env.store, Comment, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [\"2\", \"3\"]\n }, \"Primary record was correct\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"World\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Foo\", \"Secondary records found in the store\");\n});\n\ntest(\"extractSingle with embedded objects inside embedded objects of same type\", function() {\n env.container.register(\'adapter:comment\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:comment\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n children: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:comment\");\n var json_hash = {\n comment: {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [{\n id: \"2\",\n body: \"World\",\n root: false,\n children: [{\n id: \"4\",\n body: \"Another\",\n root: false\n }]\n },\n {\n id: \"3\",\n body: \"Foo\",\n root: false\n }]\n }\n };\n var json;\n run(function(){\n json = serializer.extractSingle(env.store, Comment, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [\"2\", \"3\"]\n }, \"Primary record was correct\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"World\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Foo\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"4\").get(\"body\"), \"Another\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"children.length\"), 1, \"Should have one embedded record\");\n equal(env.store.recordForId(\"comment\", \"2\").get(\"children.firstObject.body\"), \"Another\", \"Should have one embedded record\");\n});\n\ntest(\"extractSingle with embedded objects of same type, but from separate attributes\", function() {\n HomePlanet.reopen({\n reformedVillains: DS.hasMany(\'superVillain\', {inverse: null})\n });\n\n env.container.register(\'adapter:home_planet\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:home_planet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: {embedded: \'always\'},\n reformedVillains: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:home_planet\");\n var json_hash = {\n home_planet: {\n id: \"1\",\n name: \"Earth\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\"\n }, {\n id: \"3\",\n first_name: \"Yehuda\"\n }],\n reformed_villains: [{\n id: \"2\",\n first_name: \"Alex\"\n },{\n id: \"4\",\n first_name: \"Erik\"\n }]\n }\n };\n var json;\n run(function(){\n json = serializer.extractSingle(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Earth\",\n villains: [\"1\", \"3\"],\n reformedVillains: [\"2\", \"4\"]\n }, \"Primary array was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"2\").get(\"firstName\"), \"Alex\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"3\").get(\"firstName\"), \"Yehuda\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"4\").get(\"firstName\"), \"Erik\", \"Secondary records found in the store\");\n});\n\ntest(\"extractArray with embedded objects\", function() {\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\"\n }]\n }]\n };\n var array;\n\n run(function(){\n array = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n }]);\n\n run(function(){\n env.store.find(\"superVillain\", 1).then(function(minion){\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"extractArray with embedded objects with custom primary key\", function() {\n expect(2);\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend({\n primaryKey: \'villain_id\'\n }));\n env.container.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Umber\",\n villains: [{\n villain_id: \"1\",\n first_name: \"Alex\",\n last_name: \"Baizeau\"\n }]\n }]\n };\n var array;\n\n run(function(){\n array = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n }]);\n\n run(function(){\n return env.store.find(\"superVillain\", 1).then(function(minion){\n env.container.unregister(\'serializer:superVillain\');\n equal(minion.get(\'firstName\'), \"Alex\");\n });\n });\n});\ntest(\"extractArray with embedded objects with identical relationship and attribute key \", function() {\n expect(2);\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: {embedded: \'always\'}\n },\n //Makes the keyForRelationship and keyForAttribute collide.\n keyForRelationship: function(key, type) {\n return this.keyForAttribute(key, type);\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Umber\",\n villains: [{\n id: \"1\",\n first_name: \"Alex\",\n last_name: \"Baizeau\"\n }]\n }]\n };\n var array;\n\n run(function(){\n array = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n name: \"Umber\",\n villains: [\"1\"]\n }]);\n\n run(function(){\n env.store.find(\"superVillain\", 1).then(function(minion){\n equal(minion.get(\'firstName\'), \"Alex\");\n });\n });\n});\ntest(\"extractArray with embedded objects of same type as primary type\", function() {\n env.container.register(\'adapter:comment\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:comment\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n children: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:comment\");\n\n var json_hash = {\n comments: [{\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [{\n id: \"2\",\n body: \"World\",\n root: false\n },\n {\n id: \"3\",\n body: \"Foo\",\n root: false\n }]\n }]\n };\n var array;\n\n run(function(){\n array = serializer.extractArray(env.store, Comment, json_hash);\n });\n\n deepEqual(array, [{\n id: \"1\",\n body: \"Hello\",\n root: true,\n children: [\"2\", \"3\"]\n }], \"Primary array is correct\");\n\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"World\", \"Secondary record found in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Foo\", \"Secondary record found in the store\");\n});\n\ntest(\"extractArray with embedded objects of same type, but from separate attributes\", function() {\n HomePlanet.reopen({\n reformedVillains: DS.hasMany(\'superVillain\')\n });\n\n env.container.register(\'adapter:homePlanet\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: {embedded: \'always\'},\n reformedVillains: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:homePlanet\");\n var json_hash = {\n home_planets: [{\n id: \"1\",\n name: \"Earth\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\"\n },{\n id: \"3\",\n first_name: \"Yehuda\"\n }],\n reformed_villains: [{\n id: \"2\",\n first_name: \"Alex\"\n },{\n id: \"4\",\n first_name: \"Erik\"\n }]\n },{\n id: \"2\",\n name: \"Mars\",\n villains: [{\n id: \"1\",\n first_name: \"Tom\"\n },{\n id: \"3\",\n first_name: \"Yehuda\"\n }],\n reformed_villains: [{\n id: \"5\",\n first_name: \"Peter\"\n },{\n id: \"6\",\n first_name: \"Trek\"\n }]\n }]\n };\n var json;\n run(function(){\n json = serializer.extractArray(env.store, HomePlanet, json_hash);\n });\n\n deepEqual(json, [{\n id: \"1\",\n name: \"Earth\",\n villains: [\"1\", \"3\"],\n reformedVillains: [\"2\", \"4\"]\n },{\n id: \"2\",\n name: \"Mars\",\n villains: [\"1\", \"3\"],\n reformedVillains: [\"5\", \"6\"]\n }], \"Primary array was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"2\").get(\"firstName\"), \"Alex\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"3\").get(\"firstName\"), \"Yehuda\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"4\").get(\"firstName\"), \"Erik\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"5\").get(\"firstName\"), \"Peter\", \"Secondary records found in the store\");\n equal(env.store.recordForId(\"superVillain\", \"6\").get(\"firstName\"), \"Trek\", \"Secondary records found in the store\");\n});\n\ntest(\"serialize supports serialize:false on non-relationship properties\", function() {\n var tom;\n run(function(){\n tom = env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", id: \'1\' });\n });\n\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n firstName: {serialize: false}\n }\n }));\n var serializer, json;\n run(function(){\n serializer = env.container.lookup(\"serializer:superVillain\");\n json = serializer.serialize(tom);\n });\n\n deepEqual(json, {\n last_name: \"Dale\",\n home_planet_id: null,\n secret_lab_id: null\n });\n});\n\ntest(\"serialize with embedded objects (hasMany relationship)\", function() {\n var tom, league;\n run(function(){\n league = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n tom = env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", homePlanet: league, id: \'1\' });\n });\n\n env.container.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: {embedded: \'always\'}\n }\n }));\n\n var serializer, json;\n run(function(){\n serializer = env.container.lookup(\"serializer:homePlanet\");\n\n json = serializer.serialize(league);\n });\n\n deepEqual(json, {\n name: \"Villain League\",\n villains: [{\n id: get(tom, \"id\"),\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: get(league, \"id\"),\n secret_lab_id: null\n }]\n });\n});\n\ntest(\"serialize with embedded objects (hasMany relationship) supports serialize:false\", function() {\n run(function(){\n league = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", homePlanet: league, id: \'1\' });\n });\n\n env.container.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: {serialize: false}\n }\n }));\n var serializer, json;\n run(function(){\n serializer = env.container.lookup(\"serializer:homePlanet\");\n\n json = serializer.serialize(league);\n });\n\n deepEqual(json, {\n name: \"Villain League\"\n });\n});\n\ntest(\"serialize with (new) embedded objects (hasMany relationship)\", function() {\n run(function(){\n league = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n env.store.createRecord(SuperVillain, { firstName: \"Tom\", lastName: \"Dale\", homePlanet: league });\n });\n\n env.container.register(\'serializer:homePlanet\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n villains: {embedded: \'always\'}\n }\n }));\n var serializer, json;\n run(function(){\n serializer = env.container.lookup(\"serializer:homePlanet\");\n\n json = serializer.serialize(league);\n });\n deepEqual(json, {\n name: \"Villain League\",\n villains: [{\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: get(league, \"id\"),\n secret_lab_id: null\n }]\n });\n});\n\ntest(\"serialize with embedded objects (hasMany relationships, including related objects not embedded)\", function() {\n run(function(){\n superVillain = env.store.createRecord(SuperVillain, { id: 1, firstName: \"Super\", lastName: \"Villian\" });\n evilMinion = env.store.createRecord(EvilMinion, { id: 1, name: \"Evil Minion\", superVillian: superVillain });\n secretWeapon = env.store.createRecord(SecretWeapon, { id: 1, name: \"Secret Weapon\", superVillain: superVillain });\n superVillain.get(\'evilMinions\').pushObject(evilMinion);\n superVillain.get(\'secretWeapons\').pushObject(secretWeapon);\n });\n\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: {serialize: \'records\', deserialize: \'records\'},\n secretWeapons: {serialize: \'ids\'}\n }\n }));\n var serializer, json;\n run(function(){\n serializer = env.container.lookup(\"serializer:superVillain\");\n\n json = serializer.serialize(superVillain);\n });\n deepEqual(json, {\n first_name: get(superVillain, \"firstName\"),\n last_name: get(superVillain, \"lastName\"),\n home_planet_id: null,\n evil_minions: [{\n id: get(evilMinion, \"id\"),\n name: get(evilMinion, \"name\"),\n super_villain_id: \"1\"\n }],\n secret_lab_id: null,\n secret_weapon_ids: [ \"1\" ]\n });\n});\n\ntest(\"extractSingle with embedded object (belongsTo relationship)\", function() {\n expect(4);\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n var json_hash = {\n super_villain: {\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n home_planet_id: \"123\",\n evil_minion_ids: [\"1\", \"2\", \"3\"],\n secret_lab: {\n minion_capacity: 5000,\n vicinity: \"California, USA\",\n id: \"101\"\n },\n secret_weapon_ids: []\n }\n };\n var json;\n\n run(function(){\n json = serializer.extractSingle(env.store, SuperVillain, json_hash);\n });\n\n deepEqual(json, {\n \"id\": \"1\",\n \"firstName\": \"Tom\",\n \"lastName\": \"Dale\",\n \"homePlanet\": \"123\",\n \"evilMinions\": [\"1\", \"2\", \"3\"],\n \"secretLab\": \"101\",\n \"secretWeapons\": []\n });\n\n run(function(){\n env.store.find(\"secretLab\", 101).then(function(secretLab) {\n equal(secretLab.get(\'id\'), \'101\');\n equal(secretLab.get(\'minionCapacity\'), 5000);\n equal(secretLab.get(\'vicinity\'), \'California, USA\');\n });\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship)\", function() {\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: {embedded: \'always\'}\n }\n }));\n var serializer, json, tom;\n run(function(){\n serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function(){\n json = serializer.serialize(tom);\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: {\n id: get(tom, \"secretLab\").get(\"id\"),\n minion_capacity: get(tom, \"secretLab\").get(\"minionCapacity\"),\n vicinity: get(tom, \"secretLab\").get(\"vicinity\")\n }\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) works with different primaryKeys\", function() {\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n primaryKey: \'_id\',\n attrs: {\n secretLab: {embedded: \'always\'}\n }\n }));\n env.container.register(\'serializer:secretLab\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n primaryKey: \'crazy_id\'\n }));\n\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n var tom, json;\n\n run(function(){\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function(){\n json = serializer.serialize(tom);\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: {\n crazy_id: get(tom, \"secretLab\").get(\"id\"),\n minion_capacity: get(tom, \"secretLab\").get(\"minionCapacity\"),\n vicinity: get(tom, \"secretLab\").get(\"vicinity\")\n }\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship, new no id)\", function() {\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records without ids, new\n var tom, json;\n\n run(function(){\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function(){\n json = serializer.serialize(tom);\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: {\n minion_capacity: get(tom, \"secretLab\").get(\"minionCapacity\"),\n vicinity: get(tom, \"secretLab\").get(\"vicinity\")\n }\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) supports serialize:ids\", function() {\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: {serialize: \'ids\'}\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n var tom, json;\n\n run(function(){\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function(){\n json = serializer.serialize(tom);\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab_id: get(tom, \"secretLab\").get(\"id\")\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) supports serialize:id\", function() {\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: {serialize: \'id\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n var tom, json;\n\n run(function(){\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function(){\n json = serializer.serialize(tom);\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab_id: get(tom, \"secretLab\").get(\"id\")\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) supports serialize:false\", function() {\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: {serialize: false}\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n var tom, json;\n run(function(){\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function(){\n json = serializer.serialize(tom);\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\")\n });\n});\n\ntest(\"serialize with embedded object (belongsTo relationship) serializes the id by default if no option specified\", function() {\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n // records with an id, persisted\n\n var tom, json;\n\n run(function(){\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n secretLab: env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" }),\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function(){\n json = serializer.serialize(tom);\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab_id: get(tom, \"secretLab\").get(\"id\")\n });\n});\n\ntest(\"when related record is not present, serialize embedded record (with a belongsTo relationship) as null\", function() {\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretLab: {embedded: \'always\'}\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n var tom, json;\n\n run(function(){\n tom = env.store.createRecord(\n SuperVillain,\n { firstName: \"Tom\", lastName: \"Dale\", id: \"1\",\n homePlanet: env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" })\n }\n );\n });\n\n run(function(){\n json = serializer.serialize(tom);\n });\n\n deepEqual(json, {\n first_name: get(tom, \"firstName\"),\n last_name: get(tom, \"lastName\"),\n home_planet_id: get(tom, \"homePlanet\").get(\"id\"),\n secret_lab: null\n });\n});\n\ntest(\"extractSingle with multiply-nested belongsTo\", function() {\n env.container.register(\'adapter:evilMinion\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:evilMinion\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n superVillain: {embedded: \'always\'}\n }\n }));\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n homePlanet: {embedded: \'always\'}\n }\n }));\n\n var serializer = env.container.lookup(\"serializer:evilMinion\");\n var json_hash = {\n evil_minion: {\n id: \"1\",\n name: \"Alex\",\n super_villain: {\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n evil_minion_ids: [\"1\"],\n home_planet: {\n id: \"1\",\n name: \"Umber\",\n super_villain_ids: [\"1\"]\n }\n }\n }\n };\n var json;\n\n run(function(){\n json = serializer.extractSingle(env.store, EvilMinion, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Alex\",\n superVillain: \"1\"\n }, \"Primary array was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary record, Tom, found in the steore\");\n equal(env.store.recordForId(\"homePlanet\", \"1\").get(\"name\"), \"Umber\", \"Nested Secondary record, Umber, found in the store\");\n});\n\ntest(\"extractSingle with polymorphic hasMany\", function() {\n SuperVillain.reopen({\n secretWeapons: DS.hasMany(\"secretWeapon\", {polymorphic: true})\n });\n\n env.container.register(\'adapter:superVillain\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n secretWeapons: {embedded: \'always\'}\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n var json_hash = {\n super_villain: {\n id: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\",\n secret_weapons: [\n {\n id: \"1\",\n type: \"LightSaber\",\n name: \"Tom\'s LightSaber\",\n color: \"Red\"\n },\n {\n id: \"1\",\n type: \"SecretWeapon\",\n name: \"The Death Star\"\n }\n ]\n }\n };\n var json;\n\n run(function(){\n json = serializer.extractSingle(env.store, SuperVillain, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n firstName: \"Tom\",\n lastName: \"Dale\",\n secretWeapons: [\n {id: \"1\", type: \"lightSaber\"},\n {id: \"1\", type: \"secretWeapon\"}\n ]\n }, \"Primary array was correct\");\n\n equal(env.store.recordForId(\"secretWeapon\", \"1\").get(\"name\"), \"The Death Star\", \"Embedded polymorphic SecretWeapon found\");\n equal(env.store.recordForId(\"lightSaber\", \"1\").get(\"name\"), \"Tom\'s LightSaber\", \"Embedded polymorphic LightSaber found\");\n\n\n});\n\ntest(\"Mixin can be used with RESTSerializer which does not define keyForAttribute\", function() {\n run(function(){\n homePlanet = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n secretLab = env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" });\n superVillain = env.store.createRecord(SuperVillain, {\n id: \"1\", firstName: \"Super\", lastName: \"Villian\", homePlanet: homePlanet, secretLab: secretLab\n });\n secretWeapon = env.store.createRecord(SecretWeapon, { id: \"1\", name: \"Secret Weapon\", superVillain: superVillain });\n superVillain.get(\'secretWeapons\').pushObject(secretWeapon);\n evilMinion = env.store.createRecord(EvilMinion, { id: \"1\", name: \"Evil Minion\", superVillian: superVillain });\n superVillain.get(\'evilMinions\').pushObject(evilMinion);\n });\n\n env.container.register(\'serializer:evilMinion\', DS.RESTSerializer);\n env.container.register(\'serializer:secretWeapon\', DS.RESTSerializer);\n env.container.register(\'serializer:superVillain\', DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: {serialize: \'records\', deserialize: \'records\'}\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n var json;\n\n run(function(){\n json = serializer.serialize(superVillain);\n });\n\n deepEqual(json, {\n firstName: get(superVillain, \"firstName\"),\n lastName: get(superVillain, \"lastName\"),\n homePlanet: \"123\",\n evilMinions: [{\n id: get(evilMinion, \"id\"),\n name: get(evilMinion, \"name\"),\n superVillain: \"1\"\n }],\n secretLab: \"101\"\n // \"manyToOne\" relation does not serialize ids\n // sersecretWeapons: [\"1\"]\n });\n});\n\ntest(\"normalize with custom belongsTo primary key\", function() {\n env.container.register(\'adapter:evilMinion\', DS.ActiveModelAdapter);\n env.container.register(\'serializer:evilMinion\', DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n superVillain: {embedded: \'always\'}\n }\n }));\n env.container.register(\'serializer:superVillain\', DS.ActiveModelSerializer.extend({\n primaryKey: \'custom\'\n }));\n\n var serializer = env.container.lookup(\"serializer:evilMinion\");\n var json_hash = {\n evil_minion: {\n id: \"1\",\n name: \"Alex\",\n super_villain: {\n custom: \"1\",\n first_name: \"Tom\",\n last_name: \"Dale\"\n }\n }\n };\n var json;\n\n run(function(){\n json = serializer.extractSingle(env.store, EvilMinion, json_hash);\n });\n\n deepEqual(json, {\n id: \"1\",\n name: \"Alex\",\n superVillain: \"1\"\n }, \"Primary array was correct\");\n\n equal(env.store.recordForId(\"superVillain\", \"1\").get(\"firstName\"), \"Tom\", \"Secondary record, Tom, found in the steore\");\n});\n\ntest(\"serializing relationships with an embedded and without calls super when not attr not present\", function() {\n run(function(){\n homePlanet = env.store.createRecord(HomePlanet, { name: \"Villain League\", id: \"123\" });\n secretLab = env.store.createRecord(SecretLab, { minionCapacity: 5000, vicinity: \"California, USA\", id: \"101\" });\n superVillain = env.store.createRecord(SuperVillain, {\n id: \"1\", firstName: \"Super\", lastName: \"Villian\", homePlanet: homePlanet, secretLab: secretLab\n });\n secretWeapon = env.store.createRecord(SecretWeapon, { id: \"1\", name: \"Secret Weapon\", superVillain: superVillain });\n superVillain.get(\'secretWeapons\').pushObject(secretWeapon);\n evilMinion = env.store.createRecord(EvilMinion, { id: \"1\", name: \"Evil Minion\", superVillian: superVillain });\n superVillain.get(\'evilMinions\').pushObject(evilMinion);\n });\n\n var calledSerializeBelongsTo = false, calledSerializeHasMany = false;\n\n var Serializer = DS.RESTSerializer.extend({\n serializeBelongsTo: function(record, json, relationship) {\n calledSerializeBelongsTo = true;\n return this._super(record, json, relationship);\n },\n serializeHasMany: function(record, json, relationship) {\n calledSerializeHasMany = true;\n var key = relationship.key;\n var payloadKey = this.keyForRelationship ? this.keyForRelationship(key, \"hasMany\") : key;\n var relationshipType = record.constructor.determineRelationshipType(relationship);\n // \"manyToOne\" not supported in DS.RESTSerializer.prototype.serializeHasMany\n var relationshipTypes = Ember.String.w(\'manyToNone manyToMany manyToOne\');\n if (indexOf(relationshipTypes, relationshipType) > -1) {\n json[payloadKey] = get(record, key).mapBy(\'id\');\n }\n }\n });\n env.container.register(\'serializer:evilMinion\', Serializer);\n env.container.register(\'serializer:secretWeapon\', Serializer);\n env.container.register(\'serializer:superVillain\', Serializer.extend(DS.EmbeddedRecordsMixin, {\n attrs: {\n evilMinions: {serialize: \'records\', deserialize: \'records\'}\n // some relationships are not listed here, so super should be called on those\n // e.g. secretWeapons: {serialize: \'ids\'}\n }\n }));\n var serializer = env.container.lookup(\"serializer:superVillain\");\n\n var json;\n run(function(){\n json = serializer.serialize(superVillain);\n });\n\n deepEqual(json, {\n firstName: get(superVillain, \"firstName\"),\n lastName: get(superVillain, \"lastName\"),\n homePlanet: \"123\",\n evilMinions: [{\n id: get(evilMinion, \"id\"),\n name: get(evilMinion, \"name\"),\n superVillain: \"1\"\n }],\n secretLab: \"101\",\n // customized serializeHasMany method to generate ids for \"manyToOne\" relation\n secretWeapons: [\"1\"]\n });\n ok(calledSerializeBelongsTo);\n ok(calledSerializeHasMany);\n});\n})();//# sourceURL=ember-data/integration/serializers/embedded_records_mixin_test.js");
174
+
175
+ eval("(function() {var get = Ember.get;\nvar Post, post, Comment, comment, env;\nvar run = Ember.run;\n\nmodule(\"integration/serializer/json - JSONSerializer\", {\n setup: function() {\n Post = DS.Model.extend({\n title: DS.attr(\'string\'),\n comments: DS.hasMany(\'comment\', {inverse:null})\n });\n Comment = DS.Model.extend({\n body: DS.attr(\'string\'),\n post: DS.belongsTo(\'post\')\n });\n env = setupStore({\n post: Post,\n comment: Comment\n });\n env.store.modelFor(\'post\');\n env.store.modelFor(\'comment\');\n },\n\n teardown: function() {\n run(env.store, \'destroy\');\n }\n});\n\ntest(\"serializeAttribute\", function() {\n run(function(){\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\"});\n });\n var json = {};\n\n env.serializer.serializeAttribute(post, json, \"title\", {type: \"string\"});\n\n deepEqual(json, {\n title: \"Rails is omakase\"\n });\n});\n\ntest(\"serializeAttribute respects keyForAttribute\", function() {\n env.container.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForAttribute: function(key) {\n return key.toUpperCase();\n }\n }));\n\n run(function(){\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\"});\n });\n var json = {};\n\n env.container.lookup(\"serializer:post\").serializeAttribute(post, json, \"title\", {type: \"string\"});\n\n\n deepEqual(json, {\n TITLE: \"Rails is omakase\"\n });\n});\n\ntest(\"serializeBelongsTo\", function() {\n run(function(){\n post = env.store.createRecord(Post, { title: \"Rails is omakase\", id: \"1\"});\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post});\n });\n\n var json = {};\n\n env.serializer.serializeBelongsTo(comment, json, {key: \"post\", options: {}});\n\n deepEqual(json, {\n post: \"1\"\n });\n});\n\ntest(\"serializeBelongsTo with null\", function() {\n run(function(){\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: null});\n });\n var json = {};\n\n env.serializer.serializeBelongsTo(comment, json, {key: \"post\", options: {}});\n\n deepEqual(json, {\n post: null\n }, \"Can set a belongsTo to a null value\");\n});\n\ntest(\"async serializeBelongsTo with null\", function() {\n Comment.reopen({\n post: DS.belongsTo(\'post\', {async:true})\n });\n run(function(){\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: null});\n });\n var json = {};\n\n env.serializer.serializeBelongsTo(comment, json, {key: \"post\", options: {}});\n\n deepEqual(json, {\n post: null\n }, \"Can set a belongsTo to a null value\");\n});\n\ntest(\"serializeBelongsTo respects keyForRelationship\", function() {\n env.container.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForRelationship: function(key, type) {\n return key.toUpperCase();\n }\n }));\n run(function(){\n post = env.store.createRecord(Post, { title: \"Rails is omakase\", id: \"1\"});\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post});\n });\n var json = {};\n\n env.container.lookup(\"serializer:post\").serializeBelongsTo(comment, json, {key: \"post\", options: {}});\n\n deepEqual(json, {\n POST: \"1\"\n });\n});\n\ntest(\"serializeHasMany respects keyForRelationship\", function() {\n env.container.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForRelationship: function(key, type) {\n return key.toUpperCase();\n }\n }));\n\n run(function(){\n post = env.store.createRecord(Post, { title: \"Rails is omakase\", id: \"1\"});\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post, id: \"1\"});\n });\n\n var json = {};\n\n env.container.lookup(\"serializer:post\").serializeHasMany(post, json, {key: \"comments\", options: {}});\n\n deepEqual(json, {\n COMMENTS: [\"1\"]\n });\n});\n\ntest(\"serializeIntoHash\", function() {\n run(function(){\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\"});\n });\n\n var json = {};\n\n env.serializer.serializeIntoHash(json, Post, post);\n\n deepEqual(json, {\n title: \"Rails is omakase\",\n comments: []\n });\n});\n\ntest(\"serializePolymorphicType\", function() {\n env.container.register(\'serializer:comment\', DS.JSONSerializer.extend({\n serializePolymorphicType: function(record, json, relationship) {\n var key = relationship.key,\n belongsTo = get(record, key);\n json[relationship.key + \"TYPE\"] = belongsTo.constructor.typeKey;\n }\n }));\n\n run(function(){\n post = env.store.createRecord(Post, { title: \"Rails is omakase\", id: \"1\"});\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post});\n });\n\n var json = {};\n\n env.container.lookup(\"serializer:comment\").serializeBelongsTo(comment, json, {key: \"post\", options: { polymorphic: true}});\n\n deepEqual(json, {\n post: \"1\",\n postTYPE: \"post\"\n });\n});\n\ntest(\"extractArray normalizes each record in the array\", function() {\n var postNormalizeCount = 0;\n var posts = [\n { title: \"Rails is omakase\"},\n { title: \"Another Post\"}\n ];\n\n env.container.register(\'serializer:post\', DS.JSONSerializer.extend({\n normalize: function () {\n postNormalizeCount++;\n return this._super.apply(this, arguments);\n }\n }));\n\n run(function(){\n env.container.lookup(\"serializer:post\").extractArray(env.store, Post, posts);\n });\n equal(postNormalizeCount, 2, \"two posts are normalized\");\n});\n\ntest(\'Serializer should respect the attrs hash when extracting records\', function(){\n env.container.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n title: \"title_payload_key\",\n comments: { key: \'my_comments\' }\n }\n }));\n\n var jsonHash = {\n title_payload_key: \"Rails is omakase\",\n my_comments: [1, 2]\n };\n\n var post = env.container.lookup(\"serializer:post\").extractSingle(env.store, Post, jsonHash);\n\n equal(post.title, \"Rails is omakase\");\n deepEqual(post.comments, [1,2]);\n});\n\ntest(\'Serializer should respect the attrs hash when serializing records\', function(){\n Post.reopen({\n parentPost: DS.belongsTo(\'post\')\n });\n env.container.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n title: \"title_payload_key\",\n parentPost: {key: \'my_parent\'}\n }\n }));\n var parentPost;\n\n run(function(){\n parentPost = env.store.push(\"post\", { id:2, title: \"Rails is omakase\"});\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\", parentPost: parentPost});\n });\n\n var payload = env.container.lookup(\"serializer:post\").serialize(post);\n\n equal(payload.title_payload_key, \"Rails is omakase\");\n equal(payload.my_parent, \'2\');\n});\n\ntest(\'Serializer respects `serialize: false` on the attrs hash\', function(){\n expect(2);\n env.container.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n title: {serialize: false}\n }\n }));\n\n run(function(){\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\"});\n });\n\n var payload = env.container.lookup(\"serializer:post\").serialize(post);\n\n ok(!payload.hasOwnProperty(\'title\'), \"Does not add the key to instance\");\n ok(!payload.hasOwnProperty(\'[object Object]\'),\"Does not add some random key like [object Object]\");\n});\n\ntest(\'Serializer respects `serialize: false` on the attrs hash for a `hasMany` property\', function(){\n expect(1);\n env.container.register(\"serializer:post\", DS.JSONSerializer.extend({\n attrs: {\n comments: {serialize: false}\n }\n }));\n\n run(function(){\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\"});\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post});\n });\n\n var serializer = env.container.lookup(\"serializer:post\");\n var serializedProperty = serializer.keyForRelationship(\'comments\', \'hasMany\');\n\n var payload = serializer.serialize(post);\n ok(!payload.hasOwnProperty(serializedProperty), \"Does not add the key to instance\");\n});\n\ntest(\'Serializer respects `serialize: false` on the attrs hash for a `belongsTo` property\', function(){\n expect(1);\n env.container.register(\"serializer:comment\", DS.JSONSerializer.extend({\n attrs: {\n post: {serialize: false}\n }\n }));\n\n run(function(){\n post = env.store.createRecord(\"post\", { title: \"Rails is omakase\"});\n comment = env.store.createRecord(Comment, { body: \"Omakase is delicious\", post: post});\n });\n\n var serializer = env.container.lookup(\"serializer:comment\");\n var serializedProperty = serializer.keyForRelationship(\'post\', \'belongsTo\');\n\n var payload = serializer.serialize(comment);\n ok(!payload.hasOwnProperty(serializedProperty), \"Does not add the key to instance\");\n});\n\ntest(\"Serializer should respect the primaryKey attribute when extracting records\", function() {\n env.container.register(\'serializer:post\', DS.JSONSerializer.extend({\n primaryKey: \'_ID_\'\n }));\n\n var jsonHash = { \"_ID_\": 1, title: \"Rails is omakase\"};\n\n run(function(){\n post = env.container.lookup(\"serializer:post\").extractSingle(env.store, Post, jsonHash);\n });\n\n equal(post.id, \"1\");\n equal(post.title, \"Rails is omakase\");\n});\n\ntest(\"Serializer should respect the primaryKey attribute when serializing records\", function() {\n env.container.register(\'serializer:post\', DS.JSONSerializer.extend({\n primaryKey: \'_ID_\'\n }));\n\n run(function(){\n post = env.store.createRecord(\"post\", { id: \"1\", title: \"Rails is omakase\"});\n });\n\n var payload = env.container.lookup(\"serializer:post\").serialize(post, {includeId: true});\n\n equal(payload._ID_, \"1\");\n});\n\ntest(\"Serializer should respect keyForAttribute when extracting records\", function() {\n env.container.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForAttribute: function(key) {\n return key.toUpperCase();\n }\n }));\n\n var jsonHash = {id: 1, TITLE: \'Rails is omakase\'};\n\n post = env.container.lookup(\"serializer:post\").normalize(Post, jsonHash);\n\n equal(post.id, \"1\");\n equal(post.title, \"Rails is omakase\");\n});\n\ntest(\"Serializer should respect keyForRelationship when extracting records\", function() {\n env.container.register(\'serializer:post\', DS.JSONSerializer.extend({\n keyForRelationship: function(key, type) {\n return key.toUpperCase();\n }\n }));\n\n var jsonHash = {id: 1, title: \'Rails is omakase\', COMMENTS: [\'1\']};\n\n post = env.container.lookup(\"serializer:post\").normalize(Post, jsonHash);\n\n deepEqual(post.comments, [\'1\']);\n});\n\ntest(\"normalizePayload is called during extractSingle\", function() {\n env.container.register(\'serializer:post\', DS.JSONSerializer.extend({\n normalizePayload: function(payload) {\n return payload.response;\n }\n }));\n\n var jsonHash = {\n response: {\n id: 1,\n title: \"Rails is omakase\"\n }\n };\n\n run(function(){\n post = env.container.lookup(\"serializer:post\").extractSingle(env.store, Post, jsonHash);\n });\n\n equal(post.id, \"1\");\n equal(post.title, \"Rails is omakase\");\n});\n\ntest(\"Calling normalize should normalize the payload (only the passed keys)\", function () {\n expect(1);\n var Person = DS.Model.extend({\n posts: DS.hasMany(\'post\')\n });\n env.container.register(\'serializer:post\', DS.JSONSerializer.extend({\n attrs: {\n notInHash: \'aCustomAttrNotInHash\',\n inHash: \'aCustomAttrInHash\'\n }\n }));\n\n env.container.register(\'model:person\', Person);\n\n Post.reopen({\n content: DS.attr(\'string\'),\n author: DS.belongsTo(\'person\'),\n notInHash: DS.attr(\'string\'),\n inHash: DS.attr(\'string\')\n });\n\n var normalizedPayload = env.container.lookup(\"serializer:post\").normalize(Post, {\n id: \'1\',\n title: \'Ember rocks\',\n author: 1,\n aCustomAttrInHash: \'blah\'\n });\n\n deepEqual(normalizedPayload, {\n id: \'1\',\n title: \'Ember rocks\',\n author: 1,\n inHash: \'blah\'\n });\n});\n})();//# sourceURL=ember-data/integration/serializers/json_serializer_test.js");
176
+
177
+ eval("(function() {var get = Ember.get;\nvar HomePlanet, league, SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, Comment, env;\nvar run = Ember.run;\n\nmodule(\"integration/serializer/rest - RESTSerializer\", {\n setup: function() {\n HomePlanet = DS.Model.extend({\n name: DS.attr(\'string\'),\n superVillains: DS.hasMany(\'superVillain\')\n });\n SuperVillain = DS.Model.extend({\n firstName: DS.attr(\'string\'),\n lastName: DS.attr(\'string\'),\n homePlanet: DS.belongsTo(\"homePlanet\"),\n evilMinions: DS.hasMany(\"evilMinion\")\n });\n EvilMinion = DS.Model.extend({\n superVillain: DS.belongsTo(\'superVillain\'),\n name: DS.attr(\'string\')\n });\n YellowMinion = EvilMinion.extend();\n DoomsdayDevice = DS.Model.extend({\n name: DS.attr(\'string\'),\n evilMinion: DS.belongsTo(\'evilMinion\', {polymorphic: true})\n });\n Comment = DS.Model.extend({\n body: DS.attr(\'string\'),\n root: DS.attr(\'boolean\'),\n children: DS.hasMany(\'comment\')\n });\n env = setupStore({\n superVillain: SuperVillain,\n homePlanet: HomePlanet,\n evilMinion: EvilMinion,\n yellowMinion: YellowMinion,\n doomsdayDevice: DoomsdayDevice,\n comment: Comment\n });\n env.store.modelFor(\'superVillain\');\n env.store.modelFor(\'homePlanet\');\n env.store.modelFor(\'evilMinion\');\n env.store.modelFor(\'yellowMinion\');\n env.store.modelFor(\'doomsdayDevice\');\n env.store.modelFor(\'comment\');\n },\n\n teardown: function() {\n run(env.store,\'destroy\');\n }\n});\n\ntest(\"typeForRoot returns always same typeKey even for uncountable multi words keys\", function() {\n expect(2);\n Ember.Inflector.inflector.uncountable(\'words\');\n var expectedTypeKey = \'multiWords\';\n equal(env.restSerializer.typeForRoot(\'multi_words\'), expectedTypeKey);\n equal(env.restSerializer.typeForRoot(\'multiWords\'), expectedTypeKey);\n});\n\ntest(\"extractArray with custom typeForRoot\", function() {\n env.restSerializer.typeForRoot = function(root) {\n var camelized = Ember.String.camelize(root);\n return Ember.String.singularize(camelized);\n };\n\n var jsonHash = {\n home_planets: [{id: \"1\", name: \"Umber\", superVillains: [1]}],\n super_villains: [{id: \"1\", firstName: \"Tom\", lastName: \"Dale\", homePlanet: \"1\"}]\n };\n var array;\n\n run(function(){\n array = env.restSerializer.extractArray(env.store, HomePlanet, jsonHash);\n });\n\n deepEqual(array, [{\n \"id\": \"1\",\n \"name\": \"Umber\",\n \"superVillains\": [1]\n }]);\n\n run(function(){\n env.store.find(\"superVillain\", 1).then(function(minion){\n equal(minion.get(\'firstName\'), \"Tom\");\n });\n });\n});\n\ntest(\"extractArray warning with custom typeForRoot\", function() {\n var homePlanets;\n env.restSerializer.typeForRoot = function(root) {\n //return some garbage that won\"t resolve in the container\n return \"garbage\";\n };\n\n var jsonHash = {\n home_planets: [{id: \"1\", name: \"Umber\", superVillains: [1]}]\n };\n\n warns(function(){\n env.restSerializer.extractArray(env.store, HomePlanet, jsonHash);\n }, /Encountered \"home_planets\" in payload, but no model was found for model name \"garbage\"/);\n\n // should not warn if a model is found.\n env.restSerializer.typeForRoot = function(root){\n return Ember.String.camelize(Ember.String.singularize(root));\n };\n\n jsonHash = {\n home_planets: [{id: \"1\", name: \"Umber\", superVillains: [1]}]\n };\n\n noWarns(function(){\n run(function(){\n homePlanets = Ember.A(env.restSerializer.extractArray(env.store, HomePlanet, jsonHash));\n });\n });\n\n equal(get(homePlanets, \"length\"), 1);\n equal(get(homePlanets, \"firstObject.name\"), \"Umber\");\n deepEqual(get(homePlanets, \"firstObject.superVillains\"), [1]);\n});\n\ntest(\"extractSingle warning with custom typeForRoot\", function() {\n var homePlanet;\n env.restSerializer.typeForRoot = function(root) {\n //return some garbage that won\"t resolve in the container\n return \"garbage\";\n };\n\n var jsonHash = {\n home_planet: {id: \"1\", name: \"Umber\", superVillains: [1]}\n };\n\n warns(Ember.run.bind(null, function(){\n run(function(){\n env.restSerializer.extractSingle(env.store, HomePlanet, jsonHash);\n });\n }), /Encountered \"home_planet\" in payload, but no model was found for model name \"garbage\"/);\n\n // should not warn if a model is found.\n env.restSerializer.typeForRoot = function(root){\n return Ember.String.camelize(Ember.String.singularize(root));\n };\n\n jsonHash = {\n home_planet: {id: \"1\", name: \"Umber\", superVillains: [1]}\n };\n\n noWarns(function(){\n run(function(){\n homePlanet = env.restSerializer.extractSingle(env.store, HomePlanet, jsonHash);\n });\n });\n\n equal(get(homePlanet, \"name\"), \"Umber\");\n deepEqual(get(homePlanet, \"superVillains\"), [1]);\n});\n\ntest(\"pushPayload - single record payload - warning with custom typeForRoot\", function() {\n var homePlanet;\n var HomePlanetRestSerializer = DS.RESTSerializer.extend({\n typeForRoot: function(root){\n //return some garbage that won\"t resolve in the container\n if (root === \"home_planet\") {\n return \"garbage\";\n } else {\n return Ember.String.singularize(Ember.String.camelize(root));\n }\n }\n });\n\n env.container.register(\"serializer:homePlanet\", HomePlanetRestSerializer);\n\n var jsonHash = {\n home_planet: {id: \"1\", name: \"Umber\", superVillains: [1]},\n super_villains: [\n {\n \"id\": \"1\",\n \"firstName\": \"Stanley\"\n }\n ]\n };\n\n warns(function(){\n run(function(){\n env.store.pushPayload(\"homePlanet\", jsonHash);\n });\n }, /Encountered \"home_planet\" in payload, but no model was found for model name \"garbage\"/);\n\n\n // assert non-warned records get pushed into store correctly\n var superVillain = env.store.getById(\"superVillain\", \"1\");\n equal(get(superVillain, \"firstName\"), \"Stanley\");\n\n // Serializers are singletons, so that\"s why we use the store which\n // looks at the container to look it up\n env.store.serializerFor(\"homePlanet\").reopen({\n typeForRoot: function(root){\n // should not warn if a model is found.\n return Ember.String.camelize(Ember.String.singularize(root));\n }\n });\n\n jsonHash = {\n home_planet: {id: \"1\", name: \"Umber\", superVillains: [1]},\n super_villains: [\n {\n \"id\": \"1\",\n \"firstName\": \"Stanley\"\n }\n ]\n };\n\n noWarns(function(){\n run(function(){\n env.store.pushPayload(\"homePlanet\", jsonHash);\n homePlanet = env.store.getById(\"homePlanet\", \"1\");\n });\n });\n\n equal(get(homePlanet, \"name\"), \"Umber\");\n deepEqual(get(homePlanet, \"superVillains.firstObject.firstName\"), \"Stanley\");\n});\n\ntest(\"pushPayload - multiple record payload (extractArray) - warning with custom typeForRoot\", function() {\n var homePlanet;\n var HomePlanetRestSerializer = DS.RESTSerializer.extend({\n typeForRoot: function(root){\n //return some garbage that won\"t resolve in the container\n if (root === \"home_planets\") {\n return \"garbage\";\n } else {\n return Ember.String.singularize(Ember.String.camelize(root));\n }\n }\n });\n\n env.container.register(\"serializer:homePlanet\", HomePlanetRestSerializer);\n\n var jsonHash = {\n home_planets: [{id: \"1\", name: \"Umber\", superVillains: [1]}],\n super_villains: [\n {\n \"id\": \"1\",\n \"firstName\": \"Stanley\"\n }\n ]\n };\n\n warns(function(){\n run(function(){\n env.store.pushPayload(\"homePlanet\", jsonHash);\n });\n }, /Encountered \"home_planets\" in payload, but no model was found for model name \"garbage\"/);\n\n // assert non-warned records get pushed into store correctly\n var superVillain = env.store.getById(\"superVillain\", \"1\");\n equal(get(superVillain, \"firstName\"), \"Stanley\");\n\n // Serializers are singletons, so that\"s why we use the store which\n // looks at the container to look it up\n env.store.serializerFor(\"homePlanet\").reopen({\n typeForRoot: function(root){\n // should not warn if a model is found.\n return Ember.String.camelize(Ember.String.singularize(root));\n }\n });\n\n jsonHash = {\n home_planets: [{id: \"1\", name: \"Umber\", superVillains: [1]}],\n super_villains: [\n {\n \"id\": \"1\",\n \"firstName\": \"Stanley\"\n }\n ]\n };\n\n noWarns(function(){\n run(function(){\n env.store.pushPayload(\"homePlanet\", jsonHash);\n homePlanet = env.store.getById(\"homePlanet\", \"1\");\n });\n });\n\n equal(get(homePlanet, \"name\"), \"Umber\");\n deepEqual(get(homePlanet, \"superVillains.firstObject.firstName\"), \"Stanley\");\n});\n\ntest(\"serialize polymorphicType\", function() {\n var tom, ray;\n run(function(){\n tom = env.store.createRecord(YellowMinion, {name: \"Alex\", id: \"124\"});\n ray = env.store.createRecord(DoomsdayDevice, {evilMinion: tom, name: \"DeathRay\"});\n });\n\n var json = env.restSerializer.serialize(ray);\n\n deepEqual(json, {\n name: \"DeathRay\",\n evilMinionType: \"yellowMinion\",\n evilMinion: \"124\"\n });\n});\n\ntest(\"serialize polymorphicType with decamelized typeKey\", function() {\n YellowMinion.typeKey = \'yellow-minion\';\n var tom, ray;\n run(function(){\n tom = env.store.createRecord(YellowMinion, {name: \"Alex\", id: \"124\"});\n ray = env.store.createRecord(DoomsdayDevice, {evilMinion: tom, name: \"DeathRay\"});\n });\n\n var json = env.restSerializer.serialize(ray);\n\n deepEqual(json[\"evilMinionType\"], \"yellowMinion\");\n});\n\ntest(\"normalizePayload is called during extractSingle\", function() {\n env.container.register(\'serializer:application\', DS.RESTSerializer.extend({\n normalizePayload: function(payload) {\n return payload.response;\n }\n }));\n\n var jsonHash = { response: {\n evilMinion: {id: \"1\", name: \"Tom Dale\", superVillain: 1},\n superVillains: [{id: \"1\", firstName: \"Yehuda\", lastName: \"Katz\", homePlanet: \"1\"}]\n } };\n\n var applicationSerializer = env.container.lookup(\'serializer:application\');\n var data;\n\n run(function(){\n data = applicationSerializer.extractSingle(env.store, EvilMinion, jsonHash);\n });\n\n equal(data.name, jsonHash.response.evilMinion.name, \"normalize reads off the response\");\n\n});\ntest(\"serialize polymorphic when associated object is null\", function() {\n var ray;\n run(function(){\n ray = env.store.createRecord(DoomsdayDevice, {name: \"DeathRay\"});\n });\n\n var json = env.restSerializer.serialize(ray);\n\n deepEqual(json[\"evilMinionType\"], null);\n});\n\ntest(\"extractArray can load secondary records of the same type without affecting the query count\", function() {\n var jsonHash = {\n comments: [{id: \"1\", body: \"Parent Comment\", root: true, children: [2, 3]}],\n _comments: [\n { id: \"2\", body: \"Child Comment 1\", root: false },\n { id: \"3\", body: \"Child Comment 2\", root: false }\n ]\n };\n var array;\n\n run(function(){\n array = env.restSerializer.extractArray(env.store, Comment, jsonHash);\n });\n\n deepEqual(array, [{\n \"id\": \"1\",\n \"body\": \"Parent Comment\",\n \"root\": true,\n \"children\": [2, 3]\n }]);\n\n equal(array.length, 1, \"The query count is unaffected\");\n\n equal(env.store.recordForId(\"comment\", \"2\").get(\"body\"), \"Child Comment 1\", \"Secondary records are in the store\");\n equal(env.store.recordForId(\"comment\", \"3\").get(\"body\"), \"Child Comment 2\", \"Secondary records are in the store\");\n});\n\ntest(\"extractSingle loads secondary records with correct serializer\", function() {\n var superVillainNormalizeCount = 0;\n\n env.container.register(\'serializer:superVillain\', DS.RESTSerializer.extend({\n normalize: function() {\n superVillainNormalizeCount++;\n return this._super.apply(this, arguments);\n }\n }));\n\n var jsonHash = {\n evilMinion: {id: \"1\", name: \"Tom Dale\", superVillain: 1},\n superVillains: [{id: \"1\", firstName: \"Yehuda\", lastName: \"Katz\", homePlanet: \"1\"}]\n };\n\n run(function(){\n env.restSerializer.extractSingle(env.store, EvilMinion, jsonHash);\n });\n\n equal(superVillainNormalizeCount, 1, \"superVillain is normalized once\");\n});\n\ntest(\"extractSingle returns null if payload contains null\", function() {\n expect(1);\n\n var jsonHash = {\n evilMinion: null\n };\n var value;\n\n run(function(){\n value = env.restSerializer.extractSingle(env.store, EvilMinion, jsonHash);\n });\n\n equal(value, null, \"returned value is null\");\n});\n\ntest(\"extractArray loads secondary records with correct serializer\", function() {\n var superVillainNormalizeCount = 0;\n\n env.container.register(\'serializer:superVillain\', DS.RESTSerializer.extend({\n normalize: function() {\n superVillainNormalizeCount++;\n return this._super.apply(this, arguments);\n }\n }));\n\n var jsonHash = {\n evilMinions: [{id: \"1\", name: \"Tom Dale\", superVillain: 1}],\n superVillains: [{id: \"1\", firstName: \"Yehuda\", lastName: \"Katz\", homePlanet: \"1\"}]\n };\n\n run(function(){\n env.restSerializer.extractArray(env.store, EvilMinion, jsonHash);\n });\n\n equal(superVillainNormalizeCount, 1, \"superVillain is normalized once\");\n});\n\ntest(\'normalizeHash normalizes specific parts of the payload\', function(){\n env.container.register(\'serializer:application\', DS.RESTSerializer.extend({\n normalizeHash: {\n homePlanets: function(hash) {\n hash.id = hash._id;\n delete hash._id;\n return hash;\n }\n }\n }));\n\n var jsonHash = { homePlanets: [{_id: \"1\", name: \"Umber\", superVillains: [1]}] };\n var array;\n\n run(function(){\n array = env.restSerializer.extractArray(env.store, HomePlanet, jsonHash);\n });\n\n deepEqual(array, [{\n \"id\": \"1\",\n \"name\": \"Umber\",\n \"superVillains\": [1]\n }]);\n});\n\ntest(\'normalizeHash works with transforms\', function(){\n env.container.register(\'serializer:application\', DS.RESTSerializer.extend({\n normalizeHash: {\n evilMinions: function(hash) {\n hash.condition = hash._condition;\n delete hash._condition;\n return hash;\n }\n }\n }));\n\n env.container.register(\'transform:condition\', DS.Transform.extend({\n deserialize: function(serialized) {\n if (serialized === 1) {\n return \"healing\";\n } else {\n return \"unknown\";\n }\n },\n serialize: function(deserialized) {\n if (deserialized === \"healing\") {\n return 1;\n } else {\n return 2;\n }\n }\n }));\n\n EvilMinion.reopen({ condition: DS.attr(\'condition\') });\n\n var jsonHash = {\n evilMinions: [{id: \"1\", name: \"Tom Dale\", superVillain: 1, _condition: 1}]\n };\n var array;\n\n run(function(){\n array = env.restSerializer.extractArray(env.store, EvilMinion, jsonHash);\n });\n\n equal(array[0].condition, \"healing\");\n});\n\ntest(\'normalize should allow for different levels of normalization\', function(){\n env.container.register(\'serializer:application\', DS.RESTSerializer.extend({\n attrs: {\n superVillain: \'is_super_villain\'\n },\n keyForAttribute: function(attr) {\n return Ember.String.decamelize(attr);\n }\n }));\n\n var jsonHash = {\n evilMinions: [{id: \"1\", name: \"Tom Dale\", is_super_villain: 1}]\n };\n var array;\n\n run(function(){\n array = env.restSerializer.extractArray(env.store, EvilMinion, jsonHash);\n });\n\n equal(array[0].superVillain, 1);\n});\n\ntest(\"serializeIntoHash\", function() {\n run(function(){\n league = env.store.createRecord(HomePlanet, { name: \"Umber\", id: \"123\" });\n });\n var json = {};\n\n env.restSerializer.serializeIntoHash(json, HomePlanet, league);\n\n deepEqual(json, {\n homePlanet: {\n name: \"Umber\"\n }\n });\n});\n\ntest(\"serializeIntoHash with decamelized typeKey\", function() {\n HomePlanet.typeKey = \'home-planet\';\n run(function(){\n league = env.store.createRecord(HomePlanet, { name: \"Umber\", id: \"123\" });\n });\n var json = {};\n\n env.restSerializer.serializeIntoHash(json, HomePlanet, league);\n\n deepEqual(json, {\n homePlanet: {\n name: \"Umber\"\n }\n });\n});\n})();//# sourceURL=ember-data/integration/serializers/rest_serializer_test.js");
178
+
179
+ eval("(function() {var run = Ember.run,\n Container = Ember.Container,\n Store = DS.Store,\n EmberObject = Ember.Object,\n setupContainer = DS._setupContainer;\n\nvar container;\n\n/*\n These tests ensure that Ember Data works with Ember.js\' container\n initialization and dependency injection API.\n*/\n\nmodule(\"integration/setup-container - Setting up a container\", {\n setup: function() {\n container = new Container();\n setupContainer(container);\n },\n\n teardown: function() {\n run(container, container.destroy);\n }\n});\n\ntest(\"The store should be registered into a container.\", function() {\n ok(container.lookup(\'store:main\') instanceof Store, \"the custom store is instantiated\");\n});\n\ntest(\"If a store is instantiated, it should be made available to each controller.\", function() {\n container.register(\'controller:foo\', EmberObject.extend({}));\n var fooController = container.lookup(\'controller:foo\');\n ok(fooController.get(\'store\') instanceof Store, \"the store was injected\");\n});\n\ntest(\"the deprecated serializer:_default is resolved as serializer:default\", function(){\n var deprecated, valid = container.lookup(\'serializer:-default\');\n expectDeprecation(function() {\n deprecated = container.lookup(\'serializer:_default\');\n });\n\n ok(deprecated === valid, \"they should resolve to the same thing\");\n});\n\ntest(\"the deprecated serializer:_rest is resolved as serializer:rest\", function(){\n var deprecated, valid = container.lookup(\'serializer:-rest\');\n expectDeprecation(function() {\n deprecated = container.lookup(\'serializer:_rest\');\n });\n\n ok(deprecated === valid, \"they should resolve to the same thing\");\n});\n\ntest(\"the deprecated adapter:_rest is resolved as adapter:rest\", function(){\n var deprecated, valid = container.lookup(\'adapter:-rest\');\n expectDeprecation(function() {\n deprecated = container.lookup(\'adapter:_rest\');\n });\n\n ok(deprecated === valid, \"they should resolve to the same thing\");\n});\n\ntest(\"a deprecation is made when looking up adapter:_rest\", function(){\n expectDeprecation(function(){\n container.lookup(\'serializer:_default\');\n },\"You tried to look up \'serializer:_default\', but this has been deprecated in favor of \'serializer:-default\'.\");\n});\n})();//# sourceURL=ember-data/integration/setup-container-test.js");
180
+
181
+ eval("(function() {var store, env;\n\nvar Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n cars: DS.hasMany(\'car\')\n});\n\nvar run = Ember.run;\n\nPerson.toString = function() { return \"Person\"; };\n\nvar Car = DS.Model.extend({\n make: DS.attr(\'string\'),\n model: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n});\n\nCar.toString = function() { return \"Car\"; };\n\nfunction initializeStore(adapter) {\n env = setupStore({\n adapter: adapter\n });\n store = env.store;\n\n env.container.register(\'model:car\', Car);\n env.container.register(\'model:person\', Person);\n}\n\nmodule(\"integration/store - destroy\", {\n setup: function(){\n initializeStore(DS.FixtureAdapter.extend());\n }\n});\n\nfunction tap(obj, methodName, callback) {\n var old = obj[methodName];\n\n var summary = { called: [] };\n\n obj[methodName] = function() {\n var result = old.apply(obj, arguments);\n if (callback) {\n callback.apply(obj, arguments);\n }\n summary.called.push(arguments);\n return result;\n };\n\n return summary;\n}\n\nasyncTest(\"destroying record during find doesn\'t cause error\", function() {\n expect(0);\n\n var TestAdapter = DS.FixtureAdapter.extend({\n find: function() {\n return new Ember.RSVP.Promise(function(resolve, reject) {\n Ember.run.next(function() {\n store.unloadAll(type);\n reject();\n });\n });\n }\n });\n\n initializeStore(TestAdapter);\n\n var type = \"car\";\n var id = 1;\n\n function done(){\n start();\n }\n\n run(function(){\n store.find(type, id).then(done, done);\n });\n});\n\nasyncTest(\"find calls do not resolve when the store is destroyed\", function() {\n expect(0);\n\n var TestAdapter = DS.FixtureAdapter.extend({\n find: function() {\n store.destroy();\n Ember.RSVP.resolve(null);\n }\n });\n\n initializeStore(TestAdapter);\n\n\n var type = \"car\";\n var id = 1;\n\n store.push = function() {\n Ember.assert(\"The test should have destroyed the store by now\", store.get(\"isDestroyed\"));\n\n throw new Error(\"We shouldn\'t be pushing data into the store when it is destroyed\");\n };\n\n run(function(){\n store.find(type, id);\n });\n\n setTimeout(function() {\n start();\n }, 500);\n});\n\n\ntest(\"destroying the store correctly cleans everything up\", function() {\n var car, person;\n run(function(){\n car = store.push(\'car\', {\n id: 1,\n make: \'BMC\',\n model: \'Mini\',\n person: 1\n });\n\n person = store.push(\'person\', {\n id: 1,\n name: \'Tom Dale\',\n cars: [1]\n });\n });\n\n var personWillDestroy = tap(person, \'willDestroy\');\n var carWillDestroy = tap(car, \'willDestroy\');\n var carsWillDestroy = tap(car.get(\'person.cars\'), \'willDestroy\');\n\n env.adapter.findQuery = function() {\n return [{\n id: 2,\n name: \'Yehuda\'\n }];\n };\n var adapterPopulatedPeople, filterdPeople;\n\n run(function(){\n adapterPopulatedPeople = store.find(\'person\', {\n someCrazy: \'query\'\n });\n });\n\n run(function(){\n filterdPeople = store.filter(\'person\', function(){ return true; });\n });\n\n var filterdPeopleWillDestroy = tap(filterdPeople.content, \'willDestroy\');\n var adapterPopulatedPeopleWillDestroy = tap(adapterPopulatedPeople.content, \'willDestroy\');\n\n run(function(){\n store.find(\'person\', 2);\n });\n\n equal(personWillDestroy.called.length, 0, \'expected person.willDestroy to not have been called\');\n equal(carWillDestroy.called.length, 0, \'expected car.willDestroy to not have been called\');\n equal(carsWillDestroy.called.length, 0, \'expected cars.willDestroy to not have been called\');\n equal(adapterPopulatedPeopleWillDestroy.called.length, 0, \'expected adapterPopulatedPeople.willDestroy to not have been called\');\n equal(filterdPeopleWillDestroy.called.length, 0, \'expected filterdPeople.willDestroy to not have been called\');\n\n equal(filterdPeople.get(\'length\'), 2, \'expected filterdPeople to have 2 entries\');\n\n equal(car.get(\'person\'), person, \"expected car\'s person to be the correct person\");\n equal(person.get(\'cars.firstObject\'), car, \" expected persons cars\'s firstRecord to be the correct car\");\n\n Ember.run(person, person.destroy);\n Ember.run(store, \'destroy\');\n\n equal(car.get(\'person\'), null, \"expected car.person to no longer be present\");\n equal(person.get(\'cars\'), undefined, \"expected person.cars to be empty\");\n\n equal(personWillDestroy.called.length, 1, \'expected person to have recieved willDestroy once\');\n equal(carWillDestroy.called.length, 1, \'expected car to recieve willDestroy once\');\n equal(carsWillDestroy.called.length, 1, \'expected cars to recieve willDestroy once\');\n equal(adapterPopulatedPeopleWillDestroy.called.length, 1, \'expected adapterPopulatedPeople to recieve willDestroy once\');\n equal(filterdPeopleWillDestroy.called.length, 1, \'expected filterdPeople.willDestroy to have been called once\');\n});\n\nmodule(\"integration/store - fetch\", {\n setup: function(){\n initializeStore(DS.RESTAdapter.extend());\n }\n});\n\nfunction ajaxResponse(value) {\n var passedUrl, passedVerb, passedHash;\n env.adapter.ajax = function(url, verb, hash) {\n passedUrl = url;\n passedVerb = verb;\n passedHash = hash;\n\n return Ember.RSVP.resolve(value);\n };\n}\n\ntest(\"Using store#fetch on existing record reloads it\", function() {\n expect(2);\n var car;\n\n run(function(){\n car = store.push(\'car\', {\n id: 1,\n make: \'BMC\',\n model: \'Mini\'\n });\n\n });\n ajaxResponse({\n cars: [{\n id: 1,\n make: \'BMCW\',\n model: \'Mini\'\n }]\n });\n\n equal(car.get(\'make\'), \'BMC\');\n\n run(function(){\n store.fetch(\'car\', 1).then(function(car) {\n equal(car.get(\'make\'), \'BMCW\');\n });\n });\n});\n\ntest(\"Using store#fetch on non existing record calls find\", function() {\n expect(2);\n\n ajaxResponse({\n cars: [{\n id: 20,\n make: \'BMCW\',\n model: \'Mini\'\n }]\n });\n\n var car = store.hasRecordForId(\'car\', 20);\n ok(!car, \'Car with id=20 should not exist\');\n\n run(function(){\n store.fetch(\'car\', 20).then(function (car) {\n equal(car.get(\'make\'), \'BMCW\', \'Car with id=20 is now loaded\');\n });\n });\n});\n})();//# sourceURL=ember-data/integration/store_test.js");
182
+
183
+ eval("(function() {var Person, array, store;\n\nvar adapter = DS.Adapter.extend({\n deleteRecord: function(){\n return Ember.RSVP.Promise.resolve();\n }\n});\n\nmodule(\"unit/adapter_populated_record_array - DS.AdapterPopulatedRecordArray\", {\n setup: function() {\n\n store = createStore({\n adapter: adapter\n });\n\n array = [{ id: \'1\', name: \"Scumbag Dale\" },\n { id: \'2\', name: \"Scumbag Katz\" },\n { id: \'3\', name: \"Scumbag Bryn\" }];\n\n Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n }\n});\n\ntest(\"when a record is deleted in an adapter populated record array, it should be removed\", function() {\n var recordArray = store.recordArrayManager\n .createAdapterPopulatedRecordArray(Person, null);\n\n Ember.run(function(){\n recordArray.load(array);\n });\n\n equal(recordArray.get(\'length\'), 3, \"expected recordArray to contain exactly 3 records\");\n\n Ember.run(function(){\n recordArray.get(\'firstObject\').destroyRecord();\n });\n\n equal(recordArray.get(\'length\'), 2, \"expected recordArray to contain exactly 2 records\");\n});\n})();//# sourceURL=ember-data/unit/adapter_populated_record_array_test.js");
184
+
185
+ eval("(function() {var Person, Place, store, adapter, env;\nvar run = Ember.run;\n\nmodule(\"integration/adapter/ajax - building requests\", {\n setup: function() {\n Person = {typeKey: \'person\'};\n Place = {typeKey: \'place\'};\n env = setupStore({adapter: DS.RESTAdapter, person: Person, place: Place });\n store = env.store;\n adapter = env.adapter;\n },\n\n teardown: function() {\n run(function(){\n store.destroy();\n env.container.destroy();\n });\n }\n});\n\ntest(\"When an id is searched, the correct url should be generated\", function() {\n expect(2);\n var count = 0;\n adapter.ajax = function(url, method) {\n if (count === 0) {equal(url, \'/people/1\', \"should create the correct url\");}\n if (count === 1) {equal(url, \'/places/1\', \"should create the correct url\");}\n count++;\n return Ember.RSVP.resolve();\n };\n run(function(){\n adapter.find(store, Person, 1);\n adapter.find(store, Place, 1);\n });\n});\ntest(\"id\'s should be sanatized\", function() {\n expect(1);\n adapter.ajax= function(url, method) {\n equal(url, \'/people/..%2Fplace%2F1\', \"should create the correct url\");\n return Ember.RSVP.resolve();\n };\n run(function(){\n adapter.find(store, Person, \'../place/1\');\n });\n});\n})();//# sourceURL=ember-data/unit/adapters/rest_adapter/ajax.js");
186
+
187
+ eval("(function() {var GroupsAdapter, Store;\nvar maxLength = -1;\nvar lengths = Ember.A([]);\n\nmodule(\"unit/adapters/rest_adapter/group_records_for_find_many_test - DS.RESTAdapter#groupRecordsForFindMany\", {\n setup: function() {\n GroupsAdapter = DS.RESTAdapter.extend({\n\n coalesceFindRequests: true,\n\n find: function(store, type, id) {\n return Ember.RSVP.Promise.resolve({ id: id });\n },\n\n ajax: function(url, type, options) {\n var queryString = options.data.ids.map(function(i) {\n return encodeURIComponent(\'ids[]\') + \'=\' + encodeURIComponent(i);\n }).join(\'&\');\n var fullUrl = url + \'?\' + queryString;\n\n maxLength = this.get(\'maxUrlLength\');\n lengths.push(fullUrl.length);\n\n return Ember.RSVP.Promise.resolve({ \'testRecords\' : [] });\n }\n\n });\n\n Store = createStore({\n adapter: GroupsAdapter,\n testRecord: DS.Model.extend()\n });\n\n }\n});\n\r\ntest(\'groupRecordsForFindMany - findMany\', function() {\r\n\r\n Ember.run(function() {\r\n for(var i = 1; i <= 1024; i++) {\r\n Store.find(\'testRecord\', i);\r\n }\r\n });\r\n\r\n ok(lengths.every(function(len) {\r\n return len <= maxLength;\r\n }), \"Some URLs are longer than \" + maxLength + \" chars\");\r\n\r\n});\r\n})();//# sourceURL=ember-data/unit/adapters/rest_adapter/group_records_for_find_many_test.js");
188
+
189
+ eval("(function() {var env, adapter;\nmodule(\"unit/adapters/rest_adapter/path_for_type - DS.RESTAdapter#pathForType\", {\n setup: function() {\n env = setupStore({\n adapter: DS.RESTAdapter\n });\n\n adapter = env.adapter;\n }\n});\n\ntest(\'pathForType - works with camelized types\', function() {\n equal(adapter.pathForType(\'superUser\'), \"superUsers\");\n});\n\ntest(\'pathForType - works with dasherized types\', function() {\n equal(adapter.pathForType(\'super-user\'), \"superUsers\");\n});\n\ntest(\'pathForType - works with underscored types\', function() {\n equal(adapter.pathForType(\'super_user\'), \"superUsers\");\n});\n})();//# sourceURL=ember-data/unit/adapters/rest_adapter/path_for_type_test.js");
190
+
191
+ eval("(function() {var store;\nvar run = Ember.run;\n\nvar TestAdapter = DS.Adapter.extend();\n\nmodule(\"Debug\");\n\ntest(\"_debugInfo groups the attributes and relationships correctly\", function() {\n var MaritalStatus = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var Post = DS.Model.extend({\n title: DS.attr(\'string\')\n });\n\n var User = DS.Model.extend({\n name: DS.attr(\'string\'),\n isDrugAddict: DS.attr(\'boolean\'),\n maritalStatus: DS.belongsTo(\'maritalStatus\'),\n posts: DS.hasMany(\'post\')\n });\n\n var store = createStore({\n adapter: TestAdapter.extend(),\n maritalStatus: MaritalStatus,\n post: Post,\n user: User\n });\n var record;\n\n run(function(){\n record = store.createRecord(User);\n });\n\n var propertyInfo = record._debugInfo().propertyInfo;\n\n equal(propertyInfo.groups.length, 4);\n deepEqual(propertyInfo.groups[0].properties, [\'id\', \'name\', \'isDrugAddict\']);\n deepEqual(propertyInfo.groups[1].properties, [\'maritalStatus\']);\n deepEqual(propertyInfo.groups[2].properties, [\'posts\']);\n});\n})();//# sourceURL=ember-data/unit/debug_test.js");
192
+
193
+ eval("(function() {var errors;\n\nmodule(\"unit/model/errors\", {\n setup: function() {\n errors = DS.Errors.create();\n },\n\n teardown: function() {\n }\n});\n\nfunction becameInvalid(eventName) {\n if (eventName === \'becameInvalid\') {\n ok(true, \'becameInvalid send\');\n } else {\n ok(false, eventName + \' is send instead of becameInvalid\');\n }\n}\n\nfunction becameValid(eventName) {\n if (eventName === \'becameValid\') {\n ok(true, \'becameValid send\');\n } else {\n ok(false, eventName + \' is send instead of becameValid\');\n }\n}\n\nfunction unexpectedSend(eventName) {\n ok(false, \'unexpected send : \' + eventName);\n}\n\ntest(\"add error\", function() {\n expect(6);\n errors.trigger = becameInvalid;\n errors.add(\'firstName\', \'error\');\n errors.trigger = unexpectedSend;\n ok(errors.has(\'firstName\'), \'it has firstName errors\');\n equal(errors.get(\'length\'), 1, \'it has 1 error\');\n errors.add(\'firstName\', [\'error1\', \'error2\']);\n equal(errors.get(\'length\'), 3, \'it has 3 errors\');\n ok(!errors.get(\'isEmpty\'), \'it is not empty\');\n errors.add(\'lastName\', \'error\');\n errors.add(\'lastName\', \'error\');\n equal(errors.get(\'length\'), 4, \'it has 4 errors\');\n});\n\ntest(\"get error\", function() {\n expect(8);\n ok(errors.get(\'firstObject\') === undefined, \'returns undefined\');\n errors.trigger = becameInvalid;\n errors.add(\'firstName\', \'error\');\n errors.trigger = unexpectedSend;\n ok(errors.get(\'firstName\').length === 1, \'returns errors\');\n deepEqual(errors.get(\'firstObject\'), {attribute: \'firstName\', message: \'error\'});\n errors.add(\'firstName\', \'error2\');\n ok(errors.get(\'firstName\').length === 2, \'returns errors\');\n errors.add(\'lastName\', \'error3\');\n deepEqual(errors.toArray(), [\n { attribute: \'firstName\', message: \'error\' },\n { attribute: \'firstName\', message: \'error2\' },\n { attribute: \'lastName\', message: \'error3\' }\n ]);\n deepEqual(errors.get(\'firstName\'), [\n { attribute: \'firstName\', message: \'error\' },\n { attribute: \'firstName\', message: \'error2\' }\n ]);\n deepEqual(errors.get(\'messages\'), [\'error\', \'error2\', \'error3\']);\n});\n\ntest(\"remove error\", function() {\n expect(5);\n errors.trigger = becameInvalid;\n errors.add(\'firstName\', \'error\');\n errors.trigger = becameValid;\n errors.remove(\'firstName\');\n errors.trigger = unexpectedSend;\n ok(!errors.has(\'firstName\'), \'it has no firstName errors\');\n equal(errors.get(\'length\'), 0, \'it has 0 error\');\n ok(errors.get(\'isEmpty\'), \'it is empty\');\n errors.remove(\'firstName\');\n});\n\ntest(\"remove same errors from different attributes\", function() {\n expect(5);\n errors.trigger = becameInvalid;\n errors.add(\'firstName\', \'error\');\n errors.add(\'lastName\', \'error\');\n errors.trigger = unexpectedSend;\n equal(errors.get(\'length\'), 2, \'it has 2 error\');\n errors.remove(\'firstName\');\n equal(errors.get(\'length\'), 1, \'it has 1 error\');\n errors.trigger = becameValid;\n errors.remove(\'lastName\');\n ok(errors.get(\'isEmpty\'), \'it is empty\');\n});\n\ntest(\"clear errors\", function() {\n expect(5);\n errors.trigger = becameInvalid;\n errors.add(\'firstName\', [\'error\', \'error1\']);\n equal(errors.get(\'length\'), 2, \'it has 2 errors\');\n errors.trigger = becameValid;\n errors.clear();\n errors.trigger = unexpectedSend;\n ok(!errors.has(\'firstName\'), \'it has no firstName errors\');\n equal(errors.get(\'length\'), 0, \'it has 0 error\');\n errors.clear();\n});\n})();//# sourceURL=ember-data/unit/model/errors_test.js");
194
+
195
+ eval("(function() {var get = Ember.get;\nvar run = Ember.run;\n\nmodule(\"unit/model/lifecycle_callbacks - Lifecycle Callbacks\");\n\ntest(\"a record receives a didLoad callback when it has finished loading\", function() {\n var Person = DS.Model.extend({\n name: DS.attr(),\n didLoad: function() {\n ok(\"The didLoad callback was called\");\n }\n });\n\n var adapter = DS.Adapter.extend({\n find: function(store, type, id) {\n return Ember.RSVP.resolve({ id: 1, name: \"Foo\" });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n run(function(){\n store.find(Person, 1).then(function(person) {\n equal(person.get(\'id\'), \"1\", \"The person\'s ID is available\");\n equal(person.get(\'name\'), \"Foo\", \"The person\'s properties are available\");\n });\n });\n});\n\ntest(\"a record receives a didUpdate callback when it has finished updating\", function() {\n var callCount = 0;\n\n var Person = DS.Model.extend({\n bar: DS.attr(\'string\'),\n\n didUpdate: function() {\n callCount++;\n equal(get(this, \'isSaving\'), false, \"record should be saving\");\n equal(get(this, \'isDirty\'), false, \"record should not be dirty\");\n }\n });\n\n var adapter = DS.Adapter.extend({\n find: function(store, type, id) {\n return Ember.RSVP.resolve({ id: 1, name: \"Foo\" });\n },\n\n updateRecord: function(store, type, record) {\n equal(callCount, 0, \"didUpdate callback was not called until didSaveRecord is called\");\n\n return Ember.RSVP.resolve();\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n var asyncPerson;\n\n run(function(){\n asyncPerson = store.find(Person, 1);\n });\n equal(callCount, 0, \"precond - didUpdate callback was not called yet\");\n\n run(function(){\n asyncPerson.then(function(person) {\n return run(function(){\n person.set(\'bar\', \"Bar\");\n return person.save();\n });\n }).then(function() {\n equal(callCount, 1, \"didUpdate called after update\");\n });\n });\n});\n\ntest(\"a record receives a didCreate callback when it has finished updating\", function() {\n var callCount = 0;\n\n var Person = DS.Model.extend({\n didCreate: function() {\n callCount++;\n equal(get(this, \'isSaving\'), false, \"record should not be saving\");\n equal(get(this, \'isDirty\'), false, \"record should not be dirty\");\n }\n });\n\n var adapter = DS.Adapter.extend({\n createRecord: function(store, type, record) {\n equal(callCount, 0, \"didCreate callback was not called until didSaveRecord is called\");\n\n return Ember.RSVP.resolve();\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n equal(callCount, 0, \"precond - didCreate callback was not called yet\");\n var person;\n\n run(function(){\n person = store.createRecord(Person, { id: 69, name: \"Newt Gingrich\" });\n });\n\n\n run(function(){\n person.save().then(function() {\n equal(callCount, 1, \"didCreate called after commit\");\n });\n });\n});\n\ntest(\"a record receives a didDelete callback when it has finished deleting\", function() {\n var callCount = 0;\n\n var Person = DS.Model.extend({\n bar: DS.attr(\'string\'),\n\n didDelete: function() {\n callCount++;\n\n equal(get(this, \'isSaving\'), false, \"record should not be saving\");\n equal(get(this, \'isDirty\'), false, \"record should not be dirty\");\n }\n });\n\n var adapter = DS.Adapter.extend({\n find: function(store, type, id) {\n return Ember.RSVP.resolve({ id: 1, name: \"Foo\" });\n },\n\n deleteRecord: function(store, type, record) {\n equal(callCount, 0, \"didDelete callback was not called until didSaveRecord is called\");\n\n return Ember.RSVP.resolve();\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n var asyncPerson;\n\n run(function(){\n asyncPerson = store.find(Person, 1);\n });\n\n equal(callCount, 0, \"precond - didDelete callback was not called yet\");\n\n run(function(){\n asyncPerson.then(function(person) {\n return run(function(){\n person.deleteRecord();\n return person.save();\n });\n }).then(function() {\n equal(callCount, 1, \"didDelete called after delete\");\n });\n });\n});\n\ntest(\"a record receives a becameInvalid callback when it became invalid\", function() {\n var callCount = 0;\n\n var Person = DS.Model.extend({\n bar: DS.attr(\'string\'),\n\n becameInvalid: function() {\n callCount++;\n\n equal(get(this, \'isSaving\'), false, \"record should not be saving\");\n equal(get(this, \'isDirty\'), true, \"record should be dirty\");\n }\n });\n\n var adapter = DS.Adapter.extend({\n find: function(store, type, id) {\n return Ember.RSVP.resolve({ id: 1, name: \"Foo\" });\n },\n\n updateRecord: function(store, type, record) {\n equal(callCount, 0, \"becameInvalid callback was not called until recordWasInvalid is called\");\n\n return Ember.RSVP.reject(new DS.InvalidError({ bar: \'error\' }));\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n var asyncPerson;\n\n run(function(){\n asyncPerson = store.find(Person, 1);\n });\n equal(callCount, 0, \"precond - becameInvalid callback was not called yet\");\n\n // Make sure that the error handler has a chance to attach before\n // save fails.\n run(function() {\n asyncPerson.then(function(person) {\n return run(function(){\n person.set(\'bar\', \"Bar\");\n return person.save();\n });\n }).then(null, function() {\n equal(callCount, 1, \"becameInvalid called after invalidating\");\n });\n });\n});\n\ntest(\"an ID of 0 is allowed\", function() {\n var store = createStore();\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function(){\n store.push(Person, { id: 0, name: \"Tom Dale\" });\n });\n\n equal(store.all(Person).objectAt(0).get(\'name\'), \"Tom Dale\", \"found record with id 0\");\n});\n})();//# sourceURL=ember-data/unit/model/lifecycle_callbacks_test.js");
196
+
197
+ eval("(function() {var Person;\nvar run = Ember.run;\n\nmodule(\"unit/model/merge - Merging\", {\n setup: function() {\n Person = DS.Model.extend({\n name: DS.attr(),\n city: DS.attr()\n });\n },\n\n teardown: function() {\n\n }\n});\n\ntest(\"When a record is in flight, changes can be made\", function() {\n var adapter = DS.Adapter.extend({\n createRecord: function(store, type, record) {\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\" });\n }\n });\n var person;\n\n var store = createStore({ adapter: adapter });\n\n run(function(){\n person = store.createRecord(Person, { name: \"Tom Dale\" });\n });\n\n // Make sure saving isn\'t resolved synchronously\n Ember.run(function() {\n var promise = person.save();\n\n equal(person.get(\'name\'), \"Tom Dale\");\n\n person.set(\'name\', \"Thomas Dale\");\n\n promise.then(function(person) {\n equal(person.get(\'isDirty\'), true, \"The person is still dirty\");\n equal(person.get(\'name\'), \"Thomas Dale\", \"The changes made still apply\");\n });\n });\n});\n\ntest(\"When a record is in flight, pushes are applied underneath the in flight changes\", function() {\n var adapter = DS.Adapter.extend({\n updateRecord: function(store, type, record) {\n // Make sure saving isn\'t resolved synchronously\n return new Ember.RSVP.Promise(function(resolve, reject){\n Ember.run.next(null, resolve, { id: 1, name: \"Senor Thomas Dale, Esq.\", city: \"Portland\" });\n });\n }\n });\n\n var store = createStore({ adapter: adapter });\n var person;\n\n run(function(){\n person = store.push(Person, { id: 1, name: \"Tom\" });\n person.set(\'name\', \"Thomas Dale\");\n });\n\n Ember.run(function() {\n var promise = person.save();\n\n equal(person.get(\'name\'), \"Thomas Dale\");\n\n person.set(\'name\', \"Tomasz Dale\");\n\n store.push(Person, { id: 1, name: \"Tommy Dale\", city: \"PDX\" });\n\n equal(person.get(\'name\'), \"Tomasz Dale\", \"the local changes applied on top\");\n equal(person.get(\'city\'), \"PDX\", \"the pushed change is available\");\n\n promise.then(async(function(person) {\n equal(person.get(\'isDirty\'), true, \"The person is still dirty\");\n equal(person.get(\'name\'), \"Tomasz Dale\", \"The local changes apply\");\n equal(person.get(\'city\'), \"Portland\", \"The updates from the server apply on top of the previous pushes\");\n }));\n });\n});\n\ntest(\"When a record is dirty, pushes are overridden by local changes\", function() {\n var store = createStore({ adapter: DS.Adapter });\n var person;\n\n run(function(){\n person = store.push(Person, { id: 1, name: \"Tom Dale\", city: \"San Francisco\" });\n person.set(\'name\', \"Tomasz Dale\");\n });\n\n equal(person.get(\'isDirty\'), true, \"the person is currently dirty\");\n equal(person.get(\'name\'), \"Tomasz Dale\", \"the update was effective\");\n equal(person.get(\'city\'), \"San Francisco\", \"the original data applies\");\n\n run(function(){\n store.push(Person, { id: 1, name: \"Thomas Dale\", city: \"Portland\" });\n });\n\n equal(person.get(\'isDirty\'), true, \"the local changes are reapplied\");\n equal(person.get(\'name\'), \"Tomasz Dale\", \"the local changes are reapplied\");\n equal(person.get(\'city\'), \"Portland\", \"if there are no local changes, the new data applied\");\n});\n\ntest(\"A record with no changes can still be saved\", function() {\n var adapter = DS.Adapter.extend({\n updateRecord: function(store, type, record) {\n return Ember.RSVP.resolve({ id: 1, name: \"Thomas Dale\" });\n }\n });\n\n var store = createStore({ adapter: adapter });\n var person;\n\n run(function(){\n person = store.push(Person, { id: 1, name: \"Tom Dale\" });\n });\n\n run(function(){\n person.save().then(function() {\n equal(person.get(\'name\'), \"Thomas Dale\", \"the updates occurred\");\n });\n });\n});\n\ntest(\"A dirty record can be reloaded\", function() {\n var adapter = DS.Adapter.extend({\n find: function(store, type, id) {\n return Ember.RSVP.resolve({ id: 1, name: \"Thomas Dale\", city: \"Portland\" });\n }\n });\n\n var store = createStore({ adapter: adapter });\n var person;\n\n run(function(){\n person = store.push(Person, { id: 1, name: \"Tom Dale\" });\n person.set(\'name\', \"Tomasz Dale\");\n });\n\n run(function(){\n person.reload().then(function() {\n equal(person.get(\'isDirty\'), true, \"the person is dirty\");\n equal(person.get(\'name\'), \"Tomasz Dale\", \"the local changes remain\");\n equal(person.get(\'city\'), \"Portland\", \"the new changes apply\");\n });\n });\n});\n})();//# sourceURL=ember-data/unit/model/merge_test.js");
198
+
199
+ eval("(function() {var get = Ember.get, set = Ember.set;\nvar run = Ember.run;\n\nmodule(\"unit/model/relationships - DS.Model\");\n\ntest(\"exposes a hash of the relationships on a model\", function() {\n var Occupation = DS.Model.extend();\n\n var Person = DS.Model.extend({\n occupations: DS.hasMany(\'occupation\')\n });\n\n Person.reopen({\n people: DS.hasMany(\'person\', { inverse: \'parent\' }),\n parent: DS.belongsTo(\'person\')\n });\n\n var store = createStore({\n occupation: Occupation,\n person: Person\n });\n var person, occupation;\n\n run(function() {\n person = store.createRecord(\'person\');\n occupation = store.createRecord(\'occupation\');\n });\n\n var relationships = get(Person, \'relationships\');\n deepEqual(relationships.get(Person), [\n { name: \"people\", kind: \"hasMany\" },\n { name: \"parent\", kind: \"belongsTo\" }\n ]);\n deepEqual(relationships.get(Occupation), [\n { name: \"occupations\", kind: \"hasMany\" }\n ]);\n});\n\nvar env;\nmodule(\"unit/model/relationships - DS.hasMany\", {\n setup: function() {\n env = setupStore();\n }\n});\n\ntest(\"hasMany handles pre-loaded relationships\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n var Pet = DS.Model.extend({\n name: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tags: DS.hasMany(\'tag\'),\n pets: DS.hasMany(\'pet\')\n });\n\n env.container.register(\'model:tag\', Tag);\n env.container.register(\'model:pet\', Pet);\n env.container.register(\'model:person\', Person);\n\n env.adapter.find = function(store, type, id) {\n if (type === Tag && id === \'12\') {\n return Ember.RSVP.resolve({ id: 12, name: \"oohlala\" });\n } else {\n ok(false, \"find() should not be called with these values\");\n }\n };\n\n var store = env.store;\n\n run(function(){\n store.pushMany(\'tag\', [{ id: 5, name: \"friendly\" }, { id: 2, name: \"smarmy\" }]);\n store.pushMany(\'pet\', [{ id: 4, name: \"fluffy\" }, { id: 7, name: \"snowy\" }, { id: 12, name: \"cerberus\" }]);\n store.push(\'person\', { id: 1, name: \"Tom Dale\", tags: [5] });\n store.push(\'person\', { id: 2, name: \"Yehuda Katz\", tags: [12] });\n });\n\n run(function(){\n store.find(\'person\', 1).then(function(person) {\n equal(get(person, \'name\'), \"Tom Dale\", \"precond - retrieves person record from store\");\n\n var tags = get(person, \'tags\');\n equal(get(tags, \'length\'), 1, \"the list of tags should have the correct length\");\n equal(get(tags.objectAt(0), \'name\'), \"friendly\", \"the first tag should be a Tag\");\n\n run(function(){\n store.push(\'person\', { id: 1, name: \"Tom Dale\", tags: [5, 2] });\n });\n\n equal(tags, get(person, \'tags\'), \"a relationship returns the same object every time\");\n equal(get(get(person, \'tags\'), \'length\'), 2, \"the length is updated after new data is loaded\");\n\n strictEqual(get(person, \'tags\').objectAt(0), get(person, \'tags\').objectAt(0), \"the returned object is always the same\");\n asyncEqual(get(person, \'tags\').objectAt(0), store.find(Tag, 5), \"relationship objects are the same as objects retrieved directly\");\n\n run(function(){\n store.push(\'person\', { id: 3, name: \"KSelden\" });\n });\n\n return store.find(\'person\', 3);\n }).then(function(kselden) {\n equal(get(get(kselden, \'tags\'), \'length\'), 0, \"a relationship that has not been supplied returns an empty array\");\n\n run(function(){\n store.push(\'person\', { id: 4, name: \"Cyvid Hamluck\", pets: [4] });\n });\n return store.find(\'person\', 4);\n }).then(function(cyvid) {\n equal(get(cyvid, \'name\'), \"Cyvid Hamluck\", \"precond - retrieves person record from store\");\n\n var pets = get(cyvid, \'pets\');\n equal(get(pets, \'length\'), 1, \"the list of pets should have the correct length\");\n equal(get(pets.objectAt(0), \'name\'), \"fluffy\", \"the first pet should be correct\");\n\n Ember.run(function() {\n store.push(Person, { id: 4, name: \"Cyvid Hamluck\", pets: [4, 12] });\n });\n\n equal(pets, get(cyvid, \'pets\'), \"a relationship returns the same object every time\");\n equal(get(get(cyvid, \'pets\'), \'length\'), 2, \"the length is updated after new data is loaded\");\n });\n });\n});\n\ntest(\"hasMany lazily loads async relationships\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n var Pet = DS.Model.extend({\n name: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tags: DS.hasMany(\'tag\', { async: true }),\n pets: DS.hasMany(\'pet\')\n });\n\n env.container.register(\'model:tag\', Tag);\n env.container.register(\'model:pet\', Pet);\n env.container.register(\'model:person\', Person);\n\n env.adapter.find = function(store, type, id) {\n if (type === Tag && id === \'12\') {\n return Ember.RSVP.resolve({ id: 12, name: \"oohlala\" });\n } else {\n ok(false, \"find() should not be called with these values\");\n }\n };\n\n var store = env.store;\n\n run(function(){\n store.pushMany(\'tag\', [{ id: 5, name: \"friendly\" }, { id: 2, name: \"smarmy\" }]);\n store.pushMany(\'pet\', [{ id: 4, name: \"fluffy\" }, { id: 7, name: \"snowy\" }, { id: 12, name: \"cerberus\" }]);\n store.push(\'person\', { id: 1, name: \"Tom Dale\", tags: [5] });\n store.push(\'person\', { id: 2, name: \"Yehuda Katz\", tags: [12] });\n });\n\n var wycats;\n\n run(function(){\n store.find(\'person\', 2).then(function(person) {\n wycats = person;\n\n equal(get(wycats, \'name\'), \"Yehuda Katz\", \"precond - retrieves person record from store\");\n\n return Ember.RSVP.hash({\n wycats: wycats,\n tags: wycats.get(\'tags\')\n });\n }).then(function(records) {\n equal(get(records.tags, \'length\'), 1, \"the list of tags should have the correct length\");\n equal(get(records.tags.objectAt(0), \'name\'), \"oohlala\", \"the first tag should be a Tag\");\n\n strictEqual(records.tags.objectAt(0), records.tags.objectAt(0), \"the returned object is always the same\");\n asyncEqual(records.tags.objectAt(0), store.find(Tag, 12), \"relationship objects are the same as objects retrieved directly\");\n\n return get(wycats, \'tags\');\n }).then(function(tags) {\n var newTag;\n run(function(){\n newTag = store.createRecord(Tag);\n tags.pushObject(newTag);\n });\n });\n });\n});\n\ntest(\"should be able to retrieve the type for a hasMany relationship without specifying a type from its metadata\", function() {\n var Tag = DS.Model.extend({});\n\n var Person = DS.Model.extend({\n tags: DS.hasMany()\n });\n\n var env = setupStore({\n tag: Tag,\n person: Person\n });\n\n equal(env.store.modelFor(\'person\').typeForRelationship(\'tags\'), Tag, \"returns the relationship type\");\n});\n\ntest(\"should be able to retrieve the type for a hasMany relationship specified using a string from its metadata\", function() {\n var Tag = DS.Model.extend({});\n\n var Person = DS.Model.extend({\n tags: DS.hasMany(\'tag\')\n });\n\n var env = setupStore({\n tag: Tag,\n person: Person\n });\n\n equal(env.store.modelFor(\'person\').typeForRelationship(\'tags\'), Tag, \"returns the relationship type\");\n});\n\ntest(\"should be able to retrieve the type for a belongsTo relationship without specifying a type from its metadata\", function() {\n var Tag = DS.Model.extend({});\n\n var Person = DS.Model.extend({\n tag: DS.belongsTo()\n });\n\n var env = setupStore({\n tag: Tag,\n person: Person\n });\n\n equal(env.store.modelFor(\'person\').typeForRelationship(\'tag\'), Tag, \"returns the relationship type\");\n});\n\ntest(\"should be able to retrieve the type for a belongsTo relationship specified using a string from its metadata\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var Person = DS.Model.extend({\n tags: DS.belongsTo(\'tag\')\n });\n\n var env = setupStore({\n tag: Tag,\n person: Person\n });\n\n equal(env.store.modelFor(\'person\').typeForRelationship(\'tags\'), Tag, \"returns the relationship type\");\n});\n\ntest(\"relationships work when declared with a string path\", function() {\n window.App = {};\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tags: DS.hasMany(\'tag\')\n });\n\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var env = setupStore({\n person: Person,\n tag: Tag\n });\n\n run(function(){\n env.store.pushMany(\'tag\', [{ id: 5, name: \"friendly\" }, { id: 2, name: \"smarmy\" }, { id: 12, name: \"oohlala\" }]);\n env.store.push(\'person\', { id: 1, name: \"Tom Dale\", tags: [5, 2] });\n });\n\n run(function(){\n env.store.find(\'person\', 1).then(function(person) {\n equal(get(person, \'name\'), \"Tom Dale\", \"precond - retrieves person record from store\");\n equal(get(person, \'tags.length\'), 2, \"the list of tags should have the correct length\");\n });\n });\n});\n\ntest(\"hasMany relationships work when the data hash has not been loaded\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n Tag.toString = function() { return \"Tag\"; };\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tags: DS.hasMany(\'tag\', { async: true })\n });\n\n Person.toString = function() { return \"Person\"; };\n\n var env = setupStore({ tag: Tag, person: Person }),\n store = env.store;\n\n env.adapter.coalesceFindRequests = true;\n env.adapter.findMany = function(store, type, ids) {\n equal(type, Tag, \"type should be Tag\");\n deepEqual(ids, [\'5\', \'2\'], \"ids should be 5 and 2\");\n\n return Ember.RSVP.resolve([{ id: 5, name: \"friendly\" }, { id: 2, name: \"smarmy\" }]);\n };\n\n env.adapter.find = function(store, type, id) {\n equal(type, Person, \"type should be Person\");\n equal(id, 1, \"id should be 1\");\n\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\", tags: [5, 2] });\n };\n\n run(function(){\n store.find(\'person\', 1).then(function(person) {\n equal(get(person, \'name\'), \"Tom Dale\", \"The person is now populated\");\n\n return run(function(){\n return person.get(\'tags\');\n });\n }).then(function(tags) {\n equal(get(tags, \'length\'), 2, \"the tags object still exists\");\n equal(get(tags.objectAt(0), \'name\'), \"friendly\", \"Tom Dale is now friendly\");\n equal(get(tags.objectAt(0), \'isLoaded\'), true, \"Tom Dale is now loaded\");\n });\n });\n});\n\ntest(\"it is possible to add a new item to a relationship\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\'),\n people: DS.belongsTo(\'person\')\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tags: DS.hasMany(\'tag\')\n });\n\n var env = setupStore({\n tag: Tag,\n person: Person\n });\n\n var store = env.store;\n\n run(function(){\n store.push(\'person\', { id: 1, name: \"Tom Dale\", tags: [ 1 ] });\n store.push(\'tag\', { id: 1, name: \"ember\" });\n });\n\n run(function(){\n store.find(Person, 1).then(function(person) {\n var tag = get(person, \'tags\').objectAt(0);\n\n equal(get(tag, \'name\'), \"ember\", \"precond - relationships work\");\n\n tag = store.createRecord(Tag, { name: \"js\" });\n get(person, \'tags\').pushObject(tag);\n\n equal(get(person, \'tags\').objectAt(1), tag, \"newly added relationship works\");\n });\n });\n});\n\ntest(\"possible to replace items in a relationship using setObjects w/ Ember Enumerable Array/Object as the argument (GH-2533)\", function(){\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tags: DS.hasMany(\'tag\')\n });\n\n var env = setupStore({ tag: Tag, person: Person });\n var store = env.store;\n var run = Ember.run;\n\n Ember.run(function(){\n store.push(\'person\', { id: 1, name: \"Tom Dale\", tags: [ 1 ] });\n store.push(\'person\', { id: 2, name: \"Sylvain Mina\", tags: [ 2 ] });\n store.push(\'tag\', { id: 1, name: \"ember\" });\n store.push(\'tag\', { id: 2, name: \"ember-data\" });\n });\n\n var tom, sylvain;\n\n run(function(){\n tom = store.getById(\'person\', \'1\');\n sylvain = store.getById(\'person\', \'2\');\n // Test that since sylvain.get(\'tags\') instanceof DS.ManyArray,\n // addRecords on Relationship iterates correctly.\n tom.get(\'tags\').setObjects(sylvain.get(\'tags\'));\n });\n\n equal(tom.get(\'tags.length\'), 1);\n equal(tom.get(\'tags.firstObject\'), store.getById(\'tag\', 2));\n});\n\ntest(\"it is possible to remove an item from a relationship\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tags: DS.hasMany(\'tag\')\n });\n\n var env = setupStore({ tag: Tag, person: Person }),\n store = env.store;\n\n run(function(){\n store.push(\'person\', { id: 1, name: \"Tom Dale\", tags: [ 1 ] });\n store.push(\'tag\', { id: 1, name: \"ember\" });\n });\n\n run(function(){\n store.find(\'person\', 1).then(async(function(person) {\n var tag = get(person, \'tags\').objectAt(0);\n\n equal(get(tag, \'name\'), \"ember\", \"precond - relationships work\");\n\n run(function(){\n get(person, \'tags\').removeObject(tag);\n });\n\n equal(get(person, \'tags.length\'), 0, \"object is removed from the relationship\");\n }));\n });\n});\n\ntest(\"it is possible to add an item to a relationship, remove it, then add it again\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tags: DS.hasMany(\'tag\')\n });\n\n Tag.toString = function() { return \"Tag\"; };\n Person.toString = function() { return \"Person\"; };\n\n var env = setupStore({ tag: Tag, person: Person }),\n store = env.store;\n var person, tag1, tag2, tag3;\n\n run(function(){\n person = store.createRecord(\'person\');\n tag1 = store.createRecord(\'tag\');\n tag2 = store.createRecord(\'tag\');\n tag3 = store.createRecord(\'tag\');\n });\n\n var tags = get(person, \'tags\');\n\n run(function(){\n tags.pushObjects([tag1, tag2, tag3]);\n tags.removeObject(tag2);\n });\n\n equal(tags.objectAt(0), tag1);\n equal(tags.objectAt(1), tag3);\n equal(get(person, \'tags.length\'), 2, \"object is removed from the relationship\");\n\n run(function(){\n tags.insertAt(0, tag2);\n });\n\n equal(get(person, \'tags.length\'), 3, \"object is added back to the relationship\");\n equal(tags.objectAt(0), tag2);\n equal(tags.objectAt(1), tag1);\n equal(tags.objectAt(2), tag3);\n});\n\nmodule(\"unit/model/relationships - RecordArray\");\n\ntest(\"updating the content of a RecordArray updates its content\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var env = setupStore({ tag: Tag }),\n store = env.store;\n var records, tags;\n\n run(function(){\n records = store.pushMany(\'tag\', [{ id: 5, name: \"friendly\" }, { id: 2, name: \"smarmy\" }, { id: 12, name: \"oohlala\" }]);\n tags = DS.RecordArray.create({ content: Ember.A(records.slice(0, 2)), store: store, type: Tag });\n });\n\n var tag = tags.objectAt(0);\n equal(get(tag, \'name\'), \"friendly\", \"precond - we\'re working with the right tags\");\n\n run(function(){\n set(tags, \'content\', Ember.A(records.slice(1, 3)));\n });\n\n tag = tags.objectAt(0);\n equal(get(tag, \'name\'), \"smarmy\", \"the lookup was updated\");\n});\n\ntest(\"can create child record from a hasMany relationship\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tags: DS.hasMany(\'tag\')\n });\n\n var env = setupStore({ tag: Tag, person: Person }),\n store = env.store;\n\n run(function(){\n store.push(\'person\', { id: 1, name: \"Tom Dale\"});\n });\n\n run(function(){\n store.find(\'person\', 1).then(async(function(person) {\n person.get(\"tags\").createRecord({ name: \"cool\" });\n\n equal(get(person, \'name\'), \"Tom Dale\", \"precond - retrieves person record from store\");\n equal(get(person, \'tags.length\'), 1, \"tag is added to the parent record\");\n equal(get(person, \'tags\').objectAt(0).get(\"name\"), \"cool\", \"tag values are passed along\");\n }));\n });\n});\n\nmodule(\"unit/model/relationships - DS.belongsTo\");\n\ntest(\"belongsTo lazily loads relationships as needed\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\'),\n people: DS.hasMany(\'person\')\n });\n Tag.toString = function() { return \"Tag\"; };\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tag: DS.belongsTo(\'tag\')\n });\n Person.toString = function() { return \"Person\"; };\n\n var env = setupStore({ tag: Tag, person: Person }),\n store = env.store;\n\n run(function(){\n store.pushMany(\'tag\', [{ id: 5, name: \"friendly\" }, { id: 2, name: \"smarmy\" }, { id: 12, name: \"oohlala\" }]);\n store.push(\'person\', { id: 1, name: \"Tom Dale\", tag: 5 });\n });\n\n run(function(){\n store.find(\'person\', 1).then(async(function(person) {\n equal(get(person, \'name\'), \"Tom Dale\", \"precond - retrieves person record from store\");\n\n equal(get(person, \'tag\') instanceof Tag, true, \"the tag property should return a tag\");\n equal(get(person, \'tag.name\'), \"friendly\", \"the tag shuld have name\");\n\n strictEqual(get(person, \'tag\'), get(person, \'tag\'), \"the returned object is always the same\");\n asyncEqual(get(person, \'tag\'), store.find(\'tag\', 5), \"relationship object is the same as object retrieved directly\");\n }));\n });\n});\n\ntest(\"async belongsTo relationships work when the data hash has not been loaded\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tag: DS.belongsTo(\'tag\', { async: true })\n });\n\n var env = setupStore({ tag: Tag, person: Person }),\n store = env.store;\n\n env.adapter.find = function(store, type, id) {\n if (type === Person) {\n equal(id, 1, \"id should be 1\");\n\n return Ember.RSVP.resolve({ id: 1, name: \"Tom Dale\", tag: 2 });\n } else if (type === Tag) {\n equal(id, 2, \"id should be 2\");\n\n return Ember.RSVP.resolve({ id: 2, name: \"friendly\" });\n }\n };\n\n run(function(){\n store.find(\'person\', 1).then(async(function(person) {\n equal(get(person, \'name\'), \"Tom Dale\", \"The person is now populated\");\n\n return run(function(){\n return get(person, \'tag\');\n });\n })).then(async(function(tag) {\n equal(get(tag, \'name\'), \"friendly\", \"Tom Dale is now friendly\");\n equal(get(tag, \'isLoaded\'), true, \"Tom Dale is now loaded\");\n }));\n });\n});\n\ntest(\"async belongsTo relationships work when the data hash has already been loaded\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tag: DS.belongsTo(\'tag\', { async: true })\n });\n\n var env = setupStore({ tag: Tag, person: Person }),\n store = env.store;\n\n run(function(){\n store.push(\'tag\', { id: 2, name: \"friendly\"});\n store.push(\'person\', { id: 1, name: \"Tom Dale\", tag: 2});\n });\n\n run(function(){\n store.find(\'person\', 1).then(async(function(person) {\n equal(get(person, \'name\'), \"Tom Dale\", \"The person is now populated\");\n return run(function(){\n return get(person, \'tag\');\n });\n })).then(async(function(tag) {\n equal(get(tag, \'name\'), \"friendly\", \"Tom Dale is now friendly\");\n equal(get(tag, \'isLoaded\'), true, \"Tom Dale is now loaded\");\n }));\n });\n});\n\ntest(\"calling createRecord and passing in an undefined value for a relationship should be treated as if null\", function () {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tag: DS.belongsTo(\'tag\')\n });\n\n var env = setupStore({ tag: Tag, person: Person }),\n store = env.store;\n\n run(function(){\n store.createRecord(\'person\', {id: 1, tag: undefined});\n });\n\n run(function(){\n store.find(Person, 1).then(async(function(person) {\n strictEqual(person.get(\'tag\'), null, \"undefined values should return null relationships\");\n }));\n });\n});\n\ntest(\"When finding a hasMany relationship the inverse belongsTo relationship is available immediately\", function() {\n var Occupation = DS.Model.extend({\n description: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n Occupation.toString = function() { return \"Occupation\"; };\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n occupations: DS.hasMany(\'occupation\', { async: true })\n });\n\n Person.toString = function() { return \"Person\"; };\n\n var env = setupStore({ occupation: Occupation, person: Person }),\n store = env.store;\n\n env.adapter.findMany = function(store, type, ids, records) {\n equal(records[0].get(\'person.id\'), \'1\');\n return Ember.RSVP.resolve([{ id: 5, description: \"fifth\" }, { id: 2, description: \"second\" }]);\n };\n\n env.adapter.coalesceFindRequests = true;\n\n run(function(){\n store.push(\'person\', { id: 1, name: \"Tom Dale\", occupations: [5, 2] });\n });\n\n run(function(){\n store.find(\'person\', 1).then(async(function(person) {\n equal(get(person, \'isLoaded\'), true, \"isLoaded should be true\");\n equal(get(person, \'name\'), \"Tom Dale\", \"the person is still Tom Dale\");\n\n return get(person, \'occupations\');\n })).then(async(function(occupations) {\n equal(get(occupations, \'length\'), 2, \"the list of occupations should have the correct length\");\n\n equal(get(occupations.objectAt(0), \'description\'), \"fifth\", \"the occupation is the fifth\");\n equal(get(occupations.objectAt(0), \'isLoaded\'), true, \"the occupation is now loaded\");\n }));\n });\n});\n\ntest(\"When finding a belongsTo relationship the inverse belongsTo relationship is available immediately\", function() {\n expect(1);\n var Occupation = DS.Model.extend({\n description: DS.attr(\'string\'),\n person: DS.belongsTo(\'person\')\n });\n\n Occupation.toString = function() { return \"Occupation\"; };\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n occupation: DS.belongsTo(\'occupation\', { async: true })\n });\n\n Person.toString = function() { return \"Person\"; };\n\n var env = setupStore({ occupation: Occupation, person: Person }),\n store = env.store;\n\n env.adapter.find = function(store, type, id, record) {\n equal(record.get(\'person.id\'), \'1\');\n return Ember.RSVP.resolve({ id: 5, description: \"fifth\" });\n };\n\n run(function(){\n store.push(\'person\', { id: 1, name: \"Tom Dale\", occupation: 5 });\n });\n\n run(function(){\n store.getById(\'person\', 1).get(\'occupation\');\n });\n});\n\ntest(\"belongsTo supports relationships to models with id 0\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\'),\n people: DS.hasMany(\'person\')\n });\n Tag.toString = function() { return \"Tag\"; };\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n tag: DS.belongsTo(\'tag\')\n });\n Person.toString = function() { return \"Person\"; };\n\n var env = setupStore({ tag: Tag, person: Person }),\n store = env.store;\n\n run(function(){\n store.pushMany(\'tag\', [{ id: 0, name: \"friendly\" }, { id: 2, name: \"smarmy\" }, { id: 12, name: \"oohlala\" }]);\n store.push(\'person\', { id: 1, name: \"Tom Dale\", tag: 0 });\n });\n\n run(function(){\n store.find(\'person\', 1).then(async(function(person) {\n equal(get(person, \'name\'), \"Tom Dale\", \"precond - retrieves person record from store\");\n\n equal(get(person, \'tag\') instanceof Tag, true, \"the tag property should return a tag\");\n equal(get(person, \'tag.name\'), \"friendly\", \"the tag should have name\");\n\n strictEqual(get(person, \'tag\'), get(person, \'tag\'), \"the returned object is always the same\");\n asyncEqual(get(person, \'tag\'), store.find(Tag, 0), \"relationship object is the same as object retrieved directly\");\n }));\n });\n});\n})();//# sourceURL=ember-data/unit/model/relationships_test.js");
200
+
201
+ eval("(function() {var env, store, Person, Dog;\nvar run = Ember.run;\n\nmodule(\"unit/model/rollback - model.rollback()\", {\n setup: function() {\n Person = DS.Model.extend({\n firstName: DS.attr(),\n lastName: DS.attr()\n });\n\n env = setupStore({ person: Person });\n store = env.store;\n }\n});\n\ntest(\"changes to attributes can be rolled back\", function() {\n var person;\n run(function(){\n person = store.push(\'person\', { id: 1, firstName: \"Tom\", lastName: \"Dale\" });\n person.set(\'firstName\', \"Thomas\");\n });\n\n equal(person.get(\'firstName\'), \"Thomas\");\n\n run(function(){\n person.rollback();\n });\n\n equal(person.get(\'firstName\'), \"Tom\");\n equal(person.get(\'isDirty\'), false);\n});\n\ntest(\"changes to unassigned attributes can be rolled back\", function() {\n var person;\n run(function(){\n person = store.push(\'person\', { id: 1, lastName: \"Dale\" });\n person.set(\'firstName\', \"Thomas\");\n });\n\n equal(person.get(\'firstName\'), \"Thomas\");\n\n run(function(){\n person.rollback();\n });\n\n equal(person.get(\'firstName\'), undefined);\n equal(person.get(\'isDirty\'), false);\n});\n\ntest(\"changes to attributes made after a record is in-flight only rolls back the local changes\", function() {\n env.adapter.updateRecord = function(store, type, record) {\n // Make sure the save is async\n return new Ember.RSVP.Promise(function(resolve, reject){\n Ember.run.later(null, resolve, 15);\n });\n };\n var person;\n\n run(function(){\n person = store.push(\'person\', { id: 1, firstName: \"Tom\", lastName: \"Dale\" });\n person.set(\'firstName\', \"Thomas\");\n });\n\n Ember.run(function() {\n var saving = person.save();\n\n equal(person.get(\'firstName\'), \"Thomas\");\n\n person.set(\'lastName\', \"Dolly\");\n\n equal(person.get(\'lastName\'), \"Dolly\");\n\n person.rollback();\n\n equal(person.get(\'firstName\'), \"Thomas\");\n equal(person.get(\'lastName\'), \"Dale\");\n equal(person.get(\'isSaving\'), true);\n\n saving.then(async(function() {\n equal(person.get(\'isDirty\'), false, \"The person is now clean\");\n }));\n });\n});\n\ntest(\"a record\'s changes can be made if it fails to save\", function() {\n env.adapter.updateRecord = function(store, type, record) {\n return Ember.RSVP.reject();\n };\n var person;\n\n run(function(){\n person = store.push(\'person\', { id: 1, firstName: \"Tom\", lastName: \"Dale\" });\n person.set(\'firstName\', \"Thomas\");\n });\n\n deepEqual(person.changedAttributes(), {firstName: [\"Tom\", \"Thomas\"]});\n\n run(function(){\n person.save().then(null, function() {\n equal(person.get(\'isError\'), true);\n deepEqual(person.changedAttributes(), {firstName: [\"Tom\", \"Thomas\"]});\n\n person.rollback();\n\n equal(person.get(\'firstName\'), \"Tom\");\n equal(person.get(\'isError\'), false);\n deepEqual(person.changedAttributes(), {});\n });\n });\n});\n\ntest(\"a deleted record can be rollbacked if it fails to save, record arrays are updated accordingly\", function() {\n expect(6);\n env.adapter.deleteRecord = function(store, type, record) {\n return Ember.RSVP.reject();\n };\n var person, people;\n\n run(function(){\n person = store.push(\'person\', { id: 1, firstName: \"Tom\", lastName: \"Dale\" });\n people = store.all(\'person\');\n });\n\n run(function(){\n person.deleteRecord();\n });\n equal(people.get(\'length\'), 0, \"a deleted record does not appear in record array anymore\");\n\n run(function(){\n person.save().then(null, function() {\n equal(person.get(\'isError\'), true);\n equal(person.get(\'isDeleted\'), true);\n run(function(){\n person.rollback();\n });\n equal(person.get(\'isDeleted\'), false);\n equal(person.get(\'isError\'), false);\n }).then(function() {\n equal(people.get(\'length\'), 1, \"the underlying record array is updated accordingly in an asynchronous way\");\n });\n });\n});\n\ntest(\"new record can be rollbacked\", function() {\n var person;\n\n run(function(){\n person = store.createRecord(\'person\', { id: 1 });\n });\n\n equal(person.get(\'isNew\'), true, \"must be new\");\n equal(person.get(\'isDirty\'), true, \"must be dirty\");\n\n Ember.run(person, \'rollback\');\n\n equal(person.get(\'isNew\'), false, \"must not be new\");\n equal(person.get(\'isDirty\'), false, \"must not be dirty\");\n equal(person.get(\'isDeleted\'), true, \"must be deleted\");\n});\n\ntest(\"deleted record can be rollbacked\", function() {\n var person, people;\n\n run(function(){\n person = store.push(\'person\', { id: 1 });\n people = store.all(\'person\');\n person.deleteRecord();\n });\n\n equal(people.get(\'length\'), 0, \"a deleted record does not appear in record array anymore\");\n\n equal(person.get(\'isDeleted\'), true, \"must be deleted\");\n\n run(function(){\n person.rollback();\n });\n equal(people.get(\'length\'), 1, \"the rollbacked record should appear again in the record array\");\n equal(person.get(\'isDeleted\'), false, \"must not be deleted\");\n equal(person.get(\'isDirty\'), false, \"must not be dirty\");\n});\n\ntest(\"invalid record can be rollbacked\", function() {\n Dog = DS.Model.extend({\n name: DS.attr()\n });\n\n var adapter = DS.RESTAdapter.extend({\n ajax: function(url, type, hash) {\n var adapter = this;\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n /* If InvalidError is passed back in the reject it will throw the\n exception which will bubble up the call stack (crashing the test)\n instead of hitting the failure route of the promise.\n So wrapping the reject in an Ember.run.next makes it so save\n completes without failure and the failure hits the failure route\n of the promise instead of crashing the save. */\n Ember.run.next(function(){\n reject(adapter.ajaxError({name: \'is invalid\'}));\n });\n });\n },\n\n ajaxError: function(jqXHR) {\n return new DS.InvalidError(jqXHR);\n }\n });\n\n env = setupStore({ dog: Dog, adapter: adapter});\n var dog;\n run(function(){\n dog = env.store.push(\'dog\', { id: 1, name: \"Pluto\" });\n dog.set(\'name\', \"is a dwarf planet\");\n });\n\n run(function(){\n dog.save().then(null, async(function() {\n dog.rollback();\n\n equal(dog.get(\'name\'), \"Pluto\");\n ok(dog.get(\'isValid\'));\n }));\n });\n});\n\ntest(\"invalid record is rolled back to correct state after set\", function() {\n Dog = DS.Model.extend({\n name: DS.attr(),\n breed: DS.attr()\n });\n\n var adapter = DS.RESTAdapter.extend({\n ajax: function(url, type, hash) {\n var adapter = this;\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n /* If InvalidError is passed back in the reject it will throw the\n exception which will bubble up the call stack (crashing the test)\n instead of hitting the failure route of the promise.\n So wrapping the reject in an Ember.run.next makes it so save\n completes without failure and the failure hits the failure route\n of the promise instead of crashing the save. */\n Ember.run.next(function(){\n reject(adapter.ajaxError({name: \'is invalid\'}));\n });\n });\n },\n\n ajaxError: function(jqXHR) {\n return new DS.InvalidError(jqXHR);\n }\n });\n\n env = setupStore({ dog: Dog, adapter: adapter});\n var dog;\n run(function(){\n dog = env.store.push(\'dog\', { id: 1, name: \"Pluto\", breed: \"Disney\" });\n dog.set(\'name\', \"is a dwarf planet\");\n dog.set(\'breed\', \'planet\');\n });\n\n run(function(){\n dog.save().then(null, async(function() {\n equal(dog.get(\'name\'), \"is a dwarf planet\");\n equal(dog.get(\'breed\'), \"planet\");\n\n run(function(){\n dog.set(\'name\', \'Seymour Asses\');\n });\n\n equal(dog.get(\'name\'), \"Seymour Asses\");\n equal(dog.get(\'breed\'), \"planet\");\n\n run(function(){\n dog.rollback();\n });\n\n equal(dog.get(\'name\'), \"Pluto\");\n equal(dog.get(\'breed\'), \"Disney\");\n ok(dog.get(\'isValid\'));\n }));\n });\n});\n})();//# sourceURL=ember-data/unit/model/rollback_test.js");
202
+
203
+ eval("(function() {var get = Ember.get, set = Ember.set;\n\nvar Person, store, array;\nvar run = Ember.run;\n\nmodule(\"unit/model - DS.Model\", {\n setup: function() {\n store = createStore();\n\n Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n isDrugAddict: DS.attr(\'boolean\')\n });\n },\n\n teardown: function() {\n run(function(){\n store.destroy();\n });\n Person = null;\n store = null;\n }\n});\n\ntest(\"can have a property set on it\", function() {\n var record;\n run(function(){\n record = store.createRecord(Person);\n set(record, \'name\', \'bar\');\n });\n\n equal(get(record, \'name\'), \'bar\', \"property was set on the record\");\n});\n\ntest(\"setting a property on a record that has not changed does not cause it to become dirty\", function() {\n run(function(){\n store.push(Person, { id: 1, name: \"Peter\", isDrugAddict: true });\n store.find(Person, 1).then(function(person) {\n equal(person.get(\'isDirty\'), false, \"precond - person record should not be dirty\");\n\n person.set(\'name\', \"Peter\");\n person.set(\'isDrugAddict\', true);\n\n equal(person.get(\'isDirty\'), false, \"record does not become dirty after setting property to old value\");\n });\n });\n});\n\ntest(\"resetting a property on a record cause it to become clean again\", function() {\n run(function(){\n store.push(Person, { id: 1, name: \"Peter\", isDrugAddict: true });\n store.find(Person, 1).then(function(person) {\n equal(person.get(\'isDirty\'), false, \"precond - person record should not be dirty\");\n person.set(\'isDrugAddict\', false);\n equal(person.get(\'isDirty\'), true, \"record becomes dirty after setting property to a new value\");\n person.set(\'isDrugAddict\', true);\n equal(person.get(\'isDirty\'), false, \"record becomes clean after resetting property to the old value\");\n });\n });\n});\n\ntest(\"a record becomes clean again only if all changed properties are reset\", function() {\n run(function(){\n store.push(Person, { id: 1, name: \"Peter\", isDrugAddict: true });\n store.find(Person, 1).then(function(person) {\n equal(person.get(\'isDirty\'), false, \"precond - person record should not be dirty\");\n person.set(\'isDrugAddict\', false);\n equal(person.get(\'isDirty\'), true, \"record becomes dirty after setting one property to a new value\");\n person.set(\'name\', \'Mark\');\n equal(person.get(\'isDirty\'), true, \"record stays dirty after setting another property to a new value\");\n person.set(\'isDrugAddict\', true);\n equal(person.get(\'isDirty\'), true, \"record stays dirty after resetting only one property to the old value\");\n person.set(\'name\', \'Peter\');\n equal(person.get(\'isDirty\'), false, \"record becomes clean after resetting both properties to the old value\");\n });\n });\n});\n\ntest(\"a record reports its unique id via the `id` property\", function() {\n run(function(){\n store.push(Person, { id: 1 });\n store.find(Person, 1).then(function(record) {\n equal(get(record, \'id\'), 1, \"reports id as id by default\");\n });\n });\n});\n\ntest(\"a record\'s id is included in its toString representation\", function() {\n run(function(){\n store.push(Person, { id: 1 });\n\n run(function(){\n store.find(Person, 1).then(function(record) {\n equal(record.toString(), \'<(subclass of DS.Model):\'+Ember.guidFor(record)+\':1>\', \"reports id in toString\");\n });\n });\n });\n});\n\ntest(\"trying to set an `id` attribute should raise\", function() {\n Person = DS.Model.extend({\n id: DS.attr(\'number\'),\n name: \"Scumdale\"\n });\n\n expectAssertion(function() {\n run(function(){\n store.push(Person, { id: 1, name: \"Scumdale\" });\n store.find(Person, 1);\n });\n }, /You may not set `id`/);\n});\n\ntest(\"a collision of a record\'s id with object function\'s name\", function() {\n var hasWatchMethod = Object.prototype.watch;\n try {\n if (!hasWatchMethod) {\n Object.prototype.watch = function(){};\n }\n run(function(){\n store.push(Person, { id: \'watch\' });\n store.find(Person, \'watch\').then(function(record) {\n equal(get(record, \'id\'), \'watch\', \"record is successfully created and could be found by its id\");\n });\n });\n } finally {\n if (!hasWatchMethod) {\n delete Object.prototype.watch;\n }\n }\n});\n\ntest(\"it should use `_reference` and not `reference` to store its reference\", function() {\n run(function(){\n store.push(Person, { id: 1 });\n\n store.find(Person, 1).then(function(record) {\n equal(record.get(\'reference\'), undefined, \"doesn\'t shadow reference key\");\n });\n });\n});\n\ntest(\"it should cache attributes\", function() {\n var store = createStore();\n\n var Post = DS.Model.extend({\n updatedAt: DS.attr(\'string\')\n });\n\n var dateString = \"Sat, 31 Dec 2011 00:08:16 GMT\";\n var date = new Date(dateString);\n\n run(function(){\n store.push(Post, { id: 1 });\n store.find(Post, 1).then(function(record) {\n run(function(){\n record.set(\'updatedAt\', date);\n });\n deepEqual(date, get(record, \'updatedAt\'), \"setting a date returns the same date\");\n strictEqual(get(record, \'updatedAt\'), get(record, \'updatedAt\'), \"second get still returns the same object\");\n })[\"finally\"](function(){\n run(store, \'destroy\');\n });\n });\n\n});\n\ntest(\"changedAttributes() return correct values\", function() {\n expect(3);\n\n var Mascot = DS.Model.extend({\n name: DS.attr(\'string\'),\n likes: DS.attr(\'string\'),\n isMascot: DS.attr(\'boolean\')\n });\n var mascot;\n\n\n run(function(){\n mascot = store.push(Mascot, { id: 1, likes: \'JavaScript\', isMascot: true });\n });\n\n deepEqual({}, mascot.changedAttributes(), \'there are no initial changes\');\n run(function(){\n mascot.set(\'name\', \'Tomster\'); // new value\n mascot.set(\'likes\', \'Ember.js\'); // changed value\n mascot.set(\'isMascot\', true); // same value\n });\n deepEqual({ name: [undefined, \'Tomster\'], likes: [\'JavaScript\', \'Ember.js\'] }, mascot.changedAttributes(), \'attributes has changed\');\n\n run(function(){\n mascot.rollback();\n });\n deepEqual({}, mascot.changedAttributes(), \'after rollback there are no changes\');\n});\n\ntest(\"a DS.Model does not require an attribute type\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr()\n });\n var tag;\n\n run(function(){\n tag = store.createRecord(Tag, { name: \"test\" });\n });\n\n equal(get(tag, \'name\'), \"test\", \"the value is persisted\");\n});\n\ntest(\"a DS.Model can have a defaultValue without an attribute type\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr({ defaultValue: \"unknown\" })\n });\n var tag;\n\n run(function(){\n tag = store.createRecord(Tag);\n });\n\n equal(get(tag, \'name\'), \"unknown\", \"the default value is found\");\n});\n\nmodule(\"unit/model - DS.Model updating\", {\n setup: function() {\n array = [{ id: 1, name: \"Scumbag Dale\" }, { id: 2, name: \"Scumbag Katz\" }, { id: 3, name: \"Scumbag Bryn\" }];\n Person = DS.Model.extend({ name: DS.attr(\'string\') });\n store = createStore();\n run(function(){\n store.pushMany(Person, array);\n });\n },\n teardown: function() {\n run(function(){\n store.destroy();\n Person = null;\n store = null;\n array = null;\n });\n }\n});\n\ntest(\"a DS.Model can update its attributes\", function() {\n run(function(){\n store.find(Person, 2).then(function(person) {\n set(person, \'name\', \"Brohuda Katz\");\n equal(get(person, \'name\'), \"Brohuda Katz\", \"setting took hold\");\n });\n });\n});\n\ntest(\"a DS.Model can have a defaultValue\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\', { defaultValue: \"unknown\" })\n });\n var tag;\n\n run(function(){\n tag = store.createRecord(Tag);\n });\n\n equal(get(tag, \'name\'), \"unknown\", \"the default value is found\");\n\n run(function(){\n set(tag, \'name\', null);\n });\n\n equal(get(tag, \'name\'), null, \"null doesn\'t shadow defaultValue\");\n});\n\ntest(\"a defaultValue for an attribute can be a function\", function() {\n var Tag = DS.Model.extend({\n createdAt: DS.attr(\'string\', {\n defaultValue: function() {\n return \"le default value\";\n }\n })\n });\n var tag;\n\n run(function(){\n tag = store.createRecord(Tag);\n });\n equal(get(tag, \'createdAt\'), \"le default value\", \"the defaultValue function is evaluated\");\n});\n\ntest(\"a defaultValue function gets the record, options, and key\", function() {\n expect(2);\n\n var Tag = DS.Model.extend({\n createdAt: DS.attr(\'string\', {\n defaultValue: function(record, options, key) {\n deepEqual(record, tag, \"the record is passed in properly\");\n equal(key, \'createdAt\', \"the attribute being defaulted is passed in properly\");\n return \"le default value\";\n }\n })\n });\n var tag;\n\n run(function(){\n tag = store.createRecord(Tag);\n });\n\n get(tag, \'createdAt\');\n});\n\ntest(\"setting a property to undefined on a newly created record should not impact the current state\", function() {\n var Tag = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var tag;\n\n run(function(){\n tag = store.createRecord(Tag);\n });\n run(function(){\n set(tag, \'name\', \'testing\');\n });\n run(function(){\n set(tag, \'name\', undefined);\n });\n\n equal(get(tag, \'currentState.stateName\'), \"root.loaded.created.uncommitted\");\n\n run(function(){\n tag = store.createRecord(Tag, {name: undefined});\n });\n\n equal(get(tag, \'currentState.stateName\'), \"root.loaded.created.uncommitted\");\n});\n\n// NOTE: this is a \'backdoor\' test that ensures internal consistency, and should be\n// thrown out if/when the current `_attributes` hash logic is removed.\ntest(\"setting a property back to its original value removes the property from the `_attributes` hash\", function() {\n run(function(){\n store.find(Person, 1).then(function(person) {\n equal(person._attributes.name, undefined, \"the `_attributes` hash is clean\");\n\n set(person, \'name\', \"Niceguy Dale\");\n\n equal(person._attributes.name, \"Niceguy Dale\", \"the `_attributes` hash contains the changed value\");\n\n set(person, \'name\', \"Scumbag Dale\");\n\n equal(person._attributes.name, undefined, \"the `_attributes` hash is reset\");\n });\n });\n});\n\nmodule(\"unit/model - with a simple Person model\", {\n setup: function() {\n array = [{ id: 1, name: \"Scumbag Dale\" }, { id: 2, name: \"Scumbag Katz\" }, { id: 3, name: \"Scumbag Bryn\" }];\n Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n store = createStore({\n person: Person\n });\n run(function(){\n store.pushMany(Person, array);\n });\n },\n teardown: function() {\n run(function(){\n store.destroy();\n Person = null;\n store = null;\n array = null;\n });\n }\n});\n\ntest(\"can ask if record with a given id is loaded\", function() {\n equal(store.recordIsLoaded(Person, 1), true, \'should have person with id 1\');\n equal(store.recordIsLoaded(\'person\', 1), true, \'should have person with id 1\');\n equal(store.recordIsLoaded(Person, 4), false, \'should not have person with id 4\');\n equal(store.recordIsLoaded(\'person\', 4), false, \'should not have person with id 4\');\n});\n\ntest(\"a listener can be added to a record\", function() {\n var count = 0;\n var F = function() { count++; };\n var record;\n\n run(function(){\n record = store.createRecord(Person);\n });\n\n record.on(\'event!\', F);\n run(function(){\n record.trigger(\'event!\');\n });\n\n equal(count, 1, \"the event was triggered\");\n\n run(function(){\n record.trigger(\'event!\');\n });\n\n equal(count, 2, \"the event was triggered\");\n});\n\ntest(\"when an event is triggered on a record the method with the same name is invoked with arguments\", function(){\n var count = 0;\n var F = function() { count++; };\n var record;\n\n run(function(){\n record = store.createRecord(Person);\n });\n\n record.eventNamedMethod = F;\n\n run(function(){\n record.trigger(\'eventNamedMethod\');\n });\n\n equal(count, 1, \"the corresponding method was called\");\n});\n\ntest(\"when a method is invoked from an event with the same name the arguments are passed through\", function(){\n var eventMethodArgs = null;\n var F = function() {\n eventMethodArgs = arguments;\n };\n var record;\n\n run(function(){\n record = store.createRecord(Person);\n });\n\n record.eventThatTriggersMethod = F;\n\n run(function(){\n record.trigger(\'eventThatTriggersMethod\', 1, 2);\n });\n\n equal( eventMethodArgs[0], 1);\n equal( eventMethodArgs[1], 2);\n});\n\nvar converts = function(type, provided, expected) {\n var Model = DS.Model.extend({\n name: DS.attr(type)\n });\n\n var container = new Ember.Container();\n\n var testStore = createStore({model: Model}),\n serializer = DS.JSONSerializer.create({ store: testStore, container: container });\n\n run(function(){\n testStore.push(Model, serializer.normalize(Model, { id: 1, name: provided }));\n testStore.push(Model, serializer.normalize(Model, { id: 2 }));\n testStore.find(\'model\', 1).then(function(record) {\n deepEqual(get(record, \'name\'), expected, type + \" coerces \" + provided + \" to \" + expected);\n });\n });\n\n // See: Github issue #421\n // record = testStore.find(Model, 2);\n // set(record, \'name\', provided);\n // deepEqual(get(record, \'name\'), expected, type + \" coerces \" + provided + \" to \" + expected);\n};\n\nvar convertsFromServer = function(type, provided, expected) {\n var Model = DS.Model.extend({\n name: DS.attr(type)\n });\n\n var container = new Ember.Container();\n\n var testStore = createStore({model: Model}),\n serializer = DS.JSONSerializer.create({ store: testStore, container: container });\n\n run(function(){\n testStore.push(Model, serializer.normalize(Model, { id: \"1\", name: provided }));\n testStore.find(\'model\', 1).then(function(record) {\n deepEqual(get(record, \'name\'), expected, type + \" coerces \" + provided + \" to \" + expected);\n });\n });\n};\n\nvar convertsWhenSet = function(type, provided, expected) {\n var Model = DS.Model.extend({\n name: DS.attr(type)\n });\n\n var testStore = createStore({model: Model});\n\n run(function(){\n testStore.push(Model, { id: 2 });\n testStore.find(\'model\', 2).then(function(record) {\n set(record, \'name\', provided);\n deepEqual(record.serialize().name, expected, type + \" saves \" + provided + \" as \" + expected);\n });\n });\n};\n\ntest(\"a DS.Model can describe String attributes\", function() {\n converts(\'string\', \"Scumbag Tom\", \"Scumbag Tom\");\n converts(\'string\', 1, \"1\");\n converts(\'string\', \"\", \"\");\n converts(\'string\', null, null);\n converts(\'string\', undefined, null);\n convertsFromServer(\'string\', undefined, null);\n});\n\ntest(\"a DS.Model can describe Number attributes\", function() {\n converts(\'number\', \"1\", 1);\n converts(\'number\', \"0\", 0);\n converts(\'number\', 1, 1);\n converts(\'number\', 0, 0);\n converts(\'number\', \"\", null);\n converts(\'number\', null, null);\n converts(\'number\', undefined, null);\n converts(\'number\', true, 1);\n converts(\'number\', false, 0);\n});\n\ntest(\"a DS.Model can describe Boolean attributes\", function() {\n converts(\'boolean\', \"1\", true);\n converts(\'boolean\', \"\", false);\n converts(\'boolean\', 1, true);\n converts(\'boolean\', 0, false);\n converts(\'boolean\', null, false);\n converts(\'boolean\', true, true);\n converts(\'boolean\', false, false);\n});\n\ntest(\"a DS.Model can describe Date attributes\", function() {\n converts(\'date\', null, null);\n converts(\'date\', undefined, undefined);\n\n var dateString = \"2011-12-31T00:08:16.000Z\";\n var date = new Date(Ember.Date.parse(dateString));\n\n var store = createStore();\n\n var Person = DS.Model.extend({\n updatedAt: DS.attr(\'date\')\n });\n\n run(function(){\n store.push(Person, { id: 1 });\n store.find(Person, 1).then(function(record) {\n run(function(){\n record.set(\'updatedAt\', date);\n });\n deepEqual(date, get(record, \'updatedAt\'), \"setting a date returns the same date\");\n });\n });\n convertsFromServer(\'date\', dateString, date);\n convertsWhenSet(\'date\', date, dateString);\n});\n\ntest(\"don\'t allow setting\", function(){\n var store = createStore();\n\n var Person = DS.Model.extend();\n var record;\n\n run(function(){\n record = store.createRecord(Person);\n });\n\n raises(function(){\n run(function(){\n record.set(\'isLoaded\', true);\n });\n }, \"raised error when trying to set an unsettable record\");\n});\n\ntest(\"ensure model exits loading state, materializes data and fulfills promise only after data is available\", function () {\n var store = createStore({\n adapter: DS.Adapter.extend({\n find: function(store, type, id) {\n return Ember.RSVP.resolve({ id: 1, name: \"John\", isDrugAddict: false });\n }\n })\n });\n\n run(function(){\n store.find(Person, 1).then(function(person) {\n equal(get(person, \'currentState.stateName\'), \'root.loaded.saved\', \'model is in loaded state\');\n equal(get(person, \'isLoaded\'), true, \'model is loaded\');\n });\n });\n});\n\ntest(\"A DS.Model can be JSONified\", function() {\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var store = createStore({ person: Person });\n var record;\n\n run(function(){\n record = store.createRecord(\'person\', { name: \"TomHuda\" });\n });\n deepEqual(record.toJSON(), { name: \"TomHuda\" });\n});\n\ntest(\"A subclass of DS.Model can not use the `data` property\", function() {\n var Person = DS.Model.extend({\n data: DS.attr(\'string\')\n });\n\n var store = createStore({ person: Person });\n\n expectAssertion(function() {\n run(function(){\n store.createRecord(\'person\', { name: \"TomHuda\" });\n });\n }, /`data` is a reserved property name on DS.Model objects/);\n});\n})();//# sourceURL=ember-data/unit/model_test.js");
204
+
205
+ eval("(function() {module(\'PromiseManyArray\');\n\ntest(\'.reload should NOT leak the internal promise, rather return another promiseArray\', function() {\n expect(2);\n\n var content = Ember.A();\n\n content.reload = function() {\n return Ember.RSVP.Promise.resolve(content);\n };\n\n var array = DS.PromiseManyArray.create({\n content: content\n });\n\n Ember.run(function() {\n var reloaded = array.reload();\n\n ok(reloaded instanceof DS.PromiseManyArray);\n\n reloaded.then(function(value) {\n equal(content, value);\n });\n });\n});\n})();//# sourceURL=ember-data/unit/promise_proxies_test.js");
206
+
207
+ eval("(function() {var get = Ember.get;\n\nvar Person, array;\nvar run = Ember.run;\n\nmodule(\"unit/record_array - DS.RecordArray\", {\n setup: function() {\n array = [{ id: \'1\', name: \"Scumbag Dale\" }, { id: \'2\', name: \"Scumbag Katz\" }, { id: \'3\', name: \"Scumbag Bryn\" }];\n\n Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n }\n});\n\ntest(\"a record array is backed by records\", function() {\n var store = createStore();\n run(function(){\n store.pushMany(Person, array);\n });\n\n run(function(){\n store.findByIds(Person, [1,2,3]).then(function(records) {\n for (var i=0, l=get(array, \'length\'); i<l; i++) {\n deepEqual(records[i].getProperties(\'id\', \'name\'), array[i], \"a record array materializes objects on demand\");\n }\n });\n });\n});\n\ntest(\"acts as a live query\", function() {\n var store = createStore();\n\n var recordArray = store.all(Person);\n run(function(){\n store.push(Person, { id: 1, name: \'wycats\' });\n });\n equal(get(recordArray, \'lastObject.name\'), \'wycats\');\n\n run(function(){\n store.push(Person, { id: 2, name: \'brohuda\' });\n });\n equal(get(recordArray, \'lastObject.name\'), \'brohuda\');\n});\n\ntest(\"stops updating when destroyed\", function() {\n expect(3);\n var store = createStore();\n\n var recordArray = store.all(Person);\n run(function(){\n store.push(Person, { id: 1, name: \'wycats\' });\n });\n\n run(function() {\n recordArray.destroy();\n });\n\n run(function() {\n equal(recordArray.get(\'length\'), undefined, \"Has no more records\");\n store.push(Person, { id: 2, name: \'brohuda\' });\n });\n\n equal(recordArray.get(\'length\'), undefined, \"Has not been updated\");\n equal(recordArray.get(\'content\'), undefined, \"Has not been updated\");\n});\n\n\ntest(\"a loaded record is removed from a record array when it is deleted\", function() {\n var Tag = DS.Model.extend({\n people: DS.hasMany(\'person\')\n });\n\n Person.reopen({\n tag: DS.belongsTo(\'tag\')\n });\n\n var env = setupStore({ tag: Tag, person: Person }),\n store = env.store;\n\n run(function(){\n store.pushMany(\'person\', array);\n store.push(\'tag\', { id: 1 });\n });\n\n run(function(){\n var asyncRecords = Ember.RSVP.hash({\n scumbag: store.find(\'person\', 1),\n tag: store.find(\'tag\', 1)\n });\n\n asyncRecords.then(function(records) {\n var scumbag = records.scumbag, tag = records.tag;\n\n run(function(){\n tag.get(\'people\').addObject(scumbag);\n });\n equal(get(scumbag, \'tag\'), tag, \"precond - the scumbag\'s tag has been set\");\n\n var recordArray = tag.get(\'people\');\n\n equal(get(recordArray, \'length\'), 1, \"precond - record array has one item\");\n equal(get(recordArray.objectAt(0), \'name\'), \"Scumbag Dale\", \"item at index 0 is record with id 1\");\n\n scumbag.deleteRecord();\n\n equal(get(recordArray, \'length\'), 0, \"record is removed from the record array\");\n });\n });\n});\n\ntest(\"a loaded record is removed from a record array when it is deleted even if the belongsTo side isn\'t defined\", function() {\n var Tag = DS.Model.extend({\n people: DS.hasMany(\'person\')\n });\n\n var env = setupStore({ tag: Tag, person: Person }),\n store = env.store;\n var scumbag, tag;\n\n run(function(){\n scumbag = store.push(\'person\', {id:1, name: \'Scumbag Tom\'});\n tag = store.push(\'tag\', { id: 1, people:[1] });\n scumbag.deleteRecord();\n });\n\n equal(tag.get(\'people.length\'), 0, \"record is removed from the record array\");\n});\n\ntest(\"a loaded record is removed both from the record array and from the belongs to, even if the belongsTo side isn\'t defined\", function() {\n var Tag = DS.Model.extend({\n people: DS.hasMany(\'person\')\n });\n\n var Tool = DS.Model.extend({\n person: DS.belongsTo(\'person\')\n });\n\n var env = setupStore({ tag: Tag, person: Person, tool: Tool }),\n store = env.store;\n var scumbag, tag, tool;\n\n run(function(){\n scumbag = store.push(\'person\', {id:1, name: \'Scumbag Tom\'});\n tag = store.push(\'tag\', { id: 1, people:[1] });\n tool = store.push(\'tool\', {id: 1, person:1});\n });\n\n equal(tag.get(\'people.length\'), 1, \"record is in the record array\");\n equal(tool.get(\'person\'), scumbag, \"the tool belongs to the record\");\n\n run(function(){\n scumbag.deleteRecord();\n });\n\n equal(tag.get(\'people.length\'), 0, \"record is removed from the record array\");\n equal(tool.get(\'person\'), null, \"the tool is now orphan\");\n});\n\n// GitHub Issue #168\ntest(\"a newly created record is removed from a record array when it is deleted\", function() {\n var store = createStore(),\n recordArray;\n\n recordArray = store.all(Person);\n var scumbag;\n\n run(function(){\n scumbag = store.createRecord(Person, {\n name: \"Scumbag Dale\"\n });\n });\n\n equal(get(recordArray, \'length\'), 1, \"precond - record array already has the first created item\");\n\n // guarantee coalescence\n Ember.run(function() {\n store.createRecord(Person, { name: \'p1\'});\n store.createRecord(Person, { name: \'p2\'});\n store.createRecord(Person, { name: \'p3\'});\n });\n\n equal(get(recordArray, \'length\'), 4, \"precond - record array has the created item\");\n equal(get(recordArray.objectAt(0), \'name\'), \"Scumbag Dale\", \"item at index 0 is record with id 1\");\n\n run(function(){\n scumbag.deleteRecord();\n });\n\n equal(get(recordArray, \'length\'), 3, \"record is removed from the record array\");\n\n run(function(){\n recordArray.objectAt(0).set(\'name\', \'toto\');\n });\n\n equal(get(recordArray, \'length\'), 3, \"record is still removed from the record array\");\n});\n\ntest(\"a record array returns undefined when asking for a member outside of its content Array\'s range\", function() {\n var store = createStore();\n\n run(function(){\n store.pushMany(Person, array);\n });\n\n var recordArray = store.all(Person);\n\n strictEqual(recordArray.objectAt(20), undefined, \"objects outside of the range just return undefined\");\n});\n\n// This tests for a bug in the recordCache, where the records were being cached in the incorrect order.\ntest(\"a record array should be able to be enumerated in any order\", function() {\n var store = createStore();\n run(function(){\n store.pushMany(Person, array);\n });\n\n var recordArray = store.all(Person);\n\n equal(get(recordArray.objectAt(2), \'id\'), 3, \"should retrieve correct record at index 2\");\n equal(get(recordArray.objectAt(1), \'id\'), 2, \"should retrieve correct record at index 1\");\n equal(get(recordArray.objectAt(0), \'id\'), 1, \"should retrieve correct record at index 0\");\n});\n\ntest(\"an AdapterPopulatedRecordArray knows if it\'s loaded or not\", function() {\n var env = setupStore({ person: Person }),\n store = env.store;\n\n env.adapter.findQuery = function(store, type, query, recordArray) {\n return Ember.RSVP.resolve(array);\n };\n\n run(function(){\n store.find(\'person\', { page: 1 }).then(function(people) {\n equal(get(people, \'isLoaded\'), true, \"The array is now loaded\");\n });\n });\n});\n\ntest(\"a record array should return a promise when updating\", function() {\n var env = setupStore({ person: Person }),\n store = env.store, recordArray, promise;\n\n env.adapter.findAll = function(store, type, query, recordArray) {\n return Ember.RSVP.resolve(array);\n };\n\n recordArray = store.all(Person);\n run(function(){\n promise = recordArray.update();\n });\n ok((promise.then && typeof promise.then === \"function\"), \"#update returns a promise\");\n});\n})();//# sourceURL=ember-data/unit/record_array_test.js");
208
+
209
+ eval("(function() {var get = Ember.get;\n\nvar rootState, stateName;\n\nmodule(\"unit/states - Flags for record states\", {\n setup: function() {\n rootState = DS.RootState;\n }\n});\n\nvar isTrue = function(flag) {\n equal(get(rootState, stateName + \".\" + flag), true, stateName + \".\" + flag + \" should be true\");\n};\n\nvar isFalse = function(flag) {\n equal(get(rootState, stateName + \".\" + flag), false, stateName + \".\" + flag + \" should be false\");\n};\n\ntest(\"the empty state\", function() {\n stateName = \"empty\";\n isFalse(\"isLoading\");\n isFalse(\"isLoaded\");\n isFalse(\"isDirty\");\n isFalse(\"isSaving\");\n isFalse(\"isDeleted\");\n});\n\ntest(\"the loading state\", function() {\n stateName = \"loading\";\n isTrue(\"isLoading\");\n isFalse(\"isLoaded\");\n isFalse(\"isDirty\");\n isFalse(\"isSaving\");\n isFalse(\"isDeleted\");\n});\n\ntest(\"the loaded state\", function() {\n stateName = \"loaded\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isFalse(\"isDirty\");\n isFalse(\"isSaving\");\n isFalse(\"isDeleted\");\n});\n\ntest(\"the updated state\", function() {\n stateName = \"loaded.updated\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isTrue(\"isDirty\");\n isFalse(\"isSaving\");\n isFalse(\"isDeleted\");\n});\n\ntest(\"the saving state\", function() {\n stateName = \"loaded.updated.inFlight\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isTrue(\"isDirty\");\n isTrue(\"isSaving\");\n isFalse(\"isDeleted\");\n});\n\ntest(\"the deleted state\", function() {\n stateName = \"deleted\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isTrue(\"isDirty\");\n isFalse(\"isSaving\");\n isTrue(\"isDeleted\");\n});\n\ntest(\"the deleted.saving state\", function() {\n stateName = \"deleted.inFlight\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isTrue(\"isDirty\");\n isTrue(\"isSaving\");\n isTrue(\"isDeleted\");\n});\n\ntest(\"the deleted.saved state\", function() {\n stateName = \"deleted.saved\";\n isFalse(\"isLoading\");\n isTrue(\"isLoaded\");\n isFalse(\"isDirty\");\n isFalse(\"isSaving\");\n isTrue(\"isDeleted\");\n});\n})();//# sourceURL=ember-data/unit/states_test.js");
210
+
211
+ eval("(function() {var get = Ember.get, set = Ember.set;\nvar resolve = Ember.RSVP.resolve;\nvar TestAdapter, store;\nvar run = Ember.run;\n\nmodule(\"unit/store/adapter_interop - DS.Store working with a DS.Adapter\", {\n setup: function() {\n TestAdapter = DS.Adapter.extend();\n },\n teardown: function() {\n run(function(){\n if (store) { store.destroy(); }\n });\n }\n});\n\ntest(\"Adapter can be set as a factory\", function() {\n store = createStore({adapter: TestAdapter});\n\n ok(store.get(\'defaultAdapter\') instanceof TestAdapter);\n});\n\ntest(\'Adapter can be set as a name\', function() {\n store = createStore({adapter: \'-rest\'});\n\n ok(store.get(\'defaultAdapter\') instanceof DS.RESTAdapter);\n});\n\ntest(\'Adapter can not be set as an instance\', function() {\n store = DS.Store.create({\n adapter: DS.Adapter.create()\n });\n var assert = Ember.assert;\n Ember.assert = function() { ok(true, \"raises an error when passing in an instance\"); };\n store.get(\'defaultAdapter\');\n Ember.assert = assert;\n});\n\ntest(\"Calling Store#find invokes its adapter#find\", function() {\n expect(5);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id, record) {\n ok(true, \"Adapter#find was called\");\n equal(store, currentStore, \"Adapter#find was called with the right store\");\n equal(type, currentType, \"Adapter#find was called with the type passed into Store#find\");\n equal(id, 1, \"Adapter#find was called with the id passed into Store#find\");\n equal(record.get(\'id\'), \'1\', \"Adapter#find was called with the record created from Store#find\");\n\n return Ember.RSVP.resolve({ id: 1 });\n }\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend();\n\n run(function(){\n currentStore.find(currentType, 1);\n });\n});\n\ntest(\"Calling Store#findById multiple times coalesces the calls into a adapter#findMany call\", function() {\n expect(2);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id) {\n ok(false, \"Adapter#find was not called\");\n },\n findMany: function(store, type, ids) {\n start();\n ok(true, \"Adapter#findMany was called\");\n deepEqual(ids, [\"1\",\"2\"], \'Correct ids were passed in to findMany\');\n return Ember.RSVP.resolve([{ id: 1 }, { id:2}] );\n },\n coalesceFindRequests: true\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend();\n currentType.typeKey = \"test\";\n stop();\n Ember.run(function(){\n currentStore.find(currentType, 1);\n currentStore.find(currentType, 2);\n });\n});\n\ntest(\"Returning a promise from `find` asynchronously loads data\", function() {\n var adapter = TestAdapter.extend({\n find: function(store, type, id) {\n return resolve({ id: 1, name: \"Scumbag Dale\" });\n }\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function(){\n currentStore.find(currentType, 1).then(async(function(object) {\n strictEqual(get(object, \'name\'), \"Scumbag Dale\", \"the data was pushed\");\n }));\n });\n});\n\ntest(\"IDs provided as numbers are coerced to strings\", function() {\n var adapter = TestAdapter.extend({\n find: function(store, type, id) {\n equal(typeof id, \'string\', \"id has been normalized to a string\");\n return resolve({ id: 1, name: \"Scumbag Sylvain\" });\n }\n });\n\n var currentStore = createStore({ adapter: adapter });\n var currentType = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function(){\n currentStore.find(currentType, 1).then(async(function(object) {\n equal(typeof object.get(\'id\'), \'string\', \"id was coerced to a string\");\n run(function(){\n currentStore.push(currentType, { id: 2, name: \"Scumbag Sam Saffron\" });\n });\n return currentStore.find(currentType, 2);\n })).then(async(function(object) {\n ok(object, \"object was found\");\n equal(typeof object.get(\'id\'), \'string\', \"id is a string despite being supplied and searched for as a number\");\n }));\n });\n});\n\n\nvar array = [{ id: \"1\", name: \"Scumbag Dale\" }, { id: \"2\", name: \"Scumbag Katz\" }, { id: \"3\", name: \"Scumbag Bryn\" }];\n\ntest(\"can load data for the same record if it is not dirty\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function(){\n store.push(Person, { id: 1, name: \"Tom Dale\" });\n\n store.find(Person, 1).then(async(function(tom) {\n equal(get(tom, \'isDirty\'), false, \"precond - record is not dirty\");\n equal(get(tom, \'name\'), \"Tom Dale\", \"returns the correct name\");\n\n store.push(Person, { id: 1, name: \"Captain Underpants\" });\n equal(get(tom, \'name\'), \"Captain Underpants\", \"updated record with new date\");\n }));\n });\n});\n\n/*\ntest(\"DS.Store loads individual records without explicit IDs with a custom primaryKey\", function() {\n var store = DS.Store.create();\n var Person = DS.Model.extend({ name: DS.attr(\'string\'), primaryKey: \'key\' });\n\n store.load(Person, { key: 1, name: \"Tom Dale\" });\n\n var tom = store.find(Person, 1);\n equal(get(tom, \'name\'), \"Tom Dale\", \"the person was successfully loaded for the given ID\");\n});\n*/\n\ntest(\"pushMany extracts ids from an Array of hashes if no ids are specified\", function() {\n var store = createStore();\n\n var Person = DS.Model.extend({ name: DS.attr(\'string\') });\n\n run(function(){\n store.pushMany(Person, array);\n store.find(Person, 1).then(async(function(person) {\n equal(get(person, \'name\'), \"Scumbag Dale\", \"correctly extracted id for loaded data\");\n }));\n });\n});\n\ntest(\"loadMany takes an optional Object and passes it on to the Adapter\", function() {\n var passedQuery = { page: 1 };\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var adapter = TestAdapter.extend({\n findQuery: function(store, type, query) {\n equal(type, Person, \"The type was Person\");\n equal(query, passedQuery, \"The query was passed in\");\n return Ember.RSVP.resolve([]);\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n run(function(){\n store.find(Person, passedQuery);\n });\n});\n\ntest(\"Find with query calls the correct extract\", function() {\n var passedQuery = { page: 1 };\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var adapter = TestAdapter.extend({\n findQuery: function(store, type, query) {\n return Ember.RSVP.resolve([]);\n }\n });\n\n var callCount = 0;\n\n var ApplicationSerializer = DS.JSONSerializer.extend({\n extractFindQuery: function(store, type, payload) {\n callCount++;\n return [];\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n store.container.register(\'serializer:application\', ApplicationSerializer);\n\n run(function(){\n store.find(Person, passedQuery);\n });\n equal(callCount, 1, \'extractFindQuery was called\');\n});\n\ntest(\"all(type) returns a record array of all records of a specific type\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function(){\n store.push(Person, { id: 1, name: \"Tom Dale\" });\n });\n\n var results = store.all(Person);\n equal(get(results, \'length\'), 1, \"record array should have the original object\");\n equal(get(results.objectAt(0), \'name\'), \"Tom Dale\", \"record has the correct information\");\n\n run(function(){\n store.push(Person, { id: 2, name: \"Yehuda Katz\" });\n });\n equal(get(results, \'length\'), 2, \"record array should have the new object\");\n equal(get(results.objectAt(1), \'name\'), \"Yehuda Katz\", \"record has the correct information\");\n\n strictEqual(results, store.all(Person), \"subsequent calls to all return the same recordArray)\");\n});\n\ntest(\"a new record of a particular type is created via store.createRecord(type)\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var person;\n\n run(function(){\n person = store.createRecord(Person);\n });\n\n equal(get(person, \'isLoaded\'), true, \"A newly created record is loaded\");\n equal(get(person, \'isNew\'), true, \"A newly created record is new\");\n equal(get(person, \'isDirty\'), true, \"A newly created record is dirty\");\n\n run(function(){\n set(person, \'name\', \"Braaahm Dale\");\n });\n\n equal(get(person, \'name\'), \"Braaahm Dale\", \"Even if no hash is supplied, `set` still worked\");\n});\n\ntest(\"a new record with a specific id can\'t be created if this id is already used in the store\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n Person.reopenClass({\n toString: function() {\n return \'Person\';\n }\n });\n\n run(function(){\n store.createRecord(Person, {id: 5});\n });\n\n expectAssertion(function() {\n run(function(){\n store.createRecord(Person, {id: 5});\n });\n }, /The id 5 has already been used with another record of type Person/);\n});\n\ntest(\"an initial data hash can be provided via store.createRecord(type, hash)\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var person;\n\n run(function(){\n person = store.createRecord(Person, { name: \"Brohuda Katz\" });\n });\n\n equal(get(person, \'isLoaded\'), true, \"A newly created record is loaded\");\n equal(get(person, \'isNew\'), true, \"A newly created record is new\");\n equal(get(person, \'isDirty\'), true, \"A newly created record is dirty\");\n\n equal(get(person, \'name\'), \"Brohuda Katz\", \"The initial data hash is provided\");\n});\n\ntest(\"if an id is supplied in the initial data hash, it can be looked up using `store.find`\", function() {\n var store = createStore();\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n var person;\n\n run(function(){\n person = store.createRecord(Person, { id: 1, name: \"Brohuda Katz\" });\n store.find(Person, 1).then(async(function(again) {\n strictEqual(person, again, \"the store returns the loaded object\");\n }));\n });\n});\n\ntest(\"initial values of attributes can be passed in as the third argument to find\", function() {\n var adapter = TestAdapter.extend({\n find: function(store, type, query) {\n return Ember.RSVP.resolve({id: \'1\', name: \'Test\'});\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n run(function(){\n store.find(Person, 1, {name: \'Test\'}).then(async(function(){\n equal(store.getById(Person, 1).get(\'name\'), \'Test\', \'Preloaded attribtue set\');\n }));\n });\n});\n\ntest(\"initial values of belongsTo can be passed in as the third argument to find as records\", function() {\n var adapter = TestAdapter.extend({\n find: function(store, type, query) {\n return new Ember.RSVP.Promise(function(){});\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friend: DS.belongsTo(\'person\')\n });\n\n store.container.register(\'model:person\', Person);\n var tom;\n\n run(function(){\n tom = store.push(Person, {id:2, name:\'Tom\'});\n store.find(Person, 1, {friend: tom});\n });\n\n equal(store.getById(Person, 1).get(\'friend.name\'), \'Tom\', \'Preloaded belongsTo set\');\n});\n\ntest(\"initial values of belongsTo can be passed in as the third argument to find as ids\", function() {\n expect(1);\n var adapter = TestAdapter.extend({\n find: function(store, type, id) {\n return Ember.RSVP.Promise.resolve({id: id});\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friend: DS.belongsTo(\'person\', {async: true})\n });\n\n store.container.register(\'model:person\', Person);\n\n run(function(){\n store.find(Person, 1, {friend: 2}).then(async(function(){\n store.getById(Person, 1).get(\'friend\').then(async(function(friend) {\n equal(friend.get(\'id\'), \'2\', \'Preloaded belongsTo set\');\n }));\n }));\n });\n});\n\ntest(\"initial values of hasMany can be passed in as the third argument to find as records\", function() {\n var adapter = TestAdapter.extend({\n find: function(store, type, query) {\n return new Ember.RSVP.Promise(function(){});\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friends: DS.hasMany(\'person\')\n });\n\n store.container.register(\'model:person\', Person);\n var tom;\n\n run(function(){\n tom = store.push(Person, {id:2, name:\'Tom\'});\n store.find(Person, 1, {friends: [tom]});\n });\n\n equal(store.getById(Person, 1).get(\'friends\').toArray()[0].get(\'name\'), \'Tom\', \'Preloaded hasMany set\');\n});\n\ntest(\"initial values of hasMany can be passed in as the third argument to find as ids\", function() {\n expect(1);\n\n var adapter = TestAdapter.extend({\n find: function(store, type, id) {\n return Ember.RSVP.resolve({id:id});\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var Person = DS.Model.extend({\n name: DS.attr(\'string\'),\n friends: DS.hasMany(\'person\', {async: true})\n });\n\n store.container.register(\'model:person\', Person);\n\n run(function(){\n store.find(Person, 1, {friends: [2]});\n store.getById(Person, 1).get(\'friends\').then(async(function(friends){\n equal(friends.objectAt(0).get(\'id\'), \'2\', \'Preloaded hasMany set\');\n }));\n });\n});\n\ntest(\"records should have their ids updated when the adapter returns the id data\", function() {\n var Person = DS.Model.extend();\n\n var idCounter = 1;\n var adapter = TestAdapter.extend({\n createRecord: function(store, type, record) {\n return Ember.RSVP.resolve({name: record.get(\'name\'), id: idCounter++});\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var people = store.all(Person);\n var tom, yehuda;\n\n run(function(){\n tom = store.createRecord(Person, {name: \'Tom Dale\'});\n yehuda = store.createRecord(Person, {name: \'Yehuda Katz\'});\n });\n\n run(function(){\n Ember.RSVP.all([ tom.save(), yehuda.save() ]).then(async(function() {\n people.forEach(function(person, index) {\n equal(person.get(\'id\'), index + 1, \"The record\'s id should be correct.\");\n });\n }));\n });\n});\n\ntest(\"store.fetchMany should always return a promise\", function() {\n var Person = DS.Model.extend();\n var store = createStore({\n adapter: TestAdapter.extend()\n });\n run(function(){\n store.createRecord(Person);\n });\n var records = Ember.A([]);\n var results;\n\n run(function(){\n results = store.scheduleFetchMany(records);\n });\n ok(results, \"A call to store.scheduleFetchMany() should return a result\");\n ok(results.then, \"A call to store.scheduleFetchMany() should return a promise\");\n\n results.then(async(function(returnedRecords) {\n deepEqual(returnedRecords, [], \"The correct records are returned\");\n }));\n});\n\ntest(\"store.scheduleFetchMany should not resolve until all the records are resolve\", function() {\n var Person = DS.Model.extend();\n var Phone = DS.Model.extend();\n\n var adapter = TestAdapter.extend({\n find: function (store, type, id) {\n var wait = 5;\n\n var record = { id: id };\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n Ember.run.later(function() {\n resolve(record);\n }, wait);\n });\n },\n\n findMany: function(store, type, ids) {\n var wait = 15;\n\n var records = ids.map(function(id) {\n return {id: id};\n });\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n Ember.run.later(function() {\n resolve(records);\n }, wait);\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n run(function(){\n store.createRecord(Person);\n });\n\n var records = Ember.A([\n store.recordForId(Person, 10),\n store.recordForId(Phone, 20),\n store.recordForId(Phone, 21)\n ]);\n\n run(function(){\n store.scheduleFetchMany(records).then(async(function() {\n var unloadedRecords = records.filterBy(\'isEmpty\');\n equal(get(unloadedRecords, \'length\'), 0, \'All unloaded records should be loaded\');\n }));\n });\n});\n\ntest(\"the store calls adapter.findMany according to groupings returned by adapter.groupRecordsForFindMany\", function() {\n expect(3);\n\n var Person = DS.Model.extend();\n\n var adapter = TestAdapter.extend({\n groupRecordsForFindMany: function (store, records) {\n return [\n [records[0]],\n [records[1], records[2]]\n ];\n },\n\n find: function(store, type, id) {\n equal(id, \"10\", \"The first group is passed to find\");\n return Ember.RSVP.resolve({id:id});\n },\n\n findMany: function(store, type, ids) {\n var records = ids.map(function(id) {\n return {id: id};\n });\n\n deepEqual(ids, [\"20\", \"21\"], \"The second group is passed to findMany\");\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n resolve(records);\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n var records = Ember.A([\n store.recordForId(Person, 10),\n store.recordForId(Person, 20),\n store.recordForId(Person, 21)\n ]);\n\n run(function(){\n store.scheduleFetchMany(records).then(async(function() {\n var ids = records.mapBy(\'id\');\n deepEqual(ids, [\"10\", \"20\", \"21\"], \"The promise fulfills with the records\");\n }));\n });\n});\n\ntest(\"the promise returned by `scheduleFetch`, when it resolves, does not depend on the promises returned to other calls to `scheduleFetch` that are in the same run loop, but different groups\", function() {\n expect(2);\n var Person = DS.Model.extend();\n var davidResolved = false;\n\n var adapter = TestAdapter.extend({\n groupRecordsForFindMany: function (store, records) {\n return [\n [records[0]],\n [records[1]]\n ];\n },\n\n find: function(store, type, id) {\n var record = {id: id};\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n if (id === \'igor\') {\n resolve(record);\n } else {\n Ember.run.later(function () {\n davidResolved = true;\n resolve(record);\n }, 5);\n }\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n Ember.run(function () {\n var davidPromise = store.find(Person, \'david\');\n var igorPromise = store.find(Person, \'igor\');\n\n igorPromise.then(async(function () {\n equal(davidResolved, false, \"Igor did not need to wait for David\");\n }));\n\n davidPromise.then(async(function () {\n equal(davidResolved, true, \"David resolved\");\n }));\n });\n});\n\ntest(\"the promise returned by `scheduleFetch`, when it rejects, does not depend on the promises returned to other calls to `scheduleFetch` that are in the same run loop, but different groups\", function() {\n expect(2);\n var Person = DS.Model.extend();\n var davidResolved = false;\n\n var adapter = TestAdapter.extend({\n groupRecordsForFindMany: function (store, records) {\n return [\n [records[0]],\n [records[1]]\n ];\n },\n\n find: function(store, type, id) {\n var record = {id: id};\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n if (id === \'igor\') {\n reject(record);\n } else {\n Ember.run.later(function () {\n davidResolved = true;\n resolve(record);\n }, 5);\n }\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n Ember.run(function () {\n var davidPromise = store.find(Person, \'david\');\n var igorPromise = store.find(Person, \'igor\');\n\n igorPromise.then(null, async(function () {\n equal(davidResolved, false, \"Igor did not need to wait for David\");\n }));\n\n davidPromise.then(async(function () {\n equal(davidResolved, true, \"David resolved\");\n }));\n });\n});\n\ntest(\"store.fetchRecord reject records that were not found, even when those requests were coalesced with records that were found\", function() {\n expect(2);\n var Person = DS.Model.extend();\n\n var adapter = TestAdapter.extend({\n findMany: function(store, type, ids) {\n var records = ids.map(function(id) {\n return {id: id};\n });\n\n return new Ember.RSVP.Promise(function(resolve, reject) {\n resolve([\n records[0]\n ]);\n });\n }\n });\n\n var store = createStore({\n adapter: adapter\n });\n\n Ember.run(function () {\n var davidPromise = store.find(Person, \'david\');\n var igorPromise = store.find(Person, \'igor\');\n\n davidPromise.then(async(function () {\n ok(true, \"David resolved\");\n }));\n\n igorPromise.then(null, async(function () {\n ok(true, \"Igor rejected\");\n }));\n });\n});\n})();//# sourceURL=ember-data/unit/store/adapter_interop_test.js");
212
+
213
+ eval("(function() {var store, container, Record;\nvar run = Ember.run;\n\nmodule(\"unit/store/createRecord - Store creating records\", {\n setup: function() {\n store = createStore({ adapter: DS.Adapter.extend()});\n\n Record = DS.Model.extend({\n title: DS.attr(\'string\')\n });\n }\n});\n\ntest(\"doesn\'t modify passed in properties hash\", function(){\n var attributes = { foo: \'bar\' };\n run(function(){\n store.createRecord(Record, attributes);\n store.createRecord(Record, attributes);\n });\n\n deepEqual(attributes, { foo: \'bar\' }, \"The properties hash is not modified\");\n});\n\nmodule(\"unit/store/createRecord - Store with models by dash\", {\n setup: function() {\n var env = setupStore({\n \'some-thing\': DS.Model.extend({ foo: DS.attr(\'string\') })\n });\n store = env.store;\n container = env.container;\n env.replaceContainerNormalize(function(key){\n return Ember.String.dasherize(key);\n });\n }\n});\ntest(\"creating a record by camel-case string finds the model\", function(){\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function(){\n record = store.createRecord(\'someThing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'someThing\').typeKey, \'someThing\');\n});\n\ntest(\"creating a record by dasherize string finds the model\", function(){\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function(){\n record = store.createRecord(\'some-thing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'some-thing\').typeKey, \'someThing\');\n});\n\nmodule(\"unit/store/createRecord - Store with models by camelCase\", {\n setup: function() {\n var env = setupStore({\n \'someThing\': DS.Model.extend({ foo: DS.attr(\'string\') })\n });\n store = env.store;\n container = env.container;\n env.replaceContainerNormalize(Ember.String.camelize);\n }\n});\n\ntest(\"creating a record by camel-case string finds the model\", function(){\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function(){\n record = store.createRecord(\'someThing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'someThing\').typeKey, \'someThing\');\n});\n\ntest(\"creating a record by dasherize string finds the model\", function(){\n var attributes = { foo: \'bar\' };\n var record;\n\n run(function(){\n record = store.createRecord(\'some-thing\', attributes);\n });\n\n equal(record.get(\'foo\'), attributes.foo, \"The record is created\");\n equal(store.modelFor(\'some-thing\').typeKey, \'someThing\');\n});\n})();//# sourceURL=ember-data/unit/store/create_record_test.js");
214
+
215
+ eval("(function() {var store;\n\nvar run = Ember.run;\n\nmodule(\"unit/store/metadata_for - DS.Store#metadataFor\", {\n setup: function() {\n store = createStore({\n post: DS.Model.extend(),\n comment: DS.Model.extend()\n });\n },\n\n teardown: function() {\n run(function(){\n store.destroy();\n });\n }\n});\n\ntest(\"metaForType should be deprecated\", function() {\n expect(1);\n\n expectDeprecation(function() {\n store.metaForType(\'post\', { foo: \'bar\' });\n });\n});\n\ntest(\"metadataFor and setMetadataFor should return and set correct metadata\", function() {\n expect(7);\n var keys = Ember.keys;\n function metadataKeys(type){\n return keys(store.metadataFor(type));\n }\n\n // Currently not using QUnit.deepEqual due to the way deepEqual\n // comparing __proto__. In its check to see if an object has\n // no proto, it checks strict equality on null instead of null or undefined.\n\n deepEqual(metadataKeys(\'post\'), [], \'Metadata for post is initially empty\');\n\n store.setMetadataFor(\'post\', { foo: \'bar\' });\n\n deepEqual(metadataKeys(\'post\'), [\'foo\'], \'metadata for post contains foo:bar\');\n equal(store.metadataFor(\'post\').foo, \'bar\');\n\n store.setMetadataFor(\'post\', { hello: \'world\' });\n\n deepEqual(metadataKeys(\'post\'), [\'foo\', \'hello\']);\n equal(store.metadataFor(\'post\').foo, \'bar\', \'keeps original metadata\');\n equal(store.metadataFor(\'post\').hello, \'world\', \'merges new metadata\');\n\n deepEqual(metadataKeys(\'comment\'), [], \'metadata for comment is empty\');\n});\n})();//# sourceURL=ember-data/unit/store/metadata_for_test.js");
216
+
217
+ eval("(function() {var container, store;\n\nvar camelize = Ember.String.camelize,\n dasherize = Ember.String.dasherize;\n\nvar run = Ember.run;\nvar env;\n\nmodule(\"unit/store/model_for - DS.Store#modelFor\", {\n setup: function() {\n env = setupStore({\n blogPost: DS.Model.extend(),\n \"blog-post\": DS.Model.extend()\n });\n store = env.store;\n container = store.container;\n },\n\n teardown: function() {\n run(function(){\n container.destroy();\n store.destroy();\n });\n }\n});\n\ntest(\"when fetching factory from string, sets a normalized key as typeKey\", function() {\n env.replaceContainerNormalize(camelize);\n\n equal(container.normalize(\'some.post\'), \'somePost\', \'precond - container camelizes\');\n equal(store.modelFor(\"blog.post\").typeKey, \"blogPost\", \"typeKey is normalized to camelCase\");\n});\n\ntest(\"when fetching factory from string and dashing normalizer, sets a normalized key as typeKey\", function() {\n env.replaceContainerNormalize(function(fullName){\n return dasherize(camelize(fullName));\n });\n\n equal(container.normalize(\'some.post\'), \'some-post\', \'precond - container dasherizes\');\n equal(store.modelFor(\"blog.post\").typeKey, \"blogPost\", \"typeKey is normalized to camelCase\");\n});\n\ntest(\"when returning passed factory, sets a normalized key as typeKey\", function() {\n var factory = {typeKey: \'some-thing\'};\n equal(store.modelFor(factory).typeKey, \"someThing\", \"typeKey is normalized to camelCase\");\n});\n\ntest(\"when returning passed factory without typeKey, allows it\", function() {\n var factory = {typeKey: undefined};\n equal(store.modelFor(factory).typeKey, undefined, \"typeKey is undefined\");\n});\n})();//# sourceURL=ember-data/unit/store/model_for_test.js");
218
+
219
+ eval("(function() {var env, store, Person, PhoneNumber, Post;\nvar attr = DS.attr, hasMany = DS.hasMany, belongsTo = DS.belongsTo;\nvar run = Ember.run;\n\nmodule(\"unit/store/push - DS.Store#push\", {\n setup: function() {\n Person = DS.Model.extend({\n firstName: attr(\'string\'),\n lastName: attr(\'string\'),\n phoneNumbers: hasMany(\'phone-number\')\n });\n Person.toString = function() {\n return \'Person\';\n };\n\n PhoneNumber = DS.Model.extend({\n number: attr(\'string\'),\n person: belongsTo(\'person\')\n });\n PhoneNumber.toString = function() {\n return \'PhoneNumber\';\n };\n\n Post = DS.Model.extend({\n postTitle: attr(\'string\')\n });\n Post.toString = function() {\n return \'Post\';\n };\n\n env = setupStore({\"post\": Post,\n \"person\": Person,\n \"phone-number\": PhoneNumber});\n\n store = env.store;\n\n env.container.register(\'serializer:post\', DS.ActiveModelSerializer);\n },\n\n teardown: function() {\n Ember.run(function() {\n store.destroy();\n });\n }\n});\n\ntest(\"Calling push with a normalized hash returns a record\", function() {\n run(function(){\n var person = store.push(\'person\', {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n store.find(\'person\', \'wat\').then(function(foundPerson) {\n equal(foundPerson, person, \"record returned via load() is the same as the record returned from find()\");\n deepEqual(foundPerson.getProperties(\'id\', \'firstName\', \'lastName\'), {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n });\n });\n});\n\ntest(\"Supplying a model class for `push` is the same as supplying a string\", function () {\n var Programmer = Person.extend();\n env.container.register(\'model:programmer\', Programmer);\n\n run(function(){\n store.push(Programmer, {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n\n store.find(\'programmer\', \'wat\').then(function(foundProgrammer) {\n deepEqual(foundProgrammer.getProperties(\'id\', \'firstName\', \'lastName\'), {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n });\n });\n});\n\ntest(\"Calling push triggers `didLoad` even if the record hasn\'t been requested from the adapter\", function() {\n Person.reopen({\n didLoad: async(function() {\n ok(true, \"The didLoad callback was called\");\n })\n });\n\n run(function(){\n store.push(\'person\', {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n });\n});\n\ntest(\"Calling update should be deprecated\", function() {\n expectDeprecation(function() {\n run(function() {\n store.update(\'person\', { id: \'1\', name: \'Tomster\' });\n });\n });\n});\n\ntest(\"Calling push with partial records updates just those attributes\", function() {\n var person;\n run(function(){\n person = store.push(\'person\', {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n\n store.update(\'person\', {\n id: \'wat\',\n lastName: \"Katz!\"\n });\n\n store.find(\'person\', \'wat\').then(function(foundPerson) {\n equal(foundPerson, person, \"record returned via load() is the same as the record returned from find()\");\n deepEqual(foundPerson.getProperties(\'id\', \'firstName\', \'lastName\'), {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz!\"\n });\n });\n });\n});\n\ntest(\"Calling push on normalize allows partial updates with raw JSON\", function () {\n env.container.register(\'serializer:person\', DS.RESTSerializer);\n var person;\n\n run(function(){\n person = store.push(\'person\', {\n id: \'1\',\n firstName: \"Robert\",\n lastName: \"Jackson\"\n });\n\n store.push(\'person\', store.normalize(\'person\', {\n id: \'1\',\n firstName: \"Jacquie\"\n }));\n });\n\n equal(person.get(\'firstName\'), \"Jacquie\", \"you can push raw JSON into the store\");\n equal(person.get(\'lastName\'), \"Jackson\", \"existing fields are untouched\");\n});\n\ntest(\"Calling push with partial records triggers observers for just those attributes\", function() {\n expect(1);\n var person;\n\n run(function(){\n person = store.push(\'person\', {\n id: \'wat\',\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n });\n });\n\n person.addObserver(\'firstName\', function() {\n ok(false, \'firstName observer should not be triggered\');\n });\n\n person.addObserver(\'lastName\', function() {\n ok(true, \'lastName observer should be triggered\');\n });\n\n run(function(){\n store.push(\'person\', {\n id: \'wat\',\n lastName: \"Katz!\"\n });\n });\n});\n\ntest(\"Calling push with a normalized hash containing related records returns a record\", function() {\n var number1, number, person;\n run(function(){\n number1 = store.push(\'phone-number\', {\n id: 1,\n number: \'5551212\',\n person: \'wat\'\n });\n\n number2 = store.push(\'phone-number\', {\n id: 2,\n number: \'5552121\',\n person: \'wat\'\n });\n\n person = store.push(\'person\', {\n id: \'wat\',\n firstName: \'John\',\n lastName: \'Smith\',\n phoneNumbers: [number1, number2]\n });\n });\n\n\n deepEqual(person.get(\'phoneNumbers\').toArray(), [ number1, number2 ], \"phoneNumbers array is correct\");\n});\n\ntest(\"Calling push with a normalized hash containing IDs of related records returns a record\", function() {\n Person.reopen({\n phoneNumbers: hasMany(\'phone-number\', { async: true })\n });\n\n env.adapter.find = function(store, type, id) {\n if (id === \"1\") {\n return Ember.RSVP.resolve({\n id: 1,\n number: \'5551212\',\n person: \'wat\'\n });\n }\n\n if (id === \"2\") {\n return Ember.RSVP.resolve({\n id: 2,\n number: \'5552121\',\n person: \'wat\'\n });\n }\n };\n var person;\n\n run(function(){\n person = store.push(\'person\', {\n id: \'wat\',\n firstName: \'John\',\n lastName: \'Smith\',\n phoneNumbers: [\"1\", \"2\"]\n });\n person.get(\'phoneNumbers\').then(function(phoneNumbers) {\n deepEqual(phoneNumbers.map(function(item) {\n return item.getProperties(\'id\', \'number\', \'person\');\n }), [{\n id: \"1\",\n number: \'5551212\',\n person: person\n }, {\n id: \"2\",\n number: \'5552121\',\n person: person\n }]);\n });\n });\n});\n\ntest(\"Calling pushPayload allows pushing raw JSON\", function () {\n run(function(){\n store.pushPayload(\'post\', {posts: [{\n id: \'1\',\n post_title: \"Ember rocks\"\n }]});\n });\n\n var post = store.getById(\'post\', 1);\n\n equal(post.get(\'postTitle\'), \"Ember rocks\", \"you can push raw JSON into the store\");\n\n run(function(){\n store.pushPayload(\'post\', {posts: [{\n id: \'1\',\n post_title: \"Ember rocks (updated)\"\n }]});\n });\n\n equal(post.get(\'postTitle\'), \"Ember rocks (updated)\", \"You can update data in the store\");\n});\n\ntest(\"Calling pushPayload allows pushing singular payload properties\", function () {\n run(function(){\n store.pushPayload(\'post\', {post: {\n id: \'1\',\n post_title: \"Ember rocks\"\n }});\n });\n\n var post = store.getById(\'post\', 1);\n\n equal(post.get(\'postTitle\'), \"Ember rocks\", \"you can push raw JSON into the store\");\n\n run(function(){\n store.pushPayload(\'post\', {post: {\n id: \'1\',\n post_title: \"Ember rocks (updated)\"\n }});\n });\n\n equal(post.get(\'postTitle\'), \"Ember rocks (updated)\", \"You can update data in the store\");\n});\n\ntest(\"Calling pushPayload should use the type\'s serializer for normalizing\", function () {\n expect(4);\n env.container.register(\'serializer:post\', DS.RESTSerializer.extend({\n normalize: function(store, payload) {\n ok(true, \"normalized is called on Post serializer\");\n return this._super(store, payload);\n }\n }));\n env.container.register(\'serializer:person\', DS.RESTSerializer.extend({\n normalize: function(store, payload) {\n ok(true, \"normalized is called on Person serializer\");\n return this._super(store, payload);\n }\n }));\n\n run(function(){\n store.pushPayload(\'post\', {\n posts: [{\n id: 1,\n postTitle: \"Ember rocks\"\n }],\n people: [{\n id: 2,\n firstName: \"Yehuda\"\n }]\n });\n });\n\n var post = store.getById(\'post\', 1);\n\n equal(post.get(\'postTitle\'), \"Ember rocks\", \"you can push raw JSON into the store\");\n\n var person = store.getById(\'person\', 2);\n\n equal(person.get(\'firstName\'), \"Yehuda\", \"you can push raw JSON into the store\");\n});\n\ntest(\"Calling pushPayload without a type uses application serializer\'s pushPayload method\", function () {\n expect(1);\n\n env.container.register(\'serializer:application\', DS.RESTSerializer.extend({\n pushPayload: function(store, payload) {\n ok(true, \"pushPayload is called on Application serializer\");\n return this._super(store, payload);\n }\n }));\n\n run(function(){\n store.pushPayload({posts: [{\n id: \'1\',\n postTitle: \"Ember rocks\"\n }]});\n });\n});\n\ntest(\"Calling pushPayload without a type should use a model\'s serializer when normalizing\", function () {\n expect(4);\n\n env.container.register(\'serializer:post\', DS.RESTSerializer.extend({\n normalize: function(store, payload) {\n ok(true, \"normalized is called on Post serializer\");\n return this._super(store, payload);\n }\n }));\n\n env.container.register(\'serializer:application\', DS.RESTSerializer.extend({\n normalize: function(store, payload) {\n ok(true, \"normalized is called on Application serializer\");\n return this._super(store, payload);\n }\n }));\n\n run(function(){\n store.pushPayload({\n posts: [{\n id: \'1\',\n postTitle: \"Ember rocks\"\n }],\n people: [{\n id: \'2\',\n firstName: \'Yehuda\'\n }]\n });\n });\n\n var post = store.getById(\'post\', 1);\n\n equal(post.get(\'postTitle\'), \"Ember rocks\", \"you can push raw JSON into the store\");\n\n var person = store.getById(\'person\', 2);\n\n equal(person.get(\'firstName\'), \"Yehuda\", \"you can push raw JSON into the store\");\n});\n\ntest(\"Calling pushPayload allows partial updates with raw JSON\", function () {\n env.container.register(\'serializer:person\', DS.RESTSerializer);\n\n var person;\n\n run(function() {\n store.pushPayload(\'person\', {\n people: [{\n id: \'1\',\n firstName: \"Robert\",\n lastName: \"Jackson\"\n }]\n });\n });\n\n var person = store.getById(\'person\', 1);\n\n equal(person.get(\'firstName\'), \"Robert\", \"you can push raw JSON into the store\");\n equal(person.get(\'lastName\'), \"Jackson\", \"you can push raw JSON into the store\");\n\n run(function() {\n store.pushPayload(\'person\', {\n people: [{\n id: \'1\',\n firstName: \"Jacquie\"\n }]\n });\n });\n\n equal(person.get(\'firstName\'), \"Jacquie\", \"you can push raw JSON into the store\");\n equal(person.get(\'lastName\'), \"Jackson\", \"existing fields are untouched\");\n});\n\ntest(\'calling push without data argument as an object raises an error\', function(){\n var invalidValues = [\n undefined,\n null,\n 1,\n \'string\',\n Ember.Object.create(),\n Ember.Object.extend(),\n true\n ];\n\n expect(invalidValues.length);\n\n Ember.EnumerableUtils.forEach(invalidValues, function(invalidValue){\n throws(function(){\n run(function(){\n store.push(\'person\', invalidValue);\n });\n }, /object/);\n });\n});\n\ntest(\'Calling push with a link for a non async relationship should warn\', function() {\n Person.reopen({\n phoneNumbers: hasMany(\'phone-number\', { async: false })\n });\n\n warns(function() {\n run(function(){\n store.push(\'person\', {\n id: \'1\',\n links: {\n phoneNumbers: \'/api/people/1/phone-numbers\'\n }\n });\n });\n }, /You have pushed a record of type \'person\' with \'phoneNumbers\' as a link, but the association is not an aysnc relationship./);\n});\n\ntest(\'Calling push with a link containing an object throws an assertion error\', function() {\n expectAssertion(function() {\n run(function(){\n store.push(\'person\', {\n id: \'1\',\n links: {\n phoneNumbers: {\n href: \'/api/people/1/phone-numbers\'\n }\n }\n });\n });\n }, \"You have pushed a record of type \'person\' with \'phoneNumbers\' as a link, but the value of that link is not a string.\");\n});\n\ntest(\'Calling push with a link containing the value null\', function() {\n run(function(){\n store.push(\'person\', {\n id: \'1\',\n firstName: \'Tan\',\n links: {\n phoneNumbers: null\n }\n });\n });\n\n var person = store.getById(\'person\', 1);\n\n equal(person.get(\'firstName\'), \"Tan\", \"you can use links that contain null as a value\");\n});\n\ntest(\'calling push with hasMany relationship the value must be an array\', function(){\n var invalidValues = [\n 1,\n \'string\',\n Ember.Object.create(),\n Ember.Object.extend(),\n true\n ];\n\n expect(invalidValues.length);\n\n Ember.EnumerableUtils.forEach(invalidValues, function(invalidValue){\n throws(function() {\n run(function(){\n store.push(\'person\', { id: 1, phoneNumbers: invalidValue });\n });\n }, /must be an array/);\n });\n});\n\ntest(\'calling push with missing or invalid `id` throws assertion error\', function(){\n var invalidValues = [\n {},\n { id: null },\n { id: \'\' }\n ];\n\n expect(invalidValues.length);\n\n Ember.EnumerableUtils.forEach(invalidValues, function(invalidValue){\n throws(function() {\n run(function(){\n store.push(\'person\', invalidValue);\n });\n }, /You must include an `id`/);\n });\n});\n\ntest(\'calling push with belongsTo relationship the value must not be an array\', function(){\n throws(function() {\n run(function(){\n store.push(\'phone-number\', { id: 1, person: [1] });\n });\n }, /must not be an array/);\n});\n\ntest(\'calling push with an embedded relationship throws a useful error\', function(){\n throws(function() {\n run(function() {\n store.push(\'person\', {\n id: 1,\n firstName: \'Ada\',\n lastName: \'Lovelace\',\n phoneNumbers: [\n {number: \'5551212\', person: 1}\n ] });\n });\n }, /If this is an embedded relationship/);\n});\n\ntest(\"Ember.ENV.DS_NO_WARN_ON_UNUSED_KEYS suppresses unknown keys warning\", function() {\n Ember.run(function(){\n try {\n Ember.ENV.DS_NO_WARN_ON_UNUSED_KEYS = true;\n noWarns(function() {\n store.push(\'person\', {\n id: \'1\',\n firstName: \'Tomster\',\n emailAddress: \'tomster@emberjs.com\',\n isMascot: true\n });\n });\n } finally {\n Ember.ENV.DS_NO_WARN_ON_UNUSED_KEYS = null;\n }\n });\n});\n\ntest(\"Calling push with unknown keys in the provided payload should warn\", function() {\n warns(function() {\n run(function(){\n store.push(\'person\', {\n id: \'1\',\n firstName: \'Tomster\',\n emailAddress: \'tomster@emberjs.com\',\n isMascot: true\n });\n });\n }, /The payload for \'person\' contains these unknown keys: \\[emailAddress,isMascot\\]. Make sure they\'ve been defined in your model./);\n});\n})();//# sourceURL=ember-data/unit/store/push_test.js");
220
+
221
+ eval("(function() {var container, store;\nvar run = Ember.run;\n\nmodule(\"unit/store/serializer_for - DS.Store#serializerFor\", {\n setup: function() {\n store = createStore({person: DS.Model.extend()});\n container = store.container;\n },\n\n teardown: function() {\n run(function(){\n container.destroy();\n store.destroy();\n });\n }\n});\n\ntest(\"Calling serializerFor looks up \'serializer:<type>\' from the container\", function() {\n var PersonSerializer = DS.JSONSerializer.extend();\n\n container.register(\'serializer:person\', PersonSerializer);\n\n ok(store.serializerFor(\'person\') instanceof PersonSerializer, \"serializer returned from serializerFor is an instance of the registered Serializer class\");\n});\n\ntest(\"Calling serializerFor with a type that has not been registered looks up the default ApplicationSerializer\", function() {\n var ApplicationSerializer = DS.JSONSerializer.extend();\n\n container.register(\'serializer:application\', ApplicationSerializer);\n\n ok(store.serializerFor(\'person\') instanceof ApplicationSerializer, \"serializer returned from serializerFor is an instance of ApplicationSerializer\");\n});\n\ntest(\"Calling serializerFor with a type that has not been registered and in an application that does not have an ApplicationSerializer looks up the default Ember Data serializer\", function() {\n ok(store.serializerFor(\'person\') instanceof DS.JSONSerializer, \"serializer returned from serializerFor is an instance of DS.JSONSerializer\");\n});\n})();//# sourceURL=ember-data/unit/store/serializer_for_test.js");
222
+
223
+ eval("(function() {var get = Ember.get;\nvar store, tryToFind, Record;\nvar run = Ember.run;\n\nmodule(\"unit/store/unload - Store unloading records\", {\n setup: function() {\n store = createStore({ adapter: DS.Adapter.extend({\n find: function(store, type, id) {\n tryToFind = true;\n return Ember.RSVP.resolve({ id: id, wasFetched: true });\n }\n })\n });\n\n Record = DS.Model.extend({\n title: DS.attr(\'string\')\n });\n },\n\n teardown: function() {\n Ember.run(store, \'destroy\');\n }\n});\n\ntest(\"unload a dirty record\", function() {\n run(function(){\n store.push(Record, {\n id: 1,\n title: \'toto\'\n });\n\n store.find(Record, 1).then(function(record) {\n record.set(\'title\', \'toto2\');\n record.send(\'willCommit\');\n\n equal(get(record, \'isDirty\'), true, \"record is dirty\");\n\n expectAssertion(function() {\n record.unloadRecord();\n }, \"You can only unload a record which is not inFlight. `\" + Ember.inspect(record) + \"`\", \"can not unload dirty record\");\n\n // force back into safe to unload mode.\n run(function(){\n record.transitionTo(\'deleted.saved\');\n });\n });\n });\n});\n\ntest(\"unload a record\", function() {\n run(function(){\n store.push(Record, {id: 1, title: \'toto\'});\n store.find(Record, 1).then(function(record) {\n equal(get(record, \'id\'), 1, \"found record with id 1\");\n equal(get(record, \'isDirty\'), false, \"record is not dirty\");\n\n run(function(){\n store.unloadRecord(record);\n });\n\n equal(get(record, \'isDirty\'), false, \"record is not dirty\");\n equal(get(record, \'isDeleted\'), true, \"record is deleted\");\n\n tryToFind = false;\n return store.find(Record, 1).then(function(){\n equal(tryToFind, true, \"not found record with id 1\");\n });\n });\n });\n});\n\nmodule(\"DS.Store - unload record with relationships\");\n\n\ntest(\"can commit store after unload record with relationships\", function() {\n var like, product;\n\n var Brand = DS.Model.extend({\n name: DS.attr(\'string\')\n });\n\n var Product = DS.Model.extend({\n description: DS.attr(\'string\'),\n brand: DS.belongsTo(\'brand\')\n });\n\n var Like = DS.Model.extend({\n product: DS.belongsTo(\'product\')\n });\n\n var store = createStore({\n adapter: DS.Adapter.extend({\n find: function() {\n return Ember.RSVP.resolve({ id: 1, description: \'cuisinart\', brand: 1 });\n },\n createRecord: function(store, type, record) {\n return Ember.RSVP.resolve();\n }\n }),\n brand: Brand,\n product: Product,\n like: Like\n });\n var asyncRecords;\n\n run(function(){\n store.push(Brand, { id: 1, name: \'EmberJS\' });\n store.push(Product, { id: 1, description: \'toto\', brand: 1 });\n asyncRecords = Ember.RSVP.hash({\n brand: store.find(Brand, 1),\n product: store.find(Product, 1)\n });\n asyncRecords.then(function(records) {\n like = store.createRecord(Like, { id: 1, product: product });\n records.like = like.save();\n return Ember.RSVP.hash(records);\n }).then(function(records) {\n store.unloadRecord(records.product);\n return store.find(Product, 1);\n }).then(function(product) {\n equal(product.get(\'description\'), \'cuisinart\', \"The record was unloaded and the adapter\'s `find` was called\");\n store.destroy();\n });\n });\n});\n})();//# sourceURL=ember-data/unit/store/unload_test.js");
224
+
225
+ eval("(function() {module(\"unit/transform - DS.BooleanTransform\");\n\ntest(\"#serialize\", function() {\n var transform = new DS.BooleanTransform();\n\n equal(transform.serialize(null), false);\n equal(transform.serialize(undefined), false);\n\n equal(transform.serialize(true), true);\n equal(transform.serialize(false), false);\n});\n\ntest(\"#deserialize\", function() {\n var transform = new DS.BooleanTransform();\n\n equal(transform.deserialize(null), false);\n equal(transform.deserialize(undefined), false);\n\n equal(transform.deserialize(true), true);\n equal(transform.deserialize(false), false);\n\n equal(transform.deserialize(\"true\"), true);\n equal(transform.deserialize(\"TRUE\"), true);\n equal(transform.deserialize(\"false\"), false);\n equal(transform.deserialize(\"FALSE\"), false);\n\n equal(transform.deserialize(\"t\"), true);\n equal(transform.deserialize(\"T\"), true);\n equal(transform.deserialize(\"f\"), false);\n equal(transform.deserialize(\"F\"), false);\n\n equal(transform.deserialize(\"1\"), true);\n equal(transform.deserialize(\"0\"), false);\n\n equal(transform.deserialize(1), true);\n equal(transform.deserialize(2), false);\n equal(transform.deserialize(0), false);\n});\n})();//# sourceURL=ember-data/unit/transform/boolean_test.js");
226
+
227
+ eval("(function() {module(\"unit/transform - DS.DateTransform\");\n\nvar dateString = \"2015-01-01T00:00:00.000Z\";\nvar dateInMillis = Ember.Date.parse(dateString);\nvar date = new Date(dateInMillis);\n\ntest(\"#serialize\", function() {\n var transform = new DS.DateTransform();\n\n equal(transform.serialize(null), null);\n equal(transform.serialize(undefined), null);\n\n equal(transform.serialize(date), dateString);\n});\n\ntest(\"#deserialize\", function() {\n var transform = new DS.DateTransform();\n\n // from String\n equal(transform.deserialize(dateString).toISOString(), dateString);\n\n // from Number\n equal(transform.deserialize(dateInMillis).valueOf(), dateInMillis);\n\n // from other\n equal(transform.deserialize({}), null);\n\n // from none\n equal(transform.deserialize(null), null);\n equal(transform.deserialize(undefined), null);\n});\n})();//# sourceURL=ember-data/unit/transform/date_test.js");
228
+
229
+ eval("(function() {module(\"unit/transform - DS.NumberTransform\");\n\ntest(\"#serialize\", function() {\n var transform = new DS.NumberTransform();\n\n equal(transform.serialize(null), null);\n equal(transform.serialize(undefined), null);\n equal(transform.serialize(\"1.1\"), 1.1);\n equal(transform.serialize(1.1), 1.1);\n equal(transform.serialize(new Number(1.1)), 1.1);\n equal(transform.serialize(NaN), null);\n equal(transform.serialize(Infinity), null);\n equal(transform.serialize(-Infinity), null);\n});\n\ntest(\"#deserialize\", function() {\n var transform = new DS.NumberTransform();\n\n equal(transform.deserialize(null), null);\n equal(transform.deserialize(undefined), null);\n equal(transform.deserialize(\"1.1\"), 1.1);\n equal(transform.deserialize(1.1), 1.1);\n equal(transform.deserialize(new Number(1.1)), 1.1);\n equal(transform.deserialize(NaN), null);\n equal(transform.deserialize(Infinity), null);\n equal(transform.deserialize(-Infinity), null);\n});\n})();//# sourceURL=ember-data/unit/transform/number_test.js");
230
+
231
+ eval("(function() {module(\"unit/transform - DS.StringTransform\");\n\ntest(\"#serialize\", function() {\n var transform = new DS.StringTransform();\n\n equal(transform.serialize(null), null);\n equal(transform.serialize(undefined), null);\n\n equal(transform.serialize(\"foo\"), \"foo\");\n equal(transform.serialize(1), \"1\");\n});\n\ntest(\"#deserialize\", function() {\n var transform = new DS.StringTransform();\n\n equal(transform.deserialize(null), null);\n equal(transform.deserialize(undefined), null);\n\n equal(transform.deserialize(\"foo\"), \"foo\");\n equal(transform.deserialize(1), \"1\");\n});\n})();//# sourceURL=ember-data/unit/transform/string_test.js");
@@ -1,756 +1,478 @@
1
- (function(global){
2
- var enifed, requireModule, eriuqer, requirejs;
3
-
4
1
  (function() {
2
+ "use strict";
3
+ /**
4
+ @module ember-data
5
+ */
5
6
 
6
- var _isArray;
7
- if (!Array.isArray) {
8
- _isArray = function (x) {
9
- return Object.prototype.toString.call(x) === "[object Array]";
10
- };
11
- } else {
12
- _isArray = Array.isArray;
13
- }
14
-
15
- var registry = {}, seen = {}, state = {};
16
- var FAILED = false;
17
-
18
- enifed = function(name, deps, callback) {
19
-
20
- if (!_isArray(deps)) {
21
- callback = deps;
22
- deps = [];
23
- }
24
-
25
- registry[name] = {
26
- deps: deps,
27
- callback: callback
28
- };
29
- };
30
-
31
- function reify(deps, name, seen) {
32
- var length = deps.length;
33
- var reified = new Array(length);
34
- var dep;
35
- var exports;
36
-
37
- for (var i = 0, l = length; i < l; i++) {
38
- dep = deps[i];
39
- if (dep === 'exports') {
40
- exports = reified[i] = seen;
41
- } else {
42
- reified[i] = eriuqer(resolve(dep, name));
43
- }
44
- }
45
-
46
- return {
47
- deps: reified,
48
- exports: exports
49
- };
50
- }
51
-
52
- requirejs = eriuqer = requireModule = function(name) {
53
- if (state[name] !== FAILED &&
54
- seen.hasOwnProperty(name)) {
55
- return seen[name];
56
- }
7
+ var ember$data$lib$system$adapter$$get = Ember.get;
57
8
 
58
- if (!registry[name]) {
59
- throw new Error('Could not find module ' + name);
60
- }
9
+ var ember$data$lib$system$adapter$$errorProps = [
10
+ 'description',
11
+ 'fileName',
12
+ 'lineNumber',
13
+ 'message',
14
+ 'name',
15
+ 'number',
16
+ 'stack'
17
+ ];
61
18
 
62
- var mod = registry[name];
63
- var reified;
64
- var module;
65
- var loaded = false;
19
+ /**
20
+ A `DS.InvalidError` is used by an adapter to signal the external API
21
+ was unable to process a request because the content was not
22
+ semantically correct or meaningful per the API. Usually this means a
23
+ record failed some form of server side validation. When a promise
24
+ from an adapter is rejected with a `DS.InvalidError` the record will
25
+ transition to the `invalid` state and the errors will be set to the
26
+ `errors` property on the record.
66
27
 
67
- seen[name] = { }; // placeholder for run-time cycles
28
+ This function should return the entire payload as received from the
29
+ server. Error object extraction and normalization of model errors
30
+ should be performed by `extractErrors` on the serializer.
68
31
 
69
- try {
70
- reified = reify(mod.deps, name, seen[name]);
71
- module = mod.callback.apply(this, reified.deps);
72
- loaded = true;
73
- } finally {
74
- if (!loaded) {
75
- state[name] = FAILED;
76
- }
77
- }
32
+ Example
78
33
 
79
- return reified.exports ? seen[name] : (seen[name] = module);
80
- };
34
+ ```javascript
35
+ App.ApplicationAdapter = DS.RESTAdapter.extend({
36
+ ajaxError: function(jqXHR) {
37
+ var error = this._super(jqXHR);
81
38
 
82
- function resolve(child, name) {
83
- if (child.charAt(0) !== '.') { return child; }
39
+ if (jqXHR && jqXHR.status === 422) {
40
+ var jsonErrors = Ember.$.parseJSON(jqXHR.responseText);
41
+ return new DS.InvalidError(jsonErrors);
42
+ } else {
43
+ return error;
44
+ }
45
+ }
46
+ });
47
+ ```
84
48
 
85
- var parts = child.split('/');
86
- var nameParts = name.split('/');
87
- var parentBase;
49
+ The `DS.InvalidError` must be constructed with a single object whose
50
+ keys are the invalid model properties, and whose values are the
51
+ corresponding error messages. For example:
88
52
 
89
- if (nameParts.length === 1) {
90
- parentBase = nameParts;
91
- } else {
92
- parentBase = nameParts.slice(0, -1);
93
- }
53
+ ```javascript
54
+ return new DS.InvalidError({
55
+ length: 'Must be less than 15',
56
+ name: 'Must not be blank'
57
+ });
58
+ ```
94
59
 
95
- for (var i = 0, l = parts.length; i < l; i++) {
96
- var part = parts[i];
60
+ @class InvalidError
61
+ @namespace DS
62
+ */
63
+ function ember$data$lib$system$adapter$$InvalidError(errors) {
64
+ var tmp = Error.prototype.constructor.call(this, "The backend rejected the commit because it was invalid: " + Ember.inspect(errors));
65
+ this.errors = errors;
97
66
 
98
- if (part === '..') { parentBase.pop(); }
99
- else if (part === '.') { continue; }
100
- else { parentBase.push(part); }
67
+ for (var i=0, l=ember$data$lib$system$adapter$$errorProps.length; i<l; i++) {
68
+ this[ember$data$lib$system$adapter$$errorProps[i]] = tmp[ember$data$lib$system$adapter$$errorProps[i]];
69
+ }
101
70
  }
102
71
 
103
- return parentBase.join('/');
104
- }
105
-
106
- requirejs.entries = requirejs._eak_seen = registry;
107
- requirejs.clear = function(){
108
- requirejs.entries = requirejs._eak_seen = registry = {};
109
- seen = state = {};
110
- };
111
- })();
112
-
113
- enifed("activemodel-adapter",
114
- ["activemodel-adapter/system","exports"],
115
- function(__dependency1__, __exports__) {
116
- "use strict";
117
- var ActiveModelAdapter = __dependency1__.ActiveModelAdapter;
118
- var ActiveModelSerializer = __dependency1__.ActiveModelSerializer;
119
-
120
- __exports__.ActiveModelAdapter = ActiveModelAdapter;
121
- __exports__.ActiveModelSerializer = ActiveModelSerializer;
122
- });
123
- enifed("activemodel-adapter/setup-container",
124
- ["ember-data/system/container_proxy","activemodel-adapter/system/active_model_serializer","activemodel-adapter/system/active_model_adapter","exports"],
125
- function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
126
- "use strict";
127
- var ContainerProxy = __dependency1__["default"];
128
- var ActiveModelSerializer = __dependency2__["default"];
129
- var ActiveModelAdapter = __dependency3__["default"];
130
-
131
- __exports__["default"] = function setupActiveModelAdapter(container, application){
132
- var proxy = new ContainerProxy(container);
133
- proxy.registerDeprecations([
134
- { deprecated: 'serializer:_ams', valid: 'serializer:-active-model' },
135
- { deprecated: 'adapter:_ams', valid: 'adapter:-active-model' }
136
- ]);
137
-
138
- container.register('serializer:-active-model', ActiveModelSerializer);
139
- container.register('adapter:-active-model', ActiveModelAdapter);
140
- };
141
- });
142
- enifed("activemodel-adapter/system",
143
- ["activemodel-adapter/system/active_model_adapter","activemodel-adapter/system/active_model_serializer","exports"],
144
- function(__dependency1__, __dependency2__, __exports__) {
145
- "use strict";
146
- var ActiveModelAdapter = __dependency1__["default"];
147
- var ActiveModelSerializer = __dependency2__["default"];
148
-
149
- __exports__.ActiveModelAdapter = ActiveModelAdapter;
150
- __exports__.ActiveModelSerializer = ActiveModelSerializer;
151
- });
152
- enifed("activemodel-adapter/system/active_model_adapter",
153
- ["ember-data/adapters","ember-data/system/adapter","ember-inflector","exports"],
154
- function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
155
- "use strict";
156
- var RESTAdapter = __dependency1__.RESTAdapter;
157
- var InvalidError = __dependency2__.InvalidError;
158
- var pluralize = __dependency3__.pluralize;
159
-
160
- /**
161
- @module ember-data
162
- */
163
-
164
- var decamelize = Ember.String.decamelize,
165
- underscore = Ember.String.underscore;
72
+ ember$data$lib$system$adapter$$InvalidError.prototype = Ember.create(Error.prototype);
166
73
 
167
74
  /**
168
- The ActiveModelAdapter is a subclass of the RESTAdapter designed to integrate
169
- with a JSON API that uses an underscored naming convention instead of camelCasing.
170
- It has been designed to work out of the box with the
171
- [active_model_serializers](http://github.com/rails-api/active_model_serializers)
172
- Ruby gem. This Adapter expects specific settings using ActiveModel::Serializers,
173
- `embed :ids, embed_in_root: true` which sideloads the records.
174
-
175
- This adapter extends the DS.RESTAdapter by making consistent use of the camelization,
176
- decamelization and pluralization methods to normalize the serialized JSON into a
177
- format that is compatible with a conventional Rails backend and Ember Data.
178
-
179
- ## JSON Structure
75
+ An adapter is an object that receives requests from a store and
76
+ translates them into the appropriate action to take against your
77
+ persistence layer. The persistence layer is usually an HTTP API, but
78
+ may be anything, such as the browser's local storage. Typically the
79
+ adapter is not invoked directly instead its functionality is accessed
80
+ through the `store`.
180
81
 
181
- The ActiveModelAdapter expects the JSON returned from your server to follow
182
- the REST adapter conventions substituting underscored keys for camelcased ones.
82
+ ### Creating an Adapter
183
83
 
184
- Unlike the DS.RESTAdapter, async relationship keys must be the singular form
185
- of the relationship name, followed by "_id" for DS.belongsTo relationships,
186
- or "_ids" for DS.hasMany relationships.
84
+ Create a new subclass of `DS.Adapter`, then assign
85
+ it to the `ApplicationAdapter` property of the application.
187
86
 
188
- ### Conventional Names
87
+ ```javascript
88
+ var MyAdapter = DS.Adapter.extend({
89
+ // ...your code here
90
+ });
189
91
 
190
- Attribute names in your JSON payload should be the underscored versions of
191
- the attributes in your Ember.js models.
92
+ App.ApplicationAdapter = MyAdapter;
93
+ ```
192
94
 
193
- For example, if you have a `Person` model:
95
+ Model-specific adapters can be created by assigning your adapter
96
+ class to the `ModelName` + `Adapter` property of the application.
194
97
 
195
- ```js
196
- App.FamousPerson = DS.Model.extend({
197
- firstName: DS.attr('string'),
198
- lastName: DS.attr('string'),
199
- occupation: DS.attr('string')
98
+ ```javascript
99
+ var MyPostAdapter = DS.Adapter.extend({
100
+ // ...Post-specific adapter code goes here
200
101
  });
201
- ```
202
-
203
- The JSON returned should look like this:
204
102
 
205
- ```js
206
- {
207
- "famous_person": {
208
- "id": 1,
209
- "first_name": "Barack",
210
- "last_name": "Obama",
211
- "occupation": "President"
212
- }
213
- }
103
+ App.PostAdapter = MyPostAdapter;
214
104
  ```
215
105
 
216
- Let's imagine that `Occupation` is just another model:
106
+ `DS.Adapter` is an abstract base class that you should override in your
107
+ application to customize it for your backend. The minimum set of methods
108
+ that you should implement is:
217
109
 
218
- ```js
219
- App.Person = DS.Model.extend({
220
- firstName: DS.attr('string'),
221
- lastName: DS.attr('string'),
222
- occupation: DS.belongsTo('occupation')
223
- });
110
+ * `find()`
111
+ * `createRecord()`
112
+ * `updateRecord()`
113
+ * `deleteRecord()`
114
+ * `findAll()`
115
+ * `findQuery()`
224
116
 
225
- App.Occupation = DS.Model.extend({
226
- name: DS.attr('string'),
227
- salary: DS.attr('number'),
228
- people: DS.hasMany('person')
229
- });
230
- ```
117
+ To improve the network performance of your application, you can optimize
118
+ your adapter by overriding these lower-level methods:
231
119
 
232
- The JSON needed to avoid extra server calls, should look like this:
120
+ * `findMany()`
233
121
 
234
- ```js
235
- {
236
- "people": [{
237
- "id": 1,
238
- "first_name": "Barack",
239
- "last_name": "Obama",
240
- "occupation_id": 1
241
- }],
242
122
 
243
- "occupations": [{
244
- "id": 1,
245
- "name": "President",
246
- "salary": 100000,
247
- "person_ids": [1]
248
- }]
249
- }
250
- ```
123
+ For an example implementation, see `DS.RESTAdapter`, the
124
+ included REST adapter.
251
125
 
252
- @class ActiveModelAdapter
253
- @constructor
126
+ @class Adapter
254
127
  @namespace DS
255
- @extends DS.RESTAdapter
256
- **/
128
+ @extends Ember.Object
129
+ */
130
+
131
+ var ember$data$lib$system$adapter$$Adapter = Ember.Object.extend({
257
132
 
258
- var ActiveModelAdapter = RESTAdapter.extend({
259
- defaultSerializer: '-active-model',
260
133
  /**
261
- The ActiveModelAdapter overrides the `pathForType` method to build
262
- underscored URLs by decamelizing and pluralizing the object type name.
134
+ If you would like your adapter to use a custom serializer you can
135
+ set the `defaultSerializer` property to be the name of the custom
136
+ serializer.
263
137
 
264
- ```js
265
- this.pathForType("famousPerson");
266
- //=> "famous_people"
138
+ Note the `defaultSerializer` serializer has a lower priority than
139
+ a model specific serializer (i.e. `PostSerializer`) or the
140
+ `application` serializer.
141
+
142
+ ```javascript
143
+ var DjangoAdapter = DS.Adapter.extend({
144
+ defaultSerializer: 'django'
145
+ });
267
146
  ```
268
147
 
269
- @method pathForType
270
- @param {String} type
271
- @return String
148
+ @property defaultSerializer
149
+ @type {String}
272
150
  */
273
- pathForType: function(type) {
274
- var decamelized = decamelize(type);
275
- var underscored = underscore(decamelized);
276
- return pluralize(underscored);
277
- },
278
151
 
279
152
  /**
280
- The ActiveModelAdapter overrides the `ajaxError` method
281
- to return a DS.InvalidError for all 422 Unprocessable Entity
282
- responses.
153
+ The `find()` method is invoked when the store is asked for a record that
154
+ has not previously been loaded. In response to `find()` being called, you
155
+ should query your persistence layer for a record with the given ID. Once
156
+ found, you can asynchronously call the store's `push()` method to push
157
+ the record into the store.
283
158
 
284
- A 422 HTTP response from the server generally implies that the request
285
- was well formed but the API was unable to process it because the
286
- content was not semantically correct or meaningful per the API.
159
+ Here is an example `find` implementation:
287
160
 
288
- For more information on 422 HTTP Error code see 11.2 WebDAV RFC 4918
289
- https://tools.ietf.org/html/rfc4918#section-11.2
161
+ ```javascript
162
+ App.ApplicationAdapter = DS.Adapter.extend({
163
+ find: function(store, type, id) {
164
+ var url = [type.typeKey, id].join('/');
290
165
 
291
- @method ajaxError
292
- @param {Object} jqXHR
293
- @return error
294
- */
295
- ajaxError: function(jqXHR) {
296
- var error = this._super(jqXHR);
166
+ return new Ember.RSVP.Promise(function(resolve, reject) {
167
+ jQuery.getJSON(url).then(function(data) {
168
+ Ember.run(null, resolve, data);
169
+ }, function(jqXHR) {
170
+ jqXHR.then = null; // tame jQuery's ill mannered promises
171
+ Ember.run(null, reject, jqXHR);
172
+ });
173
+ });
174
+ }
175
+ });
176
+ ```
297
177
 
298
- if (jqXHR && jqXHR.status === 422) {
299
- return new InvalidError(Ember.$.parseJSON(jqXHR.responseText));
300
- } else {
301
- return error;
302
- }
303
- }
304
- });
305
-
306
- __exports__["default"] = ActiveModelAdapter;
307
- });
308
- enifed("activemodel-adapter/system/active_model_serializer",
309
- ["ember-inflector","ember-data/serializers/rest_serializer","exports"],
310
- function(__dependency1__, __dependency2__, __exports__) {
311
- "use strict";
312
- var singularize = __dependency1__.singularize;
313
- var RESTSerializer = __dependency2__["default"];
314
- /**
315
- @module ember-data
316
- */
317
-
318
- var get = Ember.get,
319
- forEach = Ember.EnumerableUtils.forEach,
320
- camelize = Ember.String.camelize,
321
- capitalize = Ember.String.capitalize,
322
- decamelize = Ember.String.decamelize,
323
- underscore = Ember.String.underscore;
324
- /**
325
- The ActiveModelSerializer is a subclass of the RESTSerializer designed to integrate
326
- with a JSON API that uses an underscored naming convention instead of camelCasing.
327
- It has been designed to work out of the box with the
328
- [active_model_serializers](http://github.com/rails-api/active_model_serializers)
329
- Ruby gem. This Serializer expects specific settings using ActiveModel::Serializers,
330
- `embed :ids, embed_in_root: true` which sideloads the records.
178
+ @method find
179
+ @param {DS.Store} store
180
+ @param {subclass of DS.Model} type
181
+ @param {String} id
182
+ @return {Promise} promise
183
+ */
184
+ find: Ember.required(Function),
331
185
 
332
- This serializer extends the DS.RESTSerializer by making consistent
333
- use of the camelization, decamelization and pluralization methods to
334
- normalize the serialized JSON into a format that is compatible with
335
- a conventional Rails backend and Ember Data.
186
+ /**
187
+ The `findAll()` method is called when you call `find` on the store
188
+ without an ID (i.e. `store.find('post')`).
336
189
 
337
- ## JSON Structure
190
+ Example
338
191
 
339
- The ActiveModelSerializer expects the JSON returned from your server
340
- to follow the REST adapter conventions substituting underscored keys
341
- for camelcased ones.
192
+ ```javascript
193
+ App.ApplicationAdapter = DS.Adapter.extend({
194
+ findAll: function(store, type, sinceToken) {
195
+ var url = type;
196
+ var query = { since: sinceToken };
197
+ return new Ember.RSVP.Promise(function(resolve, reject) {
198
+ jQuery.getJSON(url, query).then(function(data) {
199
+ Ember.run(null, resolve, data);
200
+ }, function(jqXHR) {
201
+ jqXHR.then = null; // tame jQuery's ill mannered promises
202
+ Ember.run(null, reject, jqXHR);
203
+ });
204
+ });
205
+ }
206
+ });
207
+ ```
342
208
 
343
- ### Conventional Names
209
+ @private
210
+ @method findAll
211
+ @param {DS.Store} store
212
+ @param {subclass of DS.Model} type
213
+ @param {String} sinceToken
214
+ @return {Promise} promise
215
+ */
216
+ findAll: null,
344
217
 
345
- Attribute names in your JSON payload should be the underscored versions of
346
- the attributes in your Ember.js models.
218
+ /**
219
+ This method is called when you call `find` on the store with a
220
+ query object as the second parameter (i.e. `store.find('person', {
221
+ page: 1 })`).
347
222
 
348
- For example, if you have a `Person` model:
223
+ Example
349
224
 
350
- ```js
351
- App.FamousPerson = DS.Model.extend({
352
- firstName: DS.attr('string'),
353
- lastName: DS.attr('string'),
354
- occupation: DS.attr('string')
355
- });
356
- ```
225
+ ```javascript
226
+ App.ApplicationAdapter = DS.Adapter.extend({
227
+ findQuery: function(store, type, query) {
228
+ var url = type;
229
+ return new Ember.RSVP.Promise(function(resolve, reject) {
230
+ jQuery.getJSON(url, query).then(function(data) {
231
+ Ember.run(null, resolve, data);
232
+ }, function(jqXHR) {
233
+ jqXHR.then = null; // tame jQuery's ill mannered promises
234
+ Ember.run(null, reject, jqXHR);
235
+ });
236
+ });
237
+ }
238
+ });
239
+ ```
357
240
 
358
- The JSON returned should look like this:
241
+ @private
242
+ @method findQuery
243
+ @param {DS.Store} store
244
+ @param {subclass of DS.Model} type
245
+ @param {Object} query
246
+ @param {DS.AdapterPopulatedRecordArray} recordArray
247
+ @return {Promise} promise
248
+ */
249
+ findQuery: null,
359
250
 
360
- ```js
361
- {
362
- "famous_person": {
363
- "id": 1,
364
- "first_name": "Barack",
365
- "last_name": "Obama",
366
- "occupation": "President"
367
- }
368
- }
369
- ```
251
+ /**
252
+ If the globally unique IDs for your records should be generated on the client,
253
+ implement the `generateIdForRecord()` method. This method will be invoked
254
+ each time you create a new record, and the value returned from it will be
255
+ assigned to the record's `primaryKey`.
370
256
 
371
- Let's imagine that `Occupation` is just another model:
257
+ Most traditional REST-like HTTP APIs will not use this method. Instead, the ID
258
+ of the record will be set by the server, and your adapter will update the store
259
+ with the new ID when it calls `didCreateRecord()`. Only implement this method if
260
+ you intend to generate record IDs on the client-side.
372
261
 
373
- ```js
374
- App.Person = DS.Model.extend({
375
- firstName: DS.attr('string'),
376
- lastName: DS.attr('string'),
377
- occupation: DS.belongsTo('occupation')
378
- });
262
+ The `generateIdForRecord()` method will be invoked with the requesting store as
263
+ the first parameter and the newly created record as the second parameter:
379
264
 
380
- App.Occupation = DS.Model.extend({
381
- name: DS.attr('string'),
382
- salary: DS.attr('number'),
383
- people: DS.hasMany('person')
384
- });
385
- ```
265
+ ```javascript
266
+ generateIdForRecord: function(store, record) {
267
+ var uuid = App.generateUUIDWithStatisticallyLowOddsOfCollision();
268
+ return uuid;
269
+ }
270
+ ```
386
271
 
387
- The JSON needed to avoid extra server calls, should look like this:
272
+ @method generateIdForRecord
273
+ @param {DS.Store} store
274
+ @param {DS.Model} record
275
+ @return {String|Number} id
276
+ */
277
+ generateIdForRecord: null,
388
278
 
389
- ```js
390
- {
391
- "people": [{
392
- "id": 1,
393
- "first_name": "Barack",
394
- "last_name": "Obama",
395
- "occupation_id": 1
396
- }],
279
+ /**
280
+ Proxies to the serializer's `serialize` method.
397
281
 
398
- "occupations": [{
399
- "id": 1,
400
- "name": "President",
401
- "salary": 100000,
402
- "person_ids": [1]
403
- }]
404
- }
405
- ```
282
+ Example
406
283
 
407
- @class ActiveModelSerializer
408
- @namespace DS
409
- @extends DS.RESTSerializer
410
- */
411
- var ActiveModelSerializer = RESTSerializer.extend({
412
- // SERIALIZE
284
+ ```javascript
285
+ App.ApplicationAdapter = DS.Adapter.extend({
286
+ createRecord: function(store, type, record) {
287
+ var data = this.serialize(record, { includeId: true });
288
+ var url = type;
413
289
 
414
- /**
415
- Converts camelCased attributes to underscored when serializing.
290
+ // ...
291
+ }
292
+ });
293
+ ```
416
294
 
417
- @method keyForAttribute
418
- @param {String} attribute
419
- @return String
295
+ @method serialize
296
+ @param {DS.Model} record
297
+ @param {Object} options
298
+ @return {Object} serialized record
420
299
  */
421
- keyForAttribute: function(attr) {
422
- return decamelize(attr);
300
+ serialize: function(record, options) {
301
+ return ember$data$lib$system$adapter$$get(record, 'store').serializerFor(record.constructor.typeKey).serialize(record, options);
423
302
  },
424
303
 
425
304
  /**
426
- Underscores relationship names and appends "_id" or "_ids" when serializing
427
- relationship keys.
305
+ Implement this method in a subclass to handle the creation of
306
+ new records.
428
307
 
429
- @method keyForRelationship
430
- @param {String} key
431
- @param {String} kind
432
- @return String
433
- */
434
- keyForRelationship: function(rawKey, kind) {
435
- var key = decamelize(rawKey);
436
- if (kind === "belongsTo") {
437
- return key + "_id";
438
- } else if (kind === "hasMany") {
439
- return singularize(key) + "_ids";
440
- } else {
441
- return key;
442
- }
443
- },
308
+ Serializes the record and send it to the server.
444
309
 
445
- /*
446
- Does not serialize hasMany relationships by default.
447
- */
448
- serializeHasMany: Ember.K,
310
+ Example
449
311
 
450
- /**
451
- Underscores the JSON root keys when serializing.
312
+ ```javascript
313
+ App.ApplicationAdapter = DS.Adapter.extend({
314
+ createRecord: function(store, type, record) {
315
+ var data = this.serialize(record, { includeId: true });
316
+ var url = type;
452
317
 
453
- @method serializeIntoHash
454
- @param {Object} hash
455
- @param {subclass of DS.Model} type
318
+ return new Ember.RSVP.Promise(function(resolve, reject) {
319
+ jQuery.ajax({
320
+ type: 'POST',
321
+ url: url,
322
+ dataType: 'json',
323
+