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

[FEATURE] Removes Chains in Tracked Properties Flag #17951

Merged
merged 1 commit into from
Apr 26, 2019
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { run } from '@ember/runloop';
import { get, set, addObserver, removeObserver } from '@ember/-internals/metal';
import { Object as EmberObject, A as emberA } from '@ember/-internals/runtime';
import EmberDataAdapter from '../lib/data_adapter';
import { moduleFor, ApplicationTestCase } from 'internal-test-helpers';
import { moduleFor, ApplicationTestCase, runLoopSettled } from 'internal-test-helpers';

let adapter;
const Model = EmberObject.extend();
Expand Down Expand Up @@ -267,23 +267,30 @@ moduleFor(
);
this.add('model:post', PostClass);

return this.visit('/').then(() => {
adapter = this.applicationInstance.lookup('data-adapter:main');
let release;

function recordsAdded() {
set(post, 'title', 'Post Modified');
}
return this.visit('/')
.then(() => {
adapter = this.applicationInstance.lookup('data-adapter:main');

function recordsUpdated(records) {
updatesCalled++;
assert.equal(records[0].columnValues.title, 'Post Modified');
}
function recordsAdded() {
set(post, 'title', 'Post Modified');
}

let release = adapter.watchRecords('post', recordsAdded, recordsUpdated);
release();
set(post, 'title', 'New Title');
assert.equal(updatesCalled, 1, 'Release function removes observers');
});
function recordsUpdated(records) {
updatesCalled++;
assert.equal(records[0].columnValues.title, 'Post Modified');
}

release = adapter.watchRecords('post', recordsAdded, recordsUpdated);

return runLoopSettled();
})
.then(() => {
release();
set(post, 'title', 'New Title');
assert.equal(updatesCalled, 1, 'Release function removes observers');
});
}

['@test _nameToClass does not error when not found'](assert) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getCurrentTracker } from '@ember/-internals/metal';
import { consume } from '@ember/-internals/metal';
import { Factory } from '@ember/-internals/owner';
import { HAS_NATIVE_PROXY } from '@ember/-internals/utils';
import { OwnedTemplateMeta } from '@ember/-internals/views';
Expand Down Expand Up @@ -171,12 +171,8 @@ export default class CustomComponentManager<ComponentInstance>
get(_target, prop) {
assert('args can only be strings', typeof prop === 'string');

let tracker = getCurrentTracker();
let ref = capturedArgs.named.get(prop as string);

if (tracker) {
tracker.add(ref.tag);
}
consume(ref.tag);

return ref.value();
},
Expand All @@ -200,11 +196,7 @@ export default class CustomComponentManager<ComponentInstance>
Object.defineProperty(namedArgsProxy, name, {
get() {
let ref = capturedArgs.named.get(name);
let tracker = getCurrentTracker();

if (tracker) {
tracker.add(ref.tag);
}
consume(ref.tag);

return ref.value();
},
Expand Down
45 changes: 17 additions & 28 deletions packages/@ember/-internals/glimmer/lib/utils/references.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import {
consume,
didRender,
get,
getCurrentTracker,
set,
setCurrentTracker,
tagFor,
tagForProperty,
Tracker,
track,
watchKey,
} from '@ember/-internals/metal';
import { isProxy, symbol } from '@ember/-internals/utils';
Expand Down Expand Up @@ -190,7 +189,7 @@ export class RootPropertyReference extends PropertyReference
this.tag = this.propertyTag;
}

if (DEBUG) {
if (DEBUG && !EMBER_METAL_TRACKED_PROPERTIES) {
watchKey(parentValue, propertyKey);
}
}
Expand All @@ -202,22 +201,17 @@ export class RootPropertyReference extends PropertyReference
(this.tag.inner as ITwoWayFlushDetectionTag).didCompute(parentValue);
}

let parent: Option<Tracker> = null;
let tracker: Option<Tracker> = null;

if (EMBER_METAL_TRACKED_PROPERTIES) {
parent = getCurrentTracker();
tracker = setCurrentTracker();
}

let ret = get(parentValue, propertyKey);
let ret;

if (EMBER_METAL_TRACKED_PROPERTIES) {
setCurrentTracker(parent);
let tag = tracker!.combine();
if (parent) parent.add(tag);
let tag = track(() => {
ret = get(parentValue, propertyKey);
});

consume(tag);
this.propertyTag.inner.update(tag);
} else {
ret = get(parentValue, propertyKey);
}

return ret;
Expand Down Expand Up @@ -262,31 +256,26 @@ export class NestedPropertyReference extends PropertyReference {
if ((parentValueType === 'object' && _parentValue !== null) || parentValueType === 'function') {
let parentValue = _parentValue as object;

if (DEBUG) {
if (DEBUG && !EMBER_METAL_TRACKED_PROPERTIES) {
watchKey(parentValue, propertyKey);
}

if (DEBUG) {
(this.tag.inner as ITwoWayFlushDetectionTag).didCompute(parentValue);
}

let parent: Option<Tracker> = null;
let tracker: Option<Tracker> = null;
let ret;

if (EMBER_METAL_TRACKED_PROPERTIES) {
parent = getCurrentTracker();
tracker = setCurrentTracker();
}
let tag = track(() => {
ret = get(parentValue, propertyKey);
});

let ret = get(parentValue, propertyKey);

if (EMBER_METAL_TRACKED_PROPERTIES) {
setCurrentTracker(parent!);
let tag = tracker!.combine();
if (parent) parent.add(tag);
consume(tag);

propertyTag.inner.update(tag);
} else {
ret = get(parentValue, propertyKey);
propertyTag.inner.update(tagForProperty(parentValue, propertyKey));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,7 @@ moduleFor(
});
}

['@test query params in customized controllerName have stickiness by default between model'](
async ['@test query params in customized controllerName have stickiness by default between model'](
assert
) {
assert.expect(2);
Expand All @@ -867,16 +867,16 @@ moduleFor(
this.register('template:author', compile(tmpl));
});

return this.visit('/blog/author/1?official=true').then(() => {
let suffix1 = '/blog/author/1?official=true';
let href1 = this.element.querySelector('.author-1').href;
let suffix1337 = '/blog/author/1337';
let href1337 = this.element.querySelector('.author-1337').href;
await this.visit('/blog/author/1?official=true');

// check if link ends with the suffix
assert.ok(this.stringsEndWith(href1, suffix1), `${href1} ends with ${suffix1}`);
assert.ok(this.stringsEndWith(href1337, suffix1337), `${href1337} ends with ${suffix1337}`);
});
let suffix1 = '/blog/author/1?official=true';
let href1 = this.element.querySelector('.author-1').href;
let suffix1337 = '/blog/author/1337';
let href1337 = this.element.querySelector('.author-1337').href;

// check if link ends with the suffix
assert.ok(this.stringsEndWith(href1, suffix1), `${href1} ends with ${suffix1}`);
assert.ok(this.stringsEndWith(href1337, suffix1337), `${href1337} ends with ${suffix1337}`);
}

['@test visit() routable engine which errors on init'](assert) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { moduleFor, ApplicationTestCase, strip } from 'internal-test-helpers';
import {
moduleFor,
ApplicationTestCase,
strip,
runTask,
runLoopSettled,
} from 'internal-test-helpers';

import { ENV } from '@ember/-internals/environment';
import Controller from '@ember/controller';
Expand Down Expand Up @@ -499,7 +505,12 @@ moduleFor(

await this.visit('/');

assert.rejectsAssertion(this.visit('/routeWithError'), expectedBacktrackingMessage);
assert.throwsAssertion(
() => runTask(() => this.visit('/routeWithError')),
expectedBacktrackingMessage
);

await runLoopSettled();
}

['@test route templates with {{{undefined}}} [GH#14924] [GH#16172]']() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import {
equalsElement,
styles,
runTask,
runLoopSettled,
} from 'internal-test-helpers';

import { run } from '@ember/runloop';
import { DEBUG } from '@glimmer/env';
import { alias, set, get, observer, on, computed } from '@ember/-internals/metal';
import { EMBER_METAL_TRACKED_PROPERTIES } from '@ember/canary-features';
import Service, { inject as injectService } from '@ember/service';
import { Object as EmberObject, A as emberA } from '@ember/-internals/runtime';
import { jQueryDisabled } from '@ember/-internals/views';
Expand Down Expand Up @@ -2526,15 +2528,11 @@ moduleFor(
);
}

["@test when a property is changed during children's rendering"](assert) {
let outer, middle;
["@test when a property is changed during children's rendering"]() {
let middle;

this.registerComponent('x-outer', {
ComponentClass: Component.extend({
init() {
this._super(...arguments);
outer = this;
},
value: 1,
}),
template: '{{#x-middle}}{{x-inner value=value}}{{/x-middle}}',
Expand All @@ -2554,35 +2552,17 @@ moduleFor(
this.registerComponent('x-inner', {
ComponentClass: Component.extend({
value: null,
pushDataUp: observer('value', function() {
didReceiveAttrs() {
middle.set('value', this.get('value'));
}),
},
}),
template: '<div id="inner-value">{{value}}</div>',
});

this.render('{{x-outer}}');

assert.equal(this.$('#inner-value').text(), '1', 'initial render of inner');
assert.equal(
this.$('#middle-value').text(),
'',
'initial render of middle (observers do not run during init)'
);

runTask(() => this.rerender());

assert.equal(this.$('#inner-value').text(), '1', 'initial render of inner');
assert.equal(
this.$('#middle-value').text(),
'',
'initial render of middle (observers do not run during init)'
);

let expectedBacktrackingMessage = /modified "value" twice on <.+?> in a single render\. It was rendered in "component:x-middle" and modified in "component:x-inner"/;

expectAssertion(() => {
runTask(() => outer.set('value', 2));
this.render('{{x-outer}}');
}, expectedBacktrackingMessage);
}

Expand Down Expand Up @@ -2741,9 +2721,13 @@ moduleFor(
this.assertText('initial value - initial value');

if (DEBUG) {
let message = EMBER_METAL_TRACKED_PROPERTIES
? /You attempted to update .*, but it is being tracked by a tracking context/
: /You must use set\(\) to set the `bar` property \(of .+\) to `foo-bar`\./;

expectAssertion(() => {
component.bar = 'foo-bar';
}, /You must use set\(\) to set the `bar` property \(of .+\) to `foo-bar`\./);
}, message);

this.assertText('initial value - initial value');
}
Expand Down Expand Up @@ -3208,7 +3192,7 @@ moduleFor(
this.assertText('things');
}

['@test didReceiveAttrs fires after .init() but before observers become active'](assert) {
async ['@test didReceiveAttrs fires after .init() but before observers become active'](assert) {
let barCopyDidChangeCount = 0;

this.registerComponent('foo-bar', {
Expand All @@ -3231,13 +3215,15 @@ moduleFor(
template: '{{bar}}-{{barCopy}}',
});

this.render(`{{foo-bar bar=bar}}`, { bar: 3 });
await this.render(`{{foo-bar bar=bar}}`, { bar: 3 });

this.assertText('3-4');

assert.strictEqual(barCopyDidChangeCount, 1, 'expected observer firing for: barCopy');

runTask(() => set(this.context, 'bar', 7));
set(this.context, 'bar', 7);

await runLoopSettled();

this.assertText('7-8');

Expand Down
Loading