Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 3.17 backports #7144

Merged
merged 9 commits into from
Apr 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
"command-line-args": "^5.1.1",
"common-tags": "^1.8.0",
"debug": "^4.1.1",
"ember-cli": "~3.14.0",
"ember-cli": "~3.17.0",
"ember-cli-app-version": "^3.2.0",
"ember-cli-babel": "^7.13.2",
"ember-cli-blueprint-test-helpers": "^0.19.1",
Expand Down
4 changes: 0 additions & 4 deletions packages/-ember-data/config/ember-try.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,8 @@ module.exports = function() {
},
{
name: 'ember-lts-3.12',
env: {
EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }),
},
npm: {
devDependencies: {
'@ember/jquery': '^1.1.0',
'ember-source': '~3.12.0',
},
},
Expand Down
4 changes: 2 additions & 2 deletions packages/-ember-data/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"broccoli-string-replace": "^0.1.2",
"broccoli-test-helper": "^2.0.0",
"broccoli-uglify-sourcemap": "^3.2.0",
"ember-cli": "~3.14.0",
"ember-cli": "~3.17.0",
"ember-cli-app-version": "^3.2.0",
"ember-cli-dependency-checker": "^3.2.0",
"ember-cli-htmlbars": "^4.2.2",
Expand All @@ -76,7 +76,7 @@
"ember-maybe-import-regenerator": "^0.1.6",
"ember-qunit": "^4.6.0",
"ember-resolver": "^7.0.0",
"ember-source": "^3.17.0",
"ember-source": "~3.17.0",
"ember-source-channel-url": "^2.0.1",
"ember-try": "^1.4.0",
"github": "^1.1.1",
Expand Down
51 changes: 51 additions & 0 deletions packages/-ember-data/tests/helpers/create-tracking-context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { render, settled } from '@ember/test-helpers';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';

import hbs from 'htmlbars-inline-precompile';

export default async function createTrackingContext(owner, props) {
let instance;
let testKeys = Object.keys(props);
class TestComponent extends Component {
@tracked count = 1;

constructor() {
super(...arguments);
instance = this;
}

get ___value() {
this.count;
return testKeys.map(key => this[key]);
}
}

let defs = {};
testKeys.forEach(key => (defs[key] = Object.getOwnPropertyDescriptor(props, key)));

Object.defineProperties(TestComponent.prototype, defs);

owner.register('component:test-component', TestComponent);
owner.register(
'template:components/test-component',
hbs`<div class="test">{{this.count}}<ul>{{#each this.___value as |prop|}}<li>{{prop}}</li>{{/each}}</ul></div>`
);

async function initialRender() {
await render(hbs`<TestComponent/>`);
}

return {
async render() {
if (!instance) {
await initialRender();
await settled();
} else {
instance.count++;
await settled();
}
},
instance,
};
}
105 changes: 103 additions & 2 deletions packages/-ember-data/tests/integration/references/has-many-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import { run } from '@ember/runloop';
import { module, test } from 'qunit';
import { defer, resolve } from 'rsvp';

import { gte } from 'ember-compatibility-helpers';
import DS from 'ember-data';
import { setupTest } from 'ember-qunit';
import { setupRenderingTest } from 'ember-qunit';

import JSONAPISerializer from '@ember-data/serializer/json-api';
import testInDebug from '@ember-data/unpublished-test-infra/test-support/test-in-debug';

import createTrackingContext from '../../helpers/create-tracking-context';

module('integration/references/has-many', function(hooks) {
setupTest(hooks);
setupRenderingTest(hooks);

hooks.beforeEach(function() {
const Family = DS.Model.extend({
Expand Down Expand Up @@ -178,6 +181,104 @@ module('integration/references/has-many', function(hooks) {
assert.deepEqual(personsReference.meta(), { foo: true });
});

if (gte('3.16.0')) {
test('HasManyReference#value() does not create accidental autotracking errors', async function(assert) {
let store = this.owner.lookup('service:store');
let family = store.push({
data: {
type: 'family',
id: '1',
},
});

let personsReference = family.hasMany('persons');
let renderedValue;
let context = await createTrackingContext(this.owner, {
get value() {
renderedValue = personsReference.value();
return renderedValue;
},
});

await context.render();

assert.strictEqual(renderedValue, null, 'We have no value yet, we are not loaded');

store.push({
data: {
type: 'family',
id: '1',
relationships: {
persons: {
data: [{ type: 'person', id: '1' }],
},
},
},
});

await context.render();

assert.strictEqual(renderedValue, null, 'We have no value yet, we are still not loaded');

let person1 = store.push({
data: {
type: 'person',
id: '1',
attributes: {
name: 'Chris',
},
relationships: {
family: {
data: { type: 'family', id: '1' },
},
},
},
});

await context.render();

assert.strictEqual(renderedValue.length, 1, 'We have a value');
assert.strictEqual(renderedValue.objectAt(0), person1, 'We have the right value');

store.push({
data: {
type: 'family',
id: '1',
relationships: {
persons: {
data: [
{ type: 'person', id: '1' },
{ type: 'person', id: '2' },
],
},
},
},
included: [
{
type: 'person',
id: '2',
attributes: {
name: 'James',
},
relationships: {
family: {
data: { type: 'family', id: '2' },
},
},
},
],
});

await context.render();

let person2 = store.peekRecord('person', '2');
assert.notStrictEqual(person2, null, 'we have a person');
assert.strictEqual(renderedValue.length, 2, 'We have two values');
assert.strictEqual(renderedValue.objectAt(0), person1, 'We have the right value[0]');
assert.strictEqual(renderedValue.objectAt(1), person2, 'We have the right value[1]');
});
}

testInDebug('push(array)', function(assert) {
var done = assert.async();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ module('integration/relationships/has_many - Has-Many Relationships', function(h
});

test('hasMany + canonical vs currentState + destroyRecord ', function(assert) {
assert.expect(6);
assert.expect(7);

let store = this.owner.lookup('service:store');

Expand Down Expand Up @@ -266,6 +266,8 @@ module('integration/relationships/has_many - Has-Many Relationships', function(h
);
assert.equal(contacts, user.get('contacts'));

assert.ok(!user.contacts.initialState || !user.contacts.initialState.find(model => model.id === '2'));

run(() => {
contacts.addObject(store.createRecord('user', { id: 8 }));
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { settled } from '@ember/test-helpers';

import { module, test } from 'qunit';

import { setupTest } from 'ember-qunit';
Expand Down Expand Up @@ -650,4 +652,43 @@ module('integration/relationships/inverse_relationships - Inverse Relationships'

assert.equal(comment.inverseFor('user'), null, 'Defaults to a null inverse');
});

test('Unload a destroyed record should clean the relations', async function(assert) {
assert.expect(3);

class Post extends Model {
@hasMany('comment', { async: true })
comments;
}

class Comment extends Model {
@belongsTo('post', { async: true })
post;
}

register('model:Post', Post);
register('model:Comment', Comment);

const comment = store.createRecord('comment');
const post = store.createRecord('post');

post.get('comments').pushObject(comment);

await comment.destroyRecord();
comment.unloadRecord();

await settled();

assert.deepEqual(
comment._internalModel.__recordData.__relationships.initializedRelationships,
{},
'relationships are cleared'
);
assert.equal(
comment._internalModel.__recordData.__implicitRelationships,
null,
'implicitRelationships are cleared'
);
assert.ok(comment._internalModel.__recordData.isDestroyed, 'recordData is destroyed');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { module, test } from 'qunit';

import { setupTest } from 'ember-qunit';

import Transform from '@ember-data/serializer/transform';

module('integration/store/creation-recursion', function(hooks) {
setupTest(hooks);

test('store construction does not construct transforms', function(assert) {
let storeFactory = this.owner.factoryFor('service:store');

this.owner.unregister('service:store');
this.owner.register('service:store', storeFactory);

let test = this;
test.dateTransformCreated = false;
class MockDateTransform extends Transform {
constructor(...args) {
super(...args);
test.dateTransformCreated = true;
}
}

this.owner.unregister('transform:date');
this.owner.register('transform:date', MockDateTransform);

assert.notOk(this.dateTransformCreated, 'date transform is not yet created');

// construct a store - it should now be created
this.owner.lookup('service:store');

assert.notOk(this.dateTransformCreated, 'date transform is not yet created');

// construct a date transform - it should now be created
this.owner.lookup('transform:date');

assert.ok(this.dateTransformCreated, 'date transform is now created');
});
});
2 changes: 2 additions & 0 deletions packages/adapter/node-tests/blueprints/adapter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ const modifyPackages = blueprintHelpers.modifyPackages;

const expect = chai.expect;
const enableOctane = setupTestEnvironment.enableOctane;
const enableClassic = setupTestEnvironment.enableClassic;

describe('Acceptance: generate and destroy adapter blueprints', function() {
setupTestHooks(this);

describe('classic', function() {
enableClassic();
beforeEach(function() {
return emberNew();
});
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@ember-data/unpublished-test-infra": "3.17.0",
"@ember/optional-features": "^1.3.0",
"broccoli-asset-rev": "^3.0.0",
"ember-cli": "~3.14.0",
"ember-cli": "~3.17.0",
"ember-cli-blueprint-test-helpers": "^0.19.1",
"ember-cli-dependency-checker": "^3.2.0",
"ember-cli-htmlbars": "^4.2.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/debug/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@ember-data/unpublished-test-infra": "3.17.0",
"@ember/optional-features": "^1.3.0",
"broccoli-asset-rev": "^3.0.0",
"ember-cli": "~3.14.0",
"ember-cli": "~3.17.0",
"ember-cli-blueprint-test-helpers": "^0.19.1",
"ember-cli-dependency-checker": "^3.2.0",
"ember-cli-htmlbars": "^4.2.2",
Expand Down
2 changes: 2 additions & 0 deletions packages/model/addon/-private/system/many-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ export default EmberObject.extend(MutableArray, DeprecatedEvented, {
*/
this.currentState = [];
this.flushCanonical(this.initialState, false);
// we don't need this anymore, it just prevents garbage collection the records in the initialState
this.initialState = undefined;
},

// TODO: if(DEBUG)
Expand Down
9 changes: 6 additions & 3 deletions packages/model/blueprints/model/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,11 @@ module.exports = useEditionDetector({
if (attrs.length) {
let attrTransformer, attrSeparator;

let isOctane = has('octane');
if (isOctane) {
let hasOctane = has('octane');
if (hasOctane && process.env.EMBER_EDITION === 'classic') {
hasOctane = false; //forcible override
}
if (hasOctane) {
attrTransformer = nativeAttr;
attrSeparator = ';';
} else {
Expand All @@ -78,7 +81,7 @@ module.exports = useEditionDetector({

attrs = attrs.map(attrTransformer);
attrs = ' ' + attrs.join(attrSeparator + EOL + ' ');
if (isOctane) {
if (hasOctane) {
attrs = attrs + attrSeparator;
}
}
Expand Down
Loading