From 9775d21b8d51e39e01ac9cc953dac04b31c026ed Mon Sep 17 00:00:00 2001 From: Sebastien Tisserant Date: Wed, 16 Sep 2015 11:44:54 +0200 Subject: [PATCH 1/9] Reformat code Using jsbeautifier with default settings --- tests/integration/crud-test.js | 290 ++++++++++++++++++++------------- 1 file changed, 173 insertions(+), 117 deletions(-) diff --git a/tests/integration/crud-test.js b/tests/integration/crud-test.js index 1dd390f..a8b8686 100644 --- a/tests/integration/crud-test.js +++ b/tests/integration/crud-test.js @@ -1,5 +1,8 @@ import Ember from 'ember'; -import { test } from 'ember-qunit'; +import { + test +} +from 'ember-qunit'; import startApp from '../helpers/start-app'; import FIXTURES from '../helpers/fixtures/crud'; @@ -12,15 +15,15 @@ var get = Ember.get; var set = Ember.set; module('CRUD', { - setup: function () { + setup: function() { stop(); - run(function () { - window.localforage.setItem('DS.LFAdapter', FIXTURES).then(function () { + run(function() { + window.localforage.setItem('DS.LFAdapter', FIXTURES).then(function() { start(); }); }); - run(function () { + run(function() { App = startApp(); store = App.__container__.lookup('service:store'); adapter = App.__container__.lookup('adapter:application'); @@ -28,18 +31,18 @@ module('CRUD', { }); }, - teardown: function () { + teardown: function() { run(App, 'destroy'); } }); -test('findRecord with id', function () { +test('findRecord with id', function() { expect(4); stop(); - run(function () { - store.findRecord('list', 'l1').then(function (list) { + run(function() { + store.findRecord('list', 'l1').then(function(list) { equal(get(list, 'id'), 'l1', 'id is loaded correctly'); equal(get(list, 'name'), 'one', 'name is loaded correctly'); equal(get(list, 'b'), true, 'b is loaded correctly'); @@ -50,59 +53,76 @@ test('findRecord with id', function () { }); -test('query', function () { +test('query', function() { stop(); - run(function () { - store.query('list', {name: /one|two/}).then(function (records) { + run(function() { + store.query('list', { + name: /one|two/ + }).then(function(records) { equal(get(records, 'length'), 2, 'found results for /one|two/'); start(); }); }); stop(); - run(function () { - store.query('list', {name: /.+/, id: /l1/}).then(function (records) { + run(function() { + store.query('list', { + name: /.+/, + id: /l1/ + }).then(function(records) { equal(get(records, 'length'), 1, 'found results for {name: /.+/, id: /l1/}'); start(); }); }); stop(); - run(function () { - store.query('list', {name: 'one'}).then(function (records) { + run(function() { + store.query('list', { + name: 'one' + }).then(function(records) { equal(get(records, 'length'), 1, 'found results for name "one"'); start(); }); }); stop(); - run(function () { - store.query('list', {b: true}).then(function (records) { + run(function() { + store.query('list', { + b: true + }).then(function(records) { equal(get(records, 'length'), 1, 'found results for {b: true}'); start(); }); }); stop(); - run(function () { - store.query('list', {name: 'two', b: false}).then(function (records) { + run(function() { + store.query('list', { + name: 'two', + b: false + }).then(function(records) { equal(get(records, 'length'), 1, 'found results for multiple criteria'); start(); }); }); stop(); - run(function () { - store.query('list', {name: 'four', b: false}).then(function (records) { + run(function() { + store.query('list', { + name: 'four', + b: false + }).then(function(records) { equal(get(records, 'length'), 0, 'found no results when only criteria matches'); start(); }); }); stop(); - run(function () { - store.query('list', {whatever: "dude"}).then(function (records) { + run(function() { + store.query('list', { + whatever: "dude" + }).then(function(records) { equal(get(records, 'length'), 0, 'didn\'t find results for nonsense'); start(); }); @@ -110,11 +130,13 @@ test('query', function () { }); -test('queryRecord', function () { +test('queryRecord', function() { stop(); - run(function () { - store.queryRecord('list', {name: 'one'}).then(function (list) { + run(function() { + store.queryRecord('list', { + name: 'one' + }).then(function(list) { equal(get(list, 'id'), 'l1', 'id is loaded correctly'); equal(get(list, 'name'), 'one', 'name is loaded correctly'); equal(get(list, 'b'), true, 'b is loaded correctly'); @@ -124,21 +146,22 @@ test('queryRecord', function () { }); stop(); - run(function () { - store.queryRecord('list', {whatever: "dude"}).catch(function (err) { - ok(true, "didn't find record for nonsense"); - start(); - } - ); + run(function() { + store.queryRecord('list', { + whatever: "dude" + }).catch(function(err) { + ok(true, "didn't find record for nonsense"); + start(); + }); }); }); -test('findAll', function () { +test('findAll', function() { expect(7); stop(); - run(function () { - store.findAll('list').then(function (records) { + run(function() { + store.findAll('list').then(function(records) { var firstRecord = records.objectAt(0), secondRecord = records.objectAt(1), thirdRecord = records.objectAt(2); @@ -159,11 +182,13 @@ test('findAll', function () { }); -test('queryMany', function () { +test('queryMany', function() { expect(11); stop(); - run(function () { - store.query('order', {b: true}).then(function (records) { + run(function() { + store.query('order', { + b: true + }).then(function(records) { var firstRecord = records.objectAt(0), secondRecord = records.objectAt(1), thirdRecord = records.objectAt(2); @@ -194,17 +219,25 @@ test('queryMany', function () { }); }); -test('push', function () { +test('push', function() { expect(3); stop(); - run(function () { - var list = store.push({type: 'list', id: adapter.generateIdForRecord(), attributes: {name: 'Rambo'}}); + run(function() { + var list = store.push({ + type: 'list', + id: adapter.generateIdForRecord(), + attributes: { + name: 'Rambo' + } + }); - list.save().then(function (record) { + list.save().then(function(record) { - store.query('list', {name: 'Rambo'}).then(function (records) { + store.query('list', { + name: 'Rambo' + }).then(function(records) { var record = records.objectAt(0); equal(get(records, 'length'), 1, "Only Rambo was found"); @@ -216,17 +249,21 @@ test('push', function () { }); }); -test('createRecord', function () { +test('createRecord', function() { expect(3); stop(); - run(function () { - var list = store.createRecord('list', {name: 'Rambo'}); + run(function() { + var list = store.createRecord('list', { + name: 'Rambo' + }); - list.save().then(function (record) { + list.save().then(function(record) { - store.query('list', {name: 'Rambo'}).then(function (records) { + store.query('list', { + name: 'Rambo' + }).then(function(records) { var record = records.objectAt(0); equal(get(records, 'length'), 1, "Only Rambo was found"); @@ -238,23 +275,29 @@ test('createRecord', function () { }); }); -test('updateRecords', function () { +test('updateRecords', function() { expect(3); stop(); - run(function () { - var list = store.createRecord('list', {name: 'Rambo'}); + run(function() { + var list = store.createRecord('list', { + name: 'Rambo' + }); - var UpdateList = function (list) { - return store.query('list', {name: 'Rambo'}).then(function (records) { + var UpdateList = function(list) { + return store.query('list', { + name: 'Rambo' + }).then(function(records) { var record = records.objectAt(0); record.set('name', 'Macgyver'); return record.save(); }); }; - var AssertListIsUpdated = function () { - return store.query('list', {name: 'Macgyver'}).then(function (records) { + var AssertListIsUpdated = function() { + return store.query('list', { + name: 'Macgyver' + }).then(function(records) { var record = records.objectAt(0); equal(get(records, 'length'), 1, "Only one record was found"); @@ -270,19 +313,23 @@ test('updateRecords', function () { }); -test('deleteRecord', function () { +test('deleteRecord', function() { expect(2); stop(); - run(function () { - var AssertListIsDeleted = function () { - return store.query('list', {name: 'one'}).then(function (records) { + run(function() { + var AssertListIsDeleted = function() { + return store.query('list', { + name: 'one' + }).then(function(records) { equal(get(records, 'length'), 0, "No record was found"); start(); }); }; - store.query('list', {name: 'one'}).then(function (lists) { + store.query('list', { + name: 'one' + }).then(function(lists) { var list = lists.objectAt(0); equal(get(list, "id"), "l1", "Item exists"); @@ -294,28 +341,30 @@ test('deleteRecord', function () { }); }); -test('changes in bulk', function () { +test('changes in bulk', function() { stop(); - run(function () { + run(function() { - var listToUpdate = new Ember.RSVP.Promise(function (resolve, reject) { - store.findRecord('list', 'l1').then(function (list) { + var listToUpdate = new Ember.RSVP.Promise(function(resolve, reject) { + store.findRecord('list', 'l1').then(function(list) { list.set('name', 'updated'); - list.save().then(function () { + list.save().then(function() { resolve(); }); }); }); - var listToCreate = new Ember.RSVP.Promise(function (resolve, reject) { - store.createRecord('list', {name: 'Rambo'}).save().then(function () { + var listToCreate = new Ember.RSVP.Promise(function(resolve, reject) { + store.createRecord('list', { + name: 'Rambo' + }).save().then(function() { resolve(); }); }); - var listToDelete = new Ember.RSVP.Promise(function (resolve, reject) { - store.findRecord('list', 'l2').then(function (list) { - list.destroyRecord().then(function () { + var listToDelete = new Ember.RSVP.Promise(function(resolve, reject) { + store.findRecord('list', 'l2').then(function(list) { + list.destroyRecord().then(function() { resolve(); }); }); @@ -327,13 +376,13 @@ test('changes in bulk', function () { listToDelete ]; - Ember.RSVP.all(promises).then(function () { + Ember.RSVP.all(promises).then(function() { promises = Ember.A(); promises.push( - new Ember.RSVP.Promise(function (resolve, reject) { - store.findRecord('list', 'l1').then(function (list) { + new Ember.RSVP.Promise(function(resolve, reject) { + store.findRecord('list', 'l1').then(function(list) { equal(get(list, 'name'), 'updated', "Record was updated successfully"); resolve(); }); @@ -341,8 +390,10 @@ test('changes in bulk', function () { ); promises.push( - new Ember.RSVP.Promise(function (resolve, reject) { - store.query('list', {name: 'Rambo'}).then(function (lists) { + new Ember.RSVP.Promise(function(resolve, reject) { + store.query('list', { + name: 'Rambo' + }).then(function(lists) { equal(get(lists, 'length'), 1, "Record was created successfully"); resolve(); }); @@ -350,16 +401,15 @@ test('changes in bulk', function () { ); promises.push( - new Ember.RSVP.Promise(function (resolve, reject) { - store.findRecord('list', 'l2').catch(function (err) { - ok(true, "Record was deleted successfully"); - resolve(); - } - ); + new Ember.RSVP.Promise(function(resolve, reject) { + store.findRecord('list', 'l2').catch(function(err) { + ok(true, "Record was deleted successfully"); + resolve(); + }); }) ); - Ember.RSVP.all(promises).then(function () { + Ember.RSVP.all(promises).then(function() { start(); }); }); @@ -367,12 +417,12 @@ test('changes in bulk', function () { }); -test('load hasMany association', function () { +test('load hasMany association', function() { expect(4); stop(); - run(function () { - store.findRecord('list', 'l1').then(function (list) { + run(function() { + store.findRecord('list', 'l1').then(function(list) { var items = list.get('items'); var item1 = items.get('firstObject'), @@ -389,14 +439,14 @@ test('load hasMany association', function () { }); -test('load belongsTo association', function () { +test('load belongsTo association', function() { stop(); - run(function () { - store.findRecord('item', 'i1').then(function (item) { - return new Ember.RSVP.Promise(function (resolve) { + run(function() { + store.findRecord('item', 'i1').then(function(item) { + return new Ember.RSVP.Promise(function(resolve) { resolve(get(item, 'list')); }); - }).then(function (list) { + }).then(function(list) { equal(get(list, 'id'), 'l1', "id is loaded correctly"); equal(get(list, 'name'), 'one', "name is loaded correctly"); @@ -406,21 +456,23 @@ test('load belongsTo association', function () { }); -test('saves belongsTo', function () { +test('saves belongsTo', function() { var item, listId = 'l2'; stop(); - run(function () { - store.findRecord('list', listId).then(function (list) { - item = store.createRecord('item', {name: 'three thousand'}); + run(function() { + store.findRecord('list', listId).then(function(list) { + item = store.createRecord('item', { + name: 'three thousand' + }); item.set('list', list); return item.save(); - }).then(function (item) { + }).then(function(item) { store.unloadAll('item'); return store.findRecord('item', item.get('id')); - }).then(function (item) { + }).then(function(item) { var list = item.get('list'); ok(item.get('list'), 'list is present'); equal(list.id, listId, 'list is retrieved correctly'); @@ -429,24 +481,26 @@ test('saves belongsTo', function () { }); }); -test('saves hasMany', function () { +test('saves hasMany', function() { var item, list, listId = 'l2'; stop(); - run(function () { - store.findRecord('list', listId).then(function (list) { - item = store.createRecord('item', {name: 'three thousand'}); + run(function() { + store.findRecord('list', listId).then(function(list) { + item = store.createRecord('item', { + name: 'three thousand' + }); list.get('items').pushObject(item); return list.save(); - }).then(function (list) { + }).then(function(list) { return item.save(); - }).then(function (item) { + }).then(function(item) { store.unloadAll('list'); return store.findRecord('list', listId); - }).then(function (list) { + }).then(function(list) { var items = list.get('items'), item1 = items.objectAt(0); @@ -456,13 +510,13 @@ test('saves hasMany', function () { }); }); -test("loads embedded hasMany in a 'find with id' operation", function () { +test("loads embedded hasMany in a 'find with id' operation", function() { expect(5); stop(); - run(function () { - store.findRecord('customer', '1').then(function (customer) { + run(function() { + store.findRecord('customer', '1').then(function(customer) { var addresses = customer.get('addresses'); equal(addresses.length, 2); @@ -483,13 +537,13 @@ test("loads embedded hasMany in a 'find with id' operation", function () { }); }); -test("loads embedded hasMany in a 'find all' operation", function () { +test("loads embedded hasMany in a 'find all' operation", function() { expect(6); stop(); - run(function () { - store.findAll('customer').then(function (customers) { + run(function() { + store.findAll('customer').then(function(customers) { equal(get(customers, 'length'), 1, 'one customer was retrieved'); var customer = customers.objectAt(0); @@ -513,13 +567,15 @@ test("loads embedded hasMany in a 'find all' operation", function () { }); }); -test("loads embedded hasMany in a 'find many' operation", function () { +test("loads embedded hasMany in a 'find many' operation", function() { expect(6); stop(); - run(function () { - store.query('customer', {customerNumber: '123'}).then(function (customers) { + run(function() { + store.query('customer', { + customerNumber: '123' + }).then(function(customers) { equal(get(customers, 'length'), 1); var customer = customers.objectAt(0); @@ -543,13 +599,13 @@ test("loads embedded hasMany in a 'find many' operation", function () { }); }); -test("loads embedded belongsTo in a 'find with id' operation", function () { +test("loads embedded belongsTo in a 'find with id' operation", function() { expect(2); stop(); - run(function () { - store.findRecord('customer', '1').then(function (customer) { + run(function() { + store.findRecord('customer', '1').then(function(customer) { var hour = customer.get('hour'); equal(get(hour, 'id'), 'h5', @@ -560,4 +616,4 @@ test("loads embedded belongsTo in a 'find with id' operation", function () { start(); }); }); -}); +}); \ No newline at end of file From 2fb10189c4a75da49553cb0ad92e9fcd40ba753c Mon Sep 17 00:00:00 2001 From: Sebastien Tisserant Date: Wed, 16 Sep 2015 12:19:37 +0200 Subject: [PATCH 2/9] Regroup tests by kind and split them with help of comments The goal is to identify more clearly whether tests could be missing or not --- tests/integration/crud-test.js | 646 +++++++++++++++++---------------- 1 file changed, 328 insertions(+), 318 deletions(-) diff --git a/tests/integration/crud-test.js b/tests/integration/crud-test.js index a8b8686..5e8ec4d 100644 --- a/tests/integration/crud-test.js +++ b/tests/integration/crud-test.js @@ -36,6 +36,157 @@ module('CRUD', { } }); +// Lifecycle methods +// ----------------------------------------------------------------------------- + +test('push', function() { + expect(3); + stop(); + + run(function() { + var list = store.push({ + type: 'list', + id: adapter.generateIdForRecord(), + attributes: { + name: 'Rambo' + } + }); + + list.save().then(function(record) { + + + store.query('list', { + name: 'Rambo' + }).then(function(records) { + var record = records.objectAt(0); + + equal(get(records, 'length'), 1, "Only Rambo was found"); + equal(get(record, 'name'), "Rambo", "Correct name"); + equal(get(record, 'id'), list.id, "Correct, original id"); + start(); + }); + }); + }); +}); + +test('createRecord', function() { + expect(3); + stop(); + + run(function() { + var list = store.createRecord('list', { + name: 'Rambo' + }); + + list.save().then(function(record) { + + + store.query('list', { + name: 'Rambo' + }).then(function(records) { + var record = records.objectAt(0); + + equal(get(records, 'length'), 1, "Only Rambo was found"); + equal(get(record, 'name'), "Rambo", "Correct name"); + equal(get(record, 'id'), list.id, "Correct, original id"); + start(); + }); + }); + }); +}); + +test('updateRecords', function() { + expect(3); + stop(); + + run(function() { + var list = store.createRecord('list', { + name: 'Rambo' + }); + + var UpdateList = function(list) { + return store.query('list', { + name: 'Rambo' + }).then(function(records) { + var record = records.objectAt(0); + record.set('name', 'Macgyver'); + return record.save(); + }); + }; + + var AssertListIsUpdated = function() { + return store.query('list', { + name: 'Macgyver' + }).then(function(records) { + var record = records.objectAt(0); + + equal(get(records, 'length'), 1, "Only one record was found"); + equal(get(record, 'name'), "Macgyver", "Updated name shows up"); + equal(get(record, 'id'), list.id, "Correct, original id"); + + start(); + }); + }; + + list.save().then(UpdateList).then(AssertListIsUpdated); + }); +}); + +test('deleteRecord', function() { + expect(2); + stop(); + + run(function() { + var AssertListIsDeleted = function() { + return store.query('list', { + name: 'one' + }).then(function(records) { + equal(get(records, 'length'), 0, "No record was found"); + start(); + }); + }; + + store.query('list', { + name: 'one' + }).then(function(lists) { + var list = lists.objectAt(0); + + equal(get(list, "id"), "l1", "Item exists"); + + list.deleteRecord(); + list.on("didDelete", AssertListIsDeleted); + list.save(); + }); + }); +}); + +// Find methods +// ----------------------------------------------------------------------------- + +test('findAll', function() { + expect(7); + + stop(); + run(function() { + store.findAll('list').then(function(records) { + var firstRecord = records.objectAt(0), + secondRecord = records.objectAt(1), + thirdRecord = records.objectAt(2); + + equal(get(records, 'length'), 3, "3 items were found"); + + equal(get(firstRecord, 'name'), "one", "First item's name is one"); + equal(get(secondRecord, 'name'), "two", "Second item's name is two"); + equal(get(thirdRecord, 'name'), "three", "Third item's name is three"); + + equal(get(firstRecord, 'day'), 1, "First item's day is 1"); + equal(get(secondRecord, 'day'), 2, "Second item's day is 2"); + equal(get(thirdRecord, 'day'), 3, "Third item's day is 3"); + + start(); + }); + }); +}); test('findRecord with id', function() { expect(4); @@ -52,6 +203,8 @@ test('findRecord with id', function() { }); }); +// Query methods +// ----------------------------------------------------------------------------- test('query', function() { @@ -129,7 +282,6 @@ test('query', function() { }); }); - test('queryRecord', function() { stop(); @@ -156,305 +308,193 @@ test('queryRecord', function() { }); }); -test('findAll', function() { - expect(7); +// Relationship loading +//------------------------------------------------------------------------------ +test('load hasMany association', function() { + expect(4); stop(); - run(function() { - store.findAll('list').then(function(records) { - var firstRecord = records.objectAt(0), - secondRecord = records.objectAt(1), - thirdRecord = records.objectAt(2); - equal(get(records, 'length'), 3, "3 items were found"); + run(function() { + store.findRecord('list', 'l1').then(function(list) { + var items = list.get('items'); - equal(get(firstRecord, 'name'), "one", "First item's name is one"); - equal(get(secondRecord, 'name'), "two", "Second item's name is two"); - equal(get(thirdRecord, 'name'), "three", "Third item's name is three"); + var item1 = items.get('firstObject'), + item2 = items.get('lastObject'); - equal(get(firstRecord, 'day'), 1, "First item's day is 1"); - equal(get(secondRecord, 'day'), 2, "Second item's day is 2"); - equal(get(thirdRecord, 'day'), 3, "Third item's day is 3"); + equal(get(item1, 'id'), 'i1', 'first item id is loaded correctly'); + equal(get(item1, 'name'), 'one', 'first item name is loaded correctly'); + equal(get(item2, 'id'), 'i2', 'first item id is loaded correctly'); + equal(get(item2, 'name'), 'two', 'first item name is loaded correctly'); start(); }); }); }); - -test('queryMany', function() { - expect(11); +test('load belongsTo association', function() { stop(); run(function() { - store.query('order', { - b: true - }).then(function(records) { - var firstRecord = records.objectAt(0), - secondRecord = records.objectAt(1), - thirdRecord = records.objectAt(2); - - equal(get(records, 'length'), 3, "3 orders were found"); - equal(get(firstRecord, 'name'), "one", "First order's name is one"); - equal(get(secondRecord, 'name'), "three", "Second order's name is three"); - equal(get(thirdRecord, 'name'), "four", "Third order's name is four"); - var firstHours = firstRecord.get('hours'), - secondHours = secondRecord.get('hours'), - thirdHours = thirdRecord.get('hours'); - - equal(get(firstHours, 'length'), 2, "Order one has two hours"); - equal(get(secondHours, 'length'), 2, "Order three has two hours"); - equal(get(thirdHours, 'length'), 0, "Order four has no hours"); - - var hourOne = firstHours.objectAt(0), - hourTwo = firstHours.objectAt(1), - hourThree = secondHours.objectAt(0), - hourFour = secondHours.objectAt(1); - equal(get(hourOne, 'amount'), 4, "Hour one has amount of 4"); - equal(get(hourTwo, 'amount'), 3, "Hour two has amount of 3"); - equal(get(hourThree, 'amount'), 2, "Hour three has amount of 2"); - equal(get(hourFour, 'amount'), 1, "Hour four has amount of 1"); + store.findRecord('item', 'i1').then(function(item) { + return new Ember.RSVP.Promise(function(resolve) { + resolve(get(item, 'list')); + }); + }).then(function(list) { + equal(get(list, 'id'), 'l1', "id is loaded correctly"); + equal(get(list, 'name'), 'one', "name is loaded correctly"); start(); }); }); }); -test('push', function() { - expect(3); +test("loads embedded hasMany in a 'find with id' operation", function() { + expect(5); + stop(); run(function() { - var list = store.push({ - type: 'list', - id: adapter.generateIdForRecord(), - attributes: { - name: 'Rambo' - } - }); - - list.save().then(function(record) { + store.findRecord('customer', '1').then(function(customer) { + var addresses = customer.get('addresses'); + equal(addresses.length, 2); + var address1 = addresses.get('firstObject'), + address2 = addresses.get('lastObject'); - store.query('list', { - name: 'Rambo' - }).then(function(records) { - var record = records.objectAt(0); + equal(get(address1, 'id'), '1', + 'first address id is loaded correctly'); + equal(get(address1, 'addressNumber'), '12345', + 'first address number is loaded correctly'); + equal(get(address2, 'id'), '2', + 'first address id is loaded correctly'); + equal(get(address2, 'addressNumber'), '54321', + 'first address number is loaded correctly'); - equal(get(records, 'length'), 1, "Only Rambo was found"); - equal(get(record, 'name'), "Rambo", "Correct name"); - equal(get(record, 'id'), list.id, "Correct, original id"); - start(); - }); + start(); }); }); }); -test('createRecord', function() { - expect(3); +test("loads embedded hasMany in a 'find all' operation", function() { + expect(6); + stop(); run(function() { - var list = store.createRecord('list', { - name: 'Rambo' - }); + store.findAll('customer').then(function(customers) { + equal(get(customers, 'length'), 1, 'one customer was retrieved'); - list.save().then(function(record) { + var customer = customers.objectAt(0); + var addresses = customer.get('addresses'); + equal(addresses.length, 2); + var address1 = addresses.get('firstObject'), + address2 = addresses.get('lastObject'); - store.query('list', { - name: 'Rambo' - }).then(function(records) { - var record = records.objectAt(0); + equal(get(address1, 'id'), '1', + 'first address id is loaded correctly'); + equal(get(address1, 'addressNumber'), '12345', + 'first address number is loaded correctly'); + equal(get(address2, 'id'), '2', + 'first address id is loaded correctly'); + equal(get(address2, 'addressNumber'), '54321', + 'first address number is loaded correctly'); - equal(get(records, 'length'), 1, "Only Rambo was found"); - equal(get(record, 'name'), "Rambo", "Correct name"); - equal(get(record, 'id'), list.id, "Correct, original id"); - start(); - }); + start(); }); }); }); -test('updateRecords', function() { - expect(3); - stop(); - - run(function() { - var list = store.createRecord('list', { - name: 'Rambo' - }); - - var UpdateList = function(list) { - return store.query('list', { - name: 'Rambo' - }).then(function(records) { - var record = records.objectAt(0); - record.set('name', 'Macgyver'); - return record.save(); - }); - }; - - var AssertListIsUpdated = function() { - return store.query('list', { - name: 'Macgyver' - }).then(function(records) { - var record = records.objectAt(0); - - equal(get(records, 'length'), 1, "Only one record was found"); - equal(get(record, 'name'), "Macgyver", "Updated name shows up"); - equal(get(record, 'id'), list.id, "Correct, original id"); - - start(); - }); - }; - - list.save().then(UpdateList).then(AssertListIsUpdated); - }); -}); - +test("loads embedded hasMany in a 'find many' operation", function() { + expect(6); -test('deleteRecord', function() { - expect(2); stop(); run(function() { - var AssertListIsDeleted = function() { - return store.query('list', { - name: 'one' - }).then(function(records) { - equal(get(records, 'length'), 0, "No record was found"); - start(); - }); - }; - - store.query('list', { - name: 'one' - }).then(function(lists) { - var list = lists.objectAt(0); - - equal(get(list, "id"), "l1", "Item exists"); - - list.deleteRecord(); - list.on("didDelete", AssertListIsDeleted); - list.save(); - }); - }); -}); - -test('changes in bulk', function() { - stop(); - run(function() { - - var listToUpdate = new Ember.RSVP.Promise(function(resolve, reject) { - store.findRecord('list', 'l1').then(function(list) { - list.set('name', 'updated'); - list.save().then(function() { - resolve(); - }); - }); - }); - - var listToCreate = new Ember.RSVP.Promise(function(resolve, reject) { - store.createRecord('list', { - name: 'Rambo' - }).save().then(function() { - resolve(); - }); - }); - - var listToDelete = new Ember.RSVP.Promise(function(resolve, reject) { - store.findRecord('list', 'l2').then(function(list) { - list.destroyRecord().then(function() { - resolve(); - }); - }); - }); - - var promises = [ - listToUpdate, - listToCreate, - listToDelete - ]; - - Ember.RSVP.all(promises).then(function() { - - promises = Ember.A(); + store.query('customer', { + customerNumber: '123' + }).then(function(customers) { + equal(get(customers, 'length'), 1); - promises.push( - new Ember.RSVP.Promise(function(resolve, reject) { - store.findRecord('list', 'l1').then(function(list) { - equal(get(list, 'name'), 'updated', "Record was updated successfully"); - resolve(); - }); - }) - ); + var customer = customers.objectAt(0); + var addresses = customer.get('addresses'); - promises.push( - new Ember.RSVP.Promise(function(resolve, reject) { - store.query('list', { - name: 'Rambo' - }).then(function(lists) { - equal(get(lists, 'length'), 1, "Record was created successfully"); - resolve(); - }); - }) - ); + equal(addresses.length, 2); + var address1 = addresses.get('firstObject'), + address2 = addresses.get('lastObject'); - promises.push( - new Ember.RSVP.Promise(function(resolve, reject) { - store.findRecord('list', 'l2').catch(function(err) { - ok(true, "Record was deleted successfully"); - resolve(); - }); - }) - ); + equal(get(address1, 'id'), '1', + 'first address id is loaded correctly'); + equal(get(address1, 'addressNumber'), '12345', + 'first address number is loaded correctly'); + equal(get(address2, 'id'), '2', + 'first address id is loaded correctly'); + equal(get(address2, 'addressNumber'), '54321', + 'first address number is loaded correctly'); - Ember.RSVP.all(promises).then(function() { - start(); - }); + start(); }); }); }); +test("loads embedded belongsTo in a 'find with id' operation", function() { + expect(2); -test('load hasMany association', function() { - expect(4); stop(); run(function() { - store.findRecord('list', 'l1').then(function(list) { - var items = list.get('items'); - - var item1 = items.get('firstObject'), - item2 = items.get('lastObject'); + store.findRecord('customer', '1').then(function(customer) { + var hour = customer.get('hour'); - equal(get(item1, 'id'), 'i1', 'first item id is loaded correctly'); - equal(get(item1, 'name'), 'one', 'first item name is loaded correctly'); - equal(get(item2, 'id'), 'i2', 'first item id is loaded correctly'); - equal(get(item2, 'name'), 'two', 'first item name is loaded correctly'); + equal(get(hour, 'id'), 'h5', + 'hour id is loaded correctly'); + equal(get(hour, 'name'), 'five', + 'hour name is loaded correctly'); start(); }); }); }); - -test('load belongsTo association', function() { +test('queryMany', function() { + expect(11); stop(); run(function() { - store.findRecord('item', 'i1').then(function(item) { - return new Ember.RSVP.Promise(function(resolve) { - resolve(get(item, 'list')); - }); - }).then(function(list) { - equal(get(list, 'id'), 'l1', "id is loaded correctly"); - equal(get(list, 'name'), 'one', "name is loaded correctly"); + store.query('order', { + b: true + }).then(function(records) { + var firstRecord = records.objectAt(0), + secondRecord = records.objectAt(1), + thirdRecord = records.objectAt(2); + + equal(get(records, 'length'), 3, "3 orders were found"); + equal(get(firstRecord, 'name'), "one", "First order's name is one"); + equal(get(secondRecord, 'name'), "three", "Second order's name is three"); + equal(get(thirdRecord, 'name'), "four", "Third order's name is four"); + var firstHours = firstRecord.get('hours'), + secondHours = secondRecord.get('hours'), + thirdHours = thirdRecord.get('hours'); + + equal(get(firstHours, 'length'), 2, "Order one has two hours"); + equal(get(secondHours, 'length'), 2, "Order three has two hours"); + equal(get(thirdHours, 'length'), 0, "Order four has no hours"); + + var hourOne = firstHours.objectAt(0), + hourTwo = firstHours.objectAt(1), + hourThree = secondHours.objectAt(0), + hourFour = secondHours.objectAt(1); + equal(get(hourOne, 'amount'), 4, "Hour one has amount of 4"); + equal(get(hourTwo, 'amount'), 3, "Hour two has amount of 3"); + equal(get(hourThree, 'amount'), 2, "Hour three has amount of 2"); + equal(get(hourFour, 'amount'), 1, "Hour four has amount of 1"); start(); }); }); }); +// Relationship saving +//------------------------------------------------------------------------------ test('saves belongsTo', function() { var item, @@ -510,110 +550,80 @@ test('saves hasMany', function() { }); }); -test("loads embedded hasMany in a 'find with id' operation", function() { - expect(5); +// Bulk operations +//------------------------------------------------------------------------------ +test('changes in bulk', function() { stop(); - run(function() { - store.findRecord('customer', '1').then(function(customer) { - var addresses = customer.get('addresses'); - - equal(addresses.length, 2); - var address1 = addresses.get('firstObject'), - address2 = addresses.get('lastObject'); - - equal(get(address1, 'id'), '1', - 'first address id is loaded correctly'); - equal(get(address1, 'addressNumber'), '12345', - 'first address number is loaded correctly'); - equal(get(address2, 'id'), '2', - 'first address id is loaded correctly'); - equal(get(address2, 'addressNumber'), '54321', - 'first address number is loaded correctly'); - start(); + var listToUpdate = new Ember.RSVP.Promise(function(resolve, reject) { + store.findRecord('list', 'l1').then(function(list) { + list.set('name', 'updated'); + list.save().then(function() { + resolve(); + }); + }); }); - }); -}); -test("loads embedded hasMany in a 'find all' operation", function() { - expect(6); - - stop(); - - run(function() { - store.findAll('customer').then(function(customers) { - equal(get(customers, 'length'), 1, 'one customer was retrieved'); - - var customer = customers.objectAt(0); - var addresses = customer.get('addresses'); - - equal(addresses.length, 2); - var address1 = addresses.get('firstObject'), - address2 = addresses.get('lastObject'); - - equal(get(address1, 'id'), '1', - 'first address id is loaded correctly'); - equal(get(address1, 'addressNumber'), '12345', - 'first address number is loaded correctly'); - equal(get(address2, 'id'), '2', - 'first address id is loaded correctly'); - equal(get(address2, 'addressNumber'), '54321', - 'first address number is loaded correctly'); - - start(); + var listToCreate = new Ember.RSVP.Promise(function(resolve, reject) { + store.createRecord('list', { + name: 'Rambo' + }).save().then(function() { + resolve(); + }); }); - }); -}); - -test("loads embedded hasMany in a 'find many' operation", function() { - expect(6); - - stop(); - - run(function() { - store.query('customer', { - customerNumber: '123' - }).then(function(customers) { - equal(get(customers, 'length'), 1); - var customer = customers.objectAt(0); - var addresses = customer.get('addresses'); - - equal(addresses.length, 2); - var address1 = addresses.get('firstObject'), - address2 = addresses.get('lastObject'); + var listToDelete = new Ember.RSVP.Promise(function(resolve, reject) { + store.findRecord('list', 'l2').then(function(list) { + list.destroyRecord().then(function() { + resolve(); + }); + }); + }); - equal(get(address1, 'id'), '1', - 'first address id is loaded correctly'); - equal(get(address1, 'addressNumber'), '12345', - 'first address number is loaded correctly'); - equal(get(address2, 'id'), '2', - 'first address id is loaded correctly'); - equal(get(address2, 'addressNumber'), '54321', - 'first address number is loaded correctly'); + var promises = [ + listToUpdate, + listToCreate, + listToDelete + ]; - start(); - }); - }); -}); + Ember.RSVP.all(promises).then(function() { -test("loads embedded belongsTo in a 'find with id' operation", function() { - expect(2); + promises = Ember.A(); - stop(); + promises.push( + new Ember.RSVP.Promise(function(resolve, reject) { + store.findRecord('list', 'l1').then(function(list) { + equal(get(list, 'name'), 'updated', "Record was updated successfully"); + resolve(); + }); + }) + ); - run(function() { - store.findRecord('customer', '1').then(function(customer) { - var hour = customer.get('hour'); + promises.push( + new Ember.RSVP.Promise(function(resolve, reject) { + store.query('list', { + name: 'Rambo' + }).then(function(lists) { + equal(get(lists, 'length'), 1, "Record was created successfully"); + resolve(); + }); + }) + ); - equal(get(hour, 'id'), 'h5', - 'hour id is loaded correctly'); - equal(get(hour, 'name'), 'five', - 'hour name is loaded correctly'); + promises.push( + new Ember.RSVP.Promise(function(resolve, reject) { + store.findRecord('list', 'l2').catch(function(err) { + ok(true, "Record was deleted successfully"); + resolve(); + }); + }) + ); - start(); + Ember.RSVP.all(promises).then(function() { + start(); + }); }); }); }); \ No newline at end of file From 2825561c1e263602040c8257a77dd98b327a4999 Mon Sep 17 00:00:00 2001 From: Sebastien Tisserant Date: Wed, 16 Sep 2015 12:54:54 +0200 Subject: [PATCH 3/9] Rephrase tests Make them: * more uniform with each other * more consistent with their purpose In order to: * improve readability * make the detection of missing test cases easier --- tests/integration/crud-test.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/integration/crud-test.js b/tests/integration/crud-test.js index 5e8ec4d..a8bad87 100644 --- a/tests/integration/crud-test.js +++ b/tests/integration/crud-test.js @@ -95,7 +95,7 @@ test('createRecord', function() { }); }); -test('updateRecords', function() { +test('updateRecord', function() { expect(3); stop(); @@ -188,7 +188,7 @@ test('findAll', function() { }); }); -test('findRecord with id', function() { +test('findRecord', function() { expect(4); stop(); @@ -311,7 +311,7 @@ test('queryRecord', function() { // Relationship loading //------------------------------------------------------------------------------ -test('load hasMany association', function() { +test('load hasMany relationships when finding a single record', function() { expect(4); stop(); @@ -332,7 +332,7 @@ test('load hasMany association', function() { }); }); -test('load belongsTo association', function() { +test('load belongsTo relationships when finding a single record', function() { stop(); run(function() { store.findRecord('item', 'i1').then(function(item) { @@ -348,7 +348,7 @@ test('load belongsTo association', function() { }); }); -test("loads embedded hasMany in a 'find with id' operation", function() { +test("load embedded hasMany relationships when finding a single record", function() { expect(5); stop(); @@ -375,7 +375,7 @@ test("loads embedded hasMany in a 'find with id' operation", function() { }); }); -test("loads embedded hasMany in a 'find all' operation", function() { +test("load embedded hasMany relationships when finding multiple records", function() { expect(6); stop(); @@ -405,7 +405,7 @@ test("loads embedded hasMany in a 'find all' operation", function() { }); }); -test("loads embedded hasMany in a 'find many' operation", function() { +test("load embedded hasMany relationships when querying multiple records", function() { expect(6); stop(); @@ -437,7 +437,7 @@ test("loads embedded hasMany in a 'find many' operation", function() { }); }); -test("loads embedded belongsTo in a 'find with id' operation", function() { +test("load embedded belongsTo relationships when finding a single record", function() { expect(2); stop(); @@ -456,7 +456,7 @@ test("loads embedded belongsTo in a 'find with id' operation", function() { }); }); -test('queryMany', function() { +test('load hasMany relationships when querying multiple records', function() { expect(11); stop(); run(function() { @@ -496,7 +496,7 @@ test('queryMany', function() { // Relationship saving //------------------------------------------------------------------------------ -test('saves belongsTo', function() { +test('save belongsTo relationships', function() { var item, listId = 'l2'; @@ -521,7 +521,7 @@ test('saves belongsTo', function() { }); }); -test('saves hasMany', function() { +test('save hasMany relationships', function() { var item, list, listId = 'l2'; @@ -553,7 +553,7 @@ test('saves hasMany', function() { // Bulk operations //------------------------------------------------------------------------------ -test('changes in bulk', function() { +test('perform multiple changes in bulk', function() { stop(); run(function() { From 4e77a6d65e1917466237dff1cb14e2b32df35d84 Mon Sep 17 00:00:00 2001 From: Sebastien Tisserant Date: Wed, 16 Sep 2015 13:10:24 +0200 Subject: [PATCH 4/9] Make the use of quotes and blank lines more consistent --- tests/integration/crud-test.js | 130 ++++++++++++++------------------- 1 file changed, 55 insertions(+), 75 deletions(-) diff --git a/tests/integration/crud-test.js b/tests/integration/crud-test.js index a8bad87..0837bed 100644 --- a/tests/integration/crud-test.js +++ b/tests/integration/crud-test.js @@ -14,7 +14,7 @@ var run = Ember.run; var get = Ember.get; var set = Ember.set; -module('CRUD', { +module("CRUD", { setup: function() { stop(); run(function() { @@ -39,7 +39,7 @@ module('CRUD', { // Lifecycle methods // ----------------------------------------------------------------------------- -test('push', function() { +test("push", function() { expect(3); stop(); @@ -53,13 +53,10 @@ test('push', function() { }); list.save().then(function(record) { - - store.query('list', { name: 'Rambo' }).then(function(records) { var record = records.objectAt(0); - equal(get(records, 'length'), 1, "Only Rambo was found"); equal(get(record, 'name'), "Rambo", "Correct name"); equal(get(record, 'id'), list.id, "Correct, original id"); @@ -69,7 +66,7 @@ test('push', function() { }); }); -test('createRecord', function() { +test("createRecord", function() { expect(3); stop(); @@ -79,13 +76,10 @@ test('createRecord', function() { }); list.save().then(function(record) { - - store.query('list', { name: 'Rambo' }).then(function(records) { var record = records.objectAt(0); - equal(get(records, 'length'), 1, "Only Rambo was found"); equal(get(record, 'name'), "Rambo", "Correct name"); equal(get(record, 'id'), list.id, "Correct, original id"); @@ -95,7 +89,7 @@ test('createRecord', function() { }); }); -test('updateRecord', function() { +test("updateRecord", function() { expect(3); stop(); @@ -119,11 +113,9 @@ test('updateRecord', function() { name: 'Macgyver' }).then(function(records) { var record = records.objectAt(0); - equal(get(records, 'length'), 1, "Only one record was found"); equal(get(record, 'name'), "Macgyver", "Updated name shows up"); equal(get(record, 'id'), list.id, "Correct, original id"); - start(); }); }; @@ -132,7 +124,7 @@ test('updateRecord', function() { }); }); -test('deleteRecord', function() { +test("deleteRecord", function() { expect(2); stop(); @@ -150,9 +142,7 @@ test('deleteRecord', function() { name: 'one' }).then(function(lists) { var list = lists.objectAt(0); - equal(get(list, "id"), "l1", "Item exists"); - list.deleteRecord(); list.on("didDelete", AssertListIsDeleted); list.save(); @@ -163,7 +153,7 @@ test('deleteRecord', function() { // Find methods // ----------------------------------------------------------------------------- -test('findAll', function() { +test("findAll", function() { expect(7); stop(); @@ -188,16 +178,16 @@ test('findAll', function() { }); }); -test('findRecord', function() { +test("findRecord", function() { expect(4); stop(); run(function() { store.findRecord('list', 'l1').then(function(list) { - equal(get(list, 'id'), 'l1', 'id is loaded correctly'); - equal(get(list, 'name'), 'one', 'name is loaded correctly'); - equal(get(list, 'b'), true, 'b is loaded correctly'); - equal(get(list, 'day'), 1, 'day is loaded correctly'); + equal(get(list, 'id'), 'l1', "id is loaded correctly"); + equal(get(list, 'name'), 'one', "name is loaded correctly"); + equal(get(list, 'b'), true, "b is loaded correctly"); + equal(get(list, 'day'), 1, "day is loaded correctly"); start(); }); }); @@ -206,14 +196,14 @@ test('findRecord', function() { // Query methods // ----------------------------------------------------------------------------- -test('query', function() { +test("query", function() { stop(); run(function() { store.query('list', { name: /one|two/ }).then(function(records) { - equal(get(records, 'length'), 2, 'found results for /one|two/'); + equal(get(records, 'length'), 2, "found results for /one|two/"); start(); }); }); @@ -224,7 +214,7 @@ test('query', function() { name: /.+/, id: /l1/ }).then(function(records) { - equal(get(records, 'length'), 1, 'found results for {name: /.+/, id: /l1/}'); + equal(get(records, 'length'), 1, "found results for { name: /.+/, id: /l1/ }"); start(); }); }); @@ -234,7 +224,7 @@ test('query', function() { store.query('list', { name: 'one' }).then(function(records) { - equal(get(records, 'length'), 1, 'found results for name "one"'); + equal(get(records, 'length'), 1, "found results for name 'one'"); start(); }); }); @@ -244,7 +234,7 @@ test('query', function() { store.query('list', { b: true }).then(function(records) { - equal(get(records, 'length'), 1, 'found results for {b: true}'); + equal(get(records, 'length'), 1, "found results for { b: true }"); start(); }); }); @@ -255,7 +245,7 @@ test('query', function() { name: 'two', b: false }).then(function(records) { - equal(get(records, 'length'), 1, 'found results for multiple criteria'); + equal(get(records, 'length'), 1, "found results for multiple criteria"); start(); }); }); @@ -266,7 +256,7 @@ test('query', function() { name: 'four', b: false }).then(function(records) { - equal(get(records, 'length'), 0, 'found no results when only criteria matches'); + equal(get(records, 'length'), 0, "found no results when only criteria matches"); start(); }); }); @@ -276,23 +266,23 @@ test('query', function() { store.query('list', { whatever: "dude" }).then(function(records) { - equal(get(records, 'length'), 0, 'didn\'t find results for nonsense'); + equal(get(records, 'length'), 0, "didn't find results for nonsense"); start(); }); }); }); -test('queryRecord', function() { +test("queryRecord", function() { stop(); run(function() { store.queryRecord('list', { name: 'one' }).then(function(list) { - equal(get(list, 'id'), 'l1', 'id is loaded correctly'); - equal(get(list, 'name'), 'one', 'name is loaded correctly'); - equal(get(list, 'b'), true, 'b is loaded correctly'); - equal(get(list, 'day'), 1, 'day is loaded correctly'); + equal(get(list, 'id'), 'l1', "id is loaded correctly"); + equal(get(list, 'name'), 'one', "name is loaded correctly"); + equal(get(list, 'b'), true, "b is loaded correctly"); + equal(get(list, 'day'), 1, "day is loaded correctly"); start(); }); }); @@ -311,28 +301,25 @@ test('queryRecord', function() { // Relationship loading //------------------------------------------------------------------------------ -test('load hasMany relationships when finding a single record', function() { +test("load hasMany relationships when finding a single record", function() { expect(4); stop(); run(function() { store.findRecord('list', 'l1').then(function(list) { var items = list.get('items'); - var item1 = items.get('firstObject'), item2 = items.get('lastObject'); - - equal(get(item1, 'id'), 'i1', 'first item id is loaded correctly'); - equal(get(item1, 'name'), 'one', 'first item name is loaded correctly'); - equal(get(item2, 'id'), 'i2', 'first item id is loaded correctly'); - equal(get(item2, 'name'), 'two', 'first item name is loaded correctly'); - + equal(get(item1, 'id'), 'i1', "first item id is loaded correctly"); + equal(get(item1, 'name'), 'one', "first item name is loaded correctly"); + equal(get(item2, 'id'), 'i2', "first item id is loaded correctly"); + equal(get(item2, 'name'), 'two', "first item name is loaded correctly"); start(); }); }); }); -test('load belongsTo relationships when finding a single record', function() { +test("load belongsTo relationships when finding a single record", function() { stop(); run(function() { store.findRecord('item', 'i1').then(function(item) { @@ -342,7 +329,6 @@ test('load belongsTo relationships when finding a single record', function() { }).then(function(list) { equal(get(list, 'id'), 'l1', "id is loaded correctly"); equal(get(list, 'name'), 'one', "name is loaded correctly"); - start(); }); }); @@ -356,19 +342,18 @@ test("load embedded hasMany relationships when finding a single record", functio run(function() { store.findRecord('customer', '1').then(function(customer) { var addresses = customer.get('addresses'); - equal(addresses.length, 2); + var address1 = addresses.get('firstObject'), address2 = addresses.get('lastObject'); - equal(get(address1, 'id'), '1', - 'first address id is loaded correctly'); + "first address id is loaded correctly"); equal(get(address1, 'addressNumber'), '12345', - 'first address number is loaded correctly'); + "first address number is loaded correctly"); equal(get(address2, 'id'), '2', - 'first address id is loaded correctly'); + "first address id is loaded correctly"); equal(get(address2, 'addressNumber'), '54321', - 'first address number is loaded correctly'); + "first address number is loaded correctly"); start(); }); @@ -386,19 +371,18 @@ test("load embedded hasMany relationships when finding multiple records", functi var customer = customers.objectAt(0); var addresses = customer.get('addresses'); - equal(addresses.length, 2); + var address1 = addresses.get('firstObject'), address2 = addresses.get('lastObject'); - equal(get(address1, 'id'), '1', - 'first address id is loaded correctly'); + "first address id is loaded correctly"); equal(get(address1, 'addressNumber'), '12345', - 'first address number is loaded correctly'); + "first address number is loaded correctly"); equal(get(address2, 'id'), '2', - 'first address id is loaded correctly'); + "first address id is loaded correctly"); equal(get(address2, 'addressNumber'), '54321', - 'first address number is loaded correctly'); + "first address number is loaded correctly"); start(); }); @@ -418,19 +402,18 @@ test("load embedded hasMany relationships when querying multiple records", funct var customer = customers.objectAt(0); var addresses = customer.get('addresses'); - equal(addresses.length, 2); + var address1 = addresses.get('firstObject'), address2 = addresses.get('lastObject'); - equal(get(address1, 'id'), '1', - 'first address id is loaded correctly'); + "first address id is loaded correctly"); equal(get(address1, 'addressNumber'), '12345', - 'first address number is loaded correctly'); + "first address number is loaded correctly"); equal(get(address2, 'id'), '2', - 'first address id is loaded correctly'); + "first address id is loaded correctly"); equal(get(address2, 'addressNumber'), '54321', - 'first address number is loaded correctly'); + "first address number is loaded correctly"); start(); }); @@ -447,16 +430,16 @@ test("load embedded belongsTo relationships when finding a single record", funct var hour = customer.get('hour'); equal(get(hour, 'id'), 'h5', - 'hour id is loaded correctly'); + "hour id is loaded correctly"); equal(get(hour, 'name'), 'five', - 'hour name is loaded correctly'); + "hour name is loaded correctly"); start(); }); }); }); -test('load hasMany relationships when querying multiple records', function() { +test("load hasMany relationships when querying multiple records", function() { expect(11); stop(); run(function() { @@ -466,15 +449,14 @@ test('load hasMany relationships when querying multiple records', function() { var firstRecord = records.objectAt(0), secondRecord = records.objectAt(1), thirdRecord = records.objectAt(2); - equal(get(records, 'length'), 3, "3 orders were found"); equal(get(firstRecord, 'name'), "one", "First order's name is one"); equal(get(secondRecord, 'name'), "three", "Second order's name is three"); equal(get(thirdRecord, 'name'), "four", "Third order's name is four"); + var firstHours = firstRecord.get('hours'), secondHours = secondRecord.get('hours'), thirdHours = thirdRecord.get('hours'); - equal(get(firstHours, 'length'), 2, "Order one has two hours"); equal(get(secondHours, 'length'), 2, "Order three has two hours"); equal(get(thirdHours, 'length'), 0, "Order four has no hours"); @@ -496,7 +478,7 @@ test('load hasMany relationships when querying multiple records', function() { // Relationship saving //------------------------------------------------------------------------------ -test('save belongsTo relationships', function() { +test("save belongsTo relationships", function() { var item, listId = 'l2'; @@ -514,14 +496,14 @@ test('save belongsTo relationships', function() { return store.findRecord('item', item.get('id')); }).then(function(item) { var list = item.get('list'); - ok(item.get('list'), 'list is present'); - equal(list.id, listId, 'list is retrieved correctly'); + ok(item.get('list'), "list is present"); + equal(list.id, listId, "list is retrieved correctly"); start(); }); }); }); -test('save hasMany relationships', function() { +test("save hasMany relationships", function() { var item, list, listId = 'l2'; @@ -533,7 +515,6 @@ test('save hasMany relationships', function() { name: 'three thousand' }); list.get('items').pushObject(item); - return list.save(); }).then(function(list) { return item.save(); @@ -543,8 +524,7 @@ test('save hasMany relationships', function() { }).then(function(list) { var items = list.get('items'), item1 = items.objectAt(0); - - equal(item1.get('name'), 'three thousand', 'item is saved'); + equal(item1.get('name'), 'three thousand', "item is saved"); start(); }); }); @@ -553,7 +533,7 @@ test('save hasMany relationships', function() { // Bulk operations //------------------------------------------------------------------------------ -test('perform multiple changes in bulk', function() { +test("perform multiple changes in bulk", function() { stop(); run(function() { From 9711ab6b0acadc4ad2b6fa10d743ab59de74afcf Mon Sep 17 00:00:00 2001 From: Sebastien Tisserant Date: Wed, 16 Sep 2015 19:01:39 +0200 Subject: [PATCH 5/9] Use a var declaration per assignment See https://github.com/emberjs/ember.js/blob/master/STYLEGUIDE.md#variables --- tests/integration/crud-test.js | 48 ++++++++++++++++------------------ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/tests/integration/crud-test.js b/tests/integration/crud-test.js index 0837bed..7c5bcfa 100644 --- a/tests/integration/crud-test.js +++ b/tests/integration/crud-test.js @@ -159,9 +159,9 @@ test("findAll", function() { stop(); run(function() { store.findAll('list').then(function(records) { - var firstRecord = records.objectAt(0), - secondRecord = records.objectAt(1), - thirdRecord = records.objectAt(2); + var firstRecord = records.objectAt(0); + var secondRecord = records.objectAt(1); + var thirdRecord = records.objectAt(2); equal(get(records, 'length'), 3, "3 items were found"); @@ -308,8 +308,8 @@ test("load hasMany relationships when finding a single record", function() { run(function() { store.findRecord('list', 'l1').then(function(list) { var items = list.get('items'); - var item1 = items.get('firstObject'), - item2 = items.get('lastObject'); + var item1 = items.get('firstObject'); + var item2 = items.get('lastObject'); equal(get(item1, 'id'), 'i1', "first item id is loaded correctly"); equal(get(item1, 'name'), 'one', "first item name is loaded correctly"); equal(get(item2, 'id'), 'i2', "first item id is loaded correctly"); @@ -344,8 +344,8 @@ test("load embedded hasMany relationships when finding a single record", functio var addresses = customer.get('addresses'); equal(addresses.length, 2); - var address1 = addresses.get('firstObject'), - address2 = addresses.get('lastObject'); + var address1 = addresses.get('firstObject'); + var address2 = addresses.get('lastObject'); equal(get(address1, 'id'), '1', "first address id is loaded correctly"); equal(get(address1, 'addressNumber'), '12345', @@ -373,8 +373,8 @@ test("load embedded hasMany relationships when finding multiple records", functi var addresses = customer.get('addresses'); equal(addresses.length, 2); - var address1 = addresses.get('firstObject'), - address2 = addresses.get('lastObject'); + var address1 = addresses.get('firstObject'); + var address2 = addresses.get('lastObject'); equal(get(address1, 'id'), '1', "first address id is loaded correctly"); equal(get(address1, 'addressNumber'), '12345', @@ -404,8 +404,8 @@ test("load embedded hasMany relationships when querying multiple records", funct var addresses = customer.get('addresses'); equal(addresses.length, 2); - var address1 = addresses.get('firstObject'), - address2 = addresses.get('lastObject'); + var address1 = addresses.get('firstObject'); + var address2 = addresses.get('lastObject'); equal(get(address1, 'id'), '1', "first address id is loaded correctly"); equal(get(address1, 'addressNumber'), '12345', @@ -428,7 +428,6 @@ test("load embedded belongsTo relationships when finding a single record", funct run(function() { store.findRecord('customer', '1').then(function(customer) { var hour = customer.get('hour'); - equal(get(hour, 'id'), 'h5', "hour id is loaded correctly"); equal(get(hour, 'name'), 'five', @@ -446,25 +445,25 @@ test("load hasMany relationships when querying multiple records", function() { store.query('order', { b: true }).then(function(records) { - var firstRecord = records.objectAt(0), - secondRecord = records.objectAt(1), - thirdRecord = records.objectAt(2); + var firstRecord = records.objectAt(0); + var secondRecord = records.objectAt(1); + var thirdRecord = records.objectAt(2); equal(get(records, 'length'), 3, "3 orders were found"); equal(get(firstRecord, 'name'), "one", "First order's name is one"); equal(get(secondRecord, 'name'), "three", "Second order's name is three"); equal(get(thirdRecord, 'name'), "four", "Third order's name is four"); - var firstHours = firstRecord.get('hours'), - secondHours = secondRecord.get('hours'), - thirdHours = thirdRecord.get('hours'); + var firstHours = firstRecord.get('hours'); + var secondHours = secondRecord.get('hours'); + var thirdHours = thirdRecord.get('hours'); equal(get(firstHours, 'length'), 2, "Order one has two hours"); equal(get(secondHours, 'length'), 2, "Order three has two hours"); equal(get(thirdHours, 'length'), 0, "Order four has no hours"); - var hourOne = firstHours.objectAt(0), - hourTwo = firstHours.objectAt(1), - hourThree = secondHours.objectAt(0), - hourFour = secondHours.objectAt(1); + var hourOne = firstHours.objectAt(0); + var hourTwo = firstHours.objectAt(1); + var hourThree = secondHours.objectAt(0); + var hourFour = secondHours.objectAt(1); equal(get(hourOne, 'amount'), 4, "Hour one has amount of 4"); equal(get(hourTwo, 'amount'), 3, "Hour two has amount of 3"); equal(get(hourThree, 'amount'), 2, "Hour three has amount of 2"); @@ -489,7 +488,6 @@ test("save belongsTo relationships", function() { name: 'three thousand' }); item.set('list', list); - return item.save(); }).then(function(item) { store.unloadAll('item'); @@ -522,8 +520,8 @@ test("save hasMany relationships", function() { store.unloadAll('list'); return store.findRecord('list', listId); }).then(function(list) { - var items = list.get('items'), - item1 = items.objectAt(0); + var items = list.get('items'); + var item1 = items.objectAt(0); equal(item1.get('name'), 'three thousand', "item is saved"); start(); }); From 8ff5a41b2ebeee20c6189ced6bf220571795a7a7 Mon Sep 17 00:00:00 2001 From: Sebastien Tisserant Date: Wed, 16 Sep 2015 19:31:08 +0200 Subject: [PATCH 6/9] Remove useless promise Promise resolved itself immediately --- tests/integration/crud-test.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/integration/crud-test.js b/tests/integration/crud-test.js index 7c5bcfa..4fe3a7f 100644 --- a/tests/integration/crud-test.js +++ b/tests/integration/crud-test.js @@ -323,10 +323,7 @@ test("load belongsTo relationships when finding a single record", function() { stop(); run(function() { store.findRecord('item', 'i1').then(function(item) { - return new Ember.RSVP.Promise(function(resolve) { - resolve(get(item, 'list')); - }); - }).then(function(list) { + var list = item.get('list'); equal(get(list, 'id'), 'l1', "id is loaded correctly"); equal(get(list, 'name'), 'one', "name is loaded correctly"); start(); From b5f89bb5edfd5727c3d203801743480eea3e64da Mon Sep 17 00:00:00 2001 From: Sebastien Tisserant Date: Thu, 17 Sep 2015 00:28:55 +0200 Subject: [PATCH 7/9] Avoid global var in promises Use only resolver args (less ambiguous + safer) --- tests/integration/crud-test.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tests/integration/crud-test.js b/tests/integration/crud-test.js index 4fe3a7f..9c1a923 100644 --- a/tests/integration/crud-test.js +++ b/tests/integration/crud-test.js @@ -475,13 +475,12 @@ test("load hasMany relationships when querying multiple records", function() { //------------------------------------------------------------------------------ test("save belongsTo relationships", function() { - var item, - listId = 'l2'; + var listId = 'l2'; stop(); run(function() { store.findRecord('list', listId).then(function(list) { - item = store.createRecord('item', { + var item = store.createRecord('item', { name: 'three thousand' }); item.set('list', list); @@ -499,21 +498,19 @@ test("save belongsTo relationships", function() { }); test("save hasMany relationships", function() { - var item, list, - listId = 'l2'; + var listId = 'l2'; stop(); - run(function() { store.findRecord('list', listId).then(function(list) { - item = store.createRecord('item', { + var item = store.createRecord('item', { name: 'three thousand' }); list.get('items').pushObject(item); - return list.save(); - }).then(function(list) { - return item.save(); - }).then(function(item) { + return item.save().then(function() { + return list.save(); + }); + }).then(function() { store.unloadAll('list'); return store.findRecord('list', listId); }).then(function(list) { From 6351c7aff4a5e2cf4f803a1d8827364e2afc478c Mon Sep 17 00:00:00 2001 From: Sebastien Tisserant Date: Thu, 17 Sep 2015 03:11:43 +0200 Subject: [PATCH 8/9] Chain promise where possible --- tests/integration/crud-test.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/integration/crud-test.js b/tests/integration/crud-test.js index 9c1a923..b453641 100644 --- a/tests/integration/crud-test.js +++ b/tests/integration/crud-test.js @@ -53,15 +53,15 @@ test("push", function() { }); list.save().then(function(record) { - store.query('list', { + return store.query('list', { name: 'Rambo' - }).then(function(records) { - var record = records.objectAt(0); - equal(get(records, 'length'), 1, "Only Rambo was found"); - equal(get(record, 'name'), "Rambo", "Correct name"); - equal(get(record, 'id'), list.id, "Correct, original id"); - start(); }); + }).then(function(records) { + var record = records.objectAt(0); + equal(get(records, 'length'), 1, "Only Rambo was found"); + equal(get(record, 'name'), "Rambo", "Correct name"); + equal(get(record, 'id'), list.id, "Correct, original id"); + start(); }); }); }); @@ -76,15 +76,15 @@ test("createRecord", function() { }); list.save().then(function(record) { - store.query('list', { + return store.query('list', { name: 'Rambo' - }).then(function(records) { - var record = records.objectAt(0); - equal(get(records, 'length'), 1, "Only Rambo was found"); - equal(get(record, 'name'), "Rambo", "Correct name"); - equal(get(record, 'id'), list.id, "Correct, original id"); - start(); }); + }).then(function(records) { + var record = records.objectAt(0); + equal(get(records, 'length'), 1, "Only Rambo was found"); + equal(get(record, 'name'), "Rambo", "Correct name"); + equal(get(record, 'id'), list.id, "Correct, original id"); + start(); }); }); }); From 6daa38384dcf8baabd0cd6b831d0ea323705dc01 Mon Sep 17 00:00:00 2001 From: Sebastien Tisserant Date: Thu, 17 Sep 2015 03:22:39 +0200 Subject: [PATCH 9/9] Proposal for issue #42 --- addon/adapters/localforage.js | 301 +------------------ addon/serializers/localforage.js | 96 ++---- tests/dummy/app/models/item.js | 2 +- tests/dummy/app/models/ledger.js | 4 +- tests/dummy/app/models/list.js | 2 +- tests/dummy/app/models/order.js | 2 +- tests/dummy/app/models/player.js | 4 +- tests/dummy/app/models/purchase.js | 4 +- tests/integration/crud-test.js | 91 +++--- tests/integration/display-deep-model-test.js | 12 +- 10 files changed, 109 insertions(+), 409 deletions(-) diff --git a/addon/adapters/localforage.js b/addon/adapters/localforage.js index ccff533..45cd271 100644 --- a/addon/adapters/localforage.js +++ b/addon/adapters/localforage.js @@ -29,33 +29,14 @@ export default DS.Adapter.extend(Ember.Evented, { */ findRecord: function (store, type, id, snapshot) { return new Ember.RSVP.Promise((resolve, reject) => { - var allowRecursive = true; this._namespaceForType(type).then((namespace) => { - /** - * In the case where there are relationships, this method is called again - * for each relation. Given the relations have references to the main - * object, we use allowRecursive to avoid going further into infinite - * recursiveness. - * - * Concept from ember-indexdb-adapter - */ - if (snapshot && typeof snapshot.allowRecursive !== 'undefined') { - allowRecursive = snapshot.allowRecursive; - } - var record = namespace.records[id]; if (!record) { reject(); return; } - if (allowRecursive) { - this.loadRelationships(store, type, record).then(function (finalRecord) { - resolve(finalRecord); - }); - } else { - resolve(record); - } + resolve(record); }); }); }, @@ -64,19 +45,19 @@ export default DS.Adapter.extend(Ember.Evented, { return new Ember.RSVP.Promise((resolve, reject) => { this._namespaceForType(type).then(function (namespace) { var results = []; + var record; for (var i = 0; i < ids.length; i++) { - results.push(Ember.copy(namespace.records[ids[i]])); + record = namespace.records[ids[i]]; + if (!record) { + reject(); + return; + } + results.push(Ember.copy(record)); } resolve(results); }); - }).then((records) => { - if (records.get('length')) { - return this.loadRelationshipsForMany(store, type, records); - } else { - return records; - } }); }, @@ -98,10 +79,6 @@ export default DS.Adapter.extend(Ember.Evented, { this._namespaceForType(type).then((namespace) => { var results = this._query(namespace.records, query); - if (results.get('length')) { - results = this.loadRelationshipsForMany(store, type, results); - } - resolve(results); }); }); @@ -112,13 +89,12 @@ export default DS.Adapter.extend(Ember.Evented, { return new Ember.RSVP.Promise((resolve, reject) => { this._namespaceForType(type).then((namespace) => { var result = this._query(namespace.records, query, true); - - if (result) { - result = this.loadRelationships(store, type, result); - resolve(result); - } else { + if (!result) { reject(); + return; } + + resolve(result); }); }); @@ -163,6 +139,7 @@ export default DS.Adapter.extend(Ember.Evented, { for (var id in namespace.records) { results.push(Ember.copy(namespace.records[id])); } + resolve(results); }); }); @@ -252,258 +229,6 @@ export default DS.Adapter.extend(Ember.Evented, { modelNamespace: function (type) { return type.url || type.modelName; }, - - - /** - * This takes a record, then analyzes the model relationships and replaces - * ids with the actual values. - * - * Stolen from ember-indexdb-adapter - * - * Consider the following JSON is entered: - * - * ```js - * { - * "id": 1, - * "title": "Rails Rambo", - * "comments": [1, 2] - * } - * - * This will return: - * - * ```js - * { - * "id": 1, - * "title": "Rails Rambo", - * "comments": [1, 2] - * - * "_embedded": { - * "comment": [{ - * "_id": 1, - * "comment_title": "FIRST" - * }, { - * "_id": 2, - * "comment_title": "Rails is unagi" - * }] - * } - * } - * - * This way, whenever a resource returned, its relationships will be also - * returned. - * - * @method loadRelationships - * @private - * @param {DS.Store} store - * @param {DS.Model} type - * @param {Object} record - */ - loadRelationships: function (store, type, record) { - return new Ember.RSVP.Promise((resolve, reject) => { - var resultJSON = {}, - modelName = type.modelName, - relationshipNames, relationships, - relationshipPromises = []; - - relationshipNames = Ember.get(type, 'relationshipNames'); - relationships = relationshipNames.belongsTo; - relationships = relationships.concat(relationshipNames.hasMany); - - relationships.forEach((relationName) => { - var relationModel = type.typeForRelationship(relationName, store), - relationEmbeddedId = record[relationName], - relationProp = this.relationshipProperties(type, relationName), - relationType = relationProp.kind, - promise, embedPromise; - - var opts = {allowRecursive: false}; - - /** - * embeddedIds are ids of relations that are included in the main - * payload, such as: - * - * { - * cart: { - * id: "s85fb", - * customer: "rld9u" - * } - * } - * - * In this case, cart belongsTo customer and its id is present in the - * main payload. We find each of these records and add them to _embedded. - */ - var embeddedAlways = this.isEmbeddedAlways(store, type.modelName, relationProp.key); - - // For embeddedAlways-style data, we assume the data to be present already, so no further loading is needed. - if (relationEmbeddedId && !embeddedAlways) { - if (relationType === 'belongsTo' || relationType === 'hasOne') { - promise = this.findRecord(store, relationModel, relationEmbeddedId, opts); - } else if (relationType === 'hasMany') { - promise = this.findMany(store, relationModel, relationEmbeddedId, opts); - } - - embedPromise = new Ember.RSVP.Promise((resolve, reject) => { - promise.then((relationRecord) => { - resolve(this.addEmbeddedPayload(record, relationName, relationRecord)); - }); - }); - - relationshipPromises.push(embedPromise); - } - }); - - Ember.RSVP.all(relationshipPromises).then(function () { - resolve(record); - }); - }); - }, - - - /** - * Given the following payload, - * - * { - * cart: { - * id: "1", - * customer: "2" - * } - * } - * - * With `relationshipName` being `customer` and `relationshipRecord` - * - * {id: "2", name: "Rambo"} - * - * This method returns the following payload: - * - * { - * cart: { - * id: "1", - * customer: "2" - * }, - * _embedded: { - * customer: { - * id: "2", - * name: "Rambo" - * } - * } - * } - * - * which is then treated by the serializer later. - * - * @method addEmbeddedPayload - * @private - * @param {Object} payload - * @param {String} relationshipName - * @param {Object} relationshipRecord - */ - addEmbeddedPayload: function (payload, relationshipName, relationshipRecord) { - var objectHasId = (relationshipRecord && relationshipRecord.id), - arrayHasIds = (relationshipRecord.length && relationshipRecord.isEvery("id")), - isValidRelationship = (objectHasId || arrayHasIds); - - if (isValidRelationship) { - if (!payload._embedded) { - payload._embedded = {}; - } - - payload._embedded[relationshipName] = relationshipRecord; - if (relationshipRecord.length) { - payload[relationshipName] = relationshipRecord.mapBy('id'); - } else { - payload[relationshipName] = relationshipRecord.id; - } - } - - if (this.isArray(payload[relationshipName])) { - payload[relationshipName] = payload[relationshipName].filter(function (id) { - return id; - }); - } - - return payload; - }, - - - isArray: function (value) { - return Object.prototype.toString.call(value) === '[object Array]'; - }, - - /** - * Same as `loadRelationships`, but for an array of records. - * - * @method loadRelationshipsForMany - * @private - * @param {DS.Store} store - * @param {DS.Model} type - * @param {Object} recordsArray - */ - loadRelationshipsForMany: function (store, type, recordsArray) { - return new Ember.RSVP.Promise((resolve, reject) => { - var recordsWithRelationships = [], - recordsToBeLoaded = [], - promises = []; - - /** - * Some times Ember puts some stuff in arrays. We want to clean it so - * we know exactly what to iterate over. - */ - for (var i in recordsArray) { - if (recordsArray.hasOwnProperty(i)) { - recordsToBeLoaded.push(recordsArray[i]); - } - } - - var loadNextRecord = (record) => { - /** - * Removes the first item from recordsToBeLoaded - */ - recordsToBeLoaded = recordsToBeLoaded.slice(1); - - var promise = this.loadRelationships(store, type, record); - - promise.then(function (recordWithRelationships) { - recordsWithRelationships.push(recordWithRelationships); - - if (recordsToBeLoaded[0]) { - loadNextRecord(recordsToBeLoaded[0]); - } else { - resolve(recordsWithRelationships); - } - }); - }; - - /** - * We start by the first record - */ - loadNextRecord(recordsToBeLoaded[0]); - }); - }, - - - /** - * - * @method relationshipProperties - * @private - * @param {DS.Model} type - * @param {String} relationName - */ - relationshipProperties: function (type, relationName) { - var relationships = Ember.get(type, 'relationshipsByName'); - if (relationName) { - return relationships.get(relationName); - } else { - return relationships; - } - }, - - isEmbeddedAlways: function (store, modelName, relationKey) { - if (store === undefined || store === null) { - return false; - } - - var serializer = store.serializerFor(modelName); - return typeof(serializer.hasEmbeddedAlwaysOption) === 'function' && - serializer.hasEmbeddedAlwaysOption(relationKey); - } }); function updateOrCreate(store, type, snapshot) { diff --git a/addon/serializers/localforage.js b/addon/serializers/localforage.js index b6d6df0..d2701e1 100644 --- a/addon/serializers/localforage.js +++ b/addon/serializers/localforage.js @@ -3,8 +3,6 @@ import DS from 'ember-data'; export default DS.JSONSerializer.extend({ - isNewSerializerAPI: true, - _shouldSerializeHasMany: function (snapshot, key, relationship) { var relationshipType = snapshot.type.determineRelationshipType(relationship, this.store); if (this._mustSerialize(key)) { @@ -39,79 +37,39 @@ export default DS.JSONSerializer.extend({ } }, - /** - * Normalize whatever was returned from the adapter. - * - * If the adapter returns relationships in an embedded way, such as follows: - * - * ```js - * { - * "id": 1, - * "title": "Rails Rambo", - * - * "_embedded": { - * "comment": [{ - * "id": 1, - * "comment_title": "FIRST" - * }, { - * "id": 2, - * "comment_title": "Rails is unagi" - * }] - * } - * } - * - * this method will create separated JSON for each resource and then push - * them individually to the Store. - * - * In the end, only the main resource will remain, containing the ids of its - * relationships. Given the relations are already in the Store, we will - * return a JSON with the main resource alone. The Store will sort out the - * associations by itself. - * - * @method normalize - * @param {DS.Model} primaryModelClass the type/model - * @param {Object} payload returned JSON - */ - normalize: function (primaryModelClass, payload) { - var normalizedPayload = this._normalizeEmbeddedPayload(primaryModelClass, payload); - return this._super(primaryModelClass, normalizedPayload); - }, - - _normalizeEmbeddedPayload: function (primaryModelClass, payload) { - if (payload && payload._embedded) { - for (var relation in payload._embedded) { - var relModelClass = primaryModelClass.typeForRelationship(relation, this.store); - var typeName = relModelClass.modelName, - embeddedPayload = payload._embedded[relation]; + // Remove the undefined hasMany relationships which will fail at normalization + // (see https://github.com/emberjs/data/issues/3736) + // TODO: this override will be unecessary after merge of the following PR: + // https://github.com/emberjs/data/pull/3747 + extractRelationships: function(modelClass, resourceHash) { + let relationships = {}; - if (embeddedPayload) { - var relSerializer = this.store.serializerFor(typeName); - if (Ember.isArray(embeddedPayload)) { - for (var i = 0; i < embeddedPayload.length; i++) { - this.store.push(relSerializer.normalize(relModelClass, embeddedPayload[i])); - } - } else { - this.store.push(relSerializer.normalize(relModelClass, embeddedPayload)); - } + modelClass.eachRelationship((key, relationshipMeta) => { + let relationship = null; + let relationshipKey = this.keyForRelationship(key, relationshipMeta.kind, 'deserialize'); + if (resourceHash.hasOwnProperty(relationshipKey)) { + let data = null; + let relationshipHash = resourceHash[relationshipKey]; + if (relationshipMeta.kind === 'belongsTo') { + data = this.extractRelationship(relationshipMeta.type, relationshipHash); + } else if (relationshipMeta.kind === 'hasMany') { + data = Ember.isNone(relationshipHash) ? null : relationshipHash.map((item) => this.extractRelationship(relationshipMeta.type, item)); } + relationship = { data }; } - delete payload._embedded; - } - - // Remove the undefined hasMany relationships which will fail at normalization - // (see https://github.com/emberjs/data/issues/3736) - // TODO: this block will be unecessary after merge of the following PR: - // https://github.com/emberjs/data/pull/3747 - var relationshipNames = Ember.get(primaryModelClass, 'relationshipNames'); - var relationships = relationshipNames.hasMany; + let linkKey = this.keyForLink(key, relationshipMeta.kind); + if (resourceHash.links && resourceHash.links.hasOwnProperty(linkKey)) { + let related = resourceHash.links[linkKey]; + relationship = relationship || {}; + relationship.links = { related }; + } - relationships.forEach((relationName) => { - if (Ember.isNone(payload[relationName])) { - delete payload[relationName]; + if (relationship) { + relationships[key] = relationship; } }); - return payload; - }, + return relationships; + } }); diff --git a/tests/dummy/app/models/item.js b/tests/dummy/app/models/item.js index ac3c87b..311abf4 100644 --- a/tests/dummy/app/models/item.js +++ b/tests/dummy/app/models/item.js @@ -5,5 +5,5 @@ var belongsTo = DS.belongsTo; export default DS.Model.extend({ name: attr('string'), - list: belongsTo('list', { async: false }) + list: belongsTo('list') }); \ No newline at end of file diff --git a/tests/dummy/app/models/ledger.js b/tests/dummy/app/models/ledger.js index 88c89d2..dffd7b7 100644 --- a/tests/dummy/app/models/ledger.js +++ b/tests/dummy/app/models/ledger.js @@ -3,6 +3,6 @@ import DS from 'ember-data'; export default DS.Model.extend({ title: DS.attr('string'), - purchases: DS.hasMany('purchase', {async: true}), - players: DS.hasMany('player', {async: true}) + purchases: DS.hasMany('purchase'), + players: DS.hasMany('player') }); \ No newline at end of file diff --git a/tests/dummy/app/models/list.js b/tests/dummy/app/models/list.js index 1c7d815..048bb7b 100644 --- a/tests/dummy/app/models/list.js +++ b/tests/dummy/app/models/list.js @@ -6,6 +6,6 @@ var hasMany = DS.hasMany; export default DS.Model.extend({ name: attr('string'), b: attr('boolean'), - items: hasMany('item', { async: false }), + items: hasMany('item'), day: attr('day') }); \ No newline at end of file diff --git a/tests/dummy/app/models/order.js b/tests/dummy/app/models/order.js index a40afeb..076387e 100644 --- a/tests/dummy/app/models/order.js +++ b/tests/dummy/app/models/order.js @@ -6,5 +6,5 @@ var hasMany = DS.hasMany; export default DS.Model.extend({ name: attr('string'), b: attr('boolean'), - hours: hasMany('hour', { async: false }) + hours: hasMany('hour') }); diff --git a/tests/dummy/app/models/player.js b/tests/dummy/app/models/player.js index f2f167e..49765e2 100644 --- a/tests/dummy/app/models/player.js +++ b/tests/dummy/app/models/player.js @@ -4,6 +4,6 @@ export default DS.Model.extend({ name: DS.attr('string'), balance: DS.attr('number'), - ledger: DS.belongsTo('ledger',{ async: true }), - purchases: DS.hasMany('purchase', {async: true}) + ledger: DS.belongsTo('ledger'), + purchases: DS.hasMany('purchase') }); \ No newline at end of file diff --git a/tests/dummy/app/models/purchase.js b/tests/dummy/app/models/purchase.js index ba6a1a5..4bf98f4 100644 --- a/tests/dummy/app/models/purchase.js +++ b/tests/dummy/app/models/purchase.js @@ -4,6 +4,6 @@ export default DS.Model.extend({ name: DS.attr('string'), amount: DS.attr('number'), - ledger: DS.belongsTo('ledger', {async: true}), - player: DS.belongsTo('player', {async: true}) + ledger: DS.belongsTo('ledger'), + player: DS.belongsTo('player') }); \ No newline at end of file diff --git a/tests/integration/crud-test.js b/tests/integration/crud-test.js index b453641..7d5bf4a 100644 --- a/tests/integration/crud-test.js +++ b/tests/integration/crud-test.js @@ -307,14 +307,15 @@ test("load hasMany relationships when finding a single record", function() { run(function() { store.findRecord('list', 'l1').then(function(list) { - var items = list.get('items'); - var item1 = items.get('firstObject'); - var item2 = items.get('lastObject'); - equal(get(item1, 'id'), 'i1', "first item id is loaded correctly"); - equal(get(item1, 'name'), 'one', "first item name is loaded correctly"); - equal(get(item2, 'id'), 'i2', "first item id is loaded correctly"); - equal(get(item2, 'name'), 'two', "first item name is loaded correctly"); - start(); + list.get('items').then(function(items) { + var item1 = items.get('firstObject'); + var item2 = items.get('lastObject'); + equal(get(item1, 'id'), 'i1', "first item id is loaded correctly"); + equal(get(item1, 'name'), 'one', "first item name is loaded correctly"); + equal(get(item2, 'id'), 'i2', "first item id is loaded correctly"); + equal(get(item2, 'name'), 'two', "first item name is loaded correctly"); + start(); + }); }); }); }); @@ -323,10 +324,11 @@ test("load belongsTo relationships when finding a single record", function() { stop(); run(function() { store.findRecord('item', 'i1').then(function(item) { - var list = item.get('list'); - equal(get(list, 'id'), 'l1', "id is loaded correctly"); - equal(get(list, 'name'), 'one', "name is loaded correctly"); - start(); + item.get('list').then(function(list) { + equal(get(list, 'id'), 'l1', "id is loaded correctly"); + equal(get(list, 'name'), 'one', "name is loaded correctly"); + start(); + }); }); }); }); @@ -450,23 +452,30 @@ test("load hasMany relationships when querying multiple records", function() { equal(get(secondRecord, 'name'), "three", "Second order's name is three"); equal(get(thirdRecord, 'name'), "four", "Third order's name is four"); - var firstHours = firstRecord.get('hours'); - var secondHours = secondRecord.get('hours'); - var thirdHours = thirdRecord.get('hours'); - equal(get(firstHours, 'length'), 2, "Order one has two hours"); - equal(get(secondHours, 'length'), 2, "Order three has two hours"); - equal(get(thirdHours, 'length'), 0, "Order four has no hours"); - - var hourOne = firstHours.objectAt(0); - var hourTwo = firstHours.objectAt(1); - var hourThree = secondHours.objectAt(0); - var hourFour = secondHours.objectAt(1); - equal(get(hourOne, 'amount'), 4, "Hour one has amount of 4"); - equal(get(hourTwo, 'amount'), 3, "Hour two has amount of 3"); - equal(get(hourThree, 'amount'), 2, "Hour three has amount of 2"); - equal(get(hourFour, 'amount'), 1, "Hour four has amount of 1"); + + Ember.RSVP.all([ + firstRecord.get('hours'), + secondRecord.get('hours'), + thirdRecord.get('hours') + ]).then(function(hours) { + var firstHours = hours[0]; + var secondHours = hours[1]; + var thirdHours = hours[2]; + equal(get(firstHours, 'length'), 2, "Order one has two hours"); + equal(get(secondHours, 'length'), 2, "Order three has two hours"); + equal(get(thirdHours, 'length'), 0, "Order four has no hours"); + + var hourOne = firstHours.objectAt(0); + var hourTwo = firstHours.objectAt(1); + var hourThree = secondHours.objectAt(0); + var hourFour = secondHours.objectAt(1); + equal(get(hourOne, 'amount'), 4, "Hour one has amount of 4"); + equal(get(hourTwo, 'amount'), 3, "Hour two has amount of 3"); + equal(get(hourThree, 'amount'), 2, "Hour three has amount of 2"); + equal(get(hourFour, 'amount'), 1, "Hour four has amount of 1"); - start(); + start(); + }); }); }); }); @@ -489,10 +498,11 @@ test("save belongsTo relationships", function() { store.unloadAll('item'); return store.findRecord('item', item.get('id')); }).then(function(item) { - var list = item.get('list'); - ok(item.get('list'), "list is present"); - equal(list.id, listId, "list is retrieved correctly"); - start(); + item.get('list').then(function(list) { + ok(item.get('list'), "list is present"); + equal(list.id, listId, "list is retrieved correctly"); + start(); + }); }); }); }); @@ -506,18 +516,21 @@ test("save hasMany relationships", function() { var item = store.createRecord('item', { name: 'three thousand' }); - list.get('items').pushObject(item); - return item.save().then(function() { - return list.save(); + return list.get('items').then(function(items) { + items.pushObject(item); + return item.save().then(function() { + return list.save(); + }); }); }).then(function() { store.unloadAll('list'); return store.findRecord('list', listId); }).then(function(list) { - var items = list.get('items'); - var item1 = items.objectAt(0); - equal(item1.get('name'), 'three thousand', "item is saved"); - start(); + list.get('items').then(function(items) { + var item1 = items.objectAt(0); + equal(item1.get('name'), 'three thousand', "item is saved"); + start(); + }); }); }); }); diff --git a/tests/integration/display-deep-model-test.js b/tests/integration/display-deep-model-test.js index cf12e6a..a134124 100644 --- a/tests/integration/display-deep-model-test.js +++ b/tests/integration/display-deep-model-test.js @@ -38,9 +38,13 @@ test('find customer -> hour -> order', function () { visit('/purchase/1'); andThen(function () { - equal(find('div.name').text(), 'credits'); - equal(find('div.amount').text(), '10'); - equal(find('div.player').text(), 'one'); - equal(find('div.ledger').text(), 'payable'); + stop(); + run.later(function() { + equal(find('div.name').text(), 'credits'); + equal(find('div.amount').text(), '10'); + equal(find('div.player').text(), 'one'); + equal(find('div.ledger').text(), 'payable'); + start(); + }, 300); }); }); \ No newline at end of file