From b6b5722121a3dd64b2b16fcd0ef56a252c12a583 Mon Sep 17 00:00:00 2001 From: Chris Thoburn Date: Fri, 12 Aug 2022 00:03:03 -0700 Subject: [PATCH] deprecation: implement strict relationships (#8115) * prepare to enforce string ids * cleanup missing relationship types * deprecate missing types * deprecate not passing the async flag * implement inverse deprecation * fix a lot of deprecations * 100 tests to go * 25 remain * all dev tests passing * cleanup * fixup * fix test --- .../relationships/belongs-to-test.js | 2 +- .../-ember-data/tests/dummy/app/models/foo.js | 4 +- .../adapter/build-url-mixin-test.js | 48 +- .../adapter/json-api-adapter-test.js | 16 +- .../integration/adapter/rest-adapter-test.js | 148 +- .../rest-adapter/create-record-test.js | 26 +- .../adapter/rest-adapter/find-record-test.js | 4 +- .../integration/adapter/store-adapter-test.js | 14 +- .../non-dasherized-lookups-test.js | 4 +- .../identifiers/lid-reflection-test.ts | 2 +- .../tests/integration/inverse-test.js | 468 ++-- .../polymorphic-belongs-to-test.js | 20 +- .../integration/record-array-manager-test.js | 8 +- .../record-data/record-data-test.ts | 2 +- .../record-data/store-wrapper-test.ts | 14 +- .../integration/records/delete-record-test.js | 4 +- .../records/relationship-changes-test.js | 6 +- .../tests/integration/records/reload-test.js | 2 +- .../integration/records/rematerialize-test.js | 8 +- .../tests/integration/records/save-test.js | 4 +- .../tests/integration/records/unload-test.js | 220 +- .../integration/references/belongs-to-test.js | 88 +- .../integration/references/has-many-test.js | 149 +- .../integration/references/record-test.js | 16 +- .../relationships/belongs-to-test.js | 74 +- .../relationships/has-many-test.js | 519 ++-- .../inverse-relationship-load-test.js | 2409 +++++++++-------- .../inverse-relationships-test.js | 15 +- .../relationships/json-api-links-test.js | 27 +- .../relationships/many-to-many-test.js | 8 +- .../relationships/nested-relationship-test.js | 8 +- .../relationships/one-to-many-test.js | 8 +- .../relationships/one-to-one-test.js | 124 +- .../polymorphic-mixins-belongs-to-test.js | 4 +- .../polymorphic-mixins-has-many-test.js | 4 +- .../embedded-records-mixin-test.js | 78 +- .../serializers/json-api-serializer-test.js | 40 +- .../serializers/json-serializer-test.js | 22 +- .../serializers/rest-serializer-test.js | 52 +- .../tests/integration/snapshot-test.js | 8 +- .../tests/integration/store-test.js | 8 +- .../integration/store/query-record-test.js | 2 +- .../custom-class-model-test.ts | 1 + packages/-ember-data/tests/unit/debug-test.js | 6 +- .../-ember-data/tests/unit/many-array-test.js | 8 +- packages/-ember-data/tests/unit/model-test.js | 14 +- .../tests/unit/model/merge-test.js | 8 +- .../tests/unit/model/relationships-test.js | 59 +- .../model/relationships/belongs-to-test.js | 56 +- .../unit/model/relationships/has-many-test.js | 198 +- .../model/relationships/record-array-test.js | 4 +- .../unit/model/rollback-attributes-test.js | 6 +- .../tests/unit/promise-proxies-test.js | 6 +- .../unit/record-arrays/record-array-test.js | 8 +- .../tests/unit/store/adapter-interop-test.js | 32 +- .../tests/unit/store/create-record-test.js | 2 +- .../tests/unit/store/finders-test.js | 22 +- .../tests/unit/store/peek-record-test.js | 2 +- .../-ember-data/tests/unit/store/push-test.js | 38 +- .../tests/unit/store/unload-test.js | 10 +- .../tests/unit/transform/custom-test.js | 2 +- packages/-ember-data/tests/unit/utils-test.js | 4 +- packages/model/addon/-private/belongs-to.js | 92 +- packages/model/addon/-private/has-many.js | 84 +- .../model/addon/-private/legacy-data-fetch.js | 28 +- .../-private/legacy-relationships-support.ts | 4 +- packages/model/addon/-private/model.js | 7 +- .../addon/-private/references/belongs-to.ts | 16 +- .../addon/-private/references/has-many.ts | 16 +- .../model/addon/-private/relationship-meta.ts | 26 +- .../addon/current-deprecations.ts | 3 + .../private-build-infra/addon/deprecations.ts | 3 + .../addon/-private/graph/-edge-definition.ts | 17 +- .../tests/integration/belongs-to-test.js | 10 +- .../tests/integration/has-many-test.js | 8 +- .../tests/integration/reload-test.js | 2 +- .../app/models/car.js | 6 +- .../app/models/child.js | 2 +- .../app/models/color.js | 2 +- .../app/models/make.js | 2 +- .../app/models/parent.js | 2 +- .../app/models/size.js | 2 +- .../tests/integration/relationships-test.js | 28 +- .../addon-test-support/deprecated-test.js | 3 + .../qunit-asserts/assert-deprecation.ts | 8 +- 85 files changed, 2898 insertions(+), 2646 deletions(-) diff --git a/packages/-ember-data/tests/acceptance/relationships/belongs-to-test.js b/packages/-ember-data/tests/acceptance/relationships/belongs-to-test.js index 8ec1b0b7ace..07b4b2d2ed0 100644 --- a/packages/-ember-data/tests/acceptance/relationships/belongs-to-test.js +++ b/packages/-ember-data/tests/acceptance/relationships/belongs-to-test.js @@ -31,7 +31,7 @@ class Pet extends Model { @belongsTo('person', { inverse: 'bestDog', async: false }) bestHuman; // inverse is an implicit hasMany relationship - @belongsTo('person', { async: true }) + @belongsTo('person', { async: true, inverse: null }) petOwner; @attr() name; diff --git a/packages/-ember-data/tests/dummy/app/models/foo.js b/packages/-ember-data/tests/dummy/app/models/foo.js index adf7cf013b0..774cf4568d4 100644 --- a/packages/-ember-data/tests/dummy/app/models/foo.js +++ b/packages/-ember-data/tests/dummy/app/models/foo.js @@ -2,6 +2,6 @@ import Model, { attr, belongsTo, hasMany } from '@ember-data/model'; export default class Foo extends Model { @attr name; - @belongsTo('foo', { async: false }) parent; - @hasMany('foo', { async: false }) children; + @belongsTo('foo', { async: false, inverse: 'children' }) parent; + @hasMany('foo', { async: false, inverse: 'parent' }) children; } diff --git a/packages/-ember-data/tests/integration/adapter/build-url-mixin-test.js b/packages/-ember-data/tests/integration/adapter/build-url-mixin-test.js index bebdebd1fab..565a1c632cb 100644 --- a/packages/-ember-data/tests/integration/adapter/build-url-mixin-test.js +++ b/packages/-ember-data/tests/integration/adapter/build-url-mixin-test.js @@ -65,11 +65,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - with relative paths in links', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: true }) comments; + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); @@ -92,11 +92,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - with absolute paths in links', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: true }) comments; + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); @@ -119,11 +119,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - with absolute paths in links and protocol relative host', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: true }) comments; + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); @@ -146,11 +146,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - with absolute paths in links and host is /', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: true }) comments; + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); @@ -173,11 +173,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - with full URLs in links', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: true }) comments; + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); @@ -221,11 +221,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - buildURL takes a record from find', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: true }) comments; + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); @@ -252,11 +252,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - buildURL takes the records from findMany', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: true }) comments; + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); @@ -294,11 +294,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - buildURL takes a record from create', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: true }) comments; + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); @@ -325,11 +325,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - buildURL takes a record from create to query a resolved async belongsTo relationship', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: true }) comments; + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: true }) post; + @belongsTo('post', { async: true, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); @@ -362,11 +362,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - buildURL takes a record from update', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: true }) comments; + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); @@ -399,11 +399,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - buildURL takes a record from delete', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: false }) comments; + @hasMany('comment', { async: false, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); @@ -438,11 +438,11 @@ module('integration/adapter/build-url-mixin - BuildURLMixin with RESTAdapter', f test('buildURL - with absolute namespace', async function (assert) { class PostModel extends Model { @attr('string') name; - @hasMany('comment', { async: false }) comments; + @hasMany('comment', { async: false, inverse: 'post' }) comments; } class CommentModel extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'comments' }) post; } this.owner.register('model:post', PostModel); diff --git a/packages/-ember-data/tests/integration/adapter/json-api-adapter-test.js b/packages/-ember-data/tests/integration/adapter/json-api-adapter-test.js index 3fd16a2aa70..5d289168d8e 100644 --- a/packages/-ember-data/tests/integration/adapter/json-api-adapter-test.js +++ b/packages/-ember-data/tests/integration/adapter/json-api-adapter-test.js @@ -18,24 +18,24 @@ module('integration/adapter/json-api-adapter - JSONAPIAdapter', function (hooks) class User extends Model { @attr('string') firstName; @attr('string') lastName; - @hasMany('post', { async: true }) posts; - @hasMany('handle', { async: true, polymorphic: true }) handles; - @belongsTo('company', { async: true, polymorphic: true }) company; + @hasMany('post', { async: true, inverse: 'author' }) posts; + @hasMany('handle', { async: true, inverse: 'user', polymorphic: true }) handles; + @belongsTo('company', { async: true, inverse: 'employees', polymorphic: true }) company; } class Post extends Model { @attr('string') title; - @belongsTo('user', { async: true }) author; - @hasMany('comment', { async: true }) comments; + @belongsTo('user', { async: true, inverse: 'posts' }) author; + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class Comment extends Model { @attr('string') text; - @belongsTo('post', { async: true }) post; + @belongsTo('post', { async: true, inverse: 'comments' }) post; } class Handle extends Model { - @belongsTo('user', { async: true }) user; + @belongsTo('user', { async: true, inverse: 'handles' }) user; } class GithubHandle extends Handle { @@ -48,7 +48,7 @@ module('integration/adapter/json-api-adapter - JSONAPIAdapter', function (hooks) class Company extends Model { @attr('string') name; - @hasMany('user', { async: true }) employees; + @hasMany('user', { async: true, inverse: 'company' }) employees; } class DevelopmentShop extends Company { diff --git a/packages/-ember-data/tests/integration/adapter/rest-adapter-test.js b/packages/-ember-data/tests/integration/adapter/rest-adapter-test.js index 893df575366..4786e8ee845 100644 --- a/packages/-ember-data/tests/integration/adapter/rest-adapter-test.js +++ b/packages/-ember-data/tests/integration/adapter/rest-adapter-test.js @@ -217,7 +217,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { }); let post = await store.findRecord('post', 1); - ajaxResponse({ posts: [{ id: 1, name: 'Dat Parley Letter' }] }); + ajaxResponse({ posts: [{ id: '1', name: 'Dat Parley Letter' }] }); post.set('name', 'The Parley Letter'); await post.save(); @@ -252,7 +252,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { }); let post = await store.findRecord('post', 1); - ajaxResponse({ post: { id: 1, name: 'Dat Parley Letter' } }); + ajaxResponse({ post: { id: '1', name: 'Dat Parley Letter' } }); post.set('name', 'The Parley Letter'); await post.save(); @@ -277,8 +277,8 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { let post; ajaxResponse({ - posts: [{ id: 1, name: 'Dat Parley Letter' }], - comments: [{ id: 1, name: 'FIRST' }], + posts: [{ id: '1', name: 'Dat Parley Letter' }], + comments: [{ id: '1', name: 'FIRST' }], }); post = store.createRecord('post', { name: 'The Parley Letter' }); @@ -319,8 +319,8 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { let post = await store.findRecord('post', 1); ajaxResponse({ - posts: [{ id: 1, name: 'Dat Parley Letter' }], - comments: [{ id: 1, name: 'FIRST' }], + posts: [{ id: '1', name: 'Dat Parley Letter' }], + comments: [{ id: '1', name: 'FIRST' }], }); post.set('name', 'The Parley Letter'); @@ -423,7 +423,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { }); ajaxResponse({ - posts: { id: 1, name: 'Not everyone uses Rails', comments: [2] }, + posts: { id: '1', name: 'Not everyone uses Rails', comments: [2] }, }); await store.findRecord('comment', 2); @@ -478,7 +478,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { }); ajaxResponse({ - posts: { id: 1, name: 'Everyone uses Rails', comments: [] }, + posts: { id: '1', name: 'Everyone uses Rails', comments: [] }, }); let post = await store.peekRecord('post', 1); @@ -524,7 +524,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { }); ajaxResponse({ - posts: { id: 1, name: 'Everyone uses Rails', comments: [] }, + posts: { id: '1', name: 'Everyone uses Rails', comments: [] }, }); let post = await store.peekRecord('post', 1); @@ -635,7 +635,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { }); let post = await store.findRecord('post', 1); - ajaxResponse({ comments: [{ id: 1, name: 'FIRST' }] }); + ajaxResponse({ comments: [{ id: '1', name: 'FIRST' }] }); post.deleteRecord(); await post.save(); @@ -675,7 +675,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { }); let post = await store.findRecord('post', 1); - ajaxResponse({ posts: [{ id: 2, name: 'The Parley Letter' }] }); + ajaxResponse({ posts: [{ id: '2', name: 'The Parley Letter' }] }); post.deleteRecord(); await post.save(); @@ -733,8 +733,8 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ posts: [ - { id: 1, name: 'Rails is omakase' }, - { id: 2, name: 'The Parley Letter' }, + { id: '1', name: 'Rails is omakase' }, + { id: '2', name: 'The Parley Letter' }, ], }); @@ -776,8 +776,8 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ posts: [ - { id: 1, name: 'Rails is omakase' }, - { id: 2, name: 'The Parley Letter' }, + { id: '1', name: 'Rails is omakase' }, + { id: '2', name: 'The Parley Letter' }, ], }); @@ -798,7 +798,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { this.owner.register('model:comment', Comment); ajaxResponse({ - posts: [{ id: 1, name: 'Rails is very expensive sushi' }], + posts: [{ id: '1', name: 'Rails is very expensive sushi' }], }); await store.findAll('post', { include: 'comments' }); @@ -819,10 +819,10 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ posts: [ - { id: 1, name: 'Rails is omakase' }, - { id: 2, name: 'The Parley Letter' }, + { id: '1', name: 'Rails is omakase' }, + { id: '2', name: 'The Parley Letter' }, ], - comments: [{ id: 1, name: 'FIRST' }], + comments: [{ id: '1', name: 'FIRST' }], }); await store.findAll('post'); @@ -883,7 +883,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { this.owner.register('model:comment', Comment); ajaxResponse({ - posts: [{ id: 1, name: 'Rails is very expensive sushi' }], + posts: [{ id: '1', name: 'Rails is very expensive sushi' }], }); await store.query('post', { params: 1, in: 2, wrong: 3, order: 4 }); @@ -911,7 +911,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { }; ajaxResponse({ - posts: [{ id: 1, name: 'Rails is very expensive sushi' }], + posts: [{ id: '1', name: 'Rails is very expensive sushi' }], }); await store.query('post', { params: 1, in: 2, wrong: 3, order: 4 }); @@ -931,7 +931,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { this.owner.register('model:comment', Comment); ajaxResponse({ - posts: [{ id: 1, name: 'Rails is very expensive sushi' }], + posts: [{ id: '1', name: 'Rails is very expensive sushi' }], }); adapter.sortQueryParams = null; @@ -957,7 +957,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { this.owner.register('model:comment', Comment); ajaxResponse({ - posts: [{ id: 1, name: 'Rails is very expensive sushi' }], + posts: [{ id: '1', name: 'Rails is very expensive sushi' }], }); adapter.sortQueryParams = function (obj) { @@ -993,7 +993,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ meta: { offset: 5 }, - posts: [{ id: 1, name: 'Rails is very expensive sushi' }], + posts: [{ id: '1', name: 'Rails is very expensive sushi' }], }); let posts = await store.query('post', { page: 2 }); @@ -1014,14 +1014,14 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ meta: { offset: 5 }, - posts: [{ id: 1, name: 'Rails is very expensive sushi' }], + posts: [{ id: '1', name: 'Rails is very expensive sushi' }], }); let posts = await store.query('post', { page: 2 }); assert.strictEqual(posts.meta.offset, 5, 'Reponse metadata can be accessed with recordArray.meta'); ajaxResponse({ meta: { offset: 1 }, - posts: [{ id: 1, name: 'Rails is very expensive sushi' }], + posts: [{ id: '1', name: 'Rails is very expensive sushi' }], }); let newPosts = await store.query('post', { page: 1 }); @@ -1043,8 +1043,8 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ posts: [ - { id: 1, name: 'Rails is omakase' }, - { id: 2, name: 'The Parley Letter' }, + { id: '1', name: 'Rails is omakase' }, + { id: '2', name: 'The Parley Letter' }, ], }); @@ -1078,10 +1078,10 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ posts: [ - { id: 1, name: 'Rails is omakase' }, - { id: 2, name: 'The Parley Letter' }, + { id: '1', name: 'Rails is omakase' }, + { id: '2', name: 'The Parley Letter' }, ], - comments: [{ id: 1, name: 'FIRST' }], + comments: [{ id: '1', name: 'FIRST' }], }); await store.query('post', { page: 1 }); @@ -1204,8 +1204,8 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { this.owner.register('model:comment', Comment); ajaxResponse({ - post: { id: 1, name: 'Rails is omakase' }, - comments: [{ id: 1, name: 'FIRST' }], + post: { id: '1', name: 'Rails is omakase' }, + comments: [{ id: '1', name: 'FIRST' }], }); await store.queryRecord('post', { slug: 'rails-is-omakaze' }); @@ -1228,8 +1228,8 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ post: [ - { id: 1, name: 'Rails is omakase' }, - { id: 2, name: 'Ember is js' }, + { id: '1', name: 'Rails is omakase' }, + { id: '2', name: 'Ember is js' }, ], }); @@ -1252,7 +1252,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { this.owner.register('model:comment', Comment); ajaxResponse({ - post: { id: 1, name: 'Rails is omakase' }, + post: { id: '1', name: 'Rails is omakase' }, }); assert.expectNoDeprecation(); @@ -1329,9 +1329,9 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { let post = store.peekRecord('post', 1); ajaxResponse({ comments: [ - { id: 1, name: 'FIRST' }, - { id: 2, name: 'Rails is unagi' }, - { id: 3, name: 'What is omakase?' }, + { id: '1', name: 'FIRST' }, + { id: '2', name: 'Rails is unagi' }, + { id: '3', name: 'What is omakase?' }, ], }); @@ -1381,9 +1381,9 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { let post = store.peekRecord('post', 1); ajaxResponse({ comments: [ - { id: 1, name: 'FIRST' }, - { id: 2, name: 'Rails is unagi' }, - { id: 3, name: 'What is omakase?' }, + { id: '1', name: 'FIRST' }, + { id: '2', name: 'Rails is unagi' }, + { id: '3', name: 'What is omakase?' }, ], }); @@ -1426,9 +1426,9 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { //It's still ok to return this even without coalescing because RESTSerializer supports sideloading ajaxResponse({ comments: [ - { id: 1, name: 'FIRST' }, - { id: 2, name: 'Rails is unagi' }, - { id: 3, name: 'What is omakase?' }, + { id: '1', name: 'FIRST' }, + { id: '2', name: 'Rails is unagi' }, + { id: '3', name: 'What is omakase?' }, ], }); @@ -1474,9 +1474,9 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { let post = await store.findRecord('post', 1); ajaxResponse({ comments: [ - { id: 1, name: 'FIRST' }, - { id: 2, name: 'Rails is unagi' }, - { id: 3, name: 'What is omakase?' }, + { id: '1', name: 'FIRST' }, + { id: '2', name: 'Rails is unagi' }, + { id: '3', name: 'What is omakase?' }, ], }); @@ -1531,12 +1531,12 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { let post = await store.findRecord('post', 1); ajaxResponse({ comments: [ - { id: 1, name: 'FIRST' }, - { id: 2, name: 'Rails is unagi' }, - { id: 3, name: 'What is omakase?' }, - { id: 4, name: 'Unrelated comment' }, + { id: '1', name: 'FIRST' }, + { id: '2', name: 'Rails is unagi' }, + { id: '3', name: 'What is omakase?' }, + { id: '4', name: 'Unrelated comment' }, ], - posts: [{ id: 2, name: 'The Parley Letter' }], + posts: [{ id: '2', name: 'The Parley Letter' }], }); let comments = await post.comments; @@ -1665,9 +1665,9 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ comments: [ - { id: 1, name: 'FIRST' }, - { id: 2, name: 'Rails is unagi' }, - { id: 3, name: 'What is omakase?' }, + { id: '1', name: 'FIRST' }, + { id: '2', name: 'Rails is unagi' }, + { id: '3', name: 'What is omakase?' }, ], }); @@ -1733,9 +1733,9 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ comments: [ - { id: 1, name: 'FIRST' }, - { id: 2, name: 'Rails is unagi' }, - { id: 3, name: 'What is omakase?' }, + { id: '1', name: 'FIRST' }, + { id: '2', name: 'Rails is unagi' }, + { id: '3', name: 'What is omakase?' }, ], }); @@ -1778,11 +1778,11 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ comments: [ - { id: 1, name: 'FIRST' }, - { id: 2, name: 'Rails is unagi' }, - { id: 3, name: 'What is omakase?' }, + { id: '1', name: 'FIRST' }, + { id: '2', name: 'Rails is unagi' }, + { id: '3', name: 'What is omakase?' }, ], - posts: [{ id: 2, name: 'The Parley Letter' }], + posts: [{ id: '2', name: 'The Parley Letter' }], }); let comments = await post.comments; @@ -1907,7 +1907,7 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { }); let comment = await store.findRecord('comment', '1'); - ajaxResponse({ post: { id: 1, name: 'Rails is omakase' } }); + ajaxResponse({ post: { id: '1', name: 'Rails is omakase' } }); await comment.post; }); @@ -1984,12 +1984,12 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { adapter.findRecord = function (store, type, id, snapshot) { assert.strictEqual(id, '1'); - return resolve({ comments: { id: 1 } }); + return resolve({ comments: { id: '1' } }); }; adapter.findMany = function (store, type, ids, snapshots) { assert.deepEqual(ids, ['2', '3']); - return resolve({ comments: [{ id: 2 }, { id: 3 }] }); + return resolve({ comments: [{ id: '2' }, { id: '3' }] }); }; store.push({ @@ -2036,12 +2036,12 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { adapter.findRecord = function (store, type, id, snapshot) { assert.strictEqual(id, '1'); - return resolve({ comments: { id: 1 } }); + return resolve({ comments: { id: '1' } }); }; adapter.findMany = function (store, type, ids, snapshots) { assert.deepEqual(ids, ['2', '3']); - return resolve({ comments: [{ id: 2 }, { id: 3 }] }); + return resolve({ comments: [{ id: '2' }, { id: '3' }] }); }; store.push({ @@ -2655,15 +2655,15 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ posts: [ { - id: 1, + id: '1', name: 'dhh lol', }, { - id: 2, + id: '2', name: 'james mickens is rad', }, { - id: 3, + id: '3', name: 'in the name of love', }, ], @@ -2688,17 +2688,17 @@ module('integration/adapter/rest_adapter - REST Adapter', function (hooks) { ajaxResponse({ post: { - id: 1, + id: '1', name: 'The Parley Letter', comments: [2, 3], }, comments: [ { - id: 2, + id: '2', name: 'First comment', }, { - id: 3, + id: '3', name: 'Second comment', }, ], diff --git a/packages/-ember-data/tests/integration/adapter/rest-adapter/create-record-test.js b/packages/-ember-data/tests/integration/adapter/rest-adapter/create-record-test.js index 010142b8f97..3a1a48773c4 100644 --- a/packages/-ember-data/tests/integration/adapter/rest-adapter/create-record-test.js +++ b/packages/-ember-data/tests/integration/adapter/rest-adapter/create-record-test.js @@ -150,11 +150,11 @@ module('integration/adapter/rest_adapter - REST Adapter - createRecord', functio test("createRecord - findMany doesn't overwrite owner", async function (assert) { const Post = Model.extend({ name: attr('string'), - comments: hasMany('comment', { async: true }), + comments: hasMany('comment', { async: true, inverse: 'post' }), }); const Comment = Model.extend({ name: attr('string'), - post: belongsTo('post', { async: false }), + post: belongsTo('post', { async: false, inverse: 'comments' }), }); this.owner.register('model:post', Post); @@ -317,7 +317,7 @@ module('integration/adapter/rest_adapter - REST Adapter - createRecord', functio }); const Comment = Model.extend({ name: attr('string'), - post: belongsTo('post', { async: false }), + post: belongsTo('post', { async: false, inverse: null }), }); this.owner.register('model:post', Post); @@ -360,7 +360,7 @@ module('integration/adapter/rest_adapter - REST Adapter - createRecord', functio test("createRecord - a serializer's attribute mapping takes precedence over keyForRelationship (hasMany) when building the payload", async function (assert) { const Post = Model.extend({ name: attr('string'), - comments: hasMany('comment', { async: false }), + comments: hasMany('comment', { async: false, inverse: null }), }); const Comment = Model.extend({ name: attr('string'), @@ -408,11 +408,11 @@ module('integration/adapter/rest_adapter - REST Adapter - createRecord', functio const Post = Model.extend({ name: attr('string'), - comments: hasMany('comment', { async: false }), + comments: hasMany('comment', { async: false, inverse: 'post' }), }); const Comment = Model.extend({ name: attr('string'), - post: belongsTo('post', { async: false }), + post: belongsTo('post', { async: false, inverse: 'comments' }), }); this.owner.register('model:post', Post); @@ -490,11 +490,11 @@ module('integration/adapter/rest_adapter - REST Adapter - createRecord', functio const Post = Model.extend({ name: attr('string'), - comment: belongsTo('comment', { async: false }), + comment: belongsTo('comment', { async: false, inverse: 'post' }), }); const Comment = Model.extend({ name: attr('string'), - post: belongsTo('post', { async: false }), + post: belongsTo('post', { async: false, inverse: 'comment' }), }); this.owner.register('model:post', Post); @@ -524,11 +524,11 @@ module('integration/adapter/rest_adapter - REST Adapter - createRecord', functio const Post = Model.extend({ name: attr('string'), - comments: hasMany('comment', { async: false }), + comments: hasMany('comment', { async: false, inverse: 'post' }), }); const Comment = Model.extend({ name: attr('string'), - post: belongsTo('post', { async: false }), + post: belongsTo('post', { async: false, inverse: 'comments' }), }); this.owner.register('model:post', Post); @@ -578,11 +578,11 @@ module('integration/adapter/rest_adapter - REST Adapter - createRecord', functio test('createRecord - relationships are not duplicated', async function (assert) { const Post = Model.extend({ name: attr('string'), - comments: hasMany('comment', { async: false }), + comments: hasMany('comment', { async: false, inverse: 'post' }), }); const Comment = Model.extend({ name: attr('string'), - post: belongsTo('post', { async: false }), + post: belongsTo('post', { async: false, inverse: 'comments' }), }); this.owner.register('model:post', Post); @@ -593,7 +593,7 @@ module('integration/adapter/rest_adapter - REST Adapter - createRecord', functio const store = this.owner.lookup('service:store'); const adapter = store.adapterFor('application'); const post = store.createRecord('post', { name: 'Tomtomhuda' }); - const comment = store.createRecord('comment', { id: 2, name: 'Comment title' }); + const comment = store.createRecord('comment', { id: '2', name: 'Comment title' }); ajaxResponse(adapter, { post: [{ id: '1', name: 'Rails is omakase', comments: [] }] }); diff --git a/packages/-ember-data/tests/integration/adapter/rest-adapter/find-record-test.js b/packages/-ember-data/tests/integration/adapter/rest-adapter/find-record-test.js index 588addd526d..bc18ab9fef4 100644 --- a/packages/-ember-data/tests/integration/adapter/rest-adapter/find-record-test.js +++ b/packages/-ember-data/tests/integration/adapter/rest-adapter/find-record-test.js @@ -316,8 +316,8 @@ module('integration/adapter/rest_adapter - REST Adapter - findRecord', function const store = this.owner.lookup('service:store'); const adapter = store.adapterFor('application'); const ajaxCallback = ajaxResponse(adapter, { - posts: [{ id: 1, name: 'Rails is omakase' }], - comments: [{ id: 1, name: 'FIRST' }], + posts: [{ id: '1', name: 'Rails is omakase' }], + comments: [{ id: '1', name: 'FIRST' }], }); const post = await store.findRecord('post', '1'); diff --git a/packages/-ember-data/tests/integration/adapter/store-adapter-test.js b/packages/-ember-data/tests/integration/adapter/store-adapter-test.js index 9eec2afcca5..cc4847c5ae2 100644 --- a/packages/-ember-data/tests/integration/adapter/store-adapter-test.js +++ b/packages/-ember-data/tests/integration/adapter/store-adapter-test.js @@ -937,7 +937,7 @@ module('integration/adapter/store-adapter - DS.Store and DS.Adapter integration let adapter = store.adapterFor('application'); class Person extends Model { - @hasMany('dog', { async: false }) dogs; + @hasMany('dog', { async: false, inverse: null }) dogs; } this.owner.register('model:person', Person); @@ -1019,7 +1019,7 @@ module('integration/adapter/store-adapter - DS.Store and DS.Adapter integration let adapter = store.adapterFor('application'); class Person extends Model { - @hasMany({ async: true }) dogs; + @hasMany('dog', { async: true, inverse: null }) dogs; } this.owner.register('model:person', Person); @@ -1083,7 +1083,7 @@ module('integration/adapter/store-adapter - DS.Store and DS.Adapter integration let store = this.owner.lookup('service:store'); let adapter = store.adapterFor('application'); class Person extends Model { - @hasMany({ async: true }) dogs; + @hasMany('dog', { async: true, inverse: null }) dogs; } this.owner.register('model:person', Person); @@ -1203,7 +1203,7 @@ module('integration/adapter/store-adapter - DS.Store and DS.Adapter integration let store = this.owner.lookup('service:store'); let adapter = store.adapterFor('application'); class Person extends Model { - @hasMany({ async: true }) dogs; + @hasMany('dog', { async: true, inverse: null }) dogs; } this.owner.register('model:person', Person); @@ -1247,7 +1247,7 @@ module('integration/adapter/store-adapter - DS.Store and DS.Adapter integration let store = this.owner.lookup('service:store'); let adapter = store.adapterFor('application'); class Person extends Model { - @hasMany({ async: true }) dogs; + @hasMany('dog', { async: true, inverse: null }) dogs; } this.owner.register('model:person', Person); @@ -1289,7 +1289,7 @@ module('integration/adapter/store-adapter - DS.Store and DS.Adapter integration let adapter = store.adapterFor('application'); class Person extends Model { - @belongsTo('dog', { async: true }) dog; + @belongsTo('dog', { async: true, inverse: null }) dog; } this.owner.register('model:person', Person); @@ -1471,7 +1471,7 @@ module('integration/adapter/store-adapter - DS.Store and DS.Adapter integration test('An async hasMany relationship with links should not trigger shouldBackgroundReloadRecord', async function (assert) { class Post extends Model { @attr('string') name; - @hasMany('comment', { async: true }) comments; + @hasMany('comment', { async: true, inverse: null }) comments; } class Comment extends Model { diff --git a/packages/-ember-data/tests/integration/backwards-compat/non-dasherized-lookups-test.js b/packages/-ember-data/tests/integration/backwards-compat/non-dasherized-lookups-test.js index bf20ebc7d08..f134e24aeef 100644 --- a/packages/-ember-data/tests/integration/backwards-compat/non-dasherized-lookups-test.js +++ b/packages/-ember-data/tests/integration/backwards-compat/non-dasherized-lookups-test.js @@ -87,7 +87,7 @@ module( hooks.beforeEach(function () { const PostNote = Model.extend({ - notePost: belongsTo('note-post', { async: false }), + notePost: belongsTo('note-post', { async: false, inverse: null }), name: attr('string'), }); @@ -97,7 +97,7 @@ module( }); const LongModelName = Model.extend({ - postNotes: hasMany('post_note'), + postNotes: hasMany('post_note', { async: true, inverse: null }), }); const ApplicationAdapter = JSONAPIAdapter.extend({ diff --git a/packages/-ember-data/tests/integration/identifiers/lid-reflection-test.ts b/packages/-ember-data/tests/integration/identifiers/lid-reflection-test.ts index 133c90b485a..1766c32228f 100644 --- a/packages/-ember-data/tests/integration/identifiers/lid-reflection-test.ts +++ b/packages/-ember-data/tests/integration/identifiers/lid-reflection-test.ts @@ -145,7 +145,7 @@ module('Integration | Identifiers - lid reflection', function (hooks) { test('hasMany() has correct state after .save() on a newly created record with sideposted child record when lid is provided in the response payload', async function (assert) { class Ingredient extends Model { @attr name; - @belongsTo('cake') cake; + @belongsTo('cake', { async: true, inverse: null }) cake; } class Cake extends Model { diff --git a/packages/-ember-data/tests/integration/inverse-test.js b/packages/-ember-data/tests/integration/inverse-test.js index 9e229b40822..c5b3fd3a73f 100644 --- a/packages/-ember-data/tests/integration/inverse-test.js +++ b/packages/-ember-data/tests/integration/inverse-test.js @@ -1,9 +1,11 @@ -import { module, test } from 'qunit'; +import { DEBUG } from '@glimmer/env'; + +import { module } from 'qunit'; import { setupTest } from 'ember-qunit'; import Model, { attr, belongsTo } from '@ember-data/model'; -import testInDebug from '@ember-data/unpublished-test-infra/test-support/test-in-debug'; +import { deprecatedTest } from '@ember-data/unpublished-test-infra/test-support/deprecated-test'; function stringify(string) { return function () { @@ -20,267 +22,295 @@ module('integration/inverse_test - inverseFor', function (hooks) { store = owner.lookup('service:store'); }); - test('Finds the inverse when there is only one possible available', function (assert) { - class User extends Model { - @attr() - name; + deprecatedTest( + 'Finds the inverse when there is only one possible available', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + function (assert) { + class User extends Model { + @attr() + name; - @belongsTo('user', { async: true, inverse: null }) - bestFriend; + @belongsTo('user', { async: true, inverse: null }) + bestFriend; - @belongsTo('job', { async: false }) - job; + @belongsTo('job', { async: false }) + job; - toString() { - return stringify('user'); + toString() { + return stringify('user'); + } } - } - class Job extends Model { - @attr() - isGood; + class Job extends Model { + @attr() + isGood; - @belongsTo('user', { async: false }) - user; + @belongsTo('user', { async: false }) + user; - toString() { - return stringify('job'); + toString() { + return stringify('job'); + } } - } - let { owner } = this; - owner.register('model:user', User); - owner.register('model:job', Job); - - let job = store.modelFor('job'); - let user = store.modelFor('user'); - let inverseDefinition = job.inverseFor('user', store); - - assert.deepEqual( - inverseDefinition, - { - type: user, - name: 'job', - kind: 'belongsTo', - options: { - async: false, + let { owner } = this; + owner.register('model:user', User); + owner.register('model:job', Job); + + let job = store.modelFor('job'); + let user = store.modelFor('user'); + let inverseDefinition = job.inverseFor('user', store); + + assert.deepEqual( + inverseDefinition, + { + type: user, + name: 'job', + kind: 'belongsTo', + options: { + async: false, + }, }, - }, - 'Gets correct type, name and kind' - ); - }); + 'Gets correct type, name and kind' + ); + } + ); - test('Finds the inverse when only one side has defined it manually', function (assert) { - class User extends Model { - @attr() - name; + deprecatedTest( + 'Finds the inverse when only one side has defined it manually', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 3 }, + function (assert) { + class User extends Model { + @attr() + name; - @belongsTo('user', { async: true, inverse: null }) - bestFriend; + @belongsTo('user', { async: true, inverse: null }) + bestFriend; - @belongsTo('job', { async: false }) - job; + @belongsTo('job', { async: false }) + job; - @belongsTo('job', { async: false }) - previousJob; + @belongsTo('job', { async: false }) + previousJob; - toString() { - return stringify('user'); + toString() { + return stringify('user'); + } } - } - class Job extends Model { - @attr() - isGood; + class Job extends Model { + @attr() + isGood; - @belongsTo('user', { async: false }) - user; + @belongsTo('user', { async: false }) + user; - @belongsTo('user', { inverse: 'previousJob', async: false }) - owner; + @belongsTo('user', { inverse: 'previousJob', async: false }) + owner; - toString() { - return stringify('job'); + toString() { + return stringify('job'); + } } - } - let { owner } = this; - owner.register('model:user', User); - owner.register('model:job', Job); - - let job = store.modelFor('job'); - let user = store.modelFor('user'); - - assert.deepEqual( - job.inverseFor('owner', store), - { - type: user, //the model's type - name: 'previousJob', //the models relationship key - kind: 'belongsTo', - options: { - async: false, + let { owner } = this; + owner.register('model:user', User); + owner.register('model:job', Job); + + let job = store.modelFor('job'); + let user = store.modelFor('user'); + + assert.deepEqual( + job.inverseFor('owner', store), + { + type: user, //the model's type + name: 'previousJob', //the models relationship key + kind: 'belongsTo', + options: { + async: false, + }, }, - }, - 'Gets correct type, name and kind' - ); - - assert.deepEqual( - user.inverseFor('previousJob', store), - { - type: job, //the model's type - name: 'owner', //the models relationship key - kind: 'belongsTo', - options: { - inverse: 'previousJob', - async: false, + 'Gets correct type, name and kind' + ); + + assert.deepEqual( + user.inverseFor('previousJob', store), + { + type: job, //the model's type + name: 'owner', //the models relationship key + kind: 'belongsTo', + options: { + inverse: 'previousJob', + async: false, + }, }, - }, - 'Gets correct type, name and kind' - ); - }); + 'Gets correct type, name and kind' + ); + } + ); - test('Returns null if inverse relationship it is manually set with a different relationship key', function (assert) { - class User extends Model { - @attr() - name; + deprecatedTest( + 'Returns null if inverse relationship it is manually set with a different relationship key', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 1 }, + function (assert) { + class User extends Model { + @attr() + name; - @belongsTo('user', { async: true, inverse: null }) - bestFriend; + @belongsTo('user', { async: true, inverse: null }) + bestFriend; - @belongsTo('job', { async: false }) - job; + @belongsTo('job', { async: false }) + job; - toString() { - return stringify('user'); + toString() { + return stringify('user'); + } } - } - class Job extends Model { - @attr() - isGood; + class Job extends Model { + @attr() + isGood; - @belongsTo('user', { inverse: 'previousJob', async: false }) - user; + @belongsTo('user', { inverse: 'previousJob', async: false }) + user; - toString() { - return stringify('job'); + toString() { + return stringify('job'); + } } - } - - let { owner } = this; - owner.register('model:user', User); - owner.register('model:job', Job); - let user = store.modelFor('user'); - assert.strictEqual(user.inverseFor('job', store), null, 'There is no inverse'); - }); - - testInDebug('Errors out if you define 2 inverses to the same model', function (assert) { - class User extends Model { - @attr() - name; - - @belongsTo('user', { async: true, inverse: null }) - bestFriend; + let { owner } = this; + owner.register('model:user', User); + owner.register('model:job', Job); - @belongsTo('job', { async: false }) - job; - - toString() { - return stringify('user'); - } + let user = store.modelFor('user'); + assert.strictEqual(user.inverseFor('job', store), null, 'There is no inverse'); } - - class Job extends Model { - @attr() - isGood; - - @belongsTo('user', { inverse: 'job', async: false }) - user; - - @belongsTo('user', { inverse: 'job', async: false }) - owner; - - toString() { - return stringify('job'); + ); + + if (DEBUG) { + deprecatedTest( + 'Errors out if you define 2 inverses to the same model', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 1 }, + function (assert) { + class User extends Model { + @attr() + name; + + @belongsTo('user', { async: true, inverse: null }) + bestFriend; + + @belongsTo('job', { async: false }) + job; + + toString() { + return stringify('user'); + } + } + + class Job extends Model { + @attr() + isGood; + + @belongsTo('user', { inverse: 'job', async: false }) + user; + + @belongsTo('user', { inverse: 'job', async: false }) + owner; + + toString() { + return stringify('job'); + } + } + let { owner } = this; + owner.register('model:user', User); + owner.register('model:job', Job); + + let user = store.modelFor('user'); + assert.expectAssertion(() => { + user.inverseFor('job', store); + }, /Assertion Failed: You defined the 'job' relationship on model:user, but you defined the inverse relationships of type model:job multiple times/i); } - } - let { owner } = this; - owner.register('model:user', User); - owner.register('model:job', Job); - - let user = store.modelFor('user'); - assert.expectAssertion(() => { - user.inverseFor('job', store); - }, /Assertion Failed: You defined the 'job' relationship on model:user, but you defined the inverse relationships of type model:job multiple times/i); - }); - - test('Caches findInverseFor return value', function (assert) { - assert.expect(1); - class User extends Model { - @attr() - name; - - @belongsTo('user', { async: true, inverse: null }) - bestFriend; - - @belongsTo('job', { async: false }) - job; - - toString() { - return stringify('user'); + ); + } + + deprecatedTest( + 'Caches findInverseFor return value', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + function (assert) { + assert.expect(1); + class User extends Model { + @attr() + name; + + @belongsTo('user', { async: true, inverse: null }) + bestFriend; + + @belongsTo('job', { async: false }) + job; + + toString() { + return stringify('user'); + } } - } - class Job extends Model { - @attr() - isGood; + class Job extends Model { + @attr() + isGood; - @belongsTo('user', { async: false }) - user; + @belongsTo('user', { async: false }) + user; - toString() { - return stringify('job'); + toString() { + return stringify('job'); + } } - } - let { owner } = this; - owner.register('model:user', User); - owner.register('model:job', Job); - - let job = store.modelFor('job'); + let { owner } = this; + owner.register('model:user', User); + owner.register('model:job', Job); - let inverseForUser = job.inverseFor('user', store); - job.findInverseFor = function () { - assert.ok(false, 'Find is not called anymore'); - }; + let job = store.modelFor('job'); - assert.strictEqual(inverseForUser, job.inverseFor('user', store), 'Inverse cached succesfully'); - }); - - testInDebug('Errors out if you do not define an inverse for a reflexive relationship', function (assert) { - class ReflexiveModel extends Model { - @belongsTo('reflexive-model', { async: false }) - reflexiveProp; + let inverseForUser = job.inverseFor('user', store); + job.findInverseFor = function () { + assert.ok(false, 'Find is not called anymore'); + }; - toString() { - return stringify('reflexiveModel'); - } + assert.strictEqual(inverseForUser, job.inverseFor('user', store), 'Inverse cached succesfully'); } - - let { owner } = this; - owner.register('model:reflexive-model', ReflexiveModel); - - //Maybe store is evaluated lazily, so we need this :( - assert.expectWarning(() => { - var reflexiveModel; - store.push({ - data: { - type: 'reflexive-model', - id: '1', - }, - }); - reflexiveModel = store.peekRecord('reflexive-model', 1); - reflexiveModel.reflexiveProp; - }, /Detected a reflexive relationship by the name of 'reflexiveProp'/); - }); + ); + + if (DEBUG) { + deprecatedTest( + 'Errors out if you do not define an inverse for a reflexive relationship', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 1 }, + function (assert) { + class ReflexiveModel extends Model { + @belongsTo('reflexive-model', { async: false }) + reflexiveProp; + + toString() { + return stringify('reflexiveModel'); + } + } + + let { owner } = this; + owner.register('model:reflexive-model', ReflexiveModel); + + //Maybe store is evaluated lazily, so we need this :( + assert.expectWarning(() => { + var reflexiveModel; + store.push({ + data: { + type: 'reflexive-model', + id: '1', + }, + }); + reflexiveModel = store.peekRecord('reflexive-model', 1); + reflexiveModel.reflexiveProp; + }, /Detected a reflexive relationship by the name of 'reflexiveProp'/); + } + ); + } }); diff --git a/packages/-ember-data/tests/integration/polymorphic-belongs-to-test.js b/packages/-ember-data/tests/integration/polymorphic-belongs-to-test.js index f3cd4e9f311..30321d89a1b 100644 --- a/packages/-ember-data/tests/integration/polymorphic-belongs-to-test.js +++ b/packages/-ember-data/tests/integration/polymorphic-belongs-to-test.js @@ -14,7 +14,7 @@ module('integration/polymorphic-belongs-to - Polymorphic BelongsTo', function (h @attr() title; - @belongsTo('author', { polymorphic: true, async: false }) + @belongsTo('author', { polymorphic: true, async: false, inverse: null }) author; } @@ -26,7 +26,7 @@ module('integration/polymorphic-belongs-to - Polymorphic BelongsTo', function (h class Person extends Model {} class AsyncBook extends Model { - @belongsTo('author', { polymorphic: true }) + @belongsTo('author', { polymorphic: true, async: true, inverse: null }) author; } owner.register('model:book', Book); @@ -41,20 +41,20 @@ module('integration/polymorphic-belongs-to - Polymorphic BelongsTo', function (h let payload = { data: { type: 'book', - id: 1, + id: '1', title: 'Yes, Please', relationships: { author: { data: { type: 'author', - id: 1, + id: '1', }, }, }, }, included: [ { - id: 1, + id: '1', name: 'Amy Poehler', type: 'author', }, @@ -68,7 +68,7 @@ module('integration/polymorphic-belongs-to - Polymorphic BelongsTo', function (h let payloadThatResetsBelongToRelationship = { data: { type: 'book', - id: 1, + id: '1', title: 'Yes, Please', relationships: { author: { @@ -86,20 +86,20 @@ module('integration/polymorphic-belongs-to - Polymorphic BelongsTo', function (h let payload = { data: { type: 'async-book', - id: 1, + id: '1', title: 'Yes, Please', relationships: { author: { data: { type: 'author', - id: 1, + id: '1', }, }, }, }, included: [ { - id: 1, + id: '1', name: 'Amy Poehler', type: 'author', }, @@ -112,7 +112,7 @@ module('integration/polymorphic-belongs-to - Polymorphic BelongsTo', function (h let payloadThatResetsBelongToRelationship = { data: { type: 'async-book', - id: 1, + id: '1', title: 'Yes, Please', relationships: { author: { diff --git a/packages/-ember-data/tests/integration/record-array-manager-test.js b/packages/-ember-data/tests/integration/record-array-manager-test.js index 9f99f8f9652..163082e023a 100644 --- a/packages/-ember-data/tests/integration/record-array-manager-test.js +++ b/packages/-ember-data/tests/integration/record-array-manager-test.js @@ -16,7 +16,7 @@ class Person extends Model { @attr() name; - @hasMany('car', { async: false }) + @hasMany('car', { async: false, inverse: 'person' }) cars; } @@ -27,7 +27,7 @@ class Car extends Model { @attr() model; - @belongsTo('person', { async: false }) + @belongsTo('person', { async: false, inverse: 'cars' }) person; } @@ -189,7 +189,7 @@ module('integration/record_array_manager', function (hooks) { data: [ { type: 'car', - id: 2, // this ID is already present, array wont need to change + id: '2', // this ID is already present, array wont need to change attributes: { make: 'Tesla', model: 'S', @@ -205,7 +205,7 @@ module('integration/record_array_manager', function (hooks) { data: [ { type: 'car', - id: 3, + id: '3', attributes: { make: 'Tesla', model: 'S', diff --git a/packages/-ember-data/tests/integration/record-data/record-data-test.ts b/packages/-ember-data/tests/integration/record-data/record-data-test.ts index c8b6dbe5014..2691fdc423e 100644 --- a/packages/-ember-data/tests/integration/record-data/record-data-test.ts +++ b/packages/-ember-data/tests/integration/record-data/record-data-test.ts @@ -321,7 +321,7 @@ module('integration/record-data - Custom RecordData Implementations', function ( calledRollbackAttributes = 0; calledDidCommit = 0; - let clientPerson = store.createRecord('person', { id: 2 }); + let clientPerson = store.createRecord('person', { id: '2' }); assert.strictEqual(calledClientDidCreate, 1, 'Called clientDidCreate'); clientPerson.save(); diff --git a/packages/-ember-data/tests/integration/record-data/store-wrapper-test.ts b/packages/-ember-data/tests/integration/record-data/store-wrapper-test.ts index 3248ea422ed..0a4a351828b 100644 --- a/packages/-ember-data/tests/integration/record-data/store-wrapper-test.ts +++ b/packages/-ember-data/tests/integration/record-data/store-wrapper-test.ts @@ -14,7 +14,7 @@ class Person extends Model { } class Car extends Model { - @belongsTo('house') + @belongsTo('house', { async: true, inverse: 'car' }) garage; @attr('string', {}) @@ -25,13 +25,13 @@ class House extends Model { @attr('string', {}) name; - @belongsTo('person', { async: false }) + @belongsTo('person', { async: false, inverse: null }) landlord; - @belongsTo('car', { async: false }) + @belongsTo('car', { async: false, inverse: 'garage' }) car; - @hasMany('person', { async: false }) + @hasMany('person', { async: false, inverse: null }) tenants; } @@ -172,20 +172,20 @@ module('integration/store-wrapper - RecordData StoreWrapper tests', function (ho kind: 'belongsTo', name: 'landlord', type: 'person', - options: { async: false }, + options: { async: false, inverse: null }, }, car: { key: 'car', kind: 'belongsTo', name: 'car', type: 'car', - options: { async: false }, + options: { async: false, inverse: 'garage' }, }, tenants: { key: 'tenants', kind: 'hasMany', name: 'tenants', - options: { async: false }, + options: { async: false, inverse: null }, type: 'person', }, }; diff --git a/packages/-ember-data/tests/integration/records/delete-record-test.js b/packages/-ember-data/tests/integration/records/delete-record-test.js index 132e6398fda..fe548cc834d 100644 --- a/packages/-ember-data/tests/integration/records/delete-record-test.js +++ b/packages/-ember-data/tests/integration/records/delete-record-test.js @@ -268,7 +268,7 @@ module('integration/deletedRecord - Deleting Records', function (hooks) { assert.ok(true, 'save operation resolves'); return EmberPromise.resolve({ data: { - id: 123, + id: '123', type: 'person', }, }); @@ -357,7 +357,7 @@ module('integration/deletedRecord - Deleting Records', function (hooks) { } } class Group extends Model { - @belongsTo('company', { async: true }) company; + @belongsTo('company', { async: true, inverse: null }) company; @hasMany('employee', { inverse: 'groups', async: true }) employees; toString() { return 'Group'; diff --git a/packages/-ember-data/tests/integration/records/relationship-changes-test.js b/packages/-ember-data/tests/integration/records/relationship-changes-test.js index bf37c550a48..f7a3c4af849 100644 --- a/packages/-ember-data/tests/integration/records/relationship-changes-test.js +++ b/packages/-ember-data/tests/integration/records/relationship-changes-test.js @@ -17,13 +17,13 @@ const Author = Model.extend({ }); const Post = Model.extend({ - author: belongsTo(), + author: belongsTo('author', { async: true, inverse: null }), }); const Person = Model.extend({ firstName: attr('string'), lastName: attr('string'), - siblings: hasMany('person'), + siblings: hasMany('person', { async: true, inverse: 'siblings' }), }); const sibling1 = { @@ -916,7 +916,7 @@ module('integration/records/relationship-changes - Relationship changes', functi }, included: [ { - id: 2, + id: '2', type: 'author', }, ], diff --git a/packages/-ember-data/tests/integration/records/reload-test.js b/packages/-ember-data/tests/integration/records/reload-test.js index e6787d2b00a..c7768421a6c 100644 --- a/packages/-ember-data/tests/integration/records/reload-test.js +++ b/packages/-ember-data/tests/integration/records/reload-test.js @@ -119,7 +119,7 @@ module('integration/reload - Reloading Records', function (hooks) { return reject(); } else { return resolve({ - data: { id: 1, type: 'person', attributes: { name: 'Thomas Dale' } }, + data: { id: '1', type: 'person', attributes: { name: 'Thomas Dale' } }, }); } }, diff --git a/packages/-ember-data/tests/integration/records/rematerialize-test.js b/packages/-ember-data/tests/integration/records/rematerialize-test.js index 1327d69ea48..97d2a51bd4e 100644 --- a/packages/-ember-data/tests/integration/records/rematerialize-test.js +++ b/packages/-ember-data/tests/integration/records/rematerialize-test.js @@ -22,14 +22,14 @@ module('integration/unload - Rematerializing Unloaded Records', function (hooks) test('a sync belongs to relationship to an unloaded record can restore that record', function (assert) { const Person = Model.extend({ name: attr('string'), - cars: hasMany('car', { async: false }), + cars: hasMany('car', { async: false, inverse: 'person' }), toString: () => 'Person', }); const Car = Model.extend({ make: attr('string'), model: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'cars' }), toString: () => 'Car', }); @@ -127,13 +127,13 @@ module('integration/unload - Rematerializing Unloaded Records', function (hooks) const Person = Model.extend({ name: attr('string'), - boats: hasMany('boat', { async: true }), + boats: hasMany('boat', { async: true, inverse: 'person' }), toString: () => 'Person', }); const Boat = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'boats' }), toString: () => 'Boat', }); diff --git a/packages/-ember-data/tests/integration/records/save-test.js b/packages/-ember-data/tests/integration/records/save-test.js index 51a5cb40176..d4f2959250e 100644 --- a/packages/-ember-data/tests/integration/records/save-test.js +++ b/packages/-ember-data/tests/integration/records/save-test.js @@ -42,7 +42,7 @@ module('integration/records/save - Save Record', function (hooks) { assert.strictEqual(saved.id, undefined); } - deferred.resolve({ data: { id: 123, type: 'post' } }); + deferred.resolve({ data: { id: '123', type: 'post' } }); let model = await saved; assert.ok(true, 'save operation was resolved'); if (DEPRECATE_SAVE_PROMISE_ACCESS) { @@ -96,7 +96,7 @@ module('integration/records/save - Save Record', function (hooks) { if (count++ === 0) { return reject(error); } else { - return resolve({ data: { id: 123, type: 'post' } }); + return resolve({ data: { id: '123', type: 'post' } }); } }; diff --git a/packages/-ember-data/tests/integration/records/unload-test.js b/packages/-ember-data/tests/integration/records/unload-test.js index 5aa9fa176a8..b8b6f538a1a 100644 --- a/packages/-ember-data/tests/integration/records/unload-test.js +++ b/packages/-ember-data/tests/integration/records/unload-test.js @@ -21,29 +21,29 @@ function idsFromArr(arr) { class Person extends Model { @attr('string') name; // 1:many sync - @hasMany('car', { async: false }) cars; + @hasMany('car', { async: false, inverse: 'person' }) cars; // 1:many async - @hasMany('boat', { async: true }) boats; + @hasMany('boat', { async: true, inverse: 'person' }) boats; // many:many sync - @hasMany('group', { async: false }) groups; + @hasMany('group', { async: false, inverse: 'people' }) groups; // many:many async - @hasMany('people', { async: true }) friends; + @hasMany('person', { async: true, inverse: 'friends' }) friends; // 1:1 sync inverse null @belongsTo('bike', { async: false, inverse: null }) bike; // 1:1 sync - @belongsTo('house', { async: false }) house; + @belongsTo('house', { async: false, inverse: 'person' }) house; // 1:1 async - @belongsTo('mortgage', { async: true }) mortgage; + @belongsTo('mortgage', { async: true, inverse: 'person' }) mortgage; // 1 async : 1 sync - @belongsTo('book', { async: false }) favoriteBook; + @belongsTo('book', { async: false, inverse: 'person' }) favoriteBook; // 1 async : many sync - @hasMany('spoon', { async: false }) favoriteSpoons; + @hasMany('spoon', { async: false, inverse: 'person' }) favoriteSpoons; // 1 sync: many async - @hasMany('show', { async: true }) favoriteShows; + @hasMany('show', { async: true, inverse: 'person' }) favoriteShows; // many sync : many async - @hasMany('people', { async: true, inverse: 'favoriteAsyncFriends' }) favoriteFriends; + @hasMany('person', { async: true, inverse: 'favoriteAsyncFriends' }) favoriteFriends; // many async : many sync - @hasMany('people', { async: false, inverse: 'favoriteFriends' }) favoriteAsyncFriends; + @hasMany('person', { async: false, inverse: 'favoriteFriends' }) favoriteAsyncFriends; static toString() { return 'Person'; @@ -51,7 +51,7 @@ class Person extends Model { } class House extends Model { - @belongsTo('person', { async: false }) person; + @belongsTo('person', { async: false, inverse: 'house' }) person; static toString() { return 'House'; @@ -59,7 +59,7 @@ class House extends Model { } class Mortgage extends Model { - @belongsTo('person', { async: true }) person; + @belongsTo('person', { async: true, inverse: 'mortgage' }) person; static toString() { return 'Mortgage'; @@ -67,7 +67,7 @@ class Mortgage extends Model { } class Group extends Model { - @hasMany('person', { async: false }) people; + @hasMany('person', { async: false, inverse: 'groups' }) people; static toString() { return 'Group'; @@ -77,7 +77,7 @@ class Group extends Model { class Car extends Model { @attr('string') make; @attr('string') model; - @belongsTo('person', { async: false }) person; + @belongsTo('person', { async: false, inverse: 'cars' }) person; static toString() { return 'Car'; @@ -86,7 +86,7 @@ class Car extends Model { const Boat = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: true }), + person: belongsTo('person', { async: true, inverse: 'boats' }), }); Boat.toString = function () { return 'Boat'; @@ -100,21 +100,21 @@ Bike.toString = function () { }; const Book = Model.extend({ - person: belongsTo('person', { async: true }), + person: belongsTo('person', { async: true, inverse: 'favoriteBook' }), }); Book.toString = function () { return 'Book'; }; const Spoon = Model.extend({ - person: belongsTo('person', { async: true }), + person: belongsTo('person', { async: true, inverse: 'favoriteSpoons' }), }); Spoon.toString = function () { return 'Spoon'; }; const Show = Model.extend({ - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'favoriteShows' }), }); Show.toString = function () { return 'Show'; @@ -156,7 +156,7 @@ module('integration/unload - Unloading Records', function (hooks) { cars: { data: [ { - id: 1, + id: '1', type: 'car', }, ], @@ -164,7 +164,7 @@ module('integration/unload - Unloading Records', function (hooks) { boats: { data: [ { - id: 2, + id: '2', type: 'boat', }, ], @@ -242,7 +242,7 @@ module('integration/unload - Unloading Records', function (hooks) { run(function () { store.push({ data: { - id: 1, + id: '1', type: 'person', attributes: { name: 'Richard II', @@ -642,7 +642,7 @@ module('integration/unload - Unloading Records', function (hooks) { cars: { data: [ { - id: 1, + id: '1', type: 'car', }, ], @@ -652,7 +652,7 @@ module('integration/unload - Unloading Records', function (hooks) { included: [ { type: 'car', - id: 1, + id: '1', attributes: { make: 'jeep', model: 'wrangler', @@ -949,12 +949,12 @@ module('integration/unload - Unloading Records', function (hooks) { run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { house: { data: { - id: 2, + id: '2', type: 'house', }, }, @@ -962,7 +962,7 @@ module('integration/unload - Unloading Records', function (hooks) { }, included: [ { - id: 2, + id: '2', type: 'house', }, ], @@ -983,7 +983,7 @@ module('integration/unload - Unloading Records', function (hooks) { house = run(() => store.push({ data: { - id: 2, + id: '2', type: 'house', }, }) @@ -996,12 +996,12 @@ module('integration/unload - Unloading Records', function (hooks) { run(() => store.push({ data: { - id: 2, + id: '2', type: 'house', relationships: { person: { data: { - id: 1, + id: '1', type: 'person', }, }, @@ -1018,17 +1018,17 @@ module('integration/unload - Unloading Records', function (hooks) { run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { cars: { data: [ { - id: 2, + id: '2', type: 'car', }, { - id: 3, + id: '3', type: 'car', }, ], @@ -1037,11 +1037,11 @@ module('integration/unload - Unloading Records', function (hooks) { }, included: [ { - id: 2, + id: '2', type: 'car', }, { - id: 3, + id: '3', type: 'car', }, ], @@ -1069,7 +1069,7 @@ module('integration/unload - Unloading Records', function (hooks) { person = run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', }, }) @@ -1083,17 +1083,17 @@ module('integration/unload - Unloading Records', function (hooks) { run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { cars: { data: [ { - id: 2, + id: '2', type: 'car', }, { - id: 3, + id: '3', type: 'car', }, ], @@ -1112,17 +1112,17 @@ module('integration/unload - Unloading Records', function (hooks) { run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { cars: { data: [ { - id: 2, + id: '2', type: 'car', }, { - id: 3, + id: '3', type: 'car', }, ], @@ -1131,11 +1131,11 @@ module('integration/unload - Unloading Records', function (hooks) { }, included: [ { - id: 2, + id: '2', type: 'car', }, { - id: 3, + id: '3', type: 'car', }, ], @@ -1163,7 +1163,7 @@ module('integration/unload - Unloading Records', function (hooks) { car2 = run(() => store.push({ data: { - id: 2, + id: '2', type: 'car', }, }) @@ -1176,17 +1176,17 @@ module('integration/unload - Unloading Records', function (hooks) { run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { cars: { data: [ { - id: 2, + id: '2', type: 'car', }, { - id: 3, + id: '3', type: 'car', }, ], @@ -1205,17 +1205,17 @@ module('integration/unload - Unloading Records', function (hooks) { store.push({ data: [ { - id: 1, + id: '1', type: 'person', relationships: { groups: { data: [ { - id: 3, + id: '3', type: 'group', }, { - id: 4, + id: '4', type: 'group', }, ], @@ -1223,17 +1223,17 @@ module('integration/unload - Unloading Records', function (hooks) { }, }, { - id: 2, + id: '2', type: 'person', relationships: { groups: { data: [ { - id: 3, + id: '3', type: 'group', }, { - id: 4, + id: '4', type: 'group', }, ], @@ -1243,11 +1243,11 @@ module('integration/unload - Unloading Records', function (hooks) { ], included: [ { - id: 3, + id: '3', type: 'group', }, { - id: 4, + id: '4', type: 'group', }, ], @@ -1287,7 +1287,7 @@ module('integration/unload - Unloading Records', function (hooks) { person2 = run(() => store.push({ data: { - id: 2, + id: '2', type: 'person', }, }) @@ -1301,17 +1301,17 @@ module('integration/unload - Unloading Records', function (hooks) { run(() => store.push({ data: { - id: 2, + id: '2', type: 'person', relationships: { groups: { data: [ { - id: 3, + id: '3', type: 'group', }, { - id: 4, + id: '4', type: 'group', }, ], @@ -1336,7 +1336,7 @@ module('integration/unload - Unloading Records', function (hooks) { return { data: { - id: 2, + id: '2', type: 'mortgage', }, }; @@ -1345,12 +1345,12 @@ module('integration/unload - Unloading Records', function (hooks) { let person = run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { mortgage: { data: { - id: 2, + id: '2', type: 'mortgage', }, }, @@ -1399,7 +1399,7 @@ module('integration/unload - Unloading Records', function (hooks) { return { data: { - id: 1, + id: '1', type: 'person', }, }; @@ -1413,11 +1413,11 @@ module('integration/unload - Unloading Records', function (hooks) { return { data: [ { - id: 2, + id: '2', type: 'boat', }, { - id: 3, + id: '3', type: 'boat', }, ], @@ -1427,17 +1427,17 @@ module('integration/unload - Unloading Records', function (hooks) { let person = run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { boats: { data: [ { - id: 2, + id: '2', type: 'boat', }, { - id: 3, + id: '3', type: 'boat', }, ], @@ -1496,11 +1496,11 @@ module('integration/unload - Unloading Records', function (hooks) { return { data: [ { - id: 2, + id: '2', type: 'boat', }, { - id: 3, + id: '3', type: 'boat', }, ], @@ -1509,17 +1509,17 @@ module('integration/unload - Unloading Records', function (hooks) { let person = store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { boats: { data: [ { - id: 2, + id: '2', type: 'boat', }, { - id: 3, + id: '3', type: 'boat', }, ], @@ -1570,11 +1570,11 @@ module('integration/unload - Unloading Records', function (hooks) { return { data: [ { - id: 3, + id: '3', type: 'person', }, { - id: 4, + id: '4', type: 'person', }, ], @@ -1584,17 +1584,17 @@ module('integration/unload - Unloading Records', function (hooks) { let [person1, person2] = store.push({ data: [ { - id: 1, + id: '1', type: 'person', relationships: { friends: { data: [ { - id: 3, + id: '3', type: 'person', }, { - id: 4, + id: '4', type: 'person', }, ], @@ -1602,17 +1602,17 @@ module('integration/unload - Unloading Records', function (hooks) { }, }, { - id: 2, + id: '2', type: 'person', relationships: { friends: { data: [ { - id: 3, + id: '3', type: 'person', }, { - id: 4, + id: '4', type: 'person', }, ], @@ -1712,7 +1712,7 @@ module('integration/unload - Unloading Records', function (hooks) { relationships: { person: { data: { - id: 1, + id: '1', type: 'person', }, }, @@ -1735,7 +1735,7 @@ module('integration/unload - Unloading Records', function (hooks) { return { data: { - id: 1, + id: '1', type: 'person', }, }; @@ -1744,12 +1744,12 @@ module('integration/unload - Unloading Records', function (hooks) { run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { favoriteBook: { data: { - id: 2, + id: '2', type: 'book', }, }, @@ -1757,7 +1757,7 @@ module('integration/unload - Unloading Records', function (hooks) { }, included: [ { - id: 2, + id: '2', type: 'book', }, ], @@ -1793,17 +1793,17 @@ module('integration/unload - Unloading Records', function (hooks) { run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { favoriteSpoons: { data: [ { - id: 2, + id: '2', type: 'spoon', }, { - id: 3, + id: '3', type: 'spoon', }, ], @@ -1812,11 +1812,11 @@ module('integration/unload - Unloading Records', function (hooks) { }, included: [ { - id: 2, + id: '2', type: 'spoon', }, { - id: 3, + id: '3', type: 'spoon', }, ], @@ -1848,7 +1848,7 @@ module('integration/unload - Unloading Records', function (hooks) { spoon2 = run(() => store.push({ data: { - id: 2, + id: '2', type: 'spoon', }, }) @@ -1869,17 +1869,17 @@ module('integration/unload - Unloading Records', function (hooks) { run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { favoriteSpoons: { data: [ { - id: 2, + id: '2', type: 'spoon', }, { - id: 3, + id: '3', type: 'spoon', }, ], @@ -1913,7 +1913,7 @@ module('integration/unload - Unloading Records', function (hooks) { let person = store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { favoriteSpoons: { @@ -1982,11 +1982,11 @@ module('integration/unload - Unloading Records', function (hooks) { return { data: [ { - id: 2, + id: '2', type: 'show', }, { - id: 3, + id: '3', type: 'show', }, ], @@ -1995,17 +1995,17 @@ module('integration/unload - Unloading Records', function (hooks) { let person = store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { favoriteShows: { data: [ { - id: 2, + id: '2', type: 'show', }, { - id: 3, + id: '3', type: 'show', }, ], @@ -2053,11 +2053,11 @@ module('integration/unload - Unloading Records', function (hooks) { return { data: [ { - id: 2, + id: '2', type: 'show', }, { - id: 3, + id: '3', type: 'show', }, ], @@ -2167,14 +2167,14 @@ module('integration/unload - Unloading Records', function (hooks) { person: { data: { type: 'person', - id: 1, + id: '1', }, }, }; let data = [ { - id: 3, + id: '3', type: 'boat', relationships, }, @@ -2182,7 +2182,7 @@ module('integration/unload - Unloading Records', function (hooks) { if (!isUnloaded) { data.unshift({ - id: 2, + id: '2', type: 'boat', relationships, }); @@ -2196,7 +2196,7 @@ module('integration/unload - Unloading Records', function (hooks) { let person = run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', relationships: { boats: { @@ -2243,7 +2243,7 @@ module('integration/unload - Unloading Records', function (hooks) { return { data: { - id: 1, + id: '1', type: 'person', }, }; @@ -2252,7 +2252,7 @@ module('integration/unload - Unloading Records', function (hooks) { run(() => store.push({ data: { - id: 1, + id: '1', type: 'person', }, }) diff --git a/packages/-ember-data/tests/integration/references/belongs-to-test.js b/packages/-ember-data/tests/integration/references/belongs-to-test.js index 1d9a6461eac..20084979c82 100644 --- a/packages/-ember-data/tests/integration/references/belongs-to-test.js +++ b/packages/-ember-data/tests/integration/references/belongs-to-test.js @@ -4,10 +4,10 @@ import { run } from '@ember/runloop'; import { module, test } from 'qunit'; import { defer, resolve } from 'rsvp'; -import DS from 'ember-data'; import { setupTest } from 'ember-qunit'; import JSONAPIAdapter from '@ember-data/adapter/json-api'; +import Model, { attr, belongsTo, hasMany } from '@ember-data/model'; import JSONAPISerializer from '@ember-data/serializer/json-api'; import testInDebug from '@ember-data/unpublished-test-infra/test-support/test-in-debug'; @@ -15,13 +15,13 @@ module('integration/references/belongs-to', function (hooks) { setupTest(hooks); hooks.beforeEach(function () { - const Family = DS.Model.extend({ - persons: DS.hasMany(), - name: DS.attr(), + const Family = Model.extend({ + persons: hasMany('person', { async: true, inverse: 'family' }), + name: attr(), }); - const Person = DS.Model.extend({ - family: DS.belongsTo({ async: true }), + const Person = Model.extend({ + family: belongsTo('family', { async: true, inverse: 'persons' }), }); this.owner.register('model:family', Family); @@ -39,7 +39,7 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', }, }); }); @@ -61,7 +61,7 @@ module('integration/references/belongs-to', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', }, }); }); @@ -82,10 +82,10 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { - data: { type: 'family', id: 1 }, + data: { type: 'family', id: '1' }, }, }, }, @@ -107,7 +107,7 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { links: { related: '/families/1' }, @@ -132,7 +132,7 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { links: { @@ -162,10 +162,10 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { - data: { type: 'family', id: 1 }, + data: { type: 'family', id: '1' }, }, }, }, @@ -178,7 +178,7 @@ module('integration/references/belongs-to', function (hooks) { var data = { data: { type: 'family', - id: 1, + id: '1', attributes: { name: 'Coreleone', }, @@ -207,10 +207,10 @@ module('integration/references/belongs-to', function (hooks) { var person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { - data: { type: 'family', id: 1 }, + data: { type: 'family', id: '1' }, }, }, }, @@ -225,7 +225,7 @@ module('integration/references/belongs-to', function (hooks) { deferred.resolve({ data: { type: 'family', - id: 1, + id: '1', attributes: { name: 'Coreleone', }, @@ -249,10 +249,10 @@ module('integration/references/belongs-to', function (hooks) { let person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { - data: { type: 'family', id: 1 }, + data: { type: 'family', id: '1' }, }, }, }, @@ -260,7 +260,7 @@ module('integration/references/belongs-to', function (hooks) { let anotherPerson = { data: { type: 'person', - id: 2, + id: '2', }, }; @@ -305,10 +305,10 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { - data: { type: 'family', id: 1 }, + data: { type: 'family', id: '1' }, }, }, }, @@ -327,10 +327,10 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { - data: { type: 'family', id: 1 }, + data: { type: 'family', id: '1' }, }, }, }, @@ -338,7 +338,7 @@ module('integration/references/belongs-to', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', }, }); }); @@ -352,10 +352,10 @@ module('integration/references/belongs-to', function (hooks) { let person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { - data: { type: 'family', id: 1 }, + data: { type: 'family', id: '1' }, }, }, }, @@ -363,7 +363,7 @@ module('integration/references/belongs-to', function (hooks) { let family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { links: { @@ -390,7 +390,7 @@ module('integration/references/belongs-to', function (hooks) { assert.strictEqual(snapshot.adapterOptions, adapterOptions, 'adapterOptions are passed in'); return resolve({ data: { - id: 1, + id: '1', type: 'family', attributes: { name: 'Coreleone' }, }, @@ -402,10 +402,10 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { - data: { type: 'family', id: 1 }, + data: { type: 'family', id: '1' }, }, }, }, @@ -437,7 +437,7 @@ module('integration/references/belongs-to', function (hooks) { return resolve({ data: { - id: 1, + id: '1', type: 'family', attributes: { name: 'Coreleone' }, }, @@ -449,7 +449,7 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { links: { related: '/families/1' }, @@ -490,7 +490,7 @@ module('integration/references/belongs-to', function (hooks) { const person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { links: { related: '/families/1' }, @@ -525,7 +525,7 @@ module('integration/references/belongs-to', function (hooks) { return resolve({ data: { - id: 1, + id: '1', type: 'family', attributes: { name: 'Coreleone' }, }, @@ -537,10 +537,10 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { - data: { type: 'family', id: 1 }, + data: { type: 'family', id: '1' }, }, }, }, @@ -575,7 +575,7 @@ module('integration/references/belongs-to', function (hooks) { return resolve({ data: { - id: 1, + id: '1', type: 'family', attributes: { name: 'Coreleone' }, }, @@ -587,10 +587,10 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { - data: { type: 'family', id: 1 }, + data: { type: 'family', id: '1' }, }, }, }, @@ -598,7 +598,7 @@ module('integration/references/belongs-to', function (hooks) { store.push({ data: { type: 'family', - id: 1, + id: '1', }, }); }); @@ -629,7 +629,7 @@ module('integration/references/belongs-to', function (hooks) { return resolve({ data: { - id: 1, + id: '1', type: 'family', attributes: { name: 'Coreleone' }, }, @@ -641,7 +641,7 @@ module('integration/references/belongs-to', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', relationships: { family: { links: { related: '/families/1' }, diff --git a/packages/-ember-data/tests/integration/references/has-many-test.js b/packages/-ember-data/tests/integration/references/has-many-test.js index 459608d8a83..91f8ed9d539 100755 --- a/packages/-ember-data/tests/integration/references/has-many-test.js +++ b/packages/-ember-data/tests/integration/references/has-many-test.js @@ -8,6 +8,7 @@ import { gte } from 'ember-compatibility-helpers'; import DS from 'ember-data'; import { setupRenderingTest } from 'ember-qunit'; +import Model, { attr, belongsTo, hasMany } from '@ember-data/model'; import JSONAPISerializer from '@ember-data/serializer/json-api'; import testInDebug from '@ember-data/unpublished-test-infra/test-support/test-in-debug'; @@ -17,18 +18,18 @@ module('integration/references/has-many', function (hooks) { setupRenderingTest(hooks); hooks.beforeEach(function () { - const Family = DS.Model.extend({ - persons: DS.hasMany({ async: true }), + const Family = Model.extend({ + persons: hasMany('person', { async: true, inverse: 'family' }), }); - const Person = DS.Model.extend({ - name: DS.attr(), - family: DS.belongsTo(), - pets: DS.hasMany({ async: true }), + const Person = Model.extend({ + name: attr(), + family: belongsTo('family', { async: true, inverse: 'persons' }), + pets: hasMany('pet', { async: true, inverse: null }), }); - const Pet = DS.Model.extend({ - name: DS.attr(), + const Pet = Model.extend({ + name: attr(), }); this.owner.register('model:family', Family); @@ -47,7 +48,7 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', }, }); }); @@ -69,7 +70,7 @@ module('integration/references/has-many', function (hooks) { person = store.push({ data: { type: 'person', - id: 1, + id: '1', }, }); }); @@ -90,12 +91,12 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [ - { type: 'person', id: 1 }, - { type: 'person', id: 2 }, + { type: 'person', id: '1' }, + { type: 'person', id: '2' }, ], }, }, @@ -118,7 +119,7 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { links: { related: '/families/1/persons' }, @@ -143,7 +144,7 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { links: { related: '/families/1/persons' }, @@ -268,12 +269,12 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [ - { type: 'person', id: 1 }, - { type: 'person', id: 2 }, + { type: 'person', id: '1' }, + { type: 'person', id: '2' }, ], }, }, @@ -285,8 +286,8 @@ module('integration/references/has-many', function (hooks) { run(function () { var data = [ - { data: { type: 'person', id: 1, attributes: { name: 'Vito' } } }, - { data: { type: 'person', id: 2, attributes: { name: 'Michael' } } }, + { data: { type: 'person', id: '1', attributes: { name: 'Vito' } } }, + { data: { type: 'person', id: '2', attributes: { name: 'Michael' } } }, ]; personsReference.push(data).then(function (records) { @@ -313,7 +314,7 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', }, }); }); @@ -321,7 +322,7 @@ module('integration/references/has-many', function (hooks) { var personsReference = family.hasMany('persons'); run(() => { - var data = [{ data: { type: 'mafia-boss', id: 1, attributes: { name: 'Vito' } } }]; + var data = [{ data: { type: 'mafia-boss', id: '1', attributes: { name: 'Vito' } } }]; personsReference.push(data).then(function (records) { assert.ok(records instanceof DS.ManyArray, 'push resolves with the referenced records'); @@ -338,7 +339,7 @@ module('integration/references/has-many', function (hooks) { let family = store.push({ data: { type: 'family', - id: 1, + id: '1', }, }); let personsReference = family.hasMany('persons'); @@ -358,12 +359,12 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [ - { type: 'person', id: 1 }, - { type: 'person', id: 2 }, + { type: 'person', id: '1' }, + { type: 'person', id: '2' }, ], }, }, @@ -376,8 +377,8 @@ module('integration/references/has-many', function (hooks) { run(function () { var payload = { data: [ - { data: { type: 'person', id: 1, attributes: { name: 'Vito' } } }, - { data: { type: 'person', id: 2, attributes: { name: 'Michael' } } }, + { data: { type: 'person', id: '1', attributes: { name: 'Vito' } } }, + { data: { type: 'person', id: '2', attributes: { name: 'Michael' } } }, ], }; @@ -399,12 +400,12 @@ module('integration/references/has-many', function (hooks) { const family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [ - { type: 'person', id: 1 }, - { type: 'person', id: 2 }, + { type: 'person', id: '1' }, + { type: 'person', id: '2' }, ], }, }, @@ -417,8 +418,8 @@ module('integration/references/has-many', function (hooks) { const payload = { data: [ - { data: { type: 'person', id: 1, attributes: { name: 'Vito' } } }, - { data: { type: 'person', id: 2, attributes: { name: 'Michael' } } }, + { data: { type: 'person', id: '1', attributes: { name: 'Vito' } } }, + { data: { type: 'person', id: '2', attributes: { name: 'Michael' } } }, ], }; @@ -437,12 +438,12 @@ module('integration/references/has-many', function (hooks) { const family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [ - { type: 'person', id: 1 }, - { type: 'person', id: 2 }, + { type: 'person', id: '1' }, + { type: 'person', id: '2' }, ], }, }, @@ -451,8 +452,8 @@ module('integration/references/has-many', function (hooks) { const personsReference = family.hasMany('persons'); const payload = { data: [ - { type: 'person', id: 1, attributes: { name: 'Vito' } }, - { type: 'person', id: 2, attributes: { name: 'Michael' } }, + { type: 'person', id: '1', attributes: { name: 'Vito' } }, + { type: 'person', id: '2', attributes: { name: 'Michael' } }, ], }; const pushResult = personsReference.push(payload); @@ -473,12 +474,12 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [ - { type: 'person', id: 1 }, - { type: 'person', id: 2 }, + { type: 'person', id: '1' }, + { type: 'person', id: '2' }, ], }, }, @@ -498,19 +499,19 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [ - { type: 'person', id: 1 }, - { type: 'person', id: 2 }, + { type: 'person', id: '1' }, + { type: 'person', id: '2' }, ], }, }, }, }); - store.push({ data: { type: 'person', id: 1, attributes: { name: 'Vito' } } }); - store.push({ data: { type: 'person', id: 2, attributes: { name: 'Michael' } } }); + store.push({ data: { type: 'person', id: '1', attributes: { name: 'Vito' } } }); + store.push({ data: { type: 'person', id: '2', attributes: { name: 'Michael' } } }); }); run(function () { @@ -529,7 +530,7 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [], @@ -554,7 +555,7 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [], @@ -583,8 +584,8 @@ module('integration/references/has-many', function (hooks) { assert.strictEqual(snapshots[0].adapterOptions, adapterOptions, 'adapterOptions are passed in'); return resolve({ data: [ - { id: 1, type: 'person', attributes: { name: 'Vito' } }, - { id: 2, type: 'person', attributes: { name: 'Michael' } }, + { id: '1', type: 'person', attributes: { name: 'Vito' } }, + { id: '2', type: 'person', attributes: { name: 'Michael' } }, ], }); }; @@ -594,12 +595,12 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [ - { type: 'person', id: 1 }, - { type: 'person', id: 2 }, + { type: 'person', id: '1' }, + { type: 'person', id: '2' }, ], }, }, @@ -635,8 +636,8 @@ module('integration/references/has-many', function (hooks) { return resolve({ data: [ - { id: 1, type: 'person', attributes: { name: 'Vito' } }, - { id: 2, type: 'person', attributes: { name: 'Michael' } }, + { id: '1', type: 'person', attributes: { name: 'Vito' } }, + { id: '2', type: 'person', attributes: { name: 'Michael' } }, ], }); }; @@ -646,7 +647,7 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { links: { related: '/families/1/persons' }, @@ -689,7 +690,7 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { links: { related: '/families/1/persons' }, @@ -730,12 +731,12 @@ module('integration/references/has-many', function (hooks) { const family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [ - { type: 'person', id: 1 }, - { type: 'person', id: 2 }, + { type: 'person', id: '1' }, + { type: 'person', id: '2' }, ], }, }, @@ -749,8 +750,8 @@ module('integration/references/has-many', function (hooks) { resolveRequest({ data: [ - { id: 1, type: 'person', attributes: { name: 'Vito' } }, - { id: 2, type: 'person', attributes: { name: 'Michael' } }, + { id: '1', type: 'person', attributes: { name: 'Vito' } }, + { id: '2', type: 'person', attributes: { name: 'Michael' } }, ], }); @@ -774,8 +775,8 @@ module('integration/references/has-many', function (hooks) { assert.strictEqual(snapshots[0].adapterOptions, adapterOptions, 'adapterOptions are passed in'); return resolve({ data: [ - { id: 1, type: 'person', attributes: { name: 'Vito Coreleone' } }, - { id: 2, type: 'person', attributes: { name: 'Michael Coreleone' } }, + { id: '1', type: 'person', attributes: { name: 'Vito Coreleone' } }, + { id: '2', type: 'person', attributes: { name: 'Michael Coreleone' } }, ], }); }; @@ -785,19 +786,19 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { data: [ - { type: 'person', id: 1 }, - { type: 'person', id: 2 }, + { type: 'person', id: '1' }, + { type: 'person', id: '2' }, ], }, }, }, }); - store.push({ data: { type: 'person', id: 1, attributes: { name: 'Vito' } } }); - store.push({ data: { type: 'person', id: 2, attributes: { name: 'Michael' } } }); + store.push({ data: { type: 'person', id: '1', attributes: { name: 'Vito' } } }); + store.push({ data: { type: 'person', id: '2', attributes: { name: 'Michael' } } }); }); var personsReference = family.hasMany('persons'); @@ -831,15 +832,15 @@ module('integration/references/has-many', function (hooks) { if (count === 1) { return resolve({ data: [ - { id: 1, type: 'person', attributes: { name: 'Vito' } }, - { id: 2, type: 'person', attributes: { name: 'Michael' } }, + { id: '1', type: 'person', attributes: { name: 'Vito' } }, + { id: '2', type: 'person', attributes: { name: 'Michael' } }, ], }); } else { return resolve({ data: [ - { id: 1, type: 'person', attributes: { name: 'Vito Coreleone' } }, - { id: 2, type: 'person', attributes: { name: 'Michael Coreleone' } }, + { id: '1', type: 'person', attributes: { name: 'Vito Coreleone' } }, + { id: '2', type: 'person', attributes: { name: 'Michael Coreleone' } }, ], }); } @@ -850,7 +851,7 @@ module('integration/references/has-many', function (hooks) { family = store.push({ data: { type: 'family', - id: 1, + id: '1', relationships: { persons: { links: { related: '/families/1/persons' }, diff --git a/packages/-ember-data/tests/integration/references/record-test.js b/packages/-ember-data/tests/integration/references/record-test.js index e866c7b751c..339a39d46ef 100644 --- a/packages/-ember-data/tests/integration/references/record-test.js +++ b/packages/-ember-data/tests/integration/references/record-test.js @@ -92,7 +92,7 @@ module('integration/references/record', function (hooks) { const pushed = recordReference.push({ data: { type: 'person', - id: 1, + id: '1', attributes: { name: 'le name', }, @@ -120,7 +120,7 @@ module('integration/references/record', function (hooks) { deferred.resolve({ data: { type: 'person', - id: 1, + id: '1', attributes: { name: 'le name', }, @@ -144,7 +144,7 @@ module('integration/references/record', function (hooks) { let person = store.push({ data: { type: 'person', - id: 1, + id: '1', }, }); @@ -159,7 +159,7 @@ module('integration/references/record', function (hooks) { adapter.findRecord = function (store, type, id) { return resolve({ data: { - id: 1, + id: '1', type: 'person', attributes: { name: 'Vito', @@ -204,7 +204,7 @@ module('integration/references/record', function (hooks) { let recordPromise = recordReference.load(); // second trigger resolveRequest({ data: { - id: 1, + id: '1', type: 'person', attributes: { name: 'Vito', @@ -229,7 +229,7 @@ module('integration/references/record', function (hooks) { return resolve({ data: { - id: 1, + id: '1', type: 'person', attributes: { name: 'Vito Coreleone', @@ -251,7 +251,7 @@ module('integration/references/record', function (hooks) { adapter.findRecord = function (store, type, id) { return resolve({ data: { - id: 1, + id: '1', type: 'person', attributes: { name: 'Vito Coreleone', @@ -263,7 +263,7 @@ module('integration/references/record', function (hooks) { store.push({ data: { type: 'person', - id: 1, + id: '1', attributes: { name: 'Vito', }, diff --git a/packages/-ember-data/tests/integration/relationships/belongs-to-test.js b/packages/-ember-data/tests/integration/relationships/belongs-to-test.js index 90706e1c922..f80da1a68d0 100644 --- a/packages/-ember-data/tests/integration/relationships/belongs-to-test.js +++ b/packages/-ember-data/tests/integration/relationships/belongs-to-test.js @@ -306,7 +306,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function const Author = Model.extend({ name: attr('string'), - books: hasMany('books', { async: false, inverse: 'author' }), + books: hasMany('book', { async: false, inverse: 'author' }), }); const Section = Model.extend({ @@ -341,13 +341,13 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function 'model:app', Model.extend({ name: attr('string'), - team: belongsTo('team', { async: true }), + team: belongsTo('team', { async: true, inverse: 'apps' }), }) ); this.owner.register( 'model:team', Model.extend({ - apps: hasMany('app', { async: true }), + apps: hasMany('app', { async: true, inverse: 'team' }), }) ); @@ -706,11 +706,11 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.shouldBackgroundReloadRecord = () => false; let Group = Model.extend({ - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'group' }), }); let Person = Model.extend({ - group: belongsTo({ async: true }), + group: belongsTo('group', { async: true, inverse: 'people' }), }); this.owner.register('model:group', Group); @@ -743,11 +743,11 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function return resolve({ data: { - id: 1, + id: '1', type: 'group', relationships: { people: { - data: [{ id: 1, type: 'person' }], + data: [{ id: '1', type: 'person' }], }, }, }, @@ -774,11 +774,11 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.shouldBackgroundReloadRecord = () => false; let Seat = Model.extend({ - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'seat' }), }); let Person = Model.extend({ - seat: belongsTo('seat', { async: true }), + seat: belongsTo('seat', { async: true, inverse: 'person' }), }); this.owner.register('model:seat', Seat); @@ -805,7 +805,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function }; adapter.findBelongsTo = function (store, snapshot, link, relationship) { - return resolve({ data: { id: 1, type: 'seat' } }); + return resolve({ data: { id: '1', type: 'seat' } }); }; return run(() => { @@ -829,11 +829,11 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.shouldBackgroundReloadRecord = () => false; let Group = Model.extend({ - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'group' }), }); let Person = Model.extend({ - group: belongsTo({ async: true }), + group: belongsTo('group', { async: true, inverse: 'people' }), }); this.owner.register('model:group', Group); @@ -882,11 +882,11 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.shouldBackgroundReloadRecord = () => false; let Group = Model.extend({ - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'group' }), }); let Person = Model.extend({ - group: belongsTo({ async: true }), + group: belongsTo('group', { async: true, inverse: 'people' }), }); this.owner.register('model:group', Group); @@ -895,7 +895,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function run(() => { store.push({ data: { - id: 1, + id: '1', type: 'group', }, }); @@ -929,8 +929,8 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function assert.expect(1); let store = this.owner.lookup('service:store'); - let message = store.createRecord('message', { id: 1 }); - let comment = store.createRecord('comment', { id: 2, message: message }); + let message = store.createRecord('message', { id: '1' }); + let comment = store.createRecord('comment', { id: '2', message: message }); const Message = store.modelFor('message'); assert.ok(comment instanceof Message, 'a comment is an instance of a message'); @@ -1131,7 +1131,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function assert.expectAssertion(() => { message.user; - }, /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 \(`belongsTo\({ async: true }\)`\)/); + }, /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 \(`belongsTo\(, { async: true, inverse: }\)`\)/); }); test('Rollbacking attributes for a deleted record restores implicit relationship - async', function (assert) { @@ -1231,10 +1231,10 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function const User = Model.extend(); Model.extend({ - user: belongsTo(User, { async: false }), + user: belongsTo(User, { async: false, inverse: null }), }); }, /The first argument to belongsTo must be a string/); - assert.expectDeprecation({ id: 'ember-data:deprecate-early-static' }); + assert.expectDeprecation({ id: 'ember-data:deprecate-non-strict-relationships' }); }); test('belongsTo hasAnyRelationshipData async loaded', function (assert) { @@ -1251,11 +1251,11 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.findRecord = function (store, type, id, snapshot) { return resolve({ data: { - id: 1, + id: '1', type: 'book', attributes: { name: 'The Greatest Book' }, relationships: { - author: { data: { id: 2, type: 'author' } }, + author: { data: { id: '2', type: 'author' } }, }, }, }); @@ -1278,11 +1278,11 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.findRecord = function (store, type, id, snapshot) { return resolve({ data: { - id: 1, + id: '1', type: 'book', attributes: { name: 'The Greatest Book' }, relationships: { - author: { data: { id: 2, type: 'author' } }, + author: { data: { id: '2', type: 'author' } }, }, }, }); @@ -1310,7 +1310,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.findRecord = function (store, type, id, snapshot) { return resolve({ data: { - id: 1, + id: '1', type: 'book', attributes: { name: 'The Greatest Book' }, relationships: { @@ -1337,7 +1337,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.findRecord = function (store, type, id, snapshot) { return resolve({ data: { - id: 1, + id: '1', type: 'book', attributes: { name: 'The Greatest Book' }, }, @@ -1528,7 +1528,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function assert.ok(true, "The adapter's findBelongsTo method should be called"); return resolve({ data: { - id: 1, + id: '1', type: 'author', attributes: { name: 'This is author' }, }, @@ -1630,7 +1630,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function assert.ok(true, "The adapter's findBelongsTo method should be called"); return resolve({ data: { - id: 1, + id: '1', type: 'author', attributes: { name: 'This is author' }, }, @@ -1844,7 +1844,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.findRecord = function () { return resolve({ data: { - id: 1, + id: '1', type: 'chapter', relationships: { book: { @@ -1858,7 +1858,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.findBelongsTo = function () { return resolve({ data: { - id: 1, + id: '1', type: 'book', attributes: { name: 'book title' }, }, @@ -1881,7 +1881,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.findBelongsTo = function () { return resolve({ data: { - id: 1, + id: '1', type: 'book', attributes: { name: 'updated book title' }, }, @@ -1962,10 +1962,10 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function chapter = store.push({ data: { type: 'chapter', - id: 1, + id: '1', relationships: { book: { - data: { type: 'book', id: 1 }, + data: { type: 'book', id: '1' }, }, }, }, @@ -1975,7 +1975,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.findRecord = function () { return resolve({ data: { - id: 1, + id: '1', type: 'book', attributes: { name: 'book title' }, }, @@ -1990,7 +1990,7 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function adapter.findRecord = function () { return resolve({ data: { - id: 1, + id: '1', type: 'book', attributes: { name: 'updated book title' }, }, @@ -2013,10 +2013,10 @@ module('integration/relationship/belongs_to Belongs-To Relationships', function let chapter = store.push({ data: { type: 'chapter', - id: 1, + id: '1', relationships: { book: { - data: { id: 1, name: 'The Gallic Wars' }, + data: { id: '1', name: 'The Gallic Wars' }, }, }, }, diff --git a/packages/-ember-data/tests/integration/relationships/has-many-test.js b/packages/-ember-data/tests/integration/relationships/has-many-test.js index 839e58c78ce..f18e837325a 100644 --- a/packages/-ember-data/tests/integration/relationships/has-many-test.js +++ b/packages/-ember-data/tests/integration/relationships/has-many-test.js @@ -59,7 +59,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( const Book = Model.extend({ title: attr(), - chapters: hasMany('chapter', { async: true }), + chapters: hasMany('chapter', { async: true, inverse: null }), toString: () => 'Book', }); @@ -313,7 +313,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.ok(!user.contacts.initialState || !user.contacts.initialState.find((model) => model.id === '2')); run(() => { - contacts.addObject(store.createRecord('user', { id: 8 })); + contacts.addObject(store.createRecord('user', { id: '8' })); }); assert.deepEqual( @@ -340,15 +340,15 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( data: [ { type: 'user', - id: 2, + id: '2', }, { type: 'user', - id: 3, + id: '3', }, { type: 'user', - id: 4, + id: '4', }, ], }, @@ -360,22 +360,22 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( included: [ { type: 'user', - id: 2, + id: '2', }, { type: 'user', - id: 3, + id: '3', }, { type: 'user', - id: 4, + id: '4', }, ], }); let contacts = user.contacts; store.adapterFor('user').deleteRecord = function () { - return { data: { type: 'user', id: 2 } }; + return { data: { type: 'user', id: '2' } }; }; assert.deepEqual( @@ -385,9 +385,9 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( ); run(() => { - contacts.addObject(store.createRecord('user', { id: 5 })); - contacts.addObject(store.createRecord('user', { id: 6 })); - contacts.addObject(store.createRecord('user', { id: 7 })); + contacts.addObject(store.createRecord('user', { id: '5' })); + contacts.addObject(store.createRecord('user', { id: '6' })); + contacts.addObject(store.createRecord('user', { id: '7' })); }); assert.deepEqual( @@ -406,7 +406,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( ); assert.strictEqual(contacts, user.contacts); - contacts.addObject(store.createRecord('user', { id: 8 })); + contacts.addObject(store.createRecord('user', { id: '8' })); assert.deepEqual( contacts.map((c) => c.id), ['3', '4', '5', '7', '8'], @@ -442,8 +442,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: [ - { id: 2, type: 'chapter', attributes: { title: 'Chapter One' } }, - { id: 3, type: 'chapter', attributes: { title: 'Chapter Two' } }, + { id: '2', type: 'chapter', attributes: { title: 'Chapter One' } }, + { id: '3', type: 'chapter', attributes: { title: 'Chapter Two' } }, ], }); }; @@ -470,7 +470,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( test("A serializer can materialize a hasMany as an opaque token that can be lazily fetched via the adapter's findHasMany hook", function (assert) { class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -497,7 +497,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: { - id: 1, + id: '1', type: 'post', relationships: { comments: { @@ -509,7 +509,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( }, }); }; - //({ id: 1, links: { comments: "/posts/1/comments" } }); + //({ id: '1', links: { comments: "/posts/1/comments" } }); adapter.findMany = function (store, type, ids, snapshots) { throw new Error("Adapter's findMany should not be called"); @@ -521,8 +521,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'First' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'First' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -545,7 +545,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(2); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -586,8 +586,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( setTimeout(() => { let value = { data: [ - { id: 1, type: 'comment', attributes: { body: 'First' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'First' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }; resolve(value); @@ -620,7 +620,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(1); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -642,8 +642,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findHasMany = function (store, snapshot, link, relationship) { return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'First' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'First' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -690,7 +690,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( test('A hasMany updated link should not remove new children', function (assert) { class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -715,7 +715,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.createRecord = function (store, snapshot, link, relationship) { return resolve({ data: { - id: 1, + id: '1', type: 'post', relationships: { comments: { @@ -746,7 +746,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( test('A hasMany updated link should not remove new children when the parent record has children already', function (assert) { class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -767,14 +767,14 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findHasMany = function (store, snapshot, link, relationship) { return resolve({ - data: [{ id: 5, type: 'comment', attributes: { body: 'hello' } }], + data: [{ id: '5', type: 'comment', attributes: { body: 'hello' } }], }); }; adapter.createRecord = function (store, snapshot, link, relationship) { return resolve({ data: { - id: 1, + id: '1', type: 'post', relationships: { comments: { @@ -804,7 +804,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( test("A hasMany relationship doesn't contain duplicate children, after the canonical state of the relationship is updated via store#push", function (assert) { class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -824,7 +824,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( let adapter = store.adapterFor('application'); adapter.createRecord = function (store, snapshot, link, relationship) { - return resolve({ data: { id: 1, type: 'post' } }); + return resolve({ data: { id: '1', type: 'post' } }); }; return run(() => { @@ -857,7 +857,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( store.push({ data: { type: 'post', - id: 1, + id: '1', relationships: { comments: { data: [{ id: 'local', type: 'comment' }], @@ -877,7 +877,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( test('A hasMany relationship can be reloaded if it was fetched via a link', async function (assert) { class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -902,7 +902,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: { - id: 1, + id: '1', type: 'post', relationships: { comments: { @@ -920,8 +920,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'First' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'First' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -938,9 +938,9 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'First' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, - { id: 3, type: 'comment', attributes: { body: 'Thirds' } }, + { id: '1', type: 'comment', attributes: { body: 'First' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, + { id: '3', type: 'comment', attributes: { body: 'Thirds' } }, ], }); }; @@ -960,13 +960,13 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: { - id: 1, + id: '1', type: 'post', relationships: { comments: { data: [ - { id: 1, type: 'comment' }, - { id: 2, type: 'comment' }, + { id: '1', type: 'comment' }, + { id: '2', type: 'comment' }, ], }, }, @@ -1004,8 +1004,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findMany = function (store, type, ids, snapshots) { return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'FirstUpdated' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'FirstUpdated' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -1021,7 +1021,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( test('A hasMany relationship can be reloaded if it was fetched via ids', function (assert) { class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -1046,13 +1046,13 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: { - id: 1, + id: '1', type: 'post', relationships: { comments: { data: [ - { id: 1, type: 'comment' }, - { id: 2, type: 'comment' }, + { id: '1', type: 'comment' }, + { id: '2', type: 'comment' }, ], }, }, @@ -1063,8 +1063,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findMany = function (store, type, ids, snapshots) { return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'First' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'First' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -1082,8 +1082,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findMany = function (store, type, ids, snapshots) { return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'FirstUpdated' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'FirstUpdated' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -1100,7 +1100,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(7); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -1141,8 +1141,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( } else { return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'FirstUpdated' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'FirstUpdated' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); } @@ -1182,7 +1182,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(6); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -1207,7 +1207,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: { - id: 1, + id: '1', type: 'post', relationships: { comments: { @@ -1223,8 +1223,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'FirstUpdated' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'FirstUpdated' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -1243,7 +1243,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(1); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -1267,7 +1267,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findRecord = function (store, type, id) { return resolve({ data: { - id: 1, + id: '1', type: 'post', relationships: { comments: { @@ -1283,8 +1283,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( count++; return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'First' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'First' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -1307,7 +1307,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( test('A hasMany relationship can be directly reloaded if it was fetched via ids', function (assert) { class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -1332,13 +1332,13 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: { - id: 1, + id: '1', type: 'post', relationships: { comments: { data: [ - { id: 1, type: 'comment' }, - { id: 2, type: 'comment' }, + { id: '1', type: 'comment' }, + { id: '2', type: 'comment' }, ], }, }, @@ -1349,8 +1349,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findMany = function (store, type, ids, snapshots) { return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'FirstUpdated' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'FirstUpdated' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -1370,7 +1370,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(1); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -1394,13 +1394,13 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findRecord = function (store, type, id, snapshot) { return resolve({ data: { - id: 1, + id: '1', type: 'post', relationships: { comments: { data: [ - { id: 1, type: 'comment' }, - { id: 2, type: 'comment' }, + { id: '1', type: 'comment' }, + { id: '2', type: 'comment' }, ], }, }, @@ -1413,8 +1413,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( count++; return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'FirstUpdated' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'FirstUpdated' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -1442,7 +1442,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(4); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -1464,8 +1464,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findHasMany = function (store, snapshot, link, relationship) { return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'First' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'First' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -1505,7 +1505,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(8); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -1530,16 +1530,16 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( if (link === '/first') { return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'First' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'First' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); } else if (link === '/second') { return resolve({ data: [ - { id: 3, type: 'comment', attributes: { body: 'Third' } }, - { id: 4, type: 'comment', attributes: { body: 'Fourth' } }, - { id: 5, type: 'comment', attributes: { body: 'Fifth' } }, + { id: '3', type: 'comment', attributes: { body: 'Third' } }, + { id: '4', type: 'comment', attributes: { body: 'Fourth' } }, + { id: '5', type: 'comment', attributes: { body: 'Fifth' } }, ], }); } @@ -1651,9 +1651,9 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.shouldBackgroundReloadRecord = () => false; adapter.findRecord = function (store, type, id, snapshot) { if (type === store.modelFor('post')) { - return resolve({ data: { id: 1, type: 'post' } }); + return resolve({ data: { id: '1', type: 'post' } }); } else if (type === store.modelFor('comment')) { - return resolve({ data: { id: 3, type: 'comment' } }); + return resolve({ data: { id: '3', type: 'comment' } }); } }; @@ -1703,88 +1703,43 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( }); }); - test('Type can be inferred from the key of a hasMany relationship', async function (assert) { - assert.expect(1); - - const User = Model.extend({ - name: attr(), - contacts: hasMany({ inverse: null, async: false }), - }); - - const Contact = Model.extend({ - name: attr(), - user: belongsTo('user', { async: false }), - }); - - this.owner.register('model:user', User); - this.owner.register('model:contact', Contact); - - let store = this.owner.lookup('service:store'); - let adapter = store.adapterFor('application'); + deprecatedTest( + 'Type can be inferred from the key of a hasMany relationship', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 1 }, + async function (assert) { + assert.expect(1); - adapter.findRecord = function () { - return { - data: { - id: '1', - type: 'user', - relationships: { - contacts: { - data: [{ id: '1', type: 'contact' }], - }, - }, - }, - }; - }; + const User = Model.extend({ + name: attr(), + contacts: hasMany({ inverse: null, async: false }), + }); - const user = store.push({ - data: { - type: 'user', - id: '1', - relationships: { - contacts: { - data: [{ type: 'contact', id: '1' }], - }, - }, - }, - included: [ - { - type: 'contact', - id: '1', - }, - ], - }); - const contacts = await user.contacts; - assert.strictEqual(contacts.length, 1, 'The contacts relationship is correctly set up'); - }); + const Contact = Model.extend({ + name: attr(), + user: belongsTo('user', { async: false, inverse: null }), + }); - test('Type can be inferred from the key of an async hasMany relationship', function (assert) { - assert.expect(1); - class User extends Model { - @attr name; - @hasMany('message', { polymorphic: true, async: false, inverse: 'user' }) messages; - @hasMany({ async: true, inverse: null }) contacts; - } - this.owner.register('model:user', User); + this.owner.register('model:user', User); + this.owner.register('model:contact', Contact); - let store = this.owner.lookup('service:store'); - let adapter = store.adapterFor('application'); + let store = this.owner.lookup('service:store'); + let adapter = store.adapterFor('application'); - adapter.findRecord = function (store, type, ids, snapshots) { - return { - data: { - id: 1, - type: 'user', - relationships: { - contacts: { - data: [{ id: 1, type: 'contact' }], + adapter.findRecord = function () { + return { + data: { + id: '1', + type: 'user', + relationships: { + contacts: { + data: [{ id: '1', type: 'contact' }], + }, }, }, - }, + }; }; - }; - run(function () { - store.push({ + const user = store.push({ data: { type: 'user', id: '1', @@ -1801,72 +1756,129 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( }, ], }); - }); - run(function () { - store - .findRecord('user', 1) - .then(function (user) { - return user.contacts; - }) - .then(function (contacts) { - assert.strictEqual(contacts.length, 1, 'The contacts relationship is correctly set up'); - }); - }); - }); - - test('Polymorphic relationships work with a hasMany whose type is inferred', function (assert) { - assert.expect(1); - class User extends Model { - @attr name; - @hasMany('message', { polymorphic: true, async: false, inverse: 'user' }) messages; - @hasMany({ async: false, polymorphic: true, inverse: null }) contacts; + const contacts = await user.contacts; + assert.strictEqual(contacts.length, 1, 'The contacts relationship is correctly set up'); } - this.owner.register('model:user', User); + ); - let store = this.owner.lookup('service:store'); - let adapter = store.adapterFor('application'); + deprecatedTest( + 'Type can be inferred from the key of an async hasMany relationship', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 1 }, + function (assert) { + assert.expect(1); + class User extends Model { + @attr name; + @hasMany('message', { polymorphic: true, async: false, inverse: 'user' }) messages; + @hasMany({ async: true, inverse: null }) contacts; + } + this.owner.register('model:user', User); - adapter.findRecord = function (store, type, ids, snapshots) { - return { data: { id: 1, type: 'user' } }; - }; + let store = this.owner.lookup('service:store'); + let adapter = store.adapterFor('application'); - run(function () { - store.push({ - data: { - type: 'user', - id: '1', - relationships: { - contacts: { - data: [ - { type: 'email', id: '1' }, - { type: 'phone', id: '2' }, - ], + adapter.findRecord = function (store, type, ids, snapshots) { + return { + data: { + id: '1', + type: 'user', + relationships: { + contacts: { + data: [{ id: '1', type: 'contact' }], + }, }, }, - }, - included: [ - { - type: 'email', + }; + }; + + run(function () { + store.push({ + data: { + type: 'user', id: '1', + relationships: { + contacts: { + data: [{ type: 'contact', id: '1' }], + }, + }, }, - { - type: 'phone', - id: '2', - }, - ], + included: [ + { + type: 'contact', + id: '1', + }, + ], + }); }); - }); - run(function () { - store - .findRecord('user', 1) - .then(function (user) { - return user.contacts; - }) - .then(function (contacts) { - assert.strictEqual(contacts.length, 2, 'The contacts relationship is correctly set up'); + run(function () { + store + .findRecord('user', 1) + .then(function (user) { + return user.contacts; + }) + .then(function (contacts) { + assert.strictEqual(contacts.length, 1, 'The contacts relationship is correctly set up'); + }); + }); + } + ); + + deprecatedTest( + 'Polymorphic relationships work with a hasMany whose type is inferred', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 1 }, + function (assert) { + assert.expect(1); + class User extends Model { + @attr name; + @hasMany('message', { polymorphic: true, async: false, inverse: 'user' }) messages; + @hasMany({ async: false, polymorphic: true, inverse: null }) contacts; + } + this.owner.register('model:user', User); + + let store = this.owner.lookup('service:store'); + let adapter = store.adapterFor('application'); + + adapter.findRecord = function (store, type, ids, snapshots) { + return { data: { id: '1', type: 'user' } }; + }; + + run(function () { + store.push({ + data: { + type: 'user', + id: '1', + relationships: { + contacts: { + data: [ + { type: 'email', id: '1' }, + { type: 'phone', id: '2' }, + ], + }, + }, + }, + included: [ + { + type: 'email', + id: '1', + }, + { + type: 'phone', + id: '2', + }, + ], }); - }); - }); + }); + run(function () { + store + .findRecord('user', 1) + .then(function (user) { + return user.contacts; + }) + .then(function (contacts) { + assert.strictEqual(contacts.length, 2, 'The contacts relationship is correctly set up'); + }); + }); + } + ); test('Polymorphic relationships with a hasMany is set up correctly on both sides', function (assert) { assert.expect(2); @@ -2079,7 +2091,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(4); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -2144,7 +2156,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(1); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -2197,7 +2209,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( let adapter = store.adapterFor('application'); adapter.createRecord = function (store, type, snapshot) { - return resolve({ data: { id: 1, type: snapshot.modelName } }); + return resolve({ data: { id: '1', type: snapshot.modelName } }); }; let post, comment; @@ -2214,7 +2226,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( test('dual non-async HM <-> BT', async function (assert) { class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -2280,7 +2292,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(6); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -2306,8 +2318,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.ok(true, `findMany called ${++findManyCalls}x`); return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'first' } }, - { id: 2, type: 'comment', attributes: { body: 'second' } }, + { id: '1', type: 'comment', attributes: { body: 'first' } }, + { id: '2', type: 'comment', attributes: { body: 'second' } }, ], }); }; @@ -2315,7 +2327,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findRecord = function (store, type, id, snapshot) { assert.ok(true, `findRecord called ${++findRecordCalls}x`); - return resolve({ data: { id: 3, type: 'comment', attributes: { body: 'third' } } }); + return resolve({ data: { id: '3', type: 'comment', attributes: { body: 'third' } } }); }; let post = store.push({ @@ -2401,7 +2413,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( const Post = Model.extend({ title: attr('string'), - comments: hasMany('comment', { async: true }), + comments: hasMany('comment', { async: true, inverse: 'message' }), toString: () => 'Post', }); this.owner.register('model:post', Post); @@ -2897,23 +2909,24 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( } testInDebug('Passing a model as type to hasMany should not work', function (assert) { - assert.expect(2); + assert.expect(3); assert.expectAssertion(() => { const User = Model.extend(); Model.extend({ - users: hasMany(User, { async: false }), + users: hasMany(User, { async: false, inverse: null }), }); }, /The first argument to hasMany must be a string/); assert.expectDeprecation({ id: 'ember-data:deprecate-early-static' }); + assert.expectDeprecation({ id: 'ember-data:deprecate-non-strict-relationships' }); }); test('Relationship.clear removes all records correctly', async function (assert) { class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -2990,7 +3003,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( test('unloading a record with associated records does not prevent the store from tearing down', function (assert) { class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -3072,12 +3085,12 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(4); const Post = Model.extend({ - comments: hasMany('comment', { async: true }), + comments: hasMany('comment', { async: true, inverse: 'post' }), toString: () => 'Post', }); const Comment = Model.extend({ - post: belongsTo('post', { async: false }), + post: belongsTo('post', { async: false, inverse: 'comments' }), toString: () => 'Comment', }); @@ -3181,14 +3194,14 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findRecord = function (store, type, id, snapshot) { return resolve({ data: { - id: 1, + id: '1', type: 'chapter', attributes: { title: 'The Story Begins' }, relationships: { pages: { data: [ - { id: 2, type: 'page' }, - { id: 3, type: 'page' }, + { id: '2', type: 'page' }, + { id: '3', type: 'page' }, ], }, }, @@ -3213,14 +3226,14 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findRecord = function (store, type, id, snapshot) { return resolve({ data: { - id: 1, + id: '1', type: 'chapter', attributes: { title: 'The Story Begins' }, relationships: { pages: { data: [ - { id: 2, type: 'page' }, - { id: 3, type: 'page' }, + { id: '2', type: 'page' }, + { id: '3', type: 'page' }, ], }, }, @@ -3250,7 +3263,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findRecord = function (store, type, id, snapshot) { return resolve({ data: { - id: 1, + id: '1', type: 'chapter', attributes: { title: 'The Story Begins' }, relationships: { @@ -3279,7 +3292,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findRecord = function (store, type, id, snapshot) { return resolve({ data: { - id: 1, + id: '1', type: 'chapter', attributes: { title: 'The Story Begins' }, }, @@ -3539,7 +3552,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(3); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -3609,7 +3622,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(3); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -3680,7 +3693,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(1); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -3748,7 +3761,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(3); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -3835,7 +3848,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(3); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -3858,7 +3871,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.strictEqual(url, 'comments-updated-link', 'url is correct'); assert.ok(true, "The adapter's findHasMany method should be called"); return resolve({ - data: [{ id: 1, type: 'comment', attributes: { body: 'This is updated comment' } }], + data: [{ id: '1', type: 'comment', attributes: { body: 'This is updated comment' } }], }); }; @@ -3909,7 +3922,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( assert.expect(1); class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -3931,8 +3944,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( adapter.findHasMany = function (store, record, link, relationship) { return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'First' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'First' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; @@ -3941,7 +3954,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( let post = store.push({ data: { type: 'post', - id: 1, + id: '1', relationships: { comments: { links: { @@ -4225,7 +4238,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( test('A hasMany relationship with a link will trigger the link request even if a inverse related object is pushed to the store', function (assert) { class Message extends Model { @attr('date') created_at; - @belongsTo('user', { async: false }) iser; + @belongsTo('user', { async: false, inverse: 'messages' }) user; } class Post extends Message { @@ -4292,8 +4305,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function ( return resolve({ data: [ - { id: 1, type: 'comment', attributes: { body: 'First' } }, - { id: 2, type: 'comment', attributes: { body: 'Second' } }, + { id: '1', type: 'comment', attributes: { body: 'First' } }, + { id: '2', type: 'comment', attributes: { body: 'Second' } }, ], }); }; diff --git a/packages/-ember-data/tests/integration/relationships/inverse-relationship-load-test.js b/packages/-ember-data/tests/integration/relationships/inverse-relationship-load-test.js index 3fa9feb5fd3..4ce0fdae8ec 100644 --- a/packages/-ember-data/tests/integration/relationships/inverse-relationship-load-test.js +++ b/packages/-ember-data/tests/integration/relationships/inverse-relationship-load-test.js @@ -7,7 +7,7 @@ import JSONAPIAdapter from '@ember-data/adapter/json-api'; import Model, { attr, belongsTo, hasMany } from '@ember-data/model'; import JSONAPISerializer from '@ember-data/serializer/json-api'; import Store from '@ember-data/store'; -import testInDebug from '@ember-data/unpublished-test-infra/test-support/test-in-debug'; +import { deprecatedTest } from '@ember-data/unpublished-test-infra/test-support/deprecated-test'; module('inverse relationship load test', function (hooks) { let store; @@ -27,177 +27,185 @@ module('inverse relationship load test', function (hooks) { ); }); - test('one-to-many - findHasMany/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', async function (assert) { - let { owner } = this; + deprecatedTest( + 'one-to-many - findHasMany/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findHasMany: () => { - return resolve({ - data: [ - { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findHasMany: () => { + return resolve({ + data: [ + { + id: '1', + type: 'dog', + attributes: { + name: 'Scooby', + }, }, - }, - { - id: 2, - type: 'dog', - attributes: { - name: 'Scrappy', + { + id: '2', + type: 'dog', + attributes: { + name: 'Scrappy', + }, }, - }, - ], - }); - }, - }) - ); + ], + }); + }, + }) + ); - class Person extends Model { - @hasMany('dog', { - async: true, - }) - dogs; - } - owner.register('model:person', Person); + class Person extends Model { + @hasMany('dog', { + async: true, + }) + dogs; + } + owner.register('model:person', Person); - class Dog extends Model { - @belongsTo('person', { - async: true, - }) - person; - } - owner.register('model:dog', Dog); + class Dog extends Model { + @belongsTo('person', { + async: true, + }) + person; + } + owner.register('model:dog', Dog); - let person = store.push({ - data: { - type: 'person', - id: '1', - attributes: { - name: 'John Churchill', - }, - relationships: { - dogs: { - links: { - related: 'http://example.com/person/1/dogs', + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + dogs: { + links: { + related: 'http://example.com/person/1/dogs', + }, }, }, }, - }, - }); + }); - let dogs = await person.dogs; - assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); + let dogs = await person.dogs; + assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); - assert.strictEqual(dogs.length, 2, 'hasMany relationship has correct number of records'); - let dog1 = dogs.firstObject; - let dogPerson1 = await dog1.person; - assert.strictEqual( - dogPerson1.id, - '1', - 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' - ); - let dogPerson2 = await dogs.objectAt(1).person; - assert.strictEqual( - dogPerson2.id, - '1', - 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' - ); + assert.strictEqual(dogs.length, 2, 'hasMany relationship has correct number of records'); + let dog1 = dogs.firstObject; + let dogPerson1 = await dog1.person; + assert.strictEqual( + dogPerson1.id, + '1', + 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' + ); + let dogPerson2 = await dogs.objectAt(1).person; + assert.strictEqual( + dogPerson2.id, + '1', + 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' + ); - await dog1.destroyRecord(); - assert.strictEqual(dogs.length, 1, 'record removed from hasMany relationship after deletion'); - assert.strictEqual(dogs.firstObject.id, '2', 'hasMany relationship has correct records'); - }); + await dog1.destroyRecord(); + assert.strictEqual(dogs.length, 1, 'record removed from hasMany relationship after deletion'); + assert.strictEqual(dogs.firstObject.id, '2', 'hasMany relationship has correct records'); + } + ); - test('one-to-many (left hand async, right hand sync) - findHasMany/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', async function (assert) { - let { owner } = this; + deprecatedTest( + 'one-to-many (left hand async, right hand sync) - findHasMany/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findHasMany: () => { - return resolve({ - data: [ - { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findHasMany: () => { + return resolve({ + data: [ + { + id: '1', + type: 'dog', + attributes: { + name: 'Scooby', + }, }, - }, - { - id: 2, - type: 'dog', - attributes: { - name: 'Scrappy', + { + id: '2', + type: 'dog', + attributes: { + name: 'Scrappy', + }, }, - }, - ], - }); - }, - }) - ); + ], + }); + }, + }) + ); - class Person extends Model { - @hasMany('dog', { - async: true, - }) - dogs; - } - owner.register('model:person', Person); + class Person extends Model { + @hasMany('dog', { + async: true, + }) + dogs; + } + owner.register('model:person', Person); - class Dog extends Model { - @belongsTo('person', { - async: false, - }) - person; - } - owner.register('model:dog', Dog); + class Dog extends Model { + @belongsTo('person', { + async: false, + }) + person; + } + owner.register('model:dog', Dog); - let person = store.push({ - data: { - type: 'person', - id: '1', - attributes: { - name: 'John Churchill', - }, - relationships: { - dogs: { - links: { - related: 'http://example.com/person/1/dogs', + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + dogs: { + links: { + related: 'http://example.com/person/1/dogs', + }, }, }, }, - }, - }); + }); - let dogs = await person.dogs; - assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); + let dogs = await person.dogs; + assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); - assert.strictEqual(dogs.length, 2, 'hasMany relationship has correct number of records'); - let dog1 = dogs.firstObject; - let dogPerson1 = await dog1.person; - assert.strictEqual( - dogPerson1.id, - '1', - 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' - ); - let dogPerson2 = await dogs.objectAt(1).person; - assert.strictEqual( - dogPerson2.id, - '1', - 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' - ); + assert.strictEqual(dogs.length, 2, 'hasMany relationship has correct number of records'); + let dog1 = dogs.firstObject; + let dogPerson1 = await dog1.person; + assert.strictEqual( + dogPerson1.id, + '1', + 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' + ); + let dogPerson2 = await dogs.objectAt(1).person; + assert.strictEqual( + dogPerson2.id, + '1', + 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' + ); - await dog1.destroyRecord(); - assert.strictEqual(dogs.length, 1, 'record removed from hasMany relationship after deletion'); - assert.strictEqual(dogs.firstObject.id, '2', 'hasMany relationship has correct records'); - }); + await dog1.destroyRecord(); + assert.strictEqual(dogs.length, 1, 'record removed from hasMany relationship after deletion'); + assert.strictEqual(dogs.firstObject.id, '2', 'hasMany relationship has correct records'); + } + ); test('one-to-many - findHasMany/explicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', async function (assert) { let { owner } = this; @@ -210,14 +218,14 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -241,6 +249,7 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @belongsTo('person', { async: true, + inverse: 'dogs', }) pal; } @@ -297,14 +306,14 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -389,14 +398,14 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -454,149 +463,157 @@ module('inverse relationship load test', function (hooks) { assert.strictEqual(dogs.firstObject.id, '2'); }); - test('one-to-one - findBelongsTo/implicit inverse - ensures inverse relationship is set up when payload does not return parent relationship info', async function (assert) { - let { owner } = this; + deprecatedTest( + 'one-to-one - findBelongsTo/implicit inverse - ensures inverse relationship is set up when payload does not return parent relationship info', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord() { - return resolve({ - data: null, - }); - }, - findBelongsTo() { - return resolve({ - data: { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord() { + return resolve({ + data: null, + }); + }, + findBelongsTo() { + return resolve({ + data: { + id: '1', + type: 'dog', + attributes: { + name: 'Scooby', + }, }, - }, - }); - }, - }) - ); + }); + }, + }) + ); - class Person extends Model { - @attr() - name; - @belongsTo('dog', { async: true }) - favoriteDog; - } - owner.register('model:person', Person); + class Person extends Model { + @attr() + name; + @belongsTo('dog', { async: true }) + favoriteDog; + } + owner.register('model:person', Person); - class Dog extends Model { - @attr() - name; - @belongsTo('person', { async: true }) - person; - } - owner.register('model:dog', Dog); + class Dog extends Model { + @attr() + name; + @belongsTo('person', { async: true }) + person; + } + owner.register('model:dog', Dog); - let person = store.push({ - data: { - type: 'person', - id: '1', - attributes: { - name: 'John Churchill', - }, - relationships: { - favoriteDog: { - links: { - related: 'http://example.com/person/1/favorite-dog', + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + favoriteDog: { + links: { + related: 'http://example.com/person/1/favorite-dog', + }, }, }, }, - }, - }); + }); - let favoriteDog = await person.favoriteDog; - assert.false(person.belongsTo('favoriteDog').belongsToRelationship.state.isEmpty); - assert.strictEqual(favoriteDog.id, '1', 'favoriteDog id is set correctly'); - let favoriteDogPerson = await favoriteDog.person; - assert.strictEqual( - favoriteDogPerson.id, - '1', - 'favoriteDog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' - ); - await favoriteDog.destroyRecord(); - favoriteDog = await person.favoriteDog; - assert.strictEqual(favoriteDog, null); - }); + let favoriteDog = await person.favoriteDog; + assert.false(person.belongsTo('favoriteDog').belongsToRelationship.state.isEmpty); + assert.strictEqual(favoriteDog.id, '1', 'favoriteDog id is set correctly'); + let favoriteDogPerson = await favoriteDog.person; + assert.strictEqual( + favoriteDogPerson.id, + '1', + 'favoriteDog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' + ); + await favoriteDog.destroyRecord(); + favoriteDog = await person.favoriteDog; + assert.strictEqual(favoriteDog, null); + } + ); - test('one-to-one (left hand async, right hand sync) - findBelongsTo/implicit inverse - ensures inverse relationship is set up when payload does not return parent relationship info', async function (assert) { - let { owner } = this; + deprecatedTest( + 'one-to-one (left hand async, right hand sync) - findBelongsTo/implicit inverse - ensures inverse relationship is set up when payload does not return parent relationship info', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord() { - return resolve({ - data: null, - }); - }, - findBelongsTo() { - return resolve({ - data: { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord() { + return resolve({ + data: null, + }); + }, + findBelongsTo() { + return resolve({ + data: { + id: '1', + type: 'dog', + attributes: { + name: 'Scooby', + }, }, - }, - }); - }, - }) - ); + }); + }, + }) + ); - class Person extends Model { - @attr() - name; - @belongsTo('dog', { async: true }) - favoriteDog; - } - owner.register('model:person', Person); + class Person extends Model { + @attr() + name; + @belongsTo('dog', { async: true }) + favoriteDog; + } + owner.register('model:person', Person); - class Dog extends Model { - @attr() - name; - @belongsTo('person', { async: true }) - person; - } - owner.register('model:dog', Dog); + class Dog extends Model { + @attr() + name; + @belongsTo('person', { async: true }) + person; + } + owner.register('model:dog', Dog); - let person = store.push({ - data: { - type: 'person', - id: '1', - attributes: { - name: 'John Churchill', - }, - relationships: { - favoriteDog: { - links: { - related: 'http://example.com/person/1/favorite-dog', + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + favoriteDog: { + links: { + related: 'http://example.com/person/1/favorite-dog', + }, }, }, }, - }, - }); + }); - let favoriteDog = await person.favoriteDog; - assert.false(person.belongsTo('favoriteDog').belongsToRelationship.state.isEmpty); - assert.strictEqual(favoriteDog.id, '1', 'favoriteDog id is set correctly'); - let favoriteDogPerson = await favoriteDog.person; - assert.strictEqual( - favoriteDogPerson.id, - '1', - 'favoriteDog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' - ); - await favoriteDog.destroyRecord(); - favoriteDog = await person.favoriteDog; - assert.strictEqual(favoriteDog, null); - }); + let favoriteDog = await person.favoriteDog; + assert.false(person.belongsTo('favoriteDog').belongsToRelationship.state.isEmpty); + assert.strictEqual(favoriteDog.id, '1', 'favoriteDog id is set correctly'); + let favoriteDogPerson = await favoriteDog.person; + assert.strictEqual( + favoriteDogPerson.id, + '1', + 'favoriteDog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' + ); + await favoriteDog.destroyRecord(); + favoriteDog = await person.favoriteDog; + assert.strictEqual(favoriteDog, null); + } + ); test('one-to-one - findBelongsTo/explicit inverse - ensures inverse relationship is set up when payload does not return parent relationship info', async function (assert) { let { owner } = this; @@ -612,7 +629,7 @@ module('inverse relationship load test', function (hooks) { findBelongsTo() { return resolve({ data: { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -634,7 +651,7 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @attr() name; - @belongsTo('person', { async: true }) + @belongsTo('person', { async: true, inverse: 'favoriteDog' }) pal; } owner.register('model:dog', Dog); @@ -684,7 +701,7 @@ module('inverse relationship load test', function (hooks) { findBelongsTo() { return resolve({ data: { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -706,7 +723,7 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @attr() name; - @belongsTo('person', { async: true }) + @belongsTo('person', { async: true, inverse: 'favoriteDog' }) pal; } owner.register('model:dog', Dog); @@ -756,7 +773,7 @@ module('inverse relationship load test', function (hooks) { findBelongsTo() { return resolve({ data: { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -770,7 +787,7 @@ module('inverse relationship load test', function (hooks) { class Person extends Model { @attr() name; - @belongsTo('dog', { async: true }) + @belongsTo('dog', { async: true, inverse: null }) favoriteDog; } owner.register('model:person', Person); @@ -806,167 +823,175 @@ module('inverse relationship load test', function (hooks) { assert.strictEqual(favoriteDog, null); }); - test('many-to-many - findHasMany/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', async function (assert) { - let { owner } = this; + deprecatedTest( + 'many-to-many - findHasMany/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findHasMany: () => { - return resolve({ - data: [ - { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findHasMany: () => { + return resolve({ + data: [ + { + id: '1', + type: 'dog', + attributes: { + name: 'Scooby', + }, }, - }, - { - id: 2, - type: 'dog', - attributes: { - name: 'Scrappy', + { + id: '2', + type: 'dog', + attributes: { + name: 'Scrappy', + }, }, - }, - ], - }); - }, - }) - ); + ], + }); + }, + }) + ); - class Person extends Model { - @hasMany('dog', { - async: true, - }) - dogs; - } - owner.register('model:person', Person); + class Person extends Model { + @hasMany('dog', { + async: true, + }) + dogs; + } + owner.register('model:person', Person); - class Dog extends Model { - @hasMany('person', { - async: true, - }) - walkers; - } - owner.register('model:dog', Dog); + class Dog extends Model { + @hasMany('person', { + async: true, + }) + walkers; + } + owner.register('model:dog', Dog); - let person = store.push({ - data: { - type: 'person', - id: '1', - attributes: { - name: 'John Churchill', - }, - relationships: { - dogs: { - links: { - related: 'http://example.com/person/1/dogs', + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + dogs: { + links: { + related: 'http://example.com/person/1/dogs', + }, }, }, }, - }, - }); + }); - let dogs = await person.dogs; - assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty); + let dogs = await person.dogs; + assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty); - assert.strictEqual(dogs.length, 2, 'left hand side relationship is set up with correct number of records'); - let [dog1, dog2] = dogs.toArray(); - let dog1Walkers = await dog1.walkers; - assert.strictEqual(dog1Walkers.length, 1, 'dog1.walkers inverse relationship includes correct number of records'); - assert.strictEqual(dog1Walkers.firstObject.id, '1', 'dog1.walkers inverse relationship is set up correctly'); + assert.strictEqual(dogs.length, 2, 'left hand side relationship is set up with correct number of records'); + let [dog1, dog2] = dogs.toArray(); + let dog1Walkers = await dog1.walkers; + assert.strictEqual(dog1Walkers.length, 1, 'dog1.walkers inverse relationship includes correct number of records'); + assert.strictEqual(dog1Walkers.firstObject.id, '1', 'dog1.walkers inverse relationship is set up correctly'); - let dog2Walkers = await dog2.walkers; - assert.strictEqual(dog2Walkers.length, 1, 'dog2.walkers inverse relationship includes correct number of records'); - assert.strictEqual(dog2Walkers.firstObject.id, '1', 'dog2.walkers inverse relationship is set up correctly'); + let dog2Walkers = await dog2.walkers; + assert.strictEqual(dog2Walkers.length, 1, 'dog2.walkers inverse relationship includes correct number of records'); + assert.strictEqual(dog2Walkers.firstObject.id, '1', 'dog2.walkers inverse relationship is set up correctly'); - await dog1.destroyRecord(); - assert.strictEqual(dogs.length, 1, 'person.dogs relationship was updated when record removed'); - assert.strictEqual(dogs.firstObject.id, '2', 'person.dogs relationship has the correct records'); - }); + await dog1.destroyRecord(); + assert.strictEqual(dogs.length, 1, 'person.dogs relationship was updated when record removed'); + assert.strictEqual(dogs.firstObject.id, '2', 'person.dogs relationship has the correct records'); + } + ); - test('many-to-many (left hand async, right hand sync) - findHasMany/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', async function (assert) { - let { owner } = this; + deprecatedTest( + 'many-to-many (left hand async, right hand sync) - findHasMany/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findHasMany: () => { - return resolve({ - data: [ - { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findHasMany: () => { + return resolve({ + data: [ + { + id: '1', + type: 'dog', + attributes: { + name: 'Scooby', + }, }, - }, - { - id: 2, - type: 'dog', - attributes: { - name: 'Scrappy', + { + id: '2', + type: 'dog', + attributes: { + name: 'Scrappy', + }, }, - }, - ], - }); - }, - }) - ); + ], + }); + }, + }) + ); - class Person extends Model { - @hasMany('dog', { - async: true, - }) - dogs; - } - owner.register('model:person', Person); + class Person extends Model { + @hasMany('dog', { + async: true, + }) + dogs; + } + owner.register('model:person', Person); - class Dog extends Model { - @hasMany('person', { - async: false, - }) - walkers; - } - owner.register('model:dog', Dog); + class Dog extends Model { + @hasMany('person', { + async: false, + }) + walkers; + } + owner.register('model:dog', Dog); - let person = store.push({ - data: { - type: 'person', - id: '1', - attributes: { - name: 'John Churchill', - }, - relationships: { - dogs: { - links: { - related: 'http://example.com/person/1/dogs', + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + dogs: { + links: { + related: 'http://example.com/person/1/dogs', + }, }, }, }, - }, - }); + }); - let dogs = await person.dogs; - assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty); + let dogs = await person.dogs; + assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty); - assert.strictEqual(dogs.length, 2, 'left hand side relationship is set up with correct number of records'); - let [dog1, dog2] = dogs.toArray(); - let dog1Walkers = await dog1.walkers; - assert.strictEqual(dog1Walkers.length, 1, 'dog1.walkers inverse relationship includes correct number of records'); - assert.strictEqual(dog1Walkers.firstObject.id, '1', 'dog1.walkers inverse relationship is set up correctly'); + assert.strictEqual(dogs.length, 2, 'left hand side relationship is set up with correct number of records'); + let [dog1, dog2] = dogs.toArray(); + let dog1Walkers = await dog1.walkers; + assert.strictEqual(dog1Walkers.length, 1, 'dog1.walkers inverse relationship includes correct number of records'); + assert.strictEqual(dog1Walkers.firstObject.id, '1', 'dog1.walkers inverse relationship is set up correctly'); - let dog2Walkers = await dog2.walkers; - assert.strictEqual(dog2Walkers.length, 1, 'dog2.walkers inverse relationship includes correct number of records'); - assert.strictEqual(dog2Walkers.firstObject.id, '1', 'dog2.walkers inverse relationship is set up correctly'); + let dog2Walkers = await dog2.walkers; + assert.strictEqual(dog2Walkers.length, 1, 'dog2.walkers inverse relationship includes correct number of records'); + assert.strictEqual(dog2Walkers.firstObject.id, '1', 'dog2.walkers inverse relationship is set up correctly'); - await dog1.destroyRecord(); - assert.strictEqual(dogs.length, 1, 'person.dogs relationship was updated when record removed'); - assert.strictEqual(dogs.firstObject.id, '2', 'person.dogs relationship has the correct records'); - }); + await dog1.destroyRecord(); + assert.strictEqual(dogs.length, 1, 'person.dogs relationship was updated when record removed'); + assert.strictEqual(dogs.firstObject.id, '2', 'person.dogs relationship has the correct records'); + } + ); test('many-to-many - findHasMany/explicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', async function (assert) { let { owner } = this; @@ -979,14 +1004,14 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -1010,6 +1035,7 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @hasMany('person', { async: true, + inverse: 'dogs', }) pals; } @@ -1061,14 +1087,14 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -1092,6 +1118,7 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @hasMany('person', { async: false, + inverse: 'dogs', }) pals; } @@ -1132,149 +1159,157 @@ module('inverse relationship load test', function (hooks) { assert.strictEqual(dogs.firstObject.id, '2', 'person.dogs relationship has the correct records'); }); - test('many-to-one - findBelongsTo/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', async function (assert) { - let { owner } = this; + deprecatedTest( + 'many-to-one - findBelongsTo/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findBelongsTo: () => { - return resolve({ - data: { - type: 'person', - id: '1', - attributes: { - name: 'John Churchill', + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findBelongsTo: () => { + return resolve({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, }, - }, - }); - }, - }) - ); + }); + }, + }) + ); - class Person extends Model { - @hasMany('dog', { - async: true, - }) - dogs; - } - owner.register('model:person', Person); + class Person extends Model { + @hasMany('dog', { + async: true, + }) + dogs; + } + owner.register('model:person', Person); - class Dog extends Model { - @belongsTo('person', { - async: true, - }) - person; - } - owner.register('model:dog', Dog); + class Dog extends Model { + @belongsTo('person', { + async: true, + }) + person; + } + owner.register('model:dog', Dog); - let dog = store.push({ - data: { - type: 'dog', - id: '1', - attributes: { - name: 'A Really Good Dog', - }, - relationships: { - person: { - links: { - related: 'http://example.com/person/1', + let dog = store.push({ + data: { + type: 'dog', + id: '1', + attributes: { + name: 'A Really Good Dog', + }, + relationships: { + person: { + links: { + related: 'http://example.com/person/1', + }, }, }, }, - }, - }); + }); - let person = await dog.person; - assert.false( - dog.belongsTo('person').belongsToRelationship.state.isEmpty, - 'belongsTo relationship state was populated' - ); - assert.strictEqual(person.id, '1', 'dog.person relationship is correctly set up'); + let person = await dog.person; + assert.false( + dog.belongsTo('person').belongsToRelationship.state.isEmpty, + 'belongsTo relationship state was populated' + ); + assert.strictEqual(person.id, '1', 'dog.person relationship is correctly set up'); - let dogs = await person.dogs; + let dogs = await person.dogs; - assert.strictEqual(dogs.length, 1, 'person.dogs inverse relationship includes correct number of records'); - let [dog1] = dogs.toArray(); - assert.strictEqual(dog1.id, '1', 'dog1.person inverse relationship is set up correctly'); + assert.strictEqual(dogs.length, 1, 'person.dogs inverse relationship includes correct number of records'); + let [dog1] = dogs.toArray(); + assert.strictEqual(dog1.id, '1', 'dog1.person inverse relationship is set up correctly'); - await person.destroyRecord(); - dog = await dog.person; - assert.strictEqual(dog, null, 'record deleted removed from belongsTo relationship'); - }); + await person.destroyRecord(); + dog = await dog.person; + assert.strictEqual(dog, null, 'record deleted removed from belongsTo relationship'); + } + ); - test('many-to-one (left hand async, right hand sync) - findBelongsTo/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', async function (assert) { - let { owner } = this; + deprecatedTest( + 'many-to-one (left hand async, right hand sync) - findBelongsTo/implicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findBelongsTo: () => { - return resolve({ - data: { - type: 'person', - id: '1', - attributes: { - name: 'John Churchill', + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findBelongsTo: () => { + return resolve({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, }, - }, - }); - }, - }) - ); + }); + }, + }) + ); - class Person extends Model { - @hasMany('dog', { - async: false, - }) - dogs; - } - owner.register('model:person', Person); + class Person extends Model { + @hasMany('dog', { + async: false, + }) + dogs; + } + owner.register('model:person', Person); - class Dog extends Model { - @belongsTo('person', { - async: true, - }) - person; - } - owner.register('model:dog', Dog); + class Dog extends Model { + @belongsTo('person', { + async: true, + }) + person; + } + owner.register('model:dog', Dog); - let dog = store.push({ - data: { - type: 'dog', - id: '1', - attributes: { - name: 'A Really Good Dog', - }, - relationships: { - person: { - links: { - related: 'http://example.com/person/1', + let dog = store.push({ + data: { + type: 'dog', + id: '1', + attributes: { + name: 'A Really Good Dog', + }, + relationships: { + person: { + links: { + related: 'http://example.com/person/1', + }, }, }, }, - }, - }); + }); - let person = await dog.person; - assert.false( - dog.belongsTo('person').belongsToRelationship.state.isEmpty, - 'belongsTo relationship state was populated' - ); - assert.strictEqual(person.id, '1', 'dog.person relationship is correctly set up'); + let person = await dog.person; + assert.false( + dog.belongsTo('person').belongsToRelationship.state.isEmpty, + 'belongsTo relationship state was populated' + ); + assert.strictEqual(person.id, '1', 'dog.person relationship is correctly set up'); - let dogs = await person.dogs; + let dogs = await person.dogs; - assert.strictEqual(dogs.length, 1, 'person.dogs inverse relationship includes correct number of records'); - let [dog1] = dogs.toArray(); - assert.strictEqual(dog1.id, '1', 'dog1.person inverse relationship is set up correctly'); + assert.strictEqual(dogs.length, 1, 'person.dogs inverse relationship includes correct number of records'); + let [dog1] = dogs.toArray(); + assert.strictEqual(dog1.id, '1', 'dog1.person inverse relationship is set up correctly'); - await person.destroyRecord(); - dog = await dog.person; - assert.strictEqual(dog, null, 'record deleted removed from belongsTo relationship'); - }); + await person.destroyRecord(); + dog = await dog.person; + assert.strictEqual(dog, null, 'record deleted removed from belongsTo relationship'); + } + ); test('many-to-one - findBelongsTo/explicit inverse - adds parent relationship information to the payload if it is not included/added by the serializer', async function (assert) { let { owner } = this; @@ -1309,6 +1344,7 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @belongsTo('person', { async: true, + inverse: 'dogs', }) pal; } @@ -1382,6 +1418,7 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @belongsTo('person', { async: true, + inverse: 'dogs', }) pal; } @@ -1422,8 +1459,9 @@ module('inverse relationship load test', function (hooks) { assert.strictEqual(dog, null, 'record deleted removed from belongsTo relationship'); }); - testInDebug( + deprecatedTest( 'one-to-many - findHasMany/implicit inverse - fixes mismatched parent relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -1435,7 +1473,7 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -1450,7 +1488,7 @@ module('inverse relationship load test', function (hooks) { }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -1509,8 +1547,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'one-to-many (left hand async, right hand sync) - findHasMany/implicit inverse - fixes mismatched parent relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -1522,7 +1561,7 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -1537,7 +1576,7 @@ module('inverse relationship load test', function (hooks) { }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -1596,8 +1635,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'one-to-many - findHasMany/implicit inverse - fixes null relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -1609,7 +1649,7 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -1621,7 +1661,7 @@ module('inverse relationship load test', function (hooks) { }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -1677,8 +1717,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'one-to-many (left hand async, right hand sync) - findHasMany/implicit inverse - fixes null relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -1690,7 +1731,7 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -1702,7 +1743,7 @@ module('inverse relationship load test', function (hooks) { }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -1758,8 +1799,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'one-to-one - findBelongsTo/implicit inverse - fixes mismatched parent relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -1828,8 +1870,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'one-to-one (left hand async, right hand sync) - findBelongsTo/implicit inverse - fixes mismatched parent relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -1898,8 +1941,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'one-to-one - findBelongsTo/implicit inverse - fixes null relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -1965,8 +2009,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'one-to-one (left hand async, right hand sync) - findBelongsTo/implicit inverse - fixes null relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -2032,8 +2077,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'many-to-one - findBelongsTo/implicitInverse - fixes mismatched parent relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -2104,8 +2150,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'many-to-one (left hand async, right hand sync) - findBelongsTo/implicitInverse - fixes mismatched parent relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -2176,8 +2223,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'many-to-one - findBelongsTo/implicitInverse - fixes null relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -2243,8 +2291,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'many-to-one (left hand async, right hand sync) - findBelongsTo/implicitInverse - fixes null relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -2310,8 +2359,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'many-to-many - findHasMany/implicitInverse - fixes mismatched parent relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -2323,7 +2373,7 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -2340,7 +2390,7 @@ module('inverse relationship load test', function (hooks) { }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -2401,8 +2451,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'many-to-many (left hand async, right hand sync) - findHasMany/implicitInverse - fixes mismatched parent relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -2414,7 +2465,7 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -2431,7 +2482,7 @@ module('inverse relationship load test', function (hooks) { }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -2492,8 +2543,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'many-to-many - findHasMany/implicitInverse - fixes empty relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -2505,7 +2557,7 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -2517,7 +2569,7 @@ module('inverse relationship load test', function (hooks) { }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -2573,8 +2625,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'many-to-many (left hand async, right hand sync) - findHasMany/implicitInverse - fixes empty relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -2586,7 +2639,7 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -2598,7 +2651,7 @@ module('inverse relationship load test', function (hooks) { }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -2654,8 +2707,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'many-to-many - findHasMany/implicitInverse - fixes null relationship information from the payload and deprecates', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -2667,7 +2721,7 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -2679,7 +2733,7 @@ module('inverse relationship load test', function (hooks) { }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -2735,8 +2789,9 @@ module('inverse relationship load test', function (hooks) { } ); - testInDebug( + deprecatedTest( 'many-to-many (left hand async, right hand sync) - findHasMany/implicitInverse - asserts incorrect null relationship information from the payload', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, async function (assert) { let { owner } = this; @@ -2748,7 +2803,7 @@ module('inverse relationship load test', function (hooks) { return resolve({ data: [ { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -2760,7 +2815,7 @@ module('inverse relationship load test', function (hooks) { }, }, { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -2816,11 +2871,209 @@ module('inverse relationship load test', function (hooks) { } ); - test('one-to-many - ids/non-link/implicit inverse - ids - records loaded through ids/findRecord are linked to the parent if the response from the server does not include relationship information', async function (assert) { + deprecatedTest( + 'one-to-many - ids/non-link/implicit inverse - ids - records loaded through ids/findRecord are linked to the parent if the response from the server does not include relationship information', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; + + const scooby = { + id: '1', + type: 'dog', + attributes: { + name: 'Scooby', + }, + }; + + const scrappy = { + id: '2', + type: 'dog', + attributes: { + name: 'Scrappy', + }, + }; + + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findRecord: (_store, _type, id) => { + const dog = id === '1' ? scooby : scrappy; + return resolve({ + data: dog, + }); + }, + }) + ); + + class Person extends Model { + @hasMany('dog', { + async: true, + }) + dogs; + } + owner.register('model:person', Person); + + class Dog extends Model { + @belongsTo('person', { + async: true, + }) + person; + } + owner.register('model:dog', Dog); + + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + dogs: { + data: [ + { + id: '1', + type: 'dog', + }, + { + id: '2', + type: 'dog', + }, + ], + }, + }, + }, + }); + + let dogs = await person.dogs; + assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); + + assert.strictEqual(dogs.length, 2, 'hasMany relationship has correct number of records'); + let dog1 = dogs.firstObject; + let dogPerson1 = await dog1.person; + assert.strictEqual( + dogPerson1.id, + '1', + 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' + ); + let dogPerson2 = await dogs.objectAt(1).person; + assert.strictEqual( + dogPerson2.id, + '1', + 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' + ); + + await dog1.destroyRecord(); + assert.strictEqual(dogs.length, 1, 'record removed from hasMany relationship after deletion'); + assert.strictEqual(dogs.firstObject.id, '2', 'hasMany relationship has correct records'); + } + ); + + deprecatedTest( + 'one-to-many (left hand async, right hand sync) - ids/non-link/implicit inverse - ids - records loaded through ids/findRecord are linked to the parent if the response from the server does not include relationship information', + { id: 'ember-data:deprecate-non-strict-relationships', debugOnly: true, until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; + + const scooby = { + id: '1', + type: 'dog', + attributes: { + name: 'Scooby', + }, + }; + + const scrappy = { + id: '2', + type: 'dog', + attributes: { + name: 'Scrappy', + }, + }; + + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findRecord: (_store, _type, id) => { + const dog = id === '1' ? scooby : scrappy; + return resolve({ + data: dog, + }); + }, + }) + ); + + class Person extends Model { + @hasMany('dog', { + async: true, + }) + dogs; + } + owner.register('model:person', Person); + + class Dog extends Model { + @belongsTo('person', { + async: false, + }) + person; + } + owner.register('model:dog', Dog); + + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + dogs: { + data: [ + { + id: '1', + type: 'dog', + }, + { + id: '2', + type: 'dog', + }, + ], + }, + }, + }, + }); + + let dogs = await person.dogs; + assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); + + assert.strictEqual(dogs.length, 2, 'hasMany relationship has correct number of records'); + let dog1 = dogs.firstObject; + let dogPerson1 = await dog1.person; + assert.strictEqual( + dogPerson1.id, + '1', + 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' + ); + let dogPerson2 = await dogs.objectAt(1).person; + assert.strictEqual( + dogPerson2.id, + '1', + 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' + ); + + await dog1.destroyRecord(); + assert.strictEqual(dogs.length, 1, 'record removed from hasMany relationship after deletion'); + assert.strictEqual(dogs.firstObject.id, '2', 'hasMany relationship has correct records'); + } + ); + + test('one-to-many - ids/non-link/explicit inverse - ids - records loaded through ids/findRecord are linked to the parent if the response from the server does not include relationship information', async function (assert) { let { owner } = this; const scooby = { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -2828,7 +3081,7 @@ module('inverse relationship load test', function (hooks) { }; const scrappy = { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -2851,6 +3104,7 @@ module('inverse relationship load test', function (hooks) { class Person extends Model { @hasMany('dog', { async: true, + inverse: 'pal', }) dogs; } @@ -2859,8 +3113,9 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @belongsTo('person', { async: true, + inverse: 'dogs', }) - person; + pal; } owner.register('model:dog', Dog); @@ -2893,13 +3148,13 @@ module('inverse relationship load test', function (hooks) { assert.strictEqual(dogs.length, 2, 'hasMany relationship has correct number of records'); let dog1 = dogs.firstObject; - let dogPerson1 = await dog1.person; + let dogPerson1 = await dog1.pal; assert.strictEqual( dogPerson1.id, '1', 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' ); - let dogPerson2 = await dogs.objectAt(1).person; + let dogPerson2 = await dogs.objectAt(1).pal; assert.strictEqual( dogPerson2.id, '1', @@ -2911,11 +3166,11 @@ module('inverse relationship load test', function (hooks) { assert.strictEqual(dogs.firstObject.id, '2', 'hasMany relationship has correct records'); }); - test('one-to-many (left hand async, right hand sync) - ids/non-link/implicit inverse - ids - records loaded through ids/findRecord are linked to the parent if the response from the server does not include relationship information', async function (assert) { + test('one-to-many (left hand async, right hand sync) - ids/non-link/explicit inverse - ids - records loaded through ids/findRecord are linked to the parent if the response from the server does not include relationship information', async function (assert) { let { owner } = this; const scooby = { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -2923,7 +3178,7 @@ module('inverse relationship load test', function (hooks) { }; const scrappy = { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -2946,6 +3201,7 @@ module('inverse relationship load test', function (hooks) { class Person extends Model { @hasMany('dog', { async: true, + inverse: 'pal', }) dogs; } @@ -2954,8 +3210,9 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @belongsTo('person', { async: false, + inverse: 'dogs', }) - person; + pal; } owner.register('model:dog', Dog); @@ -2988,13 +3245,13 @@ module('inverse relationship load test', function (hooks) { assert.strictEqual(dogs.length, 2, 'hasMany relationship has correct number of records'); let dog1 = dogs.firstObject; - let dogPerson1 = await dog1.person; + let dogPerson1 = await dog1.pal; assert.strictEqual( dogPerson1.id, '1', 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' ); - let dogPerson2 = await dogs.objectAt(1).person; + let dogPerson2 = await dogs.objectAt(1).pal; assert.strictEqual( dogPerson2.id, '1', @@ -3006,11 +3263,11 @@ module('inverse relationship load test', function (hooks) { assert.strictEqual(dogs.firstObject.id, '2', 'hasMany relationship has correct records'); }); - test('one-to-many - ids/non-link/explicit inverse - ids - records loaded through ids/findRecord are linked to the parent if the response from the server does not include relationship information', async function (assert) { + test('one-to-many - ids/non-link/null inverse - ids - records loaded through ids/findRecord are linked to the parent if the response from the server does not include relationship information', async function (assert) { let { owner } = this; const scooby = { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -3018,7 +3275,7 @@ module('inverse relationship load test', function (hooks) { }; const scrappy = { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -3041,18 +3298,13 @@ module('inverse relationship load test', function (hooks) { class Person extends Model { @hasMany('dog', { async: true, - inverse: 'pal', + inverse: null, }) dogs; } owner.register('model:person', Person); - class Dog extends Model { - @belongsTo('person', { - async: true, - }) - pal; - } + class Dog extends Model {} owner.register('model:dog', Dog); let person = store.push({ @@ -3084,650 +3336,479 @@ module('inverse relationship load test', function (hooks) { assert.strictEqual(dogs.length, 2, 'hasMany relationship has correct number of records'); let dog1 = dogs.firstObject; - let dogPerson1 = await dog1.pal; - assert.strictEqual( - dogPerson1.id, - '1', - 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' - ); - let dogPerson2 = await dogs.objectAt(1).pal; - assert.strictEqual( - dogPerson2.id, - '1', - 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' - ); await dog1.destroyRecord(); assert.strictEqual(dogs.length, 1, 'record removed from hasMany relationship after deletion'); assert.strictEqual(dogs.firstObject.id, '2', 'hasMany relationship has correct records'); }); - test('one-to-many (left hand async, right hand sync) - ids/non-link/explicit inverse - ids - records loaded through ids/findRecord are linked to the parent if the response from the server does not include relationship information', async function (assert) { - let { owner } = this; - - const scooby = { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', - }, - }; - - const scrappy = { - id: 2, - type: 'dog', - attributes: { - name: 'Scrappy', - }, - }; + deprecatedTest( + 'one-to-many - ids/non-link/implicit inverse - records loaded through ids/findRecord do not get associated with the parent if the server specifies another resource as the relationship value in the response', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findRecord: (_store, _type, id) => { - const dog = id === '1' ? scooby : scrappy; - return resolve({ - data: dog, - }); + const scooby = { + id: '1', + type: 'dog', + attributes: { + name: 'Scooby', }, - }) - ); - - class Person extends Model { - @hasMany('dog', { - async: true, - inverse: 'pal', - }) - dogs; - } - owner.register('model:person', Person); - - class Dog extends Model { - @belongsTo('person', { - async: false, - }) - pal; - } - owner.register('model:dog', Dog); + relationships: { + person: { + data: { + id: '2', + type: 'person', + }, + }, + }, + }; - let person = store.push({ - data: { - type: 'person', - id: '1', + const scrappy = { + id: '2', + type: 'dog', attributes: { - name: 'John Churchill', + name: 'Scrappy', }, relationships: { - dogs: { - data: [ - { - id: '1', - type: 'dog', - }, - { - id: '2', - type: 'dog', - }, - ], + person: { + data: { + id: '2', + type: 'person', + }, }, }, - }, - }); + }; - let dogs = await person.dogs; - assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findRecord: (_store, _type, id) => { + const dog = id === '1' ? scooby : scrappy; + return resolve({ + data: dog, + }); + }, + }) + ); - assert.strictEqual(dogs.length, 2, 'hasMany relationship has correct number of records'); - let dog1 = dogs.firstObject; - let dogPerson1 = await dog1.pal; - assert.strictEqual( - dogPerson1.id, - '1', - 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' - ); - let dogPerson2 = await dogs.objectAt(1).pal; - assert.strictEqual( - dogPerson2.id, - '1', - 'dog.person inverse relationship is set up correctly when adapter does not include parent relationships in data.relationships' - ); + class Person extends Model { + @hasMany('dog', { + async: true, + }) + dogs; + } + owner.register('model:person', Person); - await dog1.destroyRecord(); - assert.strictEqual(dogs.length, 1, 'record removed from hasMany relationship after deletion'); - assert.strictEqual(dogs.firstObject.id, '2', 'hasMany relationship has correct records'); - }); + class Dog extends Model { + @belongsTo('person', { + async: true, + }) + person; + } + owner.register('model:dog', Dog); - test('one-to-many - ids/non-link/null inverse - ids - records loaded through ids/findRecord are linked to the parent if the response from the server does not include relationship information', async function (assert) { - let { owner } = this; + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + dogs: { + data: [ + { + id: '1', + type: 'dog', + }, + { + id: '2', + type: 'dog', + }, + ], + }, + }, + }, + }); - const scooby = { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', - }, - }; + let person2 = store.push({ + data: { + type: 'person', + id: '2', + attributes: { + name: 'ok', + }, + }, + }); - const scrappy = { - id: 2, - type: 'dog', - attributes: { - name: 'Scrappy', - }, - }; + let dogs = await person.dogs; + assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findRecord: (_store, _type, id) => { - const dog = id === '1' ? scooby : scrappy; - return resolve({ - data: dog, - }); - }, - }) - ); + assert.strictEqual(dogs.length, 0, 'hasMany relationship for parent is empty'); - class Person extends Model { - @hasMany('dog', { - async: true, - inverse: null, - }) - dogs; + let person2Dogs = await person2.dogs; + assert.strictEqual( + person2Dogs.length, + 2, + 'hasMany relationship on specified record has correct number of associated records' + ); + + let allDogs = store.peekAll('dogs').toArray(); + for (let i = 0; i < allDogs.length; i++) { + let dog = allDogs[i]; + let dogPerson = await dog.person; + assert.strictEqual(dogPerson.id, person2.id, 'right hand side has correct belongsTo value'); + } + + let dog1 = store.peekRecord('dog', '1'); + await dog1.destroyRecord(); + assert.strictEqual(person2Dogs.length, 1, 'record removed from hasMany relationship after deletion'); + assert.strictEqual(person2Dogs.firstObject.id, '2', 'hasMany relationship has correct records'); } - owner.register('model:person', Person); + ); - class Dog extends Model {} - owner.register('model:dog', Dog); + deprecatedTest( + 'one-to-many (left hand async, right hand sync) - ids/non-link/implicit inverse - records loaded through ids/findRecord do not get associated with the parent if the server specifies another resource as the relationship value in the response', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; - let person = store.push({ - data: { - type: 'person', + const scooby = { id: '1', + type: 'dog', attributes: { - name: 'John Churchill', + name: 'Scooby', }, relationships: { - dogs: { - data: [ - { - id: '1', - type: 'dog', - }, - { - id: '2', - type: 'dog', - }, - ], + person: { + data: { + id: '2', + type: 'person', + }, }, }, - }, - }); - - let dogs = await person.dogs; - assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); + }; - assert.strictEqual(dogs.length, 2, 'hasMany relationship has correct number of records'); - let dog1 = dogs.firstObject; - - await dog1.destroyRecord(); - assert.strictEqual(dogs.length, 1, 'record removed from hasMany relationship after deletion'); - assert.strictEqual(dogs.firstObject.id, '2', 'hasMany relationship has correct records'); - }); - - test('one-to-many - ids/non-link/implicit inverse - records loaded through ids/findRecord do not get associated with the parent if the server specifies another resource as the relationship value in the response', async function (assert) { - let { owner } = this; - - const scooby = { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', - }, - relationships: { - person: { - data: { - id: '2', - type: 'person', - }, - }, - }, - }; - - const scrappy = { - id: 2, - type: 'dog', - attributes: { - name: 'Scrappy', - }, - relationships: { - person: { - data: { - id: '2', - type: 'person', - }, - }, - }, - }; - - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findRecord: (_store, _type, id) => { - const dog = id === '1' ? scooby : scrappy; - return resolve({ - data: dog, - }); - }, - }) - ); - - class Person extends Model { - @hasMany('dog', { - async: true, - }) - dogs; - } - owner.register('model:person', Person); - - class Dog extends Model { - @belongsTo('person', { - async: true, - }) - person; - } - owner.register('model:dog', Dog); - - let person = store.push({ - data: { - type: 'person', - id: '1', - attributes: { - name: 'John Churchill', - }, - relationships: { - dogs: { - data: [ - { - id: '1', - type: 'dog', - }, - { - id: '2', - type: 'dog', - }, - ], - }, - }, - }, - }); - - let person2 = store.push({ - data: { - type: 'person', + const scrappy = { id: '2', + type: 'dog', attributes: { - name: 'ok', + name: 'Scrappy', }, - }, - }); - - let dogs = await person.dogs; - assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); - - assert.strictEqual(dogs.length, 0, 'hasMany relationship for parent is empty'); - - let person2Dogs = await person2.dogs; - assert.strictEqual( - person2Dogs.length, - 2, - 'hasMany relationship on specified record has correct number of associated records' - ); - - let allDogs = store.peekAll('dogs').toArray(); - for (let i = 0; i < allDogs.length; i++) { - let dog = allDogs[i]; - let dogPerson = await dog.person; - assert.strictEqual(dogPerson.id, person2.id, 'right hand side has correct belongsTo value'); - } - - let dog1 = store.peekRecord('dog', '1'); - await dog1.destroyRecord(); - assert.strictEqual(person2Dogs.length, 1, 'record removed from hasMany relationship after deletion'); - assert.strictEqual(person2Dogs.firstObject.id, '2', 'hasMany relationship has correct records'); - }); - - test('one-to-many (left hand async, right hand sync) - ids/non-link/implicit inverse - records loaded through ids/findRecord do not get associated with the parent if the server specifies another resource as the relationship value in the response', async function (assert) { - let { owner } = this; - - const scooby = { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', - }, - relationships: { - person: { - data: { - id: '2', - type: 'person', + relationships: { + person: { + data: { + id: '2', + type: 'person', + }, }, }, - }, - }; + }; - const scrappy = { - id: 2, - type: 'dog', - attributes: { - name: 'Scrappy', - }, - relationships: { - person: { - data: { - id: '2', - type: 'person', + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findRecord: (_store, _type, id) => { + const dog = id === '1' ? scooby : scrappy; + return resolve({ + data: dog, + }); }, - }, - }, - }; - - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findRecord: (_store, _type, id) => { - const dog = id === '1' ? scooby : scrappy; - return resolve({ - data: dog, - }); - }, - }) - ); + }) + ); - class Person extends Model { - @hasMany('dog', { - async: true, - }) - dogs; - } - owner.register('model:person', Person); + class Person extends Model { + @hasMany('dog', { + async: true, + }) + dogs; + } + owner.register('model:person', Person); - class Dog extends Model { - @belongsTo('person', { - async: false, - }) - person; - } - owner.register('model:dog', Dog); + class Dog extends Model { + @belongsTo('person', { + async: false, + }) + person; + } + owner.register('model:dog', Dog); - let person = store.push({ - data: { - type: 'person', - id: '1', - attributes: { - name: 'John Churchill', - }, - relationships: { - dogs: { - data: [ - { - id: '1', - type: 'dog', - }, - { - id: '2', - type: 'dog', - }, - ], + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + dogs: { + data: [ + { + id: '1', + type: 'dog', + }, + { + id: '2', + type: 'dog', + }, + ], + }, }, }, - }, - }); - - let person2 = store.push({ - data: { - type: 'person', - id: '2', - attributes: { - name: 'ok', - }, - }, - }); - - let dogs = await person.dogs; - assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); - - assert.strictEqual(dogs.length, 0, 'hasMany relationship for parent is empty'); - - let person2Dogs = await person2.dogs; - assert.strictEqual( - person2Dogs.length, - 2, - 'hasMany relationship on specified record has correct number of associated records' - ); - - let allDogs = store.peekAll('dogs').toArray(); - for (let i = 0; i < allDogs.length; i++) { - let dog = allDogs[i]; - let dogPerson = await dog.person; - assert.strictEqual(dogPerson.id, person2.id, 'right hand side has correct belongsTo value'); - } - - let dog1 = store.peekRecord('dog', '1'); - await dog1.destroyRecord(); - assert.strictEqual(person2Dogs.length, 1, 'record removed from hasMany relationship after deletion'); - assert.strictEqual(person2Dogs.firstObject.id, '2', 'hasMany relationship has correct records'); - }); - - test('one-to-many - ids/non-link/implicit inverse - records loaded through ids/findRecord do not get associated with the parent if the server specifies null as the relationship value in the response', async function (assert) { - let { owner } = this; - - const scooby = { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', - }, - relationships: { - person: { - data: null, - }, - }, - }; - - const scrappy = { - id: 2, - type: 'dog', - attributes: { - name: 'Scrappy', - }, - relationships: { - person: { - data: null, - }, - }, - }; + }); - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findRecord: (_store, _type, id) => { - const dog = id === '1' ? scooby : scrappy; - return resolve({ - data: dog, - }); + let person2 = store.push({ + data: { + type: 'person', + id: '2', + attributes: { + name: 'ok', + }, }, - }) - ); + }); - class Person extends Model { - @hasMany('dog', { - async: true, - }) - dogs; - } - owner.register('model:person', Person); + let dogs = await person.dogs; + assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); - class Dog extends Model { - @belongsTo('person', { - async: true, - }) - person; + assert.strictEqual(dogs.length, 0, 'hasMany relationship for parent is empty'); + + let person2Dogs = await person2.dogs; + assert.strictEqual( + person2Dogs.length, + 2, + 'hasMany relationship on specified record has correct number of associated records' + ); + + let allDogs = store.peekAll('dogs').toArray(); + for (let i = 0; i < allDogs.length; i++) { + let dog = allDogs[i]; + let dogPerson = await dog.person; + assert.strictEqual(dogPerson.id, person2.id, 'right hand side has correct belongsTo value'); + } + + let dog1 = store.peekRecord('dog', '1'); + await dog1.destroyRecord(); + assert.strictEqual(person2Dogs.length, 1, 'record removed from hasMany relationship after deletion'); + assert.strictEqual(person2Dogs.firstObject.id, '2', 'hasMany relationship has correct records'); } - owner.register('model:dog', Dog); + ); - let person = store.push({ - data: { - type: 'person', + deprecatedTest( + 'one-to-many - ids/non-link/implicit inverse - records loaded through ids/findRecord do not get associated with the parent if the server specifies null as the relationship value in the response', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; + + const scooby = { id: '1', + type: 'dog', attributes: { - name: 'John Churchill', + name: 'Scooby', }, relationships: { - dogs: { - data: [ - { - id: '1', - type: 'dog', - }, - { - id: '2', - type: 'dog', - }, - ], + person: { + data: null, }, }, - }, - }); + }; - let personDogs = await person.dogs; - assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); + const scrappy = { + id: '2', + type: 'dog', + attributes: { + name: 'Scrappy', + }, + relationships: { + person: { + data: null, + }, + }, + }; - assert.strictEqual(personDogs.length, 0, 'hasMany relationship for parent is empty'); + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findRecord: (_store, _type, id) => { + const dog = id === '1' ? scooby : scrappy; + return resolve({ + data: dog, + }); + }, + }) + ); - let allDogs = store.peekAll('dogs').toArray(); - for (let i = 0; i < allDogs.length; i++) { - let dog = allDogs[i]; - let dogPerson = await dog.person; - assert.strictEqual(dogPerson, null, 'right hand side has correct belongsTo value'); - } + class Person extends Model { + @hasMany('dog', { + async: true, + }) + dogs; + } + owner.register('model:person', Person); - let dog1 = store.peekRecord('dog', '1'); - await dog1.destroyRecord(); + class Dog extends Model { + @belongsTo('person', { + async: true, + }) + person; + } + owner.register('model:dog', Dog); - assert.strictEqual(personDogs.length, 0); - }); + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + dogs: { + data: [ + { + id: '1', + type: 'dog', + }, + { + id: '2', + type: 'dog', + }, + ], + }, + }, + }, + }); - test('one-to-many (left hand async, right hand sync) - ids/non-link/implicit inverse - records loaded through ids/findRecord do not get associated with the parent if the server specifies null as the relationship value in the response', async function (assert) { - let { owner } = this; + let personDogs = await person.dogs; + assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); - const scooby = { - id: 1, - type: 'dog', - attributes: { - name: 'Scooby', - }, - relationships: { - person: { - data: null, - }, - }, - }; + assert.strictEqual(personDogs.length, 0, 'hasMany relationship for parent is empty'); - const scrappy = { - id: 2, - type: 'dog', - attributes: { - name: 'Scrappy', - }, - relationships: { - person: { - data: null, - }, - }, - }; + let allDogs = store.peekAll('dogs').toArray(); + for (let i = 0; i < allDogs.length; i++) { + let dog = allDogs[i]; + let dogPerson = await dog.person; + assert.strictEqual(dogPerson, null, 'right hand side has correct belongsTo value'); + } - owner.register( - 'adapter:application', - JSONAPIAdapter.extend({ - deleteRecord: () => resolve({ data: null }), - findRecord: (_store, _type, id) => { - const dog = id === '1' ? scooby : scrappy; - return resolve({ - data: dog, - }); - }, - }) - ); + let dog1 = store.peekRecord('dog', '1'); + await dog1.destroyRecord(); - class Person extends Model { - @hasMany('dog', { - async: true, - }) - dogs; + assert.strictEqual(personDogs.length, 0); } - owner.register('model:person', Person); + ); - class Dog extends Model { - @belongsTo('person', { - async: false, - }) - person; - } - owner.register('model:dog', Dog); + deprecatedTest( + 'one-to-many (left hand async, right hand sync) - ids/non-link/implicit inverse - records loaded through ids/findRecord do not get associated with the parent if the server specifies null as the relationship value in the response', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 2 }, + async function (assert) { + let { owner } = this; - let person = store.push({ - data: { - type: 'person', + const scooby = { id: '1', + type: 'dog', attributes: { - name: 'John Churchill', + name: 'Scooby', }, relationships: { - dogs: { - data: [ - { - id: '1', - type: 'dog', - }, - { - id: '2', - type: 'dog', - }, - ], + person: { + data: null, }, }, - }, - }); + }; - let personDogs = await person.dogs; - assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); + const scrappy = { + id: '2', + type: 'dog', + attributes: { + name: 'Scrappy', + }, + relationships: { + person: { + data: null, + }, + }, + }; + + owner.register( + 'adapter:application', + JSONAPIAdapter.extend({ + deleteRecord: () => resolve({ data: null }), + findRecord: (_store, _type, id) => { + const dog = id === '1' ? scooby : scrappy; + return resolve({ + data: dog, + }); + }, + }) + ); - assert.strictEqual(personDogs.length, 0, 'hasMany relationship for parent is empty'); + class Person extends Model { + @hasMany('dog', { + async: true, + }) + dogs; + } + owner.register('model:person', Person); - let allDogs = store.peekAll('dogs').toArray(); - for (let i = 0; i < allDogs.length; i++) { - let dog = allDogs[i]; - let dogPerson = await dog.person; - assert.strictEqual(dogPerson, null, 'right hand side has correct belongsTo value'); - } + class Dog extends Model { + @belongsTo('person', { + async: false, + }) + person; + } + owner.register('model:dog', Dog); - let dog1 = store.peekRecord('dog', '1'); - await dog1.destroyRecord(); + let person = store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'John Churchill', + }, + relationships: { + dogs: { + data: [ + { + id: '1', + type: 'dog', + }, + { + id: '2', + type: 'dog', + }, + ], + }, + }, + }, + }); - assert.strictEqual(personDogs.length, 0); - }); + let personDogs = await person.dogs; + assert.false(person.hasMany('dogs').hasManyRelationship.state.isEmpty, 'relationship state was set up correctly'); + + assert.strictEqual(personDogs.length, 0, 'hasMany relationship for parent is empty'); + + let allDogs = store.peekAll('dogs').toArray(); + for (let i = 0; i < allDogs.length; i++) { + let dog = allDogs[i]; + let dogPerson = await dog.person; + assert.strictEqual(dogPerson, null, 'right hand side has correct belongsTo value'); + } + + let dog1 = store.peekRecord('dog', '1'); + await dog1.destroyRecord(); + + assert.strictEqual(personDogs.length, 0); + } + ); test('one-to-many - ids/non-link/explicit inverse - records loaded through ids/findRecord do not get associated with the parent if the server specifies another resource as the relationship value in the response', async function (assert) { let { owner } = this; const scooby = { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -3743,7 +3824,7 @@ module('inverse relationship load test', function (hooks) { }; const scrappy = { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -3774,6 +3855,7 @@ module('inverse relationship load test', function (hooks) { class Person extends Model { @hasMany('dog', { async: true, + inverse: 'pal', }) dogs; } @@ -3782,6 +3864,7 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @belongsTo('pal', { async: true, + inverse: 'dogs', }) pal; } @@ -3850,7 +3933,7 @@ module('inverse relationship load test', function (hooks) { let { owner } = this; const scooby = { - id: 1, + id: '1', type: 'dog', attributes: { name: 'Scooby', @@ -3866,7 +3949,7 @@ module('inverse relationship load test', function (hooks) { }; const scrappy = { - id: 2, + id: '2', type: 'dog', attributes: { name: 'Scrappy', @@ -3897,6 +3980,7 @@ module('inverse relationship load test', function (hooks) { class Person extends Model { @hasMany('dog', { async: true, + inverse: 'pal', }) dogs; } @@ -3905,6 +3989,7 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @belongsTo('pal', { async: false, + inverse: 'dogs', }) pal; } @@ -4032,6 +4117,7 @@ module('inverse relationship load test', function (hooks) { class Person extends Model { @hasMany('dog', { async: false, + inverse: 'person', }) dogs; } @@ -4041,6 +4127,7 @@ module('inverse relationship load test', function (hooks) { class Dog extends Model { @belongsTo('person', { async: true, + inverse: 'dogs', }) person; diff --git a/packages/-ember-data/tests/integration/relationships/inverse-relationships-test.js b/packages/-ember-data/tests/integration/relationships/inverse-relationships-test.js index 8f7736a25cf..f85f31410d7 100644 --- a/packages/-ember-data/tests/integration/relationships/inverse-relationships-test.js +++ b/packages/-ember-data/tests/integration/relationships/inverse-relationships-test.js @@ -1,4 +1,4 @@ -import { module, test } from 'qunit'; +import { module } from 'qunit'; import { setupTest } from 'ember-qunit'; @@ -6,8 +6,13 @@ import Model, { attr, belongsTo, hasMany } from '@ember-data/model'; import { graphFor } from '@ember-data/record-data/-private'; import { recordIdentifierFor } from '@ember-data/store'; import { recordDataFor } from '@ember-data/store/-private'; +import { deprecatedTest } from '@ember-data/unpublished-test-infra/test-support/deprecated-test'; import testInDebug from '@ember-data/unpublished-test-infra/test-support/test-in-debug'; +function test(label, callback) { + deprecatedTest(label, { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 'ALL' }, callback); +} + module('integration/relationships/inverse_relationships - Inverse Relationships', function (hooks) { setupTest(hooks); @@ -623,7 +628,7 @@ module('integration/relationships/inverse_relationships - Inverse Relationships' "Inverse null relationships with models that don't exist throw a nice error if trying to use that relationship", function (assert) { class User extends Model { - @belongsTo('post', { inverse: null }) + @belongsTo('post', { async: true, inverse: null }) post; } @@ -641,7 +646,7 @@ module('integration/relationships/inverse_relationships - Inverse Relationships' class User extends Model {} class Comment extends Model { - @belongsTo('user') + @belongsTo('user', { async: true }) user; } @@ -657,12 +662,12 @@ module('integration/relationships/inverse_relationships - Inverse Relationships' assert.expect(2); class Post extends Model { - @hasMany('comment', { async: true }) + @hasMany('comment', { async: true, inverse: 'post' }) comments; } class Comment extends Model { - @belongsTo('post', { async: true }) + @belongsTo('post', { async: true, inverse: 'comments' }) post; } diff --git a/packages/-ember-data/tests/integration/relationships/json-api-links-test.js b/packages/-ember-data/tests/integration/relationships/json-api-links-test.js index ebee772330c..75b3d517f26 100644 --- a/packages/-ember-data/tests/integration/relationships/json-api-links-test.js +++ b/packages/-ember-data/tests/integration/relationships/json-api-links-test.js @@ -4,30 +4,29 @@ import { run } from '@ember/runloop'; import { module, test } from 'qunit'; import { resolve } from 'rsvp'; -import DS from 'ember-data'; import { setupTest } from 'ember-qunit'; +import Adapter from '@ember-data/adapter'; import JSONAPIAdapter from '@ember-data/adapter/json-api'; +import Model, { attr, belongsTo, hasMany } from '@ember-data/model'; import JSONAPISerializer from '@ember-data/serializer/json-api'; import deepCopy from '@ember-data/unpublished-test-infra/test-support/deep-copy'; -const { Model, attr, hasMany, belongsTo } = DS; - module('integration/relationship/json-api-links | Relationship state updates', function (hooks) { setupTest(hooks); test('Loading link with inverse:null on other model caches the two ends separately', function (assert) { - const User = DS.Model.extend({ - organisation: belongsTo('organisation', { inverse: null }), + const User = Model.extend({ + organisation: belongsTo('organisation', { async: true, inverse: null }), }); - const Organisation = DS.Model.extend({ - adminUsers: hasMany('user', { inverse: null }), + const Organisation = Model.extend({ + adminUsers: hasMany('user', { async: true, inverse: null }), }); this.owner.register('model:user', User); this.owner.register('model:organisation', Organisation); - this.owner.register('adapter:application', DS.Adapter.extend()); + this.owner.register('adapter:application', Adapter.extend()); this.owner.register('serializer:application', class extends JSONAPISerializer {}); let store = this.owner.lookup('service:store'); @@ -42,7 +41,7 @@ module('integration/relationship/json-api-links | Relationship state updates', f type: 'user', relationships: { organisation: { - data: { id: 1, type: 'organisation' }, + data: { id: '1', type: 'organisation' }, }, }, }, @@ -95,17 +94,17 @@ module('integration/relationship/json-api-links | Relationship state updates', f }); test('Pushing child record should not mark parent:children as loaded', function (assert) { - const Child = DS.Model.extend({ - parent: belongsTo('parent', { inverse: 'children' }), + const Child = Model.extend({ + parent: belongsTo('parent', { async: true, inverse: 'children' }), }); - const Parent = DS.Model.extend({ - children: hasMany('child', { inverse: 'parent' }), + const Parent = Model.extend({ + children: hasMany('child', { async: true, inverse: 'parent' }), }); this.owner.register('model:child', Child); this.owner.register('model:parent', Parent); - this.owner.register('adapter:application', DS.Adapter.extend()); + this.owner.register('adapter:application', Adapter.extend()); this.owner.register('serializer:application', class extends JSONAPISerializer {}); let store = this.owner.lookup('service:store'); diff --git a/packages/-ember-data/tests/integration/relationships/many-to-many-test.js b/packages/-ember-data/tests/integration/relationships/many-to-many-test.js index 58eecc48bf9..abcef849dfc 100644 --- a/packages/-ember-data/tests/integration/relationships/many-to-many-test.js +++ b/packages/-ember-data/tests/integration/relationships/many-to-many-test.js @@ -19,18 +19,18 @@ module('integration/relationships/many_to_many_test - ManyToMany relationships', hooks.beforeEach(function () { const User = Model.extend({ name: attr('string'), - topics: hasMany('topic', { async: true }), - accounts: hasMany('account', { async: false }), + topics: hasMany('topic', { async: true, inverse: 'users' }), + accounts: hasMany('account', { async: false, inverse: 'users' }), }); const Account = Model.extend({ state: attr(), - users: hasMany('user', { async: false }), + users: hasMany('user', { async: false, inverse: 'accounts' }), }); const Topic = Model.extend({ title: attr('string'), - users: hasMany('user', { async: true }), + users: hasMany('user', { async: true, inverse: 'topics' }), }); this.owner.register('model:topic', Topic); diff --git a/packages/-ember-data/tests/integration/relationships/nested-relationship-test.js b/packages/-ember-data/tests/integration/relationships/nested-relationship-test.js index 28d248da690..c9332d32e17 100644 --- a/packages/-ember-data/tests/integration/relationships/nested-relationship-test.js +++ b/packages/-ember-data/tests/integration/relationships/nested-relationship-test.js @@ -11,18 +11,18 @@ module('integration/relationships/nested_relationships_test - Nested relationshi hooks.beforeEach(function () { const Elder = Model.extend({ name: attr('string'), - middleAgers: hasMany('middle-ager'), + middleAgers: hasMany('middle-ager', { async: true, inverse: 'elder' }), }); const MiddleAger = Model.extend({ name: attr('string'), - elder: belongsTo('elder'), - kids: hasMany('kid'), + elder: belongsTo('elder', { async: true, inverse: 'middleAgers' }), + kids: hasMany('kid', { async: true, inverse: 'middleAger' }), }); const Kid = Model.extend({ name: attr('string'), - middleAger: belongsTo('middle-ager'), + middleAger: belongsTo('middle-ager', { async: true, inverse: 'kids' }), }); this.owner.register('model:elder', Elder); diff --git a/packages/-ember-data/tests/integration/relationships/one-to-many-test.js b/packages/-ember-data/tests/integration/relationships/one-to-many-test.js index 0a4c1a4facb..8b97b90287f 100644 --- a/packages/-ember-data/tests/integration/relationships/one-to-many-test.js +++ b/packages/-ember-data/tests/integration/relationships/one-to-many-test.js @@ -17,18 +17,18 @@ module('integration/relationships/one_to_many_test - OneToMany relationships', f hooks.beforeEach(function () { const User = Model.extend({ name: attr('string'), - messages: hasMany('message', { async: true }), - accounts: hasMany('account', { async: false }), + messages: hasMany('message', { async: true, inverse: 'user' }), + accounts: hasMany('account', { async: false, inverse: 'user' }), }); const Account = Model.extend({ state: attr(), - user: belongsTo('user', { async: false }), + user: belongsTo('user', { async: false, inverse: 'accounts' }), }); const Message = Model.extend({ title: attr('string'), - user: belongsTo('user', { async: true }), + user: belongsTo('user', { async: true, inverse: 'messages' }), }); const ApplicationAdapter = Adapter.extend({ diff --git a/packages/-ember-data/tests/integration/relationships/one-to-one-test.js b/packages/-ember-data/tests/integration/relationships/one-to-one-test.js index 0f847b7dc26..f365ab74811 100644 --- a/packages/-ember-data/tests/integration/relationships/one-to-one-test.js +++ b/packages/-ember-data/tests/integration/relationships/one-to-one-test.js @@ -18,13 +18,13 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun const User = Model.extend({ name: attr('string'), bestFriend: belongsTo('user', { async: true, inverse: 'bestFriend' }), - job: belongsTo('job', { async: false }), + job: belongsTo('job', { async: false, inverse: 'user' }), }); const Job = Model.extend({ name: attr(), isGood: attr(), - user: belongsTo('user', { async: false }), + user: belongsTo('user', { async: false, inverse: 'job' }), }); const ApplicationAdapter = Adapter.extend({ @@ -51,7 +51,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { stanley = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -59,7 +59,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 2, + id: '2', type: 'user', }, }, @@ -68,7 +68,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); stanleysFriend = store.push({ data: { - id: 2, + id: '2', type: 'user', attributes: { name: "Stanley's friend", @@ -89,7 +89,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { job = store.push({ data: { - id: 2, + id: '2', type: 'job', attributes: { isGood: true, @@ -98,7 +98,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); user = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -106,7 +106,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { job: { data: { - id: 2, + id: '2', type: 'job', }, }, @@ -124,7 +124,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { stanleysFriend = store.push({ data: { - id: 2, + id: '2', type: 'user', attributes: { name: "Stanley's friend", @@ -132,7 +132,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 1, + id: '1', type: 'user', }, }, @@ -141,7 +141,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -166,7 +166,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { job = store.push({ data: { - id: 2, + id: '2', type: 'job', attributes: { isGood: true, @@ -175,7 +175,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -183,7 +183,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { job: { data: { - id: 2, + id: '2', type: 'job', }, }, @@ -194,7 +194,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { job = store.push({ data: { - id: 2, + id: '2', type: 'job', attributes: { isGood: true, @@ -393,7 +393,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { stanley = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -402,7 +402,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); stanleysFriend = store.push({ data: { - id: 2, + id: '2', type: 'user', attributes: { name: "Stanley's friend", @@ -425,7 +425,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { job = store.push({ data: { - id: 2, + id: '2', type: 'job', attributes: { isGood: true, @@ -434,7 +434,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); user = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -455,7 +455,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { stanley = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -463,7 +463,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 2, + id: '2', type: 'user', }, }, @@ -472,7 +472,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); stanleysFriend = store.push({ data: { - id: 2, + id: '2', type: 'user', attributes: { name: "Stanley's friend", @@ -481,7 +481,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); newFriend = store.push({ data: { - id: 3, + id: '3', type: 'user', attributes: { name: 'New friend', @@ -515,7 +515,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -524,7 +524,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); igor = store.push({ data: { - id: 2, + id: '2', type: 'user', attributes: { name: 'Igor', @@ -533,7 +533,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); newFriend = store.push({ data: { - id: 3, + id: '3', type: 'user', attributes: { name: 'New friend', @@ -541,7 +541,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 1, + id: '1', type: 'user', }, }, @@ -564,7 +564,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { stanley = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -572,7 +572,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 2, + id: '2', type: 'user', }, }, @@ -581,7 +581,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); igor = store.push({ data: { - id: 3, + id: '3', type: 'user', attributes: { name: 'Igor', @@ -607,7 +607,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { stanley = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -615,7 +615,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 2, + id: '2', type: 'user', }, }, @@ -624,7 +624,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); igor = store.push({ data: { - id: 3, + id: '3', type: 'user', attributes: { name: 'Igor', @@ -632,7 +632,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 5, + id: '5', type: 'user', }, }, @@ -641,7 +641,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); newFriend = store.push({ data: { - id: 7, + id: '7', type: 'user', attributes: { name: 'New friend', @@ -652,13 +652,13 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun adapter.findRecord = function (store, type, id, snapshot) { if (id === '5') { - return resolve({ data: { id: 5, type: 'user', attributes: { name: "Igor's friend" } } }); + return resolve({ data: { id: '5', type: 'user', attributes: { name: "Igor's friend" } } }); } else if (id === '2') { let done = assert.async(); return new EmberPromise(function (resolve, reject) { setTimeout(function () { done(); - resolve({ data: { id: 2, type: 'user', attributes: { name: "Stanley's friend" } } }); + resolve({ data: { id: '2', type: 'user', attributes: { name: "Stanley's friend" } } }); }, 1); }); } @@ -680,7 +680,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { stanley = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -688,7 +688,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 2, + id: '2', type: 'user', }, }, @@ -697,7 +697,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); stanleysFriend = store.push({ data: { - id: 2, + id: '2', type: 'user', attributes: { name: "Stanley's friend", @@ -705,7 +705,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 1, + id: '1', type: 'user', }, }, @@ -729,7 +729,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { job = store.push({ data: { - id: 2, + id: '2', type: 'job', attributes: { isGood: false, @@ -737,7 +737,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { user: { data: { - id: 1, + id: '1', type: 'user', }, }, @@ -746,7 +746,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); user = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -754,7 +754,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { job: { data: { - id: 2, + id: '2', type: 'job', }, }, @@ -778,7 +778,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { stanley = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -786,7 +786,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 2, + id: '2', type: 'user', }, }, @@ -795,7 +795,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); stanleysFriend = store.push({ data: { - id: 2, + id: '2', type: 'user', attributes: { name: "Stanley's friend", @@ -803,7 +803,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 1, + id: '1', type: 'user', }, }, @@ -815,7 +815,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun assert.strictEqual(fetchedUser, stanley, 'User relationship was initally setup correctly'); var stanleysNewFriend = store.push({ data: { - id: 3, + id: '3', type: 'user', attributes: { name: "Stanley's New friend", @@ -845,7 +845,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { job = store.push({ data: { - id: 2, + id: '2', type: 'job', attributes: { isGood: false, @@ -854,7 +854,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); user = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -862,7 +862,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { job: { data: { - id: 2, + id: '2', type: 'job', }, }, @@ -876,7 +876,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { newBetterJob = store.push({ data: { - id: 3, + id: '3', type: 'job', attributes: { isGood: true, @@ -903,7 +903,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { stanley = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -911,7 +911,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { bestFriend: { data: { - id: 2, + id: '2', type: 'user', }, }, @@ -920,7 +920,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); stanleysFriend = store.push({ data: { - id: 2, + id: '2', type: 'user', attributes: { name: "Stanley's friend", @@ -949,7 +949,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun run(function () { job = store.push({ data: { - id: 2, + id: '2', type: 'job', attributes: { isGood: true, @@ -958,7 +958,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun }); user = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', @@ -966,7 +966,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun relationships: { job: { data: { - id: 2, + id: '2', type: 'job', }, }, @@ -987,7 +987,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun const stanleysFriend = store.push({ data: { - id: 2, + id: '2', type: 'user', attributes: { name: "Stanley's friend", @@ -1010,7 +1010,7 @@ module('integration/relationships/one_to_one_test - OneToOne relationships', fun const user = store.push({ data: { - id: 1, + id: '1', type: 'user', attributes: { name: 'Stanley', diff --git a/packages/-ember-data/tests/integration/relationships/polymorphic-mixins-belongs-to-test.js b/packages/-ember-data/tests/integration/relationships/polymorphic-mixins-belongs-to-test.js index e5cafa732c5..b0670313eaf 100644 --- a/packages/-ember-data/tests/integration/relationships/polymorphic-mixins-belongs-to-test.js +++ b/packages/-ember-data/tests/integration/relationships/polymorphic-mixins-belongs-to-test.js @@ -18,12 +18,12 @@ module( hooks.beforeEach(function () { const User = Model.extend({ name: attr('string'), - bestMessage: belongsTo('message', { async: true, polymorphic: true }), + bestMessage: belongsTo('message', { async: true, inverse: 'user', polymorphic: true }), }); const Message = Mixin.create({ title: attr('string'), - user: belongsTo('user', { async: true }), + user: belongsTo('user', { async: true, inverse: 'bestMessage' }), }); const NotMessage = Model.extend({ video: attr() }); diff --git a/packages/-ember-data/tests/integration/relationships/polymorphic-mixins-has-many-test.js b/packages/-ember-data/tests/integration/relationships/polymorphic-mixins-has-many-test.js index b6cf2ed899f..58632a5d7d8 100644 --- a/packages/-ember-data/tests/integration/relationships/polymorphic-mixins-has-many-test.js +++ b/packages/-ember-data/tests/integration/relationships/polymorphic-mixins-has-many-test.js @@ -20,12 +20,12 @@ module( hooks.beforeEach(function () { const User = Model.extend({ name: attr('string'), - messages: hasMany('message', { async: true, polymorphic: true }), + messages: hasMany('message', { async: true, inverse: 'user', polymorphic: true }), }); Message = Mixin.create({ title: attr('string'), - user: belongsTo('user', { async: true }), + user: belongsTo('user', { async: true, inverse: 'messages' }), }); const Video = Model.extend(Message, { video: attr() }); diff --git a/packages/-ember-data/tests/integration/serializers/embedded-records-mixin-test.js b/packages/-ember-data/tests/integration/serializers/embedded-records-mixin-test.js index 7807e457448..04cbfdc4c46 100644 --- a/packages/-ember-data/tests/integration/serializers/embedded-records-mixin-test.js +++ b/packages/-ember-data/tests/integration/serializers/embedded-records-mixin-test.js @@ -18,9 +18,9 @@ module('integration/embedded-records-mixin', function (hooks) { firstName: attr('string'), lastName: attr('string'), homePlanet: belongsTo('home-planet', { inverse: 'villains', async: true }), - secretLab: belongsTo('secret-lab', { async: false }), - secretWeapons: hasMany('secret-weapon', { async: false }), - evilMinions: hasMany('evil-minion', { async: false }), + secretLab: belongsTo('secret-lab', { async: false, inverse: 'superVillain' }), + secretWeapons: hasMany('secret-weapon', { async: false, inverse: 'superVillain' }), + evilMinions: hasMany('evil-minion', { async: false, inverse: 'superVillain' }), }); const HomePlanet = Model.extend({ name: attr('string'), @@ -29,20 +29,20 @@ module('integration/embedded-records-mixin', function (hooks) { const SecretLab = Model.extend({ minionCapacity: attr('number'), vicinity: attr('string'), - superVillain: belongsTo('super-villain', { async: false }), + superVillain: belongsTo('super-villain', { async: false, inverse: 'secretLab' }), }); const BatCave = SecretLab.extend({ infiltrated: attr('boolean'), }); const SecretWeapon = Model.extend({ name: attr('string'), - superVillain: belongsTo('super-villain', { async: false }), + superVillain: belongsTo('super-villain', { async: false, inverse: 'secretWeapons' }), }); const LightSaber = SecretWeapon.extend({ color: attr('string'), }); const EvilMinion = Model.extend({ - superVillain: belongsTo('super-villain', { async: false }), + superVillain: belongsTo('super-villain', { async: false, inverse: 'evilMinions' }), name: attr('string'), }); const Comment = Model.extend({ @@ -593,9 +593,9 @@ module('integration/embedded-records-mixin', function (hooks) { firstName: attr('string'), lastName: attr('string'), homePlanet: belongsTo('home-planet', { inverse: 'villains', async: true }), - secretLab: belongsTo('secret-lab', { async: false }), - secretWeapons: hasMany('secretWeapon', { polymorphic: true, async: false }), - evilMinions: hasMany('evil-minion', { async: false }), + secretLab: belongsTo('secret-lab', { async: false, inverse: 'superVillain' }), + secretWeapons: hasMany('secretWeapon', { polymorphic: true, async: false, inverse: 'superVillain' }), + evilMinions: hasMany('evil-minion', { async: false, inverse: 'superVillain' }), }); owner.register( @@ -689,9 +689,9 @@ module('integration/embedded-records-mixin', function (hooks) { firstName: attr('string'), lastName: attr('string'), homePlanet: belongsTo('home-planet', { inverse: 'villains', async: true }), - secretLab: belongsTo('secretLab', { polymorphic: true, async: true }), - secretWeapons: hasMany('secret-weapon', { async: false }), - evilMinions: hasMany('evil-minion', { async: false }), + secretLab: belongsTo('secretLab', { polymorphic: true, async: true, inverse: 'superVillain' }), + secretWeapons: hasMany('secret-weapon', { async: false, inverse: 'superVillain' }), + evilMinions: hasMany('evil-minion', { async: false, inverse: 'superVillain' }), }); owner.register( @@ -759,9 +759,9 @@ module('integration/embedded-records-mixin', function (hooks) { firstName: attr('string'), lastName: attr('string'), homePlanet: belongsTo('home-planet', { inverse: 'villains', async: true }), - secretLab: belongsTo('secretLab', { polymorphic: true, async: true }), - secretWeapons: hasMany('secret-weapon', { async: false }), - evilMinions: hasMany('evil-minion', { async: false }), + secretLab: belongsTo('secretLab', { polymorphic: true, async: true, inverse: 'superVillain' }), + secretWeapons: hasMany('secret-weapon', { async: false, inverse: 'superVillain' }), + evilMinions: hasMany('evil-minion', { async: false, inverse: 'superVillain' }), }); owner.register( @@ -1191,7 +1191,7 @@ module('integration/embedded-records-mixin', function (hooks) { const HomePlanetClass = Model.extend({ name: attr('string'), villains: hasMany('super-villain', { inverse: 'homePlanet', async: false }), - reformedVillains: hasMany('superVillain', { async: false }), + reformedVillains: hasMany('superVillain', { async: false, inverse: null }), }); owner.unregister('model:home-planet'); owner.register('model:home-planet', HomePlanetClass); @@ -1460,9 +1460,9 @@ module('integration/embedded-records-mixin', function (hooks) { firstName: attr('string'), lastName: attr('string'), homePlanet: belongsTo('home-planet', { inverse: 'villains', async: true }), - secretLab: belongsTo('secret-lab', { async: false }), - secretWeapons: hasMany('secretWeapon', { polymorphic: true, async: false }), - evilMinions: hasMany('evil-minion', { async: false }), + secretLab: belongsTo('secret-lab', { async: false, inverse: 'superVillain' }), + secretWeapons: hasMany('secretWeapon', { polymorphic: true, async: false, inverse: 'superVillain' }), + evilMinions: hasMany('evil-minion', { async: false, inverse: 'superVillain' }), }); owner.register( @@ -1921,17 +1921,17 @@ module('integration/embedded-records-mixin', function (hooks) { ); let superVillain = store.createRecord('super-villain', { - id: 1, + id: '1', firstName: 'Super', lastName: 'Villian', }); let evilMinion = store.createRecord('evil-minion', { - id: 1, + id: '1', name: 'Evil Minion', superVillain, }); let secretWeapon = store.createRecord('secret-weapon', { - id: 1, + id: '1', name: 'Secret Weapon', superVillain, }); @@ -1967,7 +1967,7 @@ module('integration/embedded-records-mixin', function (hooks) { const RedMinion = NormalMinion.extend(); const CommanderVillain = Model.extend({ name: attr('string'), - minions: hasMany('normal-minion', { polymorphic: true }), + minions: hasMany('normal-minion', { async: true, inverse: null, polymorphic: true }), }); owner.register('model:commander-villain', CommanderVillain); @@ -1984,15 +1984,15 @@ module('integration/embedded-records-mixin', function (hooks) { ); let yellowMinion = store.createRecord('yellow-minion', { - id: 1, + id: '1', name: 'Yellowy', }); let redMinion = store.createRecord('red-minion', { - id: 1, + id: '1', name: 'Reddy', }); let commanderVillain = store.createRecord('commander-villain', { - id: 1, + id: '1', name: 'Jeff', minions: [yellowMinion, redMinion], }); @@ -2155,9 +2155,9 @@ module('integration/embedded-records-mixin', function (hooks) { firstName: attr('string'), lastName: attr('string'), homePlanet: belongsTo('home-planet', { inverse: 'villains', async: true }), - secretLab: belongsTo('secret-lab', { polymorphic: true }), - secretWeapons: hasMany('secret-weapon', { async: false }), - evilMinions: hasMany('evil-minion', { async: false }), + secretLab: belongsTo('secret-lab', { async: true, inverse: 'superVillain', polymorphic: true }), + secretWeapons: hasMany('secret-weapon', { async: false, inverse: 'superVillain' }), + evilMinions: hasMany('evil-minion', { async: false, inverse: 'superVillain' }), }); owner.unregister('model:super-villain'); owner.register('model:super-villain', SuperVillain); @@ -2296,9 +2296,9 @@ module('integration/embedded-records-mixin', function (hooks) { firstName: attr('string'), lastName: attr('string'), homePlanet: belongsTo('home-planet', { inverse: 'villains', async: true }), - secretLab: belongsTo('secret-lab', { polymorphic: true }), - secretWeapons: hasMany('secret-weapon', { async: false }), - evilMinions: hasMany('evil-minion', { async: false }), + secretLab: belongsTo('secret-lab', { polymorphic: true, async: true, inverse: 'superVillain' }), + secretWeapons: hasMany('secret-weapon', { async: false, inverse: 'superVillain' }), + evilMinions: hasMany('evil-minion', { async: false, inverse: 'superVillain' }), }); owner.register( 'serializer:super-villain', @@ -2341,9 +2341,9 @@ module('integration/embedded-records-mixin', function (hooks) { firstName: attr('string'), lastName: attr('string'), homePlanet: belongsTo('home-planet', { inverse: 'villains', async: true }), - secretLab: belongsTo('secret-lab', { polymorphic: true }), - secretWeapons: hasMany('secret-weapon', { async: false }), - evilMinions: hasMany('evil-minion', { async: false }), + secretLab: belongsTo('secret-lab', { polymorphic: true, inverse: 'superVillain', async: true }), + secretWeapons: hasMany('secret-weapon', { async: false, inverse: 'superVillain' }), + evilMinions: hasMany('evil-minion', { async: false, inverse: 'superVillain' }), }); owner.register( @@ -2388,9 +2388,9 @@ module('integration/embedded-records-mixin', function (hooks) { firstName: attr('string'), lastName: attr('string'), homePlanet: belongsTo('home-planet', { inverse: 'villains', async: true }), - secretLab: belongsTo('secret-lab', { polymorphic: true }), - secretWeapons: hasMany('secret-weapon', { async: false }), - evilMinions: hasMany('evil-minion', { async: false }), + secretLab: belongsTo('secret-lab', { polymorphic: true, inverse: 'superVillain', async: true }), + secretWeapons: hasMany('secret-weapon', { async: false, inverse: 'superVillain' }), + evilMinions: hasMany('evil-minion', { async: false, inverse: 'superVillain' }), }); owner.register( @@ -2643,7 +2643,7 @@ module('integration/embedded-records-mixin', function (hooks) { name: attr('string'), }); const EvilMinionClass = Model.extend({ - secretWeapon: belongsTo('secret-weapon', { async: false }), + secretWeapon: belongsTo('secret-weapon', { async: false, inverse: null }), name: attr('string'), }); diff --git a/packages/-ember-data/tests/integration/serializers/json-api-serializer-test.js b/packages/-ember-data/tests/integration/serializers/json-api-serializer-test.js index fd0126b0baa..035f1423379 100644 --- a/packages/-ember-data/tests/integration/serializers/json-api-serializer-test.js +++ b/packages/-ember-data/tests/integration/serializers/json-api-serializer-test.js @@ -18,13 +18,13 @@ module('integration/serializers/json-api-serializer - JSONAPISerializer', functi firstName: DS.attr('string'), lastName: DS.attr('string'), title: DS.attr('string'), - handles: DS.hasMany('handle', { async: true, polymorphic: true }), - company: DS.belongsTo('company', { async: true }), + handles: DS.hasMany('handle', { async: true, polymorphic: true, inverse: 'user' }), + company: DS.belongsTo('company', { async: true, inverse: 'employees' }), reportsTo: DS.belongsTo('user', { async: true, inverse: null }), }); const Handle = DS.Model.extend({ - user: DS.belongsTo('user', { async: true }), + user: DS.belongsTo('user', { async: true, inverse: 'handles' }), }); const GithubHandle = Handle.extend({ @@ -37,7 +37,7 @@ module('integration/serializers/json-api-serializer - JSONAPISerializer', functi const Company = DS.Model.extend({ name: DS.attr('string'), - employees: DS.hasMany('user', { async: true }), + employees: DS.hasMany('user', { async: true, inverse: 'company' }), }); const Project = DS.Model.extend({ @@ -390,8 +390,8 @@ module('integration/serializers/json-api-serializer - JSONAPISerializer', functi firstName: DS.attr('string'), lastName: DS.attr('string'), title: DS.attr('string'), - handles: DS.hasMany('handle', { async: true, polymorphic: true }), - company: DS.belongsTo('company', { async: true }), + handles: DS.hasMany('handle', { async: true, polymorphic: true, inverse: 'user' }), + company: DS.belongsTo('company', { async: true, inverse: 'employees' }), reportsTo: DS.belongsTo('user', { async: true, inverse: null }), myCustomField: DS.attr('custom', { custom: 'config', @@ -431,7 +431,7 @@ module('integration/serializers/json-api-serializer - JSONAPISerializer', functi serializer.pushPayload(store, { data: { type: 'handles', - id: 1, + id: '1', }, }); @@ -454,7 +454,7 @@ module('integration/serializers/json-api-serializer - JSONAPISerializer', functi serializer.pushPayload(store, { data: { type: 'handles', - id: 1, + id: '1', }, }); @@ -483,7 +483,7 @@ module('integration/serializers/json-api-serializer - JSONAPISerializer', functi serializer.pushPayload(store, { data: { type: 'handles', - id: 1, + id: '1', }, }); @@ -517,19 +517,19 @@ module('integration/serializers/json-api-serializer - JSONAPISerializer', functi store.serializerFor('user').pushPayload(store, { data: { type: 'users', - id: 1, + id: '1', relationships: { handles: { data: [ - { type: 'handles', id: 1 }, - { type: 'handles', id: 2 }, + { type: 'handles', id: '1' }, + { type: 'handles', id: '2' }, ], }, }, }, included: [ - { type: 'handles', id: 1 }, - { type: 'handles', id: 2 }, + { type: 'handles', id: '1' }, + { type: 'handles', id: '2' }, ], }); @@ -575,19 +575,19 @@ module('integration/serializers/json-api-serializer - JSONAPISerializer', functi store.serializerFor('user').pushPayload(store, { data: { type: 'users', - id: 1, + id: '1', relationships: { handles: { data: [ - { type: 'handles', id: 1 }, - { type: 'handles', id: 2 }, + { type: 'handles', id: '1' }, + { type: 'handles', id: '2' }, ], }, }, }, included: [ - { type: 'handles', id: 1 }, - { type: 'handles', id: 2 }, + { type: 'handles', id: '1' }, + { type: 'handles', id: '2' }, ], }); @@ -634,7 +634,7 @@ module('integration/serializers/json-api-serializer - JSONAPISerializer', functi store.serializerFor('user').pushPayload(store, { data: { type: 'users', - id: 1, + id: '1', }, }); diff --git a/packages/-ember-data/tests/integration/serializers/json-serializer-test.js b/packages/-ember-data/tests/integration/serializers/json-serializer-test.js index 011d5bb20a1..3982ce41aa7 100644 --- a/packages/-ember-data/tests/integration/serializers/json-serializer-test.js +++ b/packages/-ember-data/tests/integration/serializers/json-serializer-test.js @@ -433,7 +433,7 @@ module('integration/serializer/json - JSONSerializer', function (hooks) { ); let store = this.owner.lookup('service:store'); - let post = store.createRecord('post', { title: 'Rails is omakase', id: 1 }); + let post = store.createRecord('post', { title: 'Rails is omakase', id: '1' }); let comment = store.createRecord('comment', { body: 'Omakase is delicious', post: post }); store @@ -465,7 +465,7 @@ module('integration/serializer/json - JSONSerializer', function (hooks) { ); let store = this.owner.lookup('service:store'); - let post = store.createRecord('post', { title: 'Rails is omakase', id: 1 }); + let post = store.createRecord('post', { title: 'Rails is omakase', id: '1' }); let comment = store.createRecord('comment', { body: 'Omakase is delicious', post: post }); store @@ -643,7 +643,7 @@ module('integration/serializer/json - JSONSerializer', function (hooks) { this.owner.register( 'model:parent', Model.extend({ - child: belongsTo('child'), + child: belongsTo('child', { async: true, inverse: null }), }) ); this.owner.register( @@ -654,9 +654,9 @@ module('integration/serializer/json - JSONSerializer', function (hooks) { ); var jsonHash = { - id: 1, + id: '1', child: { - id: 1, + id: '1', type: 'first_type', }, }; @@ -689,21 +689,21 @@ module('integration/serializer/json - JSONSerializer', function (hooks) { this.owner.register( 'model:parent', Model.extend({ - child: belongsTo('child'), + child: belongsTo('child', { async: true, inverse: null }), }) ); this.owner.register( 'model:child', Model.extend({ - type: belongsTo('le-type'), + type: belongsTo('le-type', { async: true, inverse: null }), }) ); this.owner.register('model:le-type', Model.extend()); var jsonHash = { - id: 1, + id: '1', child: { - id: 1, + id: '1', type: 'my_type_id', }, }; @@ -1095,7 +1095,7 @@ module('integration/serializer/json - JSONSerializer', function (hooks) { }) ); - let jsonHash = { id: 1, TITLE: 'Rails is omakase' }; + let jsonHash = { id: '1', TITLE: 'Rails is omakase' }; let store = this.owner.lookup('service:store'); let post = store.serializerFor('post').normalize(store.modelFor('post'), jsonHash); @@ -1126,7 +1126,7 @@ module('integration/serializer/json - JSONSerializer', function (hooks) { }) ); - let jsonHash = { id: 1, title: 'Rails is omakase', COMMENTS: ['1'] }; + let jsonHash = { id: '1', title: 'Rails is omakase', COMMENTS: ['1'] }; let store = this.owner.lookup('service:store'); let post = store.serializerFor('post').normalize(store.modelFor('post'), jsonHash); diff --git a/packages/-ember-data/tests/integration/serializers/rest-serializer-test.js b/packages/-ember-data/tests/integration/serializers/rest-serializer-test.js index b615be1301a..06daf32a21e 100644 --- a/packages/-ember-data/tests/integration/serializers/rest-serializer-test.js +++ b/packages/-ember-data/tests/integration/serializers/rest-serializer-test.js @@ -19,25 +19,25 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { hooks.beforeEach(function () { HomePlanet = Model.extend({ name: attr('string'), - superVillains: hasMany('super-villain', { async: false }), + superVillains: hasMany('super-villain', { async: false, inverse: 'homePlanet' }), }); SuperVillain = Model.extend({ firstName: attr('string'), lastName: attr('string'), - homePlanet: belongsTo('home-planet', { async: false }), - evilMinions: hasMany('evil-minion', { async: false }), + homePlanet: belongsTo('home-planet', { async: false, inverse: 'superVillains' }), + evilMinions: hasMany('evil-minion', { async: false, inverse: 'superVillain' }), }); EvilMinion = Model.extend({ - superVillain: belongsTo('super-villain', { async: false }), + superVillain: belongsTo('super-villain', { async: false, inverse: 'evilMinions' }), name: attr('string'), - doomsdayDevice: belongsTo('doomsday-device', { async: false }), + doomsdayDevice: belongsTo('doomsday-device', { async: false, inverse: 'evilMinion' }), }); YellowMinion = EvilMinion.extend({ eyes: attr('number'), }); DoomsdayDevice = Model.extend({ name: attr('string'), - evilMinion: belongsTo('evil-minion', { polymorphic: true, async: true }), + evilMinion: belongsTo('evil-minion', { polymorphic: true, async: true, inverse: 'doomsdayDevice' }), }); Comment = Model.extend({ body: attr('string'), @@ -49,7 +49,7 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { size: attr('number'), }); Container = Model.extend({ - type: belongsTo('basket', { async: true }), + type: belongsTo('basket', { async: true, inverse: null }), volume: attr('string'), }); @@ -547,9 +547,9 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { let json = {}; let expected = { evilMinion: '1', evilMinionType: 'evilMinion' }; - let evilMinion = store.createRecord('evil-minion', { id: 1, name: 'Tomster' }); + let evilMinion = store.createRecord('evil-minion', { id: '1', name: 'Tomster' }); let doomsdayDevice = store.createRecord('doomsday-device', { - id: 2, + id: '2', name: 'Yehuda', evilMinion: evilMinion, }); @@ -573,9 +573,9 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { return 'typeForEvilMinion'; }; - let evilMinion = store.createRecord('evil-minion', { id: 1, name: 'Tomster' }); + let evilMinion = store.createRecord('evil-minion', { id: '1', name: 'Tomster' }); let doomsdayDevice = store.createRecord('doomsday-device', { - id: 2, + id: '2', name: 'Yehuda', evilMinion: evilMinion, }); @@ -659,7 +659,7 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { if (type.modelName === 'doomsday-device') { return { doomsdayDevice: { - id: 1, + id: '1', name: 'DeathRay', evilMinion: 1, evilMinionType: 'yellowMinion', @@ -671,7 +671,7 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { return { yellowMinion: { - id: 1, + id: '1', type: 'yellowMinion', name: 'Alex', eyes: 3, @@ -699,7 +699,7 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { return { doomsdayDevices: [ { - id: 1, + id: '1', name: 'DeathRay', links: { evilMinion: '/doomsday-device/1/evil-minion', @@ -712,7 +712,7 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { adapter.findBelongsTo = () => { return { evilMinion: { - id: 1, + id: '1', type: 'yellowMinion', name: 'Alex', eyes: 3, @@ -735,16 +735,16 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { test('normalizeResponse with async polymorphic hasMany', function (assert) { const HomePlanet = Model.extend({ name: attr('string'), - superVillains: hasMany('super-villain2', { async: false }), + superVillains: hasMany('super-villain2', { async: false, inverse: 'homePlanet' }), }); const SuperVillain = Model.extend({ firstName: attr('string'), lastName: attr('string'), - homePlanet: belongsTo('home-planet2', { async: false }), - evilMinions: hasMany('evil-minion2', { async: true, polymorphic: true }), + homePlanet: belongsTo('home-planet2', { async: false, inverse: 'superVillains' }), + evilMinions: hasMany('evil-minion2', { async: true, polymorphic: true, inverse: 'superVillain' }), }); const EvilMinion = Model.extend({ - superVillain: belongsTo('super-villain2', { async: false }), + superVillain: belongsTo('super-villain2', { async: false, inverse: 'evilMinions' }), name: attr('string'), }); const YellowMinion = EvilMinion.extend({ @@ -778,7 +778,7 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { return { evilMinion2: [ { - id: 1, + id: '1', type: 'yellowMinion2', name: 'Alex', eyes: 3, @@ -913,8 +913,8 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { adapter.findRecord = () => { return { - containers: [{ id: 42, volume: '10 liters', type: 1 }], - baskets: [{ id: 1, size: 4 }], + containers: [{ id: '42', volume: '10 liters', type: 1 }], + baskets: [{ id: '1', size: 4 }], }; }; @@ -968,11 +968,11 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { let payload = { doomsdayDevice: { - id: 1, + id: '1', evilMinion: 2, }, evilMinion: { - id: 2, + id: '2', doomsdayDevice: 1, }, }; @@ -1004,11 +1004,11 @@ module('integration/serializer/rest - RESTSerializer', function (hooks) { let payload = { homePlanet: { - id: 1, + id: '1', superVillains: [2], }, superVillain: { - id: 2, + id: '2', homePlanet: 1, }, }; diff --git a/packages/-ember-data/tests/integration/snapshot-test.js b/packages/-ember-data/tests/integration/snapshot-test.js index dcb8b07b7e9..43ff444b0af 100644 --- a/packages/-ember-data/tests/integration/snapshot-test.js +++ b/packages/-ember-data/tests/integration/snapshot-test.js @@ -21,7 +21,7 @@ module('integration/snapshot - Snapshot', function (hooks) { @attr() title; - @hasMany({ async: true }) + @hasMany('comment', { async: true, inverse: 'post' }) comments; } @@ -29,7 +29,7 @@ module('integration/snapshot - Snapshot', function (hooks) { @attr() body; - @belongsTo({ async: true }) + @belongsTo('post', { async: true, inverse: 'comments' }) post; } _Post = Post; @@ -540,7 +540,7 @@ module('integration/snapshot - Snapshot', function (hooks) { assert.expect(4); store.adapterFor('application').findBelongsTo = function (store, snapshot, link, relationship) { - return resolve({ data: { id: 1, type: 'post', attributes: { title: 'Hello World' } } }); + return resolve({ data: { id: '1', type: 'post', attributes: { title: 'Hello World' } } }); }; store.push({ @@ -1013,7 +1013,7 @@ module('integration/snapshot - Snapshot', function (hooks) { store.adapterFor('application').findHasMany = function (store, snapshot, link, relationship) { return resolve({ - data: [{ id: 2, type: 'comment', attributes: { body: 'This is comment' } }], + data: [{ id: '2', type: 'comment', attributes: { body: 'This is comment' } }], }); }; diff --git a/packages/-ember-data/tests/integration/store-test.js b/packages/-ember-data/tests/integration/store-test.js index 17447121868..3c0902f2858 100644 --- a/packages/-ember-data/tests/integration/store-test.js +++ b/packages/-ember-data/tests/integration/store-test.js @@ -18,7 +18,7 @@ import testInDebug from '@ember-data/unpublished-test-infra/test-support/test-in class Person extends Model { @attr('string') name; - @hasMany('car', { async: false }) cars; + @hasMany('car', { async: false, inverse: 'person' }) cars; static toString() { return 'Person'; @@ -28,7 +28,7 @@ class Person extends Model { class Car extends Model { @attr('string') make; @attr('string') model; - @belongsTo('person', { async: false }) person; + @belongsTo('person', { async: false, inverse: 'cars' }) person; static toString() { return 'Car'; @@ -1210,13 +1210,13 @@ module('integration/store - queryRecord', function (hooks) { adapter.queryRecord = function () { return { - cars: [{ id: 1 }], + cars: [{ id: '1' }], }; }; serializer.normalizeQueryRecordResponse = function () { return { - data: [{ id: 1, type: 'car' }], + data: [{ id: '1', type: 'car' }], }; }; diff --git a/packages/-ember-data/tests/integration/store/query-record-test.js b/packages/-ember-data/tests/integration/store/query-record-test.js index e0941093df0..8f7d72d3236 100644 --- a/packages/-ember-data/tests/integration/store/query-record-test.js +++ b/packages/-ember-data/tests/integration/store/query-record-test.js @@ -49,7 +49,7 @@ module('integration/store/query-record - Query one record with a query hash', fu queryRecord(store, type, query) { assert.strictEqual(type, Person, 'the query method is called with the correct type'); return resolve({ - data: { id: 1, type: 'person', attributes: { name: 'Peter Wagenet' } }, + data: { id: '1', type: 'person', attributes: { name: 'Peter Wagenet' } }, }); }, }) diff --git a/packages/-ember-data/tests/unit/custom-class-support/custom-class-model-test.ts b/packages/-ember-data/tests/unit/custom-class-support/custom-class-model-test.ts index 2d44fa4e4ac..a66678ffe8c 100644 --- a/packages/-ember-data/tests/unit/custom-class-support/custom-class-model-test.ts +++ b/packages/-ember-data/tests/unit/custom-class-support/custom-class-model-test.ts @@ -404,6 +404,7 @@ module('unit/model - Custom Class Model', function (hooks) { kind: 'belongsTo', options: { inverse: null, + async: true, }, key: 'house', name: 'house', diff --git a/packages/-ember-data/tests/unit/debug-test.js b/packages/-ember-data/tests/unit/debug-test.js index fb99fcee4b1..2b536e28c28 100644 --- a/packages/-ember-data/tests/unit/debug-test.js +++ b/packages/-ember-data/tests/unit/debug-test.js @@ -24,8 +24,8 @@ if (has('@ember-data/debug')) { const User = Model.extend({ name: attr('string'), isDrugAddict: attr('boolean'), - maritalStatus: belongsTo('marital-status', { async: false }), - posts: hasMany('post', { async: false }), + maritalStatus: belongsTo('marital-status', { async: false, inverse: null }), + posts: hasMany('post', { async: false, inverse: null }), }); this.owner.register('model:marital-status', MaritalStatus); @@ -57,7 +57,7 @@ if (has('@ember-data/debug')) { const User = Model.extend({ name: attr('string'), isDrugAddict: attr('boolean'), - maritalStatus: belongsTo('marital-status', { async: false }), + maritalStatus: belongsTo('marital-status', { async: false, inverse: null }), posts: computed(() => [1, 2, 3]) .readOnly() .meta({ diff --git a/packages/-ember-data/tests/unit/many-array-test.js b/packages/-ember-data/tests/unit/many-array-test.js index a5df7929224..265d8469f77 100644 --- a/packages/-ember-data/tests/unit/many-array-test.js +++ b/packages/-ember-data/tests/unit/many-array-test.js @@ -17,12 +17,12 @@ module('unit/many_array - ManyArray', function (hooks) { class Post extends Model { @attr('string') title; - @hasMany('tag', { async: false }) tags; + @hasMany('tag', { async: false, inverse: 'post' }) tags; } class Tag extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'tags' }) post; save() { assert.ok(true, 'record.save() was called'); @@ -82,12 +82,12 @@ module('unit/many_array - ManyArray', function (hooks) { assert.expect(6); class Post extends Model { @attr('string') title; - @hasMany('tag', { async: false }) tags; + @hasMany('tag', { async: false, inverse: 'post' }) tags; } class Tag extends Model { @attr('string') name; - @belongsTo('post', { async: false }) post; + @belongsTo('post', { async: false, inverse: 'tags' }) post; } this.owner.register('model:post', Post); diff --git a/packages/-ember-data/tests/unit/model-test.js b/packages/-ember-data/tests/unit/model-test.js index 3b2cd60c945..96be704c38a 100644 --- a/packages/-ember-data/tests/unit/model-test.js +++ b/packages/-ember-data/tests/unit/model-test.js @@ -368,7 +368,7 @@ module('unit/model - Model', function (hooks) { store.push({ data: { type: 'person', - id: 0, // explicit number 0 to make this as risky as possible + id: '0', // explicit number 0 to make this as risky as possible attributes: { name: 'Tom Dale', }, @@ -482,8 +482,8 @@ module('unit/model - Model', function (hooks) { owner.register('model:model', TestModel); owner.register('serializer:model', JSONSerializer); - store.push(store.normalize('model', { id: 1, name: provided })); - store.push(store.normalize('model', { id: 2 })); + store.push(store.normalize('model', { id: '1', name: provided })); + store.push(store.normalize('model', { id: '2' })); let record = store.peekRecord('model', 1); @@ -665,7 +665,7 @@ module('unit/model - Model', function (hooks) { adapter.findRecord = () => resolve({ data: { - id: 1, + id: '1', type: 'person', attributes: { name: 'John' }, }, @@ -678,7 +678,7 @@ module('unit/model - Model', function (hooks) { }); test('Pushing a record into the store should transition new records to the loaded state', async function (assert) { - let person = store.createRecord('person', { id: 1, name: 'TomHuda' }); + let person = store.createRecord('person', { id: '1', name: 'TomHuda' }); assert.true(person.isNew, 'createRecord should put records into the new state'); @@ -1169,7 +1169,7 @@ module('unit/model - Model', function (hooks) { likes: [undefined, 'Cheese'], }); - return resolve({ data: { id: 1, type: 'mascot' } }); + return resolve({ data: { id: '1', type: 'mascot' } }); }; let cat; @@ -1264,7 +1264,7 @@ module('unit/model - Model', function (hooks) { module('Misc', function () { testInDebug('Calling record.attr() asserts', async function (assert) { - let person = store.createRecord('person', { id: 1, name: 'TomHuda' }); + let person = store.createRecord('person', { id: '1', name: 'TomHuda' }); assert.expectAssertion(() => { person.attr(); diff --git a/packages/-ember-data/tests/unit/model/merge-test.js b/packages/-ember-data/tests/unit/model/merge-test.js index 5ac1ded0e0c..b671b26502a 100644 --- a/packages/-ember-data/tests/unit/model/merge-test.js +++ b/packages/-ember-data/tests/unit/model/merge-test.js @@ -30,7 +30,7 @@ module('unit/model/merge - Merging', function (hooks) { const ApplicationAdapter = Adapter.extend({ createRecord(store, type, snapshot) { - return { data: { id: 1, type: 'person', attributes: { name: 'Tom Dale' } } }; + return { data: { id: '1', type: 'person', attributes: { name: 'Tom Dale' } } }; }, }); @@ -105,7 +105,7 @@ module('unit/model/merge - Merging', function (hooks) { return new EmberPromise((resolve) => { next(null, resolve, { data: { - id: 1, + id: '1', type: 'person', attributes: { name: 'Senor Thomas Dale, Esq.', city: 'Portland' }, }, @@ -260,7 +260,7 @@ module('unit/model/merge - Merging', function (hooks) { const ApplicationAdapter = Adapter.extend({ updateRecord(store, type, snapshot) { - return { data: { id: 1, type: 'person', attributes: { name: 'Thomas Dale' } } }; + return { data: { id: '1', type: 'person', attributes: { name: 'Thomas Dale' } } }; }, }); @@ -291,7 +291,7 @@ module('unit/model/merge - Merging', function (hooks) { const ApplicationAdapter = Adapter.extend({ findRecord(store, type, id, snapshot) { return { - data: { id: 1, type: 'person', attributes: { name: 'Thomas Dale', city: 'Portland' } }, + data: { id: '1', type: 'person', attributes: { name: 'Thomas Dale', city: 'Portland' } }, }; }, }); diff --git a/packages/-ember-data/tests/unit/model/relationships-test.js b/packages/-ember-data/tests/unit/model/relationships-test.js index bbc022ff2eb..c04521e7f1e 100644 --- a/packages/-ember-data/tests/unit/model/relationships-test.js +++ b/packages/-ember-data/tests/unit/model/relationships-test.js @@ -6,19 +6,20 @@ import { gte } from 'ember-compatibility-helpers'; import { setupTest } from 'ember-qunit'; import Model, { belongsTo, hasMany } from '@ember-data/model'; +import { deprecatedTest } from '@ember-data/unpublished-test-infra/test-support/deprecated-test'; class Person extends Model { - @hasMany('occupation', { async: false }) occupations; + @hasMany('occupation', { async: false, inverse: null }) occupations; @hasMany('person', { inverse: 'parent', async: false }) people; @belongsTo('person', { inverse: 'people', async: false }) parent; } class UserProfile extends Model { - @belongsTo() user; + @belongsTo('user', { async: true, inverse: 'userProfile' }) user; } class User extends Model { - @belongsTo() userProfile; + @belongsTo('user-profile', { async: true, inverse: 'user' }) userProfile; } class Occupation extends Model {} @@ -64,7 +65,7 @@ module('[@ember-data/model] unit - relationships', function (hooks) { ); assert.deepEqual( extractDetails('occupation'), - [{ name: 'occupations', kind: 'hasMany', options: { async: false } }], + [{ name: 'occupations', kind: 'hasMany', options: { async: false, inverse: null } }], 'occupation relationships contains the expected meta information' ); }); @@ -97,7 +98,7 @@ module('[@ember-data/model] unit - relationships', function (hooks) { const relationship = relationships.get('user-profile')[0]; - assert.strictEqual(relationship.meta.name, 'userProfile', 'relationship name has not been changed'); + assert.strictEqual(relationship.name, 'userProfile', 'relationship name has not been changed'); }); test('normalizing hasMany relationship names', function (assert) { @@ -105,11 +106,11 @@ module('[@ember-data/model] unit - relationships', function (hooks) { let { owner } = this; class StreamItem extends Model { - @belongsTo() user; + @belongsTo('user', { async: true, inverse: 'streamItems' }) user; } class User extends Model { - @hasMany() streamItems; + @hasMany('stream-item', { async: true, inverse: 'user' }) streamItems; } owner.unregister('model:user'); @@ -126,37 +127,41 @@ module('[@ember-data/model] unit - relationships', function (hooks) { const relationship = relationships.get('stream-item')[0]; - assert.strictEqual(relationship.meta.name, 'streamItems', 'relationship name has not been changed'); + assert.strictEqual(relationship.name, 'streamItems', 'relationship name has not been changed'); }); if (gte('3.10.0')) { - test('decorators works without parens', function (assert) { - let store; - let { owner } = this; + deprecatedTest( + 'decorators works without parens', + { id: 'ember-data:deprecate-non-strict-relationships', until: '5.0', count: 6 }, + function (assert) { + let store; + let { owner } = this; - class StreamItem extends Model { - @belongsTo user; - } + class StreamItem extends Model { + @belongsTo user; + } - class User extends Model { - @hasMany streamItems; - } + class User extends Model { + @hasMany streamItems; + } - owner.unregister('model:user'); - owner.register('model:stream-item', StreamItem); - owner.register('model:user', User); + owner.unregister('model:user'); + owner.register('model:stream-item', StreamItem); + owner.register('model:user', User); - store = owner.lookup('service:store'); + store = owner.lookup('service:store'); - let user = store.modelFor('user'); + let user = store.modelFor('user'); - const relationships = get(user, 'relationships'); + const relationships = get(user, 'relationships'); - assert.ok(relationships.has('stream-item'), 'relationship key has been normalized'); + assert.ok(relationships.has('stream-item'), 'relationship key has been normalized'); - const relationship = relationships.get('stream-item')[0]; + const relationship = relationships.get('stream-item')[0]; - assert.strictEqual(relationship.meta.name, 'streamItems', 'relationship name has not been changed'); - }); + assert.strictEqual(relationship.name, 'streamItems', 'relationship name has not been changed'); + } + ); } }); diff --git a/packages/-ember-data/tests/unit/model/relationships/belongs-to-test.js b/packages/-ember-data/tests/unit/model/relationships/belongs-to-test.js index 8b73d401a54..4991d12e45a 100644 --- a/packages/-ember-data/tests/unit/model/relationships/belongs-to-test.js +++ b/packages/-ember-data/tests/unit/model/relationships/belongs-to-test.js @@ -25,12 +25,12 @@ module('unit/model/relationships - belongsTo', function (hooks) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'tag' }), }); const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); this.owner.register('model:tag', Tag); @@ -97,13 +97,13 @@ module('unit/model/relationships - belongsTo', function (hooks) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'tag' }), }); Tag.toString = () => 'Tag'; const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); Person.toString = () => 'Person'; @@ -120,14 +120,14 @@ module('unit/model/relationships - belongsTo', function (hooks) { data: [ { type: 'tag', - id: 1, + id: '1', attributes: { name: 'whatever', }, }, { type: 'person', - id: 2, + id: '2', attributes: { name: 'David J. Hamilton', }, @@ -167,7 +167,7 @@ module('unit/model/relationships - belongsTo', function (hooks) { const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: true }), + tag: belongsTo('tag', { async: true, inverse: null }), }); this.owner.register('model:tag', Tag); @@ -182,16 +182,16 @@ module('unit/model/relationships - belongsTo', function (hooks) { return { data: { - id: 1, + id: '1', type: 'person', attributes: { name: 'Tom Dale' }, - relationships: { tag: { data: { id: 2, type: 'tag' } } }, + relationships: { tag: { data: { id: '2', type: 'tag' } } }, }, }; } else if (type === Tag) { assert.strictEqual(id, '2', 'id should be 2'); - return { data: { id: 2, type: 'tag', attributes: { name: 'friendly' } } }; + return { data: { id: '2', type: 'tag', attributes: { name: 'friendly' } } }; } }; @@ -221,7 +221,7 @@ module('unit/model/relationships - belongsTo', function (hooks) { const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: true }), + tag: belongsTo('tag', { async: true, inverse: null }), }); this.owner.register('model:tag', Tag); @@ -306,7 +306,7 @@ module('unit/model/relationships - belongsTo', function (hooks) { const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: true }), + tag: belongsTo('tag', { async: true, inverse: null }), }); this.owner.register('model:tag', Tag); @@ -389,7 +389,7 @@ module('unit/model/relationships - belongsTo', function (hooks) { const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: true }), + tag: belongsTo('tag', { async: true, inverse: null }), }); this.owner.register('model:tag', Tag); @@ -499,12 +499,12 @@ module('unit/model/relationships - belongsTo', function (hooks) { const Tag = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'tag' }), }); const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'person' }), }); this.owner.register('model:tag', Tag); @@ -527,12 +527,12 @@ module('unit/model/relationships - belongsTo', function (hooks) { test('When finding a hasMany relationship the inverse belongsTo relationship is available immediately', function (assert) { const Occupation = Model.extend({ description: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'occupations' }), }); const Person = Model.extend({ name: attr('string'), - occupations: hasMany('occupation', { async: true }), + occupations: hasMany('occupation', { async: true, inverse: 'person' }), }); this.owner.register('model:occupation', Occupation); @@ -547,8 +547,8 @@ module('unit/model/relationships - belongsTo', function (hooks) { assert.strictEqual(snapshots[0].belongsTo('person').id, '1'); return { data: [ - { id: 5, type: 'occupation', attributes: { description: 'fifth' } }, - { id: 2, type: 'occupation', attributes: { description: 'second' } }, + { id: '5', type: 'occupation', attributes: { description: 'fifth' } }, + { id: '2', type: 'occupation', attributes: { description: 'second' } }, ], }; }; @@ -598,12 +598,12 @@ module('unit/model/relationships - belongsTo', function (hooks) { const Occupation = Model.extend({ description: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'occupation' }), }); const Person = Model.extend({ name: attr('string'), - occupation: belongsTo('occupation', { async: true }), + occupation: belongsTo('occupation', { async: true, inverse: 'person' }), }); this.owner.register('model:occupation', Occupation); @@ -614,7 +614,7 @@ module('unit/model/relationships - belongsTo', function (hooks) { adapter.findRecord = function (store, type, id, snapshot) { assert.strictEqual(snapshot.belongsTo('person').id, '1'); - return { data: { id: 5, type: 'occupation', attributes: { description: 'fifth' } } }; + return { data: { id: '5', type: 'occupation', attributes: { description: 'fifth' } } }; }; run(() => { @@ -642,12 +642,12 @@ module('unit/model/relationships - belongsTo', function (hooks) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'tag' }), }); const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); this.owner.register('model:tag', Tag); @@ -717,7 +717,7 @@ module('unit/model/relationships - belongsTo', function (hooks) { const Person = Model.extend({ name: attr('string'), - hobby: belongsTo('hobby', { serialize: true, async: true }), + hobby: belongsTo('hobby', { serialize: true, async: true, inverse: null }), }); this.owner.register('model:hobby', Hobby); @@ -777,7 +777,7 @@ module('unit/model/relationships - belongsTo', function (hooks) { const Person = Model.extend({ name: attr('string'), - hobby: belongsTo('hobby', { embedded: true, async: true }), + hobby: belongsTo('hobby', { embedded: true, inverse: null, async: true }), }); this.owner.register('model:hobby', Hobby); @@ -833,12 +833,12 @@ module('unit/model/relationships - belongsTo', function (hooks) { test('belongsTo should be async by default', function (assert) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'tag' }), }); const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag'), + tag: belongsTo('tag', { async: true, inverse: 'people' }), }); this.owner.register('model:tag', Tag); diff --git a/packages/-ember-data/tests/unit/model/relationships/has-many-test.js b/packages/-ember-data/tests/unit/model/relationships/has-many-test.js index 0ee6e9fb916..3e0f343850f 100644 --- a/packages/-ember-data/tests/unit/model/relationships/has-many-test.js +++ b/packages/-ember-data/tests/unit/model/relationships/has-many-test.js @@ -27,18 +27,18 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'tags' }), }); const Pet = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'pets' }), }); const Person = Model.extend({ name: attr('string'), - tags: hasMany('tag', { async: false }), - pets: hasMany('pet', { async: false }), + tags: hasMany('tag', { async: false, inverse: 'person' }), + pets: hasMany('pet', { async: false, inverse: 'person' }), }); this.owner.register('model:tag', Tag); @@ -50,7 +50,7 @@ module('unit/model/relationships - hasMany', function (hooks) { adapter.findRecord = function (store, type, id, snapshot) { if (type === Tag && id === '12') { - return { id: 12, name: 'oohlala' }; + return { id: '12', name: 'oohlala' }; } else { assert.ok(false, 'findRecord() should not be called with these values'); } @@ -244,13 +244,13 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'tag' }), }); Tag.toString = () => 'Tag'; const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); Person.toString = () => 'Person'; @@ -267,7 +267,7 @@ module('unit/model/relationships - hasMany', function (hooks) { data: [ { type: 'tag', - id: 1, + id: '1', attributes: { name: 'whatever', }, @@ -275,7 +275,7 @@ module('unit/model/relationships - hasMany', function (hooks) { people: { data: [ { - id: 2, + id: '2', type: 'person', }, ], @@ -284,7 +284,7 @@ module('unit/model/relationships - hasMany', function (hooks) { }, { type: 'person', - id: 2, + id: '2', attributes: { name: 'David J. Hamilton', }, @@ -311,12 +311,12 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'tag' }), }); const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); this.owner.register('model:tag', Tag); @@ -331,7 +331,7 @@ module('unit/model/relationships - hasMany', function (hooks) { store.push({ data: { type: 'tag', - id: 1, + id: '1', attributes: { name: 'whatever', }, @@ -356,12 +356,12 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'tag' }), }); const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); this.owner.register('model:tag', Tag); @@ -377,7 +377,7 @@ module('unit/model/relationships - hasMany', function (hooks) { store.push({ data: { type: 'person', - id: 1, + id: '1', attributes: { name: 'David J. Hamilton', }, @@ -385,7 +385,7 @@ module('unit/model/relationships - hasMany', function (hooks) { tag: { data: { type: 'tag', - id: 1, + id: '1', }, }, }, @@ -393,7 +393,7 @@ module('unit/model/relationships - hasMany', function (hooks) { included: [ { type: 'tag', - id: 1, + id: '1', attributes: { name: 'whatever', }, @@ -402,7 +402,7 @@ module('unit/model/relationships - hasMany', function (hooks) { data: [ { type: 'person', - id: 1, + id: '1', }, ], }, @@ -415,7 +415,7 @@ module('unit/model/relationships - hasMany', function (hooks) { store.push({ data: { type: 'tag', - id: 1, + id: '1', attributes: { name: 'whatever', }, @@ -442,7 +442,7 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'tag' }), }); Tag.toString = () => { @@ -451,7 +451,7 @@ module('unit/model/relationships - hasMany', function (hooks) { const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); Person.toString = () => { @@ -468,7 +468,7 @@ module('unit/model/relationships - hasMany', function (hooks) { store.push({ data: { type: 'person', - id: 1, + id: '1', attributes: { name: 'David J. Hamilton', }, @@ -476,7 +476,7 @@ module('unit/model/relationships - hasMany', function (hooks) { tag: { data: { type: 'tag', - id: 1, + id: '1', }, }, }, @@ -484,7 +484,7 @@ module('unit/model/relationships - hasMany', function (hooks) { included: [ { type: 'tag', - id: 1, + id: '1', attributes: { name: 'whatever', }, @@ -493,11 +493,11 @@ module('unit/model/relationships - hasMany', function (hooks) { data: [ { type: 'person', - id: 1, + id: '1', }, { type: 'person', - id: 1, + id: '1', }, ], }, @@ -518,7 +518,7 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'tags' }), }); Tag.toString = () => { @@ -527,7 +527,7 @@ module('unit/model/relationships - hasMany', function (hooks) { const Person = Model.extend({ name: attr('string'), - tags: hasMany('tags', { async: false }), + tags: hasMany('tag', { async: false, inverse: 'people' }), }); Person.toString = () => { @@ -545,7 +545,7 @@ module('unit/model/relationships - hasMany', function (hooks) { data: [ { type: 'person', - id: 1, + id: '1', attributes: { name: 'David J. Hamilton', }, @@ -554,13 +554,13 @@ module('unit/model/relationships - hasMany', function (hooks) { { data: { type: 'tag', - id: 1, + id: '1', }, }, { data: { type: 'tag', - id: 2, + id: '2', }, }, ], @@ -568,7 +568,7 @@ module('unit/model/relationships - hasMany', function (hooks) { }, { type: 'person', - id: 2, + id: '2', attributes: { name: 'Gerald Dempsey Posey', }, @@ -577,13 +577,13 @@ module('unit/model/relationships - hasMany', function (hooks) { { data: { type: 'tag', - id: 1, + id: '1', }, }, { data: { type: 'tag', - id: 2, + id: '2', }, }, ], @@ -591,7 +591,7 @@ module('unit/model/relationships - hasMany', function (hooks) { }, { type: 'tag', - id: 1, + id: '1', attributes: { name: 'whatever', }, @@ -600,11 +600,11 @@ module('unit/model/relationships - hasMany', function (hooks) { data: [ { type: 'person', - id: 1, + id: '1', }, { type: 'person', - id: 2, + id: '2', }, ], }, @@ -612,7 +612,7 @@ module('unit/model/relationships - hasMany', function (hooks) { }, { type: 'tag', - id: 2, + id: '2', attributes: { name: 'nothing', }, @@ -621,11 +621,11 @@ module('unit/model/relationships - hasMany', function (hooks) { data: [ { type: 'person', - id: 1, + id: '1', }, { type: 'person', - id: 2, + id: '2', }, ], }, @@ -650,12 +650,12 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person', { async: false }), + people: hasMany('person', { async: false, inverse: 'tag' }), }); const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); this.owner.register('model:tag', Tag); @@ -671,7 +671,7 @@ module('unit/model/relationships - hasMany', function (hooks) { store.push({ data: { type: 'person', - id: 1, + id: '1', attributes: { name: 'David J. Hamilton', }, @@ -679,7 +679,7 @@ module('unit/model/relationships - hasMany', function (hooks) { tag: { data: { type: 'tag', - id: 1, + id: '1', }, }, }, @@ -687,7 +687,7 @@ module('unit/model/relationships - hasMany', function (hooks) { included: [ { type: 'tag', - id: 1, + id: '1', attributes: { name: 'whatever', }, @@ -696,7 +696,7 @@ module('unit/model/relationships - hasMany', function (hooks) { data: [ { type: 'person', - id: 1, + id: '1', }, ], }, @@ -718,7 +718,7 @@ module('unit/model/relationships - hasMany', function (hooks) { store.push({ data: { type: 'tag', - id: 1, + id: '1', attributes: { name: 'whatever', }, @@ -745,7 +745,7 @@ module('unit/model/relationships - hasMany', function (hooks) { const Person = Model.extend({ name: attr(), - trueFriends: hasMany('person', { async: false }), + trueFriends: hasMany('person', { async: false, inverse: 'trueFriends' }), }); this.owner.register('model:person', Person); @@ -786,18 +786,18 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'tags' }), }); const Pet = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'pets' }), }); const Person = Model.extend({ name: attr('string'), - tags: hasMany('tag', { async: true }), - pets: hasMany('pet', { async: false }), + tags: hasMany('tag', { async: true, inverse: 'person' }), + pets: hasMany('pet', { async: false, inverse: 'person' }), }); this.owner.register('model:tag', Tag); @@ -809,7 +809,7 @@ module('unit/model/relationships - hasMany', function (hooks) { adapter.findRecord = function (store, type, id, snapshot) { if (type === Tag && id === '12') { - return { data: { id: 12, type: 'tag', attributes: { name: 'oohlala' } } }; + return { data: { id: '12', type: 'tag', attributes: { name: 'oohlala' } } }; } else { assert.ok(false, 'findRecord() should not be called with these values'); } @@ -924,7 +924,7 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({}); const Person = Model.extend({ - tags: hasMany('tag', { async: false }), + tags: hasMany('tag', { async: false, inverse: null }), }); this.owner.register('model:tag', Tag); @@ -943,7 +943,7 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({}); const Person = Model.extend({ - tags: hasMany('tag', { async: false }), + tags: hasMany('tag', { async: false, inverse: null }), }); this.owner.register('model:tag', Tag); @@ -962,7 +962,7 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({}); const Person = Model.extend({ - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: null }), }); this.owner.register('model:tag', Tag); @@ -983,7 +983,7 @@ module('unit/model/relationships - hasMany', function (hooks) { }); const Person = Model.extend({ - tags: belongsTo('tag', { async: false }), + tags: belongsTo('tag', { async: false, inverse: null }), }); this.owner.register('model:tag', Tag); @@ -1003,7 +1003,7 @@ module('unit/model/relationships - hasMany', function (hooks) { const Person = Model.extend({ name: attr('string'), - tags: hasMany('tag', { async: false }), + tags: hasMany('tag', { async: false, inverse: null }), }); const Tag = Model.extend({ @@ -1074,12 +1074,12 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'tags' }), }); const Person = Model.extend({ name: attr('string'), - tags: hasMany('tag', { async: true }), + tags: hasMany('tag', { async: true, inverse: 'person' }), }); this.owner.register('model:tag', Tag); @@ -1095,8 +1095,8 @@ module('unit/model/relationships - hasMany', function (hooks) { return { data: [ - { id: 5, type: 'tag', attributes: { name: 'friendly' } }, - { id: 2, type: 'tag', attributes: { name: 'smarmy' } }, + { id: '5', type: 'tag', attributes: { name: 'friendly' } }, + { id: '2', type: 'tag', attributes: { name: 'smarmy' } }, ], }; }; @@ -1107,14 +1107,14 @@ module('unit/model/relationships - hasMany', function (hooks) { return { data: { - id: 1, + id: '1', type: 'person', attributes: { name: 'Tom Dale' }, relationships: { tags: { data: [ - { id: 5, type: 'tag' }, - { id: 2, type: 'tag' }, + { id: '5', type: 'tag' }, + { id: '2', type: 'tag' }, ], }, }, @@ -1143,12 +1143,12 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - people: belongsTo('person', { async: false }), + people: belongsTo('person', { async: false, inverse: 'tags' }), }); const Person = Model.extend({ name: attr('string'), - tags: hasMany('tag', { async: false }), + tags: hasMany('tag', { async: false, inverse: 'people' }), }); this.owner.register('model:tag', Tag); @@ -1875,7 +1875,7 @@ module('unit/model/relationships - hasMany', function (hooks) { test('hasMany.firstObject.unloadRecord should not break that hasMany', function (assert) { const Person = Model.extend({ - cars: hasMany('car', { async: false }), + cars: hasMany('car', { async: false, inverse: null }), name: attr(), }); @@ -1901,21 +1901,21 @@ module('unit/model/relationships - hasMany', function (hooks) { data: [ { type: 'person', - id: 1, + id: '1', attributes: { name: 'marvin', }, relationships: { cars: { data: [ - { type: 'car', id: 1 }, - { type: 'car', id: 2 }, + { type: 'car', id: '1' }, + { type: 'car', id: '2' }, ], }, }, }, - { type: 'car', id: 1, attributes: { name: 'a' } }, - { type: 'car', id: 2, attributes: { name: 'b' } }, + { type: 'car', id: '1', attributes: { name: 'a' } }, + { type: 'car', id: '2', attributes: { name: 'b' } }, ], }); }); @@ -2067,12 +2067,12 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'tags' }), }); const Person = Model.extend({ name: attr('string'), - tags: hasMany('tag', { async: false }), + tags: hasMany('tag', { async: false, inverse: 'person' }), }); this.owner.register('model:tag', Tag); @@ -2144,12 +2144,12 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'tags' }), }); const Person = Model.extend({ name: attr('string'), - tags: hasMany('tag', { async: false }), + tags: hasMany('tag', { async: false, inverse: 'person' }), }); this.owner.register('model:tag', Tag); @@ -2205,12 +2205,12 @@ module('unit/model/relationships - hasMany', function (hooks) { const Tag = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'tags' }), }); const Person = Model.extend({ name: attr('string'), - tags: hasMany('tag', { async: false }), + tags: hasMany('tag', { async: false, inverse: 'person' }), }); this.owner.register('model:tag', Tag); @@ -2263,12 +2263,12 @@ module('unit/model/relationships - hasMany', function (hooks) { test('it is possible to add an item to a relationship, remove it, then add it again', function (assert) { const Tag = Model.extend({ name: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'tags' }), }); const Person = Model.extend({ name: attr('string'), - tags: hasMany('tag', { async: false }), + tags: hasMany('tag', { async: false, inverse: 'person' }), }); this.owner.register('model:tag', Tag); @@ -2304,12 +2304,12 @@ module('unit/model/relationships - hasMany', function (hooks) { test('hasMany is async by default', function (assert) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person'), + people: hasMany('person', { async: true, inverse: 'tag' }), }); const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); this.owner.register('model:tag', Tag); @@ -2324,12 +2324,12 @@ module('unit/model/relationships - hasMany', function (hooks) { test('hasMany is stable', function (assert) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person'), + people: hasMany('person', { async: true, inverse: 'tag' }), }); const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); this.owner.register('model:tag', Tag); @@ -2353,12 +2353,12 @@ module('unit/model/relationships - hasMany', function (hooks) { test('hasMany proxy is destroyed', async function (assert) { const Tag = Model.extend({ name: attr('string'), - people: hasMany('person'), + people: hasMany('person', { async: true, inverse: 'tag' }), }); const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); this.owner.register('model:tag', Tag); @@ -2614,7 +2614,7 @@ module('unit/model/relationships - hasMany', function (hooks) { let peopleDidChange = 0; const Tag = Model.extend({ name: attr('string'), - people: hasMany('person'), + people: hasMany('person', { async: true, inverse: 'tag' }), peopleDidChange: observer('people.@each', function () { peopleDidChange++; }), @@ -2622,7 +2622,7 @@ module('unit/model/relationships - hasMany', function (hooks) { const Person = Model.extend({ name: attr('string'), - tag: belongsTo('tag', { async: false }), + tag: belongsTo('tag', { async: false, inverse: 'people' }), }); this.owner.register('model:tag', Tag); @@ -2680,9 +2680,9 @@ module('unit/model/relationships - hasMany', function (hooks) { return { data: [ - { id: 1, type: 'tag', attributes: { name: 'first' } }, - { id: 2, type: 'tag', attributes: { name: 'second' } }, - { id: 3, type: 'tag', attributes: { name: 'third' } }, + { id: '1', type: 'tag', attributes: { name: 'first' } }, + { id: '2', type: 'tag', attributes: { name: 'second' } }, + { id: '3', type: 'tag', attributes: { name: 'third' } }, ], }; }; @@ -2691,7 +2691,7 @@ module('unit/model/relationships - hasMany', function (hooks) { if (type === Person) { return { data: { - id: 1, + id: '1', type: 'person', attributes: { name: 'Watson' }, relationships: { @@ -2702,12 +2702,12 @@ module('unit/model/relationships - hasMany', function (hooks) { } else if (type === Tag) { return { data: { - id: 2, + id: '2', type: 'tag', attributes: { name: 'second' }, relationships: { person: { - data: { id: 1, type: 'person' }, + data: { id: '1', type: 'person' }, }, }, }, @@ -2738,7 +2738,7 @@ module('unit/model/relationships - hasMany', function (hooks) { testInDebug('throws assertion if of not set with an array', function (assert) { const Person = Model.extend(); const Tag = Model.extend({ - people: hasMany('person'), + people: hasMany('person', { async: true, inverse: null }), }); this.owner.register('model:tag', Tag); @@ -2758,7 +2758,7 @@ module('unit/model/relationships - hasMany', function (hooks) { testInDebug('checks if passed array only contains instances of Model', function (assert) { const Person = Model.extend(); const Tag = Model.extend({ - people: hasMany('person'), + people: hasMany('person', { async: true, inverse: null }), }); this.owner.register('model:tag', Tag); @@ -2771,7 +2771,7 @@ module('unit/model/relationships - hasMany', function (hooks) { return { data: { type: 'person', - id: 1, + id: '1', }, }; }; diff --git a/packages/-ember-data/tests/unit/model/relationships/record-array-test.js b/packages/-ember-data/tests/unit/model/relationships/record-array-test.js index 4efd7aba314..1e728bae973 100644 --- a/packages/-ember-data/tests/unit/model/relationships/record-array-test.js +++ b/packages/-ember-data/tests/unit/model/relationships/record-array-test.js @@ -66,12 +66,12 @@ module('unit/model/relationships - RecordArray', function (hooks) { const Tag = DS.Model.extend({ name: DS.attr('string'), - person: DS.belongsTo('person', { async: false }), + person: DS.belongsTo('person', { async: false, inverse: 'tags' }), }); const Person = DS.Model.extend({ name: DS.attr('string'), - tags: DS.hasMany('tag', { async: false }), + tags: DS.hasMany('tag', { async: false, inverse: 'person' }), }); this.owner.register('model:tag', Tag); diff --git a/packages/-ember-data/tests/unit/model/rollback-attributes-test.js b/packages/-ember-data/tests/unit/model/rollback-attributes-test.js index b68ea1e617d..59bbd45f363 100644 --- a/packages/-ember-data/tests/unit/model/rollback-attributes-test.js +++ b/packages/-ember-data/tests/unit/model/rollback-attributes-test.js @@ -238,7 +238,7 @@ module('unit/model/rollbackAttributes - model.rollbackAttributes()', function (h test(`new record's attributes can be rollbacked`, function (assert) { let store = this.owner.lookup('service:store'); - let person = store.createRecord('person', { id: 1 }); + let person = store.createRecord('person', { id: '1' }); assert.true(person.isNew, 'must be new'); assert.true(person.hasDirtyAttributes, 'must be dirty'); @@ -268,7 +268,7 @@ module('unit/model/rollbackAttributes - model.rollbackAttributes()', function (h this.owner.register('serializer:application', RESTSerializer.extend()); let store = this.owner.lookup('service:store'); - let person = store.createRecord('person', { id: 1 }); + let person = store.createRecord('person', { id: '1' }); assert.true(person.isNew, 'must be new'); assert.true(person.hasDirtyAttributes, 'must be dirty'); @@ -305,7 +305,7 @@ module('unit/model/rollbackAttributes - model.rollbackAttributes()', function (h person = store.push({ data: { type: 'person', - id: 1, + id: '1', attributes: { firstName: 'original name', }, diff --git a/packages/-ember-data/tests/unit/promise-proxies-test.js b/packages/-ember-data/tests/unit/promise-proxies-test.js index 19edc249f06..6f4a30f42d2 100644 --- a/packages/-ember-data/tests/unit/promise-proxies-test.js +++ b/packages/-ember-data/tests/unit/promise-proxies-test.js @@ -119,11 +119,11 @@ module('unit/PromiseBelongsTo', function (hooks) { setupTest(hooks); class Parent extends Model { - @belongsTo('child', { async: true }) + @belongsTo('child', { async: true, inverse: 'parent' }) child; } class Child extends Model { - @belongsTo('parent', { async: false }) + @belongsTo('parent', { async: false, inverse: 'child' }) parent; } class ChildAdapter extends Adapter { @@ -135,7 +135,7 @@ module('unit/PromiseBelongsTo', function (hooks) { relationships: { parent: { data: { - id: 1, + id: '1', type: 'parent', }, }, diff --git a/packages/-ember-data/tests/unit/record-arrays/record-array-test.js b/packages/-ember-data/tests/unit/record-arrays/record-array-test.js index dd9aba05111..1166fa5fd32 100644 --- a/packages/-ember-data/tests/unit/record-arrays/record-array-test.js +++ b/packages/-ember-data/tests/unit/record-arrays/record-array-test.js @@ -282,7 +282,7 @@ module('unit/record-arrays/record-array - DS.RecordArray', function (hooks) { let store = this.owner.lookup('service:store'); let model1 = { - id: 1, + id: '1', type: 'tag', }; let record = store.push({ @@ -343,12 +343,12 @@ module('unit/record-arrays/record-array - DS.RecordArray', function (hooks) { let store = this.owner.lookup('service:store'); let model1 = { - id: 1, + id: '1', type: 'tag', }; let model2 = { - id: 2, + id: '2', type: 'tag', }; let records = store.push({ @@ -383,7 +383,7 @@ module('unit/record-arrays/record-array - DS.RecordArray', function (hooks) { let store = this.owner.lookup('service:store'); let model1 = { - id: 1, + id: '1', type: 'tag', }; let record = store.push({ diff --git a/packages/-ember-data/tests/unit/store/adapter-interop-test.js b/packages/-ember-data/tests/unit/store/adapter-interop-test.js index 6136d9867f8..d1d3a1cbd13 100644 --- a/packages/-ember-data/tests/unit/store/adapter-interop-test.js +++ b/packages/-ember-data/tests/unit/store/adapter-interop-test.js @@ -35,7 +35,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho return resolve({ data: { - id: 1, + id: '1', type: 'test', }, }); @@ -61,8 +61,8 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho assert.deepEqual(ids, ['1', '2'], 'Correct ids were passed in to findMany'); return resolve({ data: [ - { id: 1, type: 'test' }, - { id: 2, type: 'test' }, + { id: '1', type: 'test' }, + { id: '2', type: 'test' }, ], }); }, @@ -149,7 +149,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho const ApplicationAdapter = Adapter.extend({ findRecord(store, type, id, snapshot) { - return resolve({ data: { id: 1, type: 'test', attributes: { name: 'Scumbag Dale' } } }); + return resolve({ data: { id: '1', type: 'test', attributes: { name: 'Scumbag Dale' } } }); }, }); @@ -392,10 +392,10 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho let store = this.owner.lookup('service:store'); - store.createRecord('person', { id: 5 }); + store.createRecord('person', { id: '5' }); assert.expectAssertion(() => { - store.createRecord('person', { id: 5 }); + store.createRecord('person', { id: '5' }); }, /The id 5 has already been used with another 'person' record./); } ); @@ -434,7 +434,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho let store = this.owner.lookup('service:store'); return run(() => { - let person = store.createRecord('person', { id: 1, name: 'Brohuda Katz' }); + let person = store.createRecord('person', { id: '1', name: 'Brohuda Katz' }); return store.findRecord('person', 1).then((again) => { assert.strictEqual(person, again, 'the store returns the loaded object'); @@ -913,7 +913,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho }, findRecord() { assert.ok(true, 'find is always called when the record is not in the store'); - return { data: { id: 1, type: 'person' } }; + return { data: { id: '1', type: 'person' } }; }, }); @@ -970,7 +970,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho }, findRecord() { assert.ok(true, 'find should not be called when shouldReloadRecord returns false'); - return { data: { id: 1, type: 'person', attributes: { name: 'Tom' } } }; + return { data: { id: '1', type: 'person', attributes: { name: 'Tom' } } }; }, }); @@ -1010,7 +1010,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho }, findRecord() { assert.ok(true, 'find should be called'); - return { data: { id: 1, type: 'person', attributes: { name: 'Tom' } } }; + return { data: { id: '1', type: 'person', attributes: { name: 'Tom' } } }; }, }); @@ -1044,7 +1044,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho }, findRecord() { assert.ok(false, 'find should not be called'); - return { data: { id: 1, type: 'person', attributes: { name: 'Tom' } } }; + return { data: { id: '1', type: 'person', attributes: { name: 'Tom' } } }; }, }); @@ -1078,7 +1078,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho }, findRecord() { assert.ok(true, 'find should not be called'); - return { data: { id: 1, type: 'person', attributes: { name: 'Tom' } } }; + return { data: { id: '1', type: 'person', attributes: { name: 'Tom' } } }; }, }); @@ -1145,7 +1145,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho }, findAll() { assert.ok(true, 'findAll should be called when shouldReloadAll returns true'); - return { data: [{ id: 1, type: 'person', attributes: { name: 'Tom' } }] }; + return { data: [{ id: '1', type: 'person', attributes: { name: 'Tom' } }] }; }, }); @@ -1178,7 +1178,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho }, findAll() { assert.ok(true, 'find should be called'); - return { data: [{ id: 1, type: 'person', attributes: { name: 'Tom' } }] }; + return { data: [{ id: '1', type: 'person', attributes: { name: 'Tom' } }] }; }, }); @@ -1209,7 +1209,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho }, findAll() { assert.ok(false, 'findAll should not be called'); - return { data: [{ id: 1, type: 'person', attributes: { name: 'Tom' } }] }; + return { data: [{ id: '1', type: 'person', attributes: { name: 'Tom' } }] }; }, }); @@ -1246,7 +1246,7 @@ module('unit/store/adapter-interop - Store working with a Adapter', function (ho assert.ok(true, 'findAll should be called'); return new Promise((resolve) => setTimeout(resolve, 1)).then(() => { return { - data: [{ id: 1, type: 'person', attributes: { name: 'Tom' } }], + data: [{ id: '1', type: 'person', attributes: { name: 'Tom' } }], }; }); }, diff --git a/packages/-ember-data/tests/unit/store/create-record-test.js b/packages/-ember-data/tests/unit/store/create-record-test.js index b1181e9c9b7..f59d5a2ea33 100644 --- a/packages/-ember-data/tests/unit/store/create-record-test.js +++ b/packages/-ember-data/tests/unit/store/create-record-test.js @@ -73,7 +73,7 @@ module('unit/store/createRecord - Store creating records', function (hooks) { const Storage = Model.extend({ name: attr('name'), - records: hasMany('record', { async: false }), + records: hasMany('record', { async: false, inverse: null }), }); this.owner.register('model:record', Record); diff --git a/packages/-ember-data/tests/unit/store/finders-test.js b/packages/-ember-data/tests/unit/store/finders-test.js index ca8f0393758..6a299fd51c6 100644 --- a/packages/-ember-data/tests/unit/store/finders-test.js +++ b/packages/-ember-data/tests/unit/store/finders-test.js @@ -12,8 +12,8 @@ class Person extends Model { @attr('string') name; @attr('string') firstName; @attr('string') lastName; - @hasMany('dog', { async: true }) dogs; - @belongsTo('dog', { async: true }) favoriteDog; + @hasMany('dog', { async: true, inverse: null }) dogs; + @belongsTo('dog', { async: true, inverse: null }) favoriteDog; } class Dog extends Model { @@ -57,7 +57,7 @@ module('unit/store/finders', function (hooks) { assert.false(serializerLoaded, 'serializer is not eagerly loaded'); deferedFind.resolve({ - data: { id: 1, type: 'person', attributes: { name: 'John Churchill' } }, + data: { id: '1', type: 'person', attributes: { name: 'John Churchill' } }, }); await storePromise; @@ -93,8 +93,8 @@ module('unit/store/finders', function (hooks) { deferedFind.resolve({ data: [ - { id: 1, type: 'person', attributes: { name: 'John Churchill' } }, - { id: 2, type: 'person', attributes: { name: 'Louis Joseph' } }, + { id: '1', type: 'person', attributes: { name: 'John Churchill' } }, + { id: '2', type: 'person', attributes: { name: 'Louis Joseph' } }, ], }); @@ -146,8 +146,8 @@ module('unit/store/finders', function (hooks) { deferedFind.resolve({ data: [ - { id: 1, type: 'dog', attributes: { name: 'Scooby' } }, - { id: 2, type: 'dog', attributes: { name: 'Scrappy' } }, + { id: '1', type: 'dog', attributes: { name: 'Scooby' } }, + { id: '2', type: 'dog', attributes: { name: 'Scrappy' } }, ], }); @@ -198,7 +198,7 @@ module('unit/store/finders', function (hooks) { assert.false(serializerLoaded, 'serializer is not eagerly loaded'); - deferedFind.resolve({ data: { id: 1, type: 'dog', attributes: { name: 'Scooby' } } }); + deferedFind.resolve({ data: { id: '1', type: 'dog', attributes: { name: 'Scooby' } } }); await storePromise; @@ -230,7 +230,7 @@ module('unit/store/finders', function (hooks) { assert.false(serializerLoaded, 'serializer is not eagerly loaded'); deferedFind.resolve({ - data: [{ id: 1, type: 'person', attributes: { name: 'John Churchill' } }], + data: [{ id: '1', type: 'person', attributes: { name: 'John Churchill' } }], }); await storePromise; @@ -263,7 +263,7 @@ module('unit/store/finders', function (hooks) { assert.false(serializerLoaded, 'serializer is not eagerly loaded'); deferedFind.resolve({ - data: [{ id: 1, type: 'person', attributes: { name: 'John Churchill' } }], + data: [{ id: '1', type: 'person', attributes: { name: 'John Churchill' } }], }); await storePromise; @@ -296,7 +296,7 @@ module('unit/store/finders', function (hooks) { assert.false(serializerLoaded, 'serializer is not eagerly loaded'); deferedFind.resolve({ - data: { id: 1, type: 'person', attributes: { name: 'John Churchill' } }, + data: { id: '1', type: 'person', attributes: { name: 'John Churchill' } }, }); await storePromise; diff --git a/packages/-ember-data/tests/unit/store/peek-record-test.js b/packages/-ember-data/tests/unit/store/peek-record-test.js index ab40c6fa5c9..4fb804c0d50 100644 --- a/packages/-ember-data/tests/unit/store/peek-record-test.js +++ b/packages/-ember-data/tests/unit/store/peek-record-test.js @@ -42,7 +42,7 @@ module('unit/store/peekRecord - Store peekRecord', function (hooks) { }); assert.strictEqual( person, - store.peekRecord({ type: 'person', id: 1 }), + store.peekRecord({ type: 'person', id: '1' }), 'peekRecord only return the corresponding record in the store' ); }); diff --git a/packages/-ember-data/tests/unit/store/push-test.js b/packages/-ember-data/tests/unit/store/push-test.js index 4f7144f911c..88a8446603d 100644 --- a/packages/-ember-data/tests/unit/store/push-test.js +++ b/packages/-ember-data/tests/unit/store/push-test.js @@ -38,7 +38,7 @@ module('unit/store/push - Store#push', function (hooks) { let person = store.push({ data: { type: 'person', - id: 1, + id: '1', attributes: { firstName: 'original first name', }, @@ -66,7 +66,7 @@ module('unit/store/push - Store#push', function (hooks) { store.push({ data: { type: 'person', - id: 1, + id: '1', attributes: { firstName: 'updated first name', }, @@ -208,7 +208,7 @@ module('unit/store/push - Store#push', function (hooks) { if (id === '1') { return resolve({ data: { - id: 1, + id: '1', type: 'phone-number', attributes: { number: '5551212' }, relationships: { @@ -223,7 +223,7 @@ module('unit/store/push - Store#push', function (hooks) { if (id === '2') { return resolve({ data: { - id: 2, + id: '2', type: 'phone-number', attributes: { number: '5552121' }, relationships: { @@ -247,8 +247,8 @@ module('unit/store/push - Store#push', function (hooks) { relationships: { 'phone-numbers': { data: [ - { id: 1, type: 'phone-number' }, - { id: 2, type: 'phone-number' }, + { id: '1', type: 'phone-number' }, + { id: '2', type: 'phone-number' }, ], }, }, @@ -545,7 +545,7 @@ module('unit/store/push - Store#push', function (hooks) { const store = this.owner.lookup('service:store'); let pushResult = store._push({ data: { - id: 1, + id: '1', type: 'person', }, }); @@ -564,7 +564,7 @@ module('unit/store/push - Store#push', function (hooks) { run(() => { store._push({ data: { - id: 1, + id: '1', type: 'person', }, }); @@ -582,7 +582,7 @@ module('unit/store/push - Store#push', function (hooks) { pushResult = store._push({ data: [ { - id: 1, + id: '1', type: 'person', }, ], @@ -711,13 +711,13 @@ module('unit/store/push - Store#pushPayload', function (hooks) { store.pushPayload('post', { posts: [ { - id: 1, + id: '1', postTitle: 'Ember rocks', }, ], people: [ { - id: 2, + id: '2', firstName: 'Yehuda', }, ], @@ -937,13 +937,13 @@ module('unit/store/push - Store#push with JSON-API', function (hooks) { hooks.beforeEach(function () { const Person = Model.extend({ name: attr('string'), - cars: hasMany('car', { async: false }), + cars: hasMany('car', { async: false, inverse: 'person' }), }); const Car = Model.extend({ make: attr('string'), model: attr('string'), - person: belongsTo('person', { async: false }), + person: belongsTo('person', { async: false, inverse: 'cars' }), }); this.owner.register('model:person', Person); @@ -962,14 +962,14 @@ module('unit/store/push - Store#push with JSON-API', function (hooks) { data: [ { type: 'person', - id: 1, + id: '1', attributes: { name: 'Tom Dale', }, }, { type: 'person', - id: 2, + id: '2', attributes: { name: 'Tomster', }, @@ -994,7 +994,7 @@ module('unit/store/push - Store#push with JSON-API', function (hooks) { data: [ { type: 'person', - id: 1, + id: '1', attributes: { name: 'Tomster', }, @@ -1003,7 +1003,7 @@ module('unit/store/push - Store#push with JSON-API', function (hooks) { { data: { type: 'person', - id: 1, + id: '1', }, }, ], @@ -1013,7 +1013,7 @@ module('unit/store/push - Store#push with JSON-API', function (hooks) { included: [ { type: 'car', - id: 1, + id: '1', attributes: { make: 'Dodge', model: 'Neon', @@ -1021,7 +1021,7 @@ module('unit/store/push - Store#push with JSON-API', function (hooks) { relationships: { person: { data: { - id: 1, + id: '1', type: 'person', }, }, diff --git a/packages/-ember-data/tests/unit/store/unload-test.js b/packages/-ember-data/tests/unit/store/unload-test.js index f1929498d5b..0b12c1c8a41 100644 --- a/packages/-ember-data/tests/unit/store/unload-test.js +++ b/packages/-ember-data/tests/unit/store/unload-test.js @@ -109,13 +109,13 @@ module('unit/store/unload - Store unloading records', function (hooks) { }); test('unload followed by create of the same type + id', function (assert) { - let record = store.createRecord('record', { id: 1 }); + let record = store.createRecord('record', { id: '1' }); assert.strictEqual(store.peekRecord('record', 1), record, 'record should exactly equal'); return run(() => { record.unloadRecord(); - let createdRecord = store.createRecord('record', { id: 1 }); + let createdRecord = store.createRecord('record', { id: '1' }); assert.notStrictEqual(record, createdRecord, 'newly created record is fresh (and was created)'); }); }); @@ -135,12 +135,14 @@ module('Store - unload record with relationships', function (hooks) { description: attr('string'), brand: belongsTo('brand', { async: false, + inverse: null, }), }); const Like = Model.extend({ product: belongsTo('product', { async: false, + inverse: null, }), }); @@ -156,7 +158,7 @@ module('Store - unload record with relationships', function (hooks) { findRecord(store, type, id, snapshot) { return resolve({ data: { - id: 1, + id: '1', type: snapshot.modelName, attributes: { description: 'cuisinart', @@ -200,7 +202,7 @@ module('Store - unload record with relationships', function (hooks) { }); let product = store.peekRecord('product', 1); - let like = store.createRecord('like', { id: 1, product: product }); + let like = store.createRecord('like', { id: '1', product: product }); return like.save(); }) diff --git a/packages/-ember-data/tests/unit/transform/custom-test.js b/packages/-ember-data/tests/unit/transform/custom-test.js index 81ae54ba52e..e0a5954f896 100644 --- a/packages/-ember-data/tests/unit/transform/custom-test.js +++ b/packages/-ember-data/tests/unit/transform/custom-test.js @@ -23,7 +23,7 @@ module('unit/transform - CustomTransform', function (hooks) { this.owner.register('serializer:user', JSONSerializer); assert.throws( - () => store.normalize('user', { id: 1, name: 'Chris' }), + () => store.normalize('user', { id: '1', name: 'Chris' }), TypeError, 'throws with missing deserialize method' ); diff --git a/packages/-ember-data/tests/unit/utils-test.js b/packages/-ember-data/tests/unit/utils-test.js index e3d8ce15d3a..539c143dca9 100644 --- a/packages/-ember-data/tests/unit/utils-test.js +++ b/packages/-ember-data/tests/unit/utils-test.js @@ -15,12 +15,12 @@ module('unit/utils', function (hooks) { hooks.beforeEach(function () { const Person = Model.extend(); const User = Model.extend({ - messages: hasMany('message', { async: false }), + messages: hasMany('message', { async: false, inverse: null }), }); const Message = Model.extend(); const Post = Message.extend({ - medias: hasMany('medium', { async: false }), + medias: hasMany('medium', { async: false, inverse: null, polymorphic: true }), }); const Medium = Mixin.create(); diff --git a/packages/model/addon/-private/belongs-to.js b/packages/model/addon/-private/belongs-to.js index 3e2e4c32c5f..359ad730f0e 100644 --- a/packages/model/addon/-private/belongs-to.js +++ b/packages/model/addon/-private/belongs-to.js @@ -1,10 +1,24 @@ -import { assert, inspect, warn } from '@ember/debug'; +import { assert, deprecate, warn } from '@ember/debug'; import { computed } from '@ember/object'; +import { dasherize } from '@ember/string'; import { DEBUG } from '@glimmer/env'; +import { + DEPRECATE_RELATIONSHIPS_WITHOUT_ASYNC, + DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE, + DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE, +} from '@ember-data/private-build-infra/deprecations'; + import { LEGACY_SUPPORT } from './model'; import { computedMacroWithOptionalParams } from './util'; +function normalizeType(type) { + if (DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE && !type) { + return; + } + + return dasherize(type); +} /** @module @ember-data/model */ @@ -111,29 +125,71 @@ import { computedMacroWithOptionalParams } from './util'; @return {Ember.computed} relationship */ function belongsTo(modelName, options) { - let opts, userEnteredModelName; - if (typeof modelName === 'object') { - opts = modelName; - userEnteredModelName = undefined; - } else { - opts = options; - userEnteredModelName = modelName; + let opts = options; + let userEnteredModelName = modelName; + if (DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE && (typeof modelName !== 'string' || !modelName.length)) { + deprecate('belongsTo() must specify the string type of the related resource as the first parameter', false, { + id: 'ember-data:deprecate-non-strict-relationships', + for: 'ember-data', + until: '5.0', + since: { enabled: '4.8', available: '4.8' }, + }); + + if (typeof modelName === 'object') { + opts = modelName; + userEnteredModelName = undefined; + } else { + opts = options; + userEnteredModelName = modelName; + } + + assert( + 'The first argument to belongsTo must be a string representing a model type key, not an instance of ' + + typeof userEnteredModelName + + ". E.g., to define a relation to the Person model, use belongsTo('person')", + typeof userEnteredModelName === 'string' || typeof userEnteredModelName === 'undefined' + ); } - assert( - 'The first argument to belongsTo must be a string representing a model type key, not an instance of ' + - inspect(userEnteredModelName) + - ". E.g., to define a relation to the Person model, use belongsTo('person')", - typeof userEnteredModelName === 'string' || typeof userEnteredModelName === 'undefined' - ); + if (DEPRECATE_RELATIONSHIPS_WITHOUT_ASYNC && (!opts || typeof opts.async !== 'boolean')) { + opts = opts || {}; + if (!('async' in opts)) { + opts.async = true; + } + deprecate('belongsTo(, ) must specify options.async as either `true` or `false`.', false, { + id: 'ember-data:deprecate-non-strict-relationships', + for: 'ember-data', + until: '5.0', + since: { enabled: '4.8', available: '4.8' }, + }); + } else { + assert(`Expected belongsTo options.async to be a boolean`, opts && typeof opts.async === 'boolean'); + } - opts = opts || {}; - if (!('async' in opts)) { - opts.async = true; + if ( + DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE && + opts.inverse !== null && + (typeof opts.inverse !== 'string' || opts.inverse.length === 0) + ) { + deprecate( + 'belongsTo(, ) must specify options.inverse as either `null` or string type of the related resource.', + false, + { + id: 'ember-data:deprecate-non-strict-relationships', + for: 'ember-data', + until: '5.0', + since: { enabled: '4.8', available: '4.8' }, + } + ); + } else { + assert( + `Expected belongsTo options.inverse to be either null or the string type of the related resource.`, + opts.inverse === null || (typeof opts.inverse === 'string' && opts.inverse.length > 0) + ); } let meta = { - type: userEnteredModelName, + type: normalizeType(userEnteredModelName), isRelationship: true, options: opts, kind: 'belongsTo', diff --git a/packages/model/addon/-private/has-many.js b/packages/model/addon/-private/has-many.js index c104eac20a2..c203898c668 100644 --- a/packages/model/addon/-private/has-many.js +++ b/packages/model/addon/-private/has-many.js @@ -2,13 +2,30 @@ @module @ember-data/model */ import { A } from '@ember/array'; -import { assert, inspect } from '@ember/debug'; +import { assert, deprecate, inspect } from '@ember/debug'; import { computed } from '@ember/object'; +import { dasherize } from '@ember/string'; import { DEBUG } from '@glimmer/env'; +import { singularize } from 'ember-inflector'; + +import { + DEPRECATE_RELATIONSHIPS_WITHOUT_ASYNC, + DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE, + DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE, +} from '@ember-data/private-build-infra/deprecations'; + import { LEGACY_SUPPORT } from './model'; import { computedMacroWithOptionalParams } from './util'; +function normalizeType(type) { + if (DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE && !type) { + return; + } + + return singularize(dasherize(type)); +} + /** `hasMany` is used to define One-To-Many and Many-To-Many relationships on a [Model](/ember-data/release/classes/Model). @@ -151,21 +168,60 @@ import { computedMacroWithOptionalParams } from './util'; @return {Ember.computed} relationship */ function hasMany(type, options) { - if (typeof type === 'object') { - options = type; - type = undefined; + if (DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE && (typeof type !== 'string' || !type.length)) { + deprecate( + 'hasMany(, ) must specify the string type of the related resource as the first parameter', + false, + { + id: 'ember-data:deprecate-non-strict-relationships', + for: 'ember-data', + until: '5.0', + since: { enabled: '4.8', available: '4.8' }, + } + ); + if (typeof type === 'object') { + options = type; + type = undefined; + } + + assert( + `The first argument to hasMany must be a string representing a model type key, not an instance of ${inspect( + type + )}. E.g., to define a relation to the Comment model, use hasMany('comment')`, + typeof type === 'string' || typeof type === 'undefined' + ); } - assert( - `The first argument to hasMany must be a string representing a model type key, not an instance of ${inspect( - type - )}. E.g., to define a relation to the Comment model, use hasMany('comment')`, - typeof type === 'string' || typeof type === 'undefined' - ); + if (DEPRECATE_RELATIONSHIPS_WITHOUT_ASYNC && (!options || typeof options.async !== 'boolean')) { + options = options || {}; + if (!('async' in options)) { + options.async = true; + } + deprecate('hasMany(, ) must specify options.async as either `true` or `false`.', false, { + id: 'ember-data:deprecate-non-strict-relationships', + for: 'ember-data', + until: '5.0', + since: { enabled: '4.8', available: '4.8' }, + }); + } else { + assert(`Expected hasMany options.async to be a boolean`, options && typeof options.async === 'boolean'); + } - options = options || {}; - if (!('async' in options)) { - options.async = true; + if ( + DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE && + options.inverse !== null && + (typeof options.inverse !== 'string' || options.inverse.length === 0) + ) { + deprecate( + 'hasMany(, ) must specify options.inverse as either `null` or string type of the related resource.', + false, + { + id: 'ember-data:deprecate-non-strict-relationships', + for: 'ember-data', + until: '5.0', + since: { enabled: '4.8', available: '4.8' }, + } + ); } // Metadata about relationships is stored on the meta of @@ -173,7 +229,7 @@ function hasMany(type, options) { // serialization. Note that `key` is populated lazily // the first time the CP is called. let meta = { - type, + type: normalizeType(type), options, isRelationship: true, kind: 'hasMany', diff --git a/packages/model/addon/-private/legacy-data-fetch.js b/packages/model/addon/-private/legacy-data-fetch.js index 6d42a0a5e3e..a7a2e34801d 100644 --- a/packages/model/addon/-private/legacy-data-fetch.js +++ b/packages/model/addon/-private/legacy-data-fetch.js @@ -3,7 +3,10 @@ import { DEBUG } from '@glimmer/env'; import { resolve } from 'rsvp'; -import { DEPRECATE_RSVP_PROMISE } from '@ember-data/private-build-infra/deprecations'; +import { + DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE, + DEPRECATE_RSVP_PROMISE, +} from '@ember-data/private-build-infra/deprecations'; import { iterateData, normalizeResponseHelper } from './legacy-data-utils'; @@ -231,10 +234,6 @@ function ensureRelationshipIsSetToParent(payload, parentIdentifier, store, paren } } -function getInverse(store, parentIdentifier, parentRelationship, type) { - return recordDataFindInverseRelationshipInfo(store, parentIdentifier, parentRelationship, type); -} - function metaIsRelationshipDefinition(meta) { return typeof meta._inverseKey === 'function'; } @@ -245,25 +244,26 @@ function inverseForRelationship(store, identifier, key) { return null; } - if (metaIsRelationshipDefinition(definition)) { + if (DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE && metaIsRelationshipDefinition(definition)) { const modelClass = store.modelFor(identifier.type); return definition._inverseKey(store, modelClass); - } else if (definition.options && definition.options.inverse !== undefined) { - return definition.options.inverse; - } else { - return null; } + assert( + `Expected the relationship defintion to specify the inverse type or null.`, + definition.options?.inverse === null || + (typeof definition.options?.inverse === 'string' && definition.options.inverse.length > 0) + ); + return definition.options.inverse; } -function recordDataFindInverseRelationshipInfo(store, parentIdentifier, parentRelationship, type) { +function getInverse(store, parentIdentifier, parentRelationship, type) { let { name: lhs_relationshipName } = parentRelationship; let { type: parentType } = parentIdentifier; let inverseKey = inverseForRelationship(store, { type: parentType }, lhs_relationshipName); if (inverseKey) { - let { - meta: { kind }, - } = store.getSchemaDefinitionService().relationshipsDefinitionFor({ type })[inverseKey]; + const definition = store.getSchemaDefinitionService().relationshipsDefinitionFor({ type }); + let { kind } = definition[inverseKey]; return { inverseKey, kind, diff --git a/packages/model/addon/-private/legacy-relationships-support.ts b/packages/model/addon/-private/legacy-relationships-support.ts index 316ede4392f..cd4306da68d 100644 --- a/packages/model/addon/-private/legacy-relationships-support.ts +++ b/packages/model/addon/-private/legacy-relationships-support.ts @@ -139,7 +139,7 @@ export class LegacySupport { assert( `You looked up the '${key}' relationship on a '${identifier.type}' with id ${ identifier.id || 'null' - } 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 (\`belongsTo({ async: true })\`)`, + } 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 (\`belongsTo(, { async: true, inverse: })\`)`, toReturn === null || store._instanceCache.recordIsLoaded(relatedIdentifier, true) ); return toReturn; @@ -250,7 +250,7 @@ export class LegacySupport { assert( `You looked up the '${key}' relationship on a '${this.identifier.type}' with id ${ this.identifier.id || 'null' - } 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 ('hasMany({ async: true })')`, + } 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 ('hasMany(, { async: true, inverse: })')`, !anyUnloaded(this.store, relationship) ); diff --git a/packages/model/addon/-private/model.js b/packages/model/addon/-private/model.js index e93354b1f9b..711243c47cd 100644 --- a/packages/model/addon/-private/model.js +++ b/packages/model/addon/-private/model.js @@ -19,6 +19,7 @@ import { HAS_DEBUG_PACKAGE } from '@ember-data/private-build-infra'; import { DEPRECATE_EARLY_STATIC, DEPRECATE_MODEL_REOPEN, + DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE, DEPRECATE_SAVE_PROMISE_ACCESS, } from '@ember-data/private-build-infra/deprecations'; import { recordIdentifierFor, storeFor } from '@ember-data/store'; @@ -980,7 +981,7 @@ class Model extends EmberObject { import Model, { belongsTo } from '@ember-data/model'; export default class BlogModel extends Model { - @belongsTo({ async: true }) user; + @belongsTo('user', { async: true, inverse: null }) user; } ``` @@ -1048,7 +1049,7 @@ class Model extends EmberObject { import Model, { hasMany } from '@ember-data/model'; export default class BlogModel extends Model { - @hasMany({ async: true }) comments; + @hasMany('comment', { async: true, inverse: null }) comments; } let blog = store.push({ @@ -1795,7 +1796,7 @@ class Model extends EmberObject { meta.key = name; meta.name = name; meta.parentModelName = modelName; - relationships[name] = relationshipFromMeta(meta); + relationships[name] = DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE ? relationshipFromMeta(meta) : meta; } }); return relationships; diff --git a/packages/model/addon/-private/references/belongs-to.ts b/packages/model/addon/-private/references/belongs-to.ts index d7b1a1e5930..ef6beb5c96f 100644 --- a/packages/model/addon/-private/references/belongs-to.ts +++ b/packages/model/addon/-private/references/belongs-to.ts @@ -134,7 +134,7 @@ export default class BelongsToReference { import Model, { belongsTo } from '@ember-data/model'; export default class BlogModel extends Model { - @belongsTo({ async: true }) user; + @belongsTo('user', { async: true, inverse: null }) user; } let blog = store.push({ @@ -174,7 +174,7 @@ export default class BelongsToReference { // models/blog.js import Model, { belongsTo } from '@ember-data/model'; export default Model.extend({ - user: belongsTo({ async: true }) + user: belongsTo('user', { async: true, inverse: null }) }); let blog = store.push({ @@ -236,7 +236,7 @@ export default class BelongsToReference { // models/blog.js import Model, { belongsTo } from '@ember-data/model'; export default Model.extend({ - user: belongsTo({ async: true }) + user: belongsTo('user', { async: true, inverse: null }) }); let blog = store.push({ @@ -291,7 +291,7 @@ export default class BelongsToReference { import Model, { hasMany } from '@ember-data/model'; export default class PostModel extends Model { - @hasMany({ async: true }) comments; + @hasMany('comment', { async: true, inverse: null }) comments; } ``` @@ -341,7 +341,7 @@ export default class BelongsToReference { import Model, { belongsTo } from '@ember-data/model'; export default class BlogModel extends Model { - @belongsTo({ async: true }) user; + @belongsTo('user', { async: true, inverse: null }) user; } let blog = store.push({ @@ -416,7 +416,7 @@ export default class BelongsToReference { import Model, { belongsTo } from '@ember-data/model'; export default class BlogModel extends Model { - @belongsTo({ async: true }) user; + @belongsTo('user', { async: true, inverse: null }) user; } let blog = store.push({ @@ -469,7 +469,7 @@ export default class BelongsToReference { import Model, { belongsTo } from '@ember-data/model'; export default class BlogModel extends Model { - @belongsTo({ async: true }) user; + @belongsTo('user', { async: true, inverse: null }) user; } let blog = store.push({ @@ -539,7 +539,7 @@ export default class BelongsToReference { import Model, { belongsTo } from '@ember-data/model'; export default class BlogModel extends Model { - @belongsTo({ async: true }) user; + @belongsTo('user', { async: true, inverse: null }) user; } let blog = store.push({ diff --git a/packages/model/addon/-private/references/has-many.ts b/packages/model/addon/-private/references/has-many.ts index 780e3981d4f..19bd4611a16 100644 --- a/packages/model/addon/-private/references/has-many.ts +++ b/packages/model/addon/-private/references/has-many.ts @@ -145,7 +145,7 @@ export default class HasManyReference { import Model, { hasMany } from '@ember-data/model'; export default class PostModel extends Model { - @hasMany({ async: true }) comments; + @hasMany('comment', { async: true, inverse: null }) comments; } ``` @@ -194,7 +194,7 @@ export default class HasManyReference { import Model, { hasMany } from '@ember-data/model'; export default class PostModel extends Model { - @hasMany({ async: true }) comments; + @hasMany('comment', { async: true, inverse: null }) comments; } ``` @@ -234,7 +234,7 @@ export default class HasManyReference { // models/blog.js import Model, { belongsTo } from '@ember-data/model'; export default Model.extend({ - user: belongsTo({ async: true }) + user: belongsTo('user', { async: true, inverse: null }) }); let blog = store.push({ @@ -296,7 +296,7 @@ export default class HasManyReference { // models/blog.js import Model, { hasMany } from '@ember-data/model'; export default Model.extend({ - users: hasMany({ async: true }) + users: hasMany('user', { async: true, inverse: null }) }); let blog = store.push({ @@ -347,7 +347,7 @@ export default class HasManyReference { import Model, { hasMany } from '@ember-data/model'; export default class PostModel extends Model { - @hasMany({ async: true }) comments; + @hasMany('comment', { async: true, inverse: null }) comments; } ``` @@ -453,7 +453,7 @@ export default class HasManyReference { import Model, { hasMany } from '@ember-data/model'; export default class PostModel extends Model { - @hasMany({ async: true }) comments; + @hasMany('comment', { async: true, inverse: null }) comments; } ``` @@ -501,7 +501,7 @@ export default class HasManyReference { import Model, { hasMany } from '@ember-data/model'; export default class PostModel extends Model { - @hasMany({ async: true }) comments; + @hasMany('comment', { async: true, inverse: null }) comments; } ``` @@ -570,7 +570,7 @@ export default class HasManyReference { import Model, { hasMany } from '@ember-data/model'; export default class PostModel extends Model { - @hasMany({ async: true }) comments; + @hasMany('comment', { async: true, inverse: null }) comments; } ``` diff --git a/packages/model/addon/-private/relationship-meta.ts b/packages/model/addon/-private/relationship-meta.ts index e38b25f6d33..3baeea16f65 100644 --- a/packages/model/addon/-private/relationship-meta.ts +++ b/packages/model/addon/-private/relationship-meta.ts @@ -6,10 +6,6 @@ import { singularize } from 'ember-inflector'; import type Store from '@ember-data/store'; import type { RelationshipSchema } from '@ember-data/types/q/record-data-schemas'; -/** - @module @ember-data/store -*/ - function typeForRelationshipMeta(meta) { let modelName = dasherize(meta.type || meta.key); @@ -25,10 +21,9 @@ function shouldFindInverse(relationshipMeta) { return !(options && options.inverse === null); } -export class RelationshipDefinition implements RelationshipSchema { +class RelationshipDefinition implements RelationshipSchema { declare _type: string; declare __inverseKey: string; - declare __inverseIsAsync: boolean; declare __hasCalculatedInverse: boolean; declare parentModelName: string; declare inverseIsAsync: string | null; @@ -37,7 +32,6 @@ export class RelationshipDefinition implements RelationshipSchema { constructor(meta: any) { this._type = ''; this.__inverseKey = ''; - this.__inverseIsAsync = true; this.__hasCalculatedInverse = false; this.parentModelName = meta.parentModelName; this.meta = meta; @@ -74,16 +68,9 @@ export class RelationshipDefinition implements RelationshipSchema { return this.__inverseKey; } - _inverseIsAsync(store: Store, modelClass): boolean { - if (this.__hasCalculatedInverse === false) { - this._calculateInverse(store, modelClass); - } - return this.__inverseIsAsync; - } - _calculateInverse(store: Store, modelClass): void { this.__hasCalculatedInverse = true; - let inverseKey, inverseIsAsync; + let inverseKey; let inverse: any = null; if (shouldFindInverse(this.meta)) { @@ -94,20 +81,13 @@ export class RelationshipDefinition implements RelationshipSchema { if (inverse) { inverseKey = inverse.name; - inverseIsAsync = isRelationshipAsync(inverse); } else { inverseKey = null; - inverseIsAsync = false; } this.__inverseKey = inverseKey; - this.__inverseIsAsync = inverseIsAsync; } } - -function isRelationshipAsync(meta: RelationshipSchema): boolean { - let inverseAsync = meta.options && meta.options.async; - return typeof inverseAsync === 'undefined' ? true : inverseAsync; -} +export type { RelationshipDefinition }; export function relationshipFromMeta(meta: RelationshipSchema): RelationshipDefinition { return new RelationshipDefinition(meta); diff --git a/packages/private-build-infra/addon/current-deprecations.ts b/packages/private-build-infra/addon/current-deprecations.ts index 5d1d6396dbd..af2934693ed 100644 --- a/packages/private-build-infra/addon/current-deprecations.ts +++ b/packages/private-build-infra/addon/current-deprecations.ts @@ -52,4 +52,7 @@ export default { DEPRECATE_HELPERS: '4.8', DEPRECATE_PROMISE_MANY_ARRAY_BEHAVIORS: '4.8', DEPRECATE_V1CACHE_STORE_APIS: '4.8', + DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE: '4.8', + DEPRECATE_RELATIONSHIPS_WITHOUT_ASYNC: '4.8', + DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE: '4.8', }; diff --git a/packages/private-build-infra/addon/deprecations.ts b/packages/private-build-infra/addon/deprecations.ts index 81302ac0b01..05550dfa492 100644 --- a/packages/private-build-infra/addon/deprecations.ts +++ b/packages/private-build-infra/addon/deprecations.ts @@ -21,3 +21,6 @@ export const DEPRECATE_CLASSIC = deprecationState('DEPRECATE_CLASSIC'); export const DEPRECATE_HELPERS = deprecationState('DEPRECATE_HELPERS'); export const DEPRECATE_PROMISE_MANY_ARRAY_BEHAVIORS = deprecationState('DEPRECATE_PROMISE_MANY_ARRAY_BEHAVIORS'); export const DEPRECATE_V1CACHE_STORE_APIS = deprecationState('DEPRECATE_V1CACHE_STORE_APIS'); +export const DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE = deprecationState('DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE'); +export const DEPRECATE_RELATIONSHIPS_WITHOUT_ASYNC = deprecationState('DEPRECATE_RELATIONSHIPS_WITHOUT_ASYNC'); +export const DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE = deprecationState('DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE'); diff --git a/packages/record-data/addon/-private/graph/-edge-definition.ts b/packages/record-data/addon/-private/graph/-edge-definition.ts index 14308570254..cf70beb8040 100644 --- a/packages/record-data/addon/-private/graph/-edge-definition.ts +++ b/packages/record-data/addon/-private/graph/-edge-definition.ts @@ -1,6 +1,7 @@ import { assert } from '@ember/debug'; import type { RelationshipDefinition } from '@ember-data/model/-private/relationship-meta'; +import { DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE } from '@ember-data/private-build-infra/deprecations'; import type Store from '@ember-data/store'; import type { StableRecordIdentifier } from '@ember-data/types/q/identifier'; import type { RelationshipSchema } from '@ember-data/types/q/record-data-schemas'; @@ -73,7 +74,8 @@ function upgradeMeta(meta: RelationshipSchema): UpgradedMeta { niceMeta.kind = meta.kind; niceMeta.key = meta.name; niceMeta.type = meta.type; - niceMeta.isAsync = options && options.async !== undefined ? !!options.async : true; + assert(`Expected relationship definition to specify async`, typeof options?.async === 'boolean'); + niceMeta.isAsync = options.async; niceMeta.isImplicit = false; niceMeta.isCollection = meta.kind === 'hasMany'; niceMeta.isPolymorphic = options && !!options.polymorphic; @@ -315,12 +317,15 @@ function inverseForRelationship(store: Store, identifier: StableRecordIdentifier return null; } - if (metaIsRelationshipDefinition(definition)) { + if (DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE && metaIsRelationshipDefinition(definition)) { const modelClass = store.modelFor(identifier.type); return definition._inverseKey(store, modelClass); - } else if (definition.options && definition.options.inverse !== undefined) { - return definition.options.inverse; - } else { - return null; } + + assert( + `Expected the relationship defintion to specify the inverse type or null.`, + definition.options?.inverse === null || + (typeof definition.options?.inverse === 'string' && definition.options.inverse.length > 0) + ); + return definition.options.inverse; } diff --git a/packages/unpublished-adapter-encapsulation-test-app/tests/integration/belongs-to-test.js b/packages/unpublished-adapter-encapsulation-test-app/tests/integration/belongs-to-test.js index d4e4d9e4e07..64c0bfcf90e 100644 --- a/packages/unpublished-adapter-encapsulation-test-app/tests/integration/belongs-to-test.js +++ b/packages/unpublished-adapter-encapsulation-test-app/tests/integration/belongs-to-test.js @@ -42,7 +42,7 @@ class MinimalSerializer extends EmberObject { // minimal implementation, not json-api compliant serializeBelongsTo(snapshot, json, relationship) { - let key = relationship.key; + let key = relationship.name; let belongsTo = snapshot.belongsTo(key); if (belongsTo) { @@ -77,7 +77,7 @@ class Post extends Model { @attr text; - @hasMany('comments') + @hasMany('comments', { async: true, inverse: 'post' }) comments; } @@ -85,7 +85,7 @@ class Comment extends Model { @attr text; - @belongsTo('post') + @belongsTo('post', { async: true, inverse: 'comments' }) post; } @@ -160,7 +160,7 @@ module('integration/belongs-to - Belongs To Tests', function (hooks) { let expectedURL = initialRecord.data.relationships.post.links.related; assert.strictEqual(url, expectedURL, 'url is passed to findBelongsTo'); - assert.strictEqual(relationship.meta.key, 'post', 'relationship is passed to findBelongsTo'); + assert.strictEqual(relationship.key, 'post', 'relationship is passed to findBelongsTo'); assert.strictEqual(snapshot.modelName, 'comment', 'snapshot is passed to findBelongsTo with correct modelName'); assert.strictEqual(snapshot.id, '3', 'snapshot is passed to findBelongsTo with correct id'); @@ -434,7 +434,7 @@ module('integration/belongs-to - Belongs To Tests', function (hooks) { let expectedURL = initialRecord.data.relationships.post.links.related; assert.strictEqual(url, expectedURL, 'url is passed to findBelongsTo'); - assert.strictEqual(relationship.meta.key, 'post', 'relationship is passed to findBelongsTo'); + assert.strictEqual(relationship.name, 'post', 'relationship is passed to findBelongsTo'); assert.strictEqual(snapshot.modelName, 'comment', 'snapshot is passed to findBelongsTo with correct modelName'); assert.strictEqual(snapshot.id, '3', 'snapshot is passed to findBelongsTo with correct id'); diff --git a/packages/unpublished-adapter-encapsulation-test-app/tests/integration/has-many-test.js b/packages/unpublished-adapter-encapsulation-test-app/tests/integration/has-many-test.js index de002677ba0..d22a3d6a475 100644 --- a/packages/unpublished-adapter-encapsulation-test-app/tests/integration/has-many-test.js +++ b/packages/unpublished-adapter-encapsulation-test-app/tests/integration/has-many-test.js @@ -77,7 +77,7 @@ class Post extends Model { @attr text; - @hasMany('comments') + @hasMany('comments', { async: true, inverse: 'post' }) comments; } @@ -85,7 +85,7 @@ class Comment extends Model { @attr text; - @belongsTo('post') + @belongsTo('post', { async: true, inverse: 'comments' }) post; } @@ -180,7 +180,7 @@ module('integration/has-many - Has Many Tests', function (hooks) { let expectedURL = initialRecord.data.relationships.comments.links.related; assert.strictEqual(url, expectedURL, 'url is passed to findHasMany'); - assert.strictEqual(relationship.meta.key, 'comments', 'relationship is passed to findHasMany'); + assert.strictEqual(relationship.name, 'comments', 'relationship is passed to findHasMany'); assert.strictEqual(snapshot.modelName, 'post', 'snapshot is passed to findHasMany with correct modelName'); assert.strictEqual(snapshot.id, '2', 'snapshot is passed to findHasMany with correct id'); @@ -602,7 +602,7 @@ module('integration/has-many - Has Many Tests', function (hooks) { let expectedURL = initialRecord.data.relationships.comments.links.related; assert.strictEqual(url, expectedURL, 'url is passed to findHasMany'); - assert.strictEqual(relationship.meta.key, 'comments', 'relationship is passed to findHasMany'); + assert.strictEqual(relationship.name, 'comments', 'relationship is passed to findHasMany'); assert.strictEqual(snapshot.modelName, 'post', 'snapshot is passed to findHasMany with correct modelName'); assert.strictEqual(snapshot.id, '2', 'snapshot is passed to findHasMany with correct id'); diff --git a/packages/unpublished-adapter-encapsulation-test-app/tests/integration/reload-test.js b/packages/unpublished-adapter-encapsulation-test-app/tests/integration/reload-test.js index eeba0496772..bfaa7e06aa9 100644 --- a/packages/unpublished-adapter-encapsulation-test-app/tests/integration/reload-test.js +++ b/packages/unpublished-adapter-encapsulation-test-app/tests/integration/reload-test.js @@ -119,7 +119,7 @@ module('integration/reload - Reloading Tests', function (hooks) { this.store.push({ data: { - id: 1, + id: '1', type: 'person', attributes: { firstName: 'Gaurav', diff --git a/packages/unpublished-relationship-performance-test-app/app/models/car.js b/packages/unpublished-relationship-performance-test-app/app/models/car.js index 454926f39e7..ad55ea27b46 100644 --- a/packages/unpublished-relationship-performance-test-app/app/models/car.js +++ b/packages/unpublished-relationship-performance-test-app/app/models/car.js @@ -3,7 +3,7 @@ import DS from 'ember-data'; const { Model, belongsTo, hasMany } = DS; export default Model.extend({ - make: belongsTo('make', { async: false }), - size: belongsTo('size', { async: false }), - colors: hasMany('color', { async: false }), + make: belongsTo('make', { async: false, inverse: 'cars' }), + size: belongsTo('size', { async: false, inverse: 'cars' }), + colors: hasMany('color', { async: false, inverse: 'cars' }), }); diff --git a/packages/unpublished-relationship-performance-test-app/app/models/child.js b/packages/unpublished-relationship-performance-test-app/app/models/child.js index 59c58b6904c..ac3b442da51 100644 --- a/packages/unpublished-relationship-performance-test-app/app/models/child.js +++ b/packages/unpublished-relationship-performance-test-app/app/models/child.js @@ -7,5 +7,5 @@ export default Model.extend({ friends: hasMany('child', { async: true, inverse: null }), bestFriend: belongsTo('child', { async: true, inverse: 'bestFriend' }), secondBestFriend: belongsTo('child', { async: true, inverse: 'secondBestFriend' }), - parent: belongsTo('parent', { async: true }), + parent: belongsTo('parent', { async: true, inverse: 'children' }), }); diff --git a/packages/unpublished-relationship-performance-test-app/app/models/color.js b/packages/unpublished-relationship-performance-test-app/app/models/color.js index 182d36267c9..99eaadfc486 100644 --- a/packages/unpublished-relationship-performance-test-app/app/models/color.js +++ b/packages/unpublished-relationship-performance-test-app/app/models/color.js @@ -4,5 +4,5 @@ const { Model, attr, hasMany } = DS; export default Model.extend({ name: attr('string'), - cars: hasMany('car', { async: false }), + cars: hasMany('car', { async: false, inverse: 'colors' }), }); diff --git a/packages/unpublished-relationship-performance-test-app/app/models/make.js b/packages/unpublished-relationship-performance-test-app/app/models/make.js index 182d36267c9..007940b5ee6 100644 --- a/packages/unpublished-relationship-performance-test-app/app/models/make.js +++ b/packages/unpublished-relationship-performance-test-app/app/models/make.js @@ -4,5 +4,5 @@ const { Model, attr, hasMany } = DS; export default Model.extend({ name: attr('string'), - cars: hasMany('car', { async: false }), + cars: hasMany('car', { async: false, inverse: 'make' }), }); diff --git a/packages/unpublished-relationship-performance-test-app/app/models/parent.js b/packages/unpublished-relationship-performance-test-app/app/models/parent.js index 8e053d487e2..c94b54e6f96 100644 --- a/packages/unpublished-relationship-performance-test-app/app/models/parent.js +++ b/packages/unpublished-relationship-performance-test-app/app/models/parent.js @@ -4,5 +4,5 @@ const { Model, attr, hasMany } = DS; export default Model.extend({ parentName: attr('string'), - children: hasMany('child', { async: true }), + children: hasMany('child', { async: true, inverse: 'parent' }), }); diff --git a/packages/unpublished-relationship-performance-test-app/app/models/size.js b/packages/unpublished-relationship-performance-test-app/app/models/size.js index 182d36267c9..7293e621d4c 100644 --- a/packages/unpublished-relationship-performance-test-app/app/models/size.js +++ b/packages/unpublished-relationship-performance-test-app/app/models/size.js @@ -4,5 +4,5 @@ const { Model, attr, hasMany } = DS; export default Model.extend({ name: attr('string'), - cars: hasMany('car', { async: false }), + cars: hasMany('car', { async: false, inverse: 'size' }), }); diff --git a/packages/unpublished-serializer-encapsulation-test-app/tests/integration/relationships-test.js b/packages/unpublished-serializer-encapsulation-test-app/tests/integration/relationships-test.js index 8892341919e..69f1a238858 100644 --- a/packages/unpublished-serializer-encapsulation-test-app/tests/integration/relationships-test.js +++ b/packages/unpublished-serializer-encapsulation-test-app/tests/integration/relationships-test.js @@ -45,7 +45,7 @@ module('integration/relationships - running requests for async relatonships with return { data: [ { - id: 1, + id: '1', type: 'comment', attributes: { message: 'Message 1', @@ -53,14 +53,14 @@ module('integration/relationships - running requests for async relatonships with relationships: { post: { data: { - id: 1, + id: '1', type: 'post', }, }, }, }, { - id: 2, + id: '2', type: 'comment', attributes: { message: 'Message 2', @@ -68,7 +68,7 @@ module('integration/relationships - running requests for async relatonships with relationships: { post: { data: { - id: 1, + id: '1', type: 'post', }, }, @@ -93,7 +93,7 @@ module('integration/relationships - running requests for async relatonships with let post = store.push({ data: { - id: 1, + id: '1', type: 'post', attributes: { title: 'Post 1', @@ -102,11 +102,11 @@ module('integration/relationships - running requests for async relatonships with comments: { data: [ { - id: 1, + id: '1', type: 'comment', }, { - id: 2, + id: '2', type: 'comment', }, ], @@ -131,14 +131,14 @@ module('integration/relationships - running requests for async relatonships with return { data: [ { - id: 1, + id: '1', type: 'comment', attributes: { message: 'Message 1', }, }, { - id: 2, + id: '2', type: 'comment', attributes: { message: 'Message 2', @@ -163,7 +163,7 @@ module('integration/relationships - running requests for async relatonships with let post = store.push({ data: { - id: 1, + id: '1', type: 'post', attributes: { title: 'Post 1', @@ -192,7 +192,7 @@ module('integration/relationships - running requests for async relatonships with assert.strictEqual(requestType, 'findBelongsTo', 'expected method name is correct'); assert.deepEqual(rawPayload, { data: { - id: 1, + id: '1', type: 'post', attributes: { title: 'John', @@ -201,7 +201,7 @@ module('integration/relationships - running requests for async relatonships with }); return { data: { - id: 1, + id: '1', type: 'post', attributes: { title: 'Chris', @@ -218,7 +218,7 @@ module('integration/relationships - running requests for async relatonships with ajax(url, type) { return resolve({ data: { - id: 1, + id: '1', type: 'post', attributes: { title: 'John', @@ -233,7 +233,7 @@ module('integration/relationships - running requests for async relatonships with let comment = store.push({ data: { - id: 1, + id: '1', type: 'comment', attributes: { message: 'Message 1', diff --git a/packages/unpublished-test-infra/addon-test-support/deprecated-test.js b/packages/unpublished-test-infra/addon-test-support/deprecated-test.js index 51cafc2e534..bdf622b8b2e 100644 --- a/packages/unpublished-test-infra/addon-test-support/deprecated-test.js +++ b/packages/unpublished-test-infra/addon-test-support/deprecated-test.js @@ -39,6 +39,9 @@ export function deprecatedTest(testName, deprecation, testCallback) { if (COMPAT_VERSION && gte(COMPAT_VERSION, VERSION)) { testFn = skip; } + if (!DEBUG && deprecation.debugOnly) { + testFn = skip; + } if (gte(VERSION, deprecation.until)) { testFn(`DEPRECATION ${deprecation.id} until ${deprecation.until} | ${testName}`, interceptor); diff --git a/packages/unpublished-test-infra/addon-test-support/qunit-asserts/assert-deprecation.ts b/packages/unpublished-test-infra/addon-test-support/qunit-asserts/assert-deprecation.ts index fea23e3cfec..169bce71e43 100644 --- a/packages/unpublished-test-infra/addon-test-support/qunit-asserts/assert-deprecation.ts +++ b/packages/unpublished-test-infra/addon-test-support/qunit-asserts/assert-deprecation.ts @@ -80,13 +80,15 @@ function verifyDeprecation(config: DeprecationConfig, label?: string): AssertSom }); HANDLED_DEPRECATIONS_FOR_TEST.push(...matchedDeprecations); - let expectedCount = typeof config.count === 'number' ? config.count : 1; - let passed = matchedDeprecations.length === expectedCount; + const expectedCount: number | 'ALL' = typeof config.count === 'number' || config.count === 'ALL' ? config.count : 1; + //@ts-expect-error TS having trouble realizing expectedCount can be 'ALL' + let passed = expectedCount === 'ALL' ? true : matchedDeprecations.length === expectedCount; return { result: passed, actual: { id: config.id, count: matchedDeprecations.length }, - expected: { id: config.id, count: expectedCount }, + //@ts-expect-error TS having trouble realizing expectedCount can be 'ALL' + expected: { id: config.id, count: expectedCount === 'ALL' ? matchedDeprecations.length : expectedCount }, message: label || `Expected ${expectedCount} deprecation${expectedCount === 1 ? '' : 's'} for ${config.id} during test, ${