Skip to content
Draft
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 @@ -11,7 +11,6 @@ import { Component } from '@ember/-internals/glimmer';
import { setModifierManager, modifierCapabilities } from '@glimmer/manager';
import EmberObject, { set } from '@ember/object';
import { tracked } from '@ember/-internals/metal';
import { backtrackingMessageFor } from '../utils/debug-stack';

class ModifierManagerTest extends RenderingTestCase {
'@test throws a useful error when missing capabilities'(assert) {
Expand Down Expand Up @@ -242,9 +241,9 @@ class ModifierManagerTest extends RenderingTestCase {
assert.equal(updateCount, 2);
}

'@test provides a helpful assertion when mutating a value that was consumed already'() {
'@test allows get/set (lazy initialization) within modifier didInsertElement'(assert) {
class Person {
@tracked name = 'bob';
@tracked name;
}

let ModifierClass = setModifierManager(
Expand All @@ -262,24 +261,25 @@ class ModifierManagerTest extends RenderingTestCase {
}
);

let person = new Person();

this.registerModifier(
'foo-bar',
class MyModifier extends ModifierClass {
didInsertElement([person]) {
person.name;
person.name = 'sam';
// get/set/get pattern (lazy initialization)
let val = person.name;
if (val === undefined) {
person.name = 'sam';
val = person.name;
}
}
}
);

let expectedMessage = backtrackingMessageFor('name', Person.name, {
renderTree: [],
includeTopLevel: false,
});
this.render('<h1 {{foo-bar this.person}}>hello world</h1>', { person });

expectAssertion(() => {
this.render('<h1 {{foo-bar this.person}}>hello world</h1>', { person: new Person() });
}, expectedMessage);
assert.strictEqual(person.name, 'sam', 'lazy initialization in modifier works');
}

'@test capabilities helper function must be used to generate capabilities'(assert) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { set } from '@ember/object';
import { setOwner } from '@ember/-internals/owner';
import Service, { service } from '@ember/service';
import { registerDestructor } from '@glimmer/destroyable';
import { backtrackingMessageFor } from '../../utils/debug-stack';

class TestHelperManager {
capabilities = helperCapabilities('3.23', {
Expand Down Expand Up @@ -216,7 +215,7 @@ moduleFor(
this.assertText('hello');
}

['@test debug name is used for backtracking message']() {
['@test allows get/set within the same tracking frame (lazy initialization)']() {
this.registerCustomHelper(
'hello',
class extends TestHelper {
Expand All @@ -225,17 +224,13 @@ moduleFor(
value() {
this.foo;
this.foo = 456;
return this.foo;
}
}
);

let expectedMessage = backtrackingMessageFor('foo', '.*', {
renderTree: ['\\(result of a `TEST_HELPER` helper\\)'],
});

expectAssertion(() => {
this.render('{{hello}}');
}, expectedMessage);
this.render('{{hello}}');
this.assertText('456');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should probably assert renderSettled or stablerender, whatever that helper is we use all over the place in other tests

}

['@test asserts against using both `hasValue` and `hasScheduledEffect`'](assert) {
Expand Down Expand Up @@ -347,20 +342,20 @@ moduleFor(
assert.verifySteps([]);
}

'@test custom helpers gives helpful assertion when reading then mutating a tracked value within constructor'() {
'@test custom helpers allows get/set/get (lazy initialization) within constructor'() {
this.registerCustomHelper(
'hello',
class extends TestHelper {
@tracked foo = 123;
@tracked foo;

constructor() {
super(...arguments);

// first read the tracked property
this.foo;

// then attempt to update the tracked property
this.foo = 456;
// get/set/get pattern (lazy initialization)
let val = this.foo;
if (val === undefined) {
this.foo = 456;
}
}

value() {
Expand All @@ -369,36 +364,29 @@ moduleFor(
}
);

let expectedMessage = backtrackingMessageFor('foo');

expectAssertion(() => {
this.render('{{hello}}');
}, expectedMessage);
this.render('{{hello}}');
this.assertText('456');
}

'@test custom helpers gives helpful assertion when reading then mutating a tracked value within value'() {
'@test custom helpers allows get/set/get (lazy initialization) within value'() {
this.registerCustomHelper(
'hello',
class extends TestHelper {
@tracked foo = 123;
@tracked foo;

value() {
// first read the tracked property
this.foo;

// then attempt to update the tracked property
this.foo = 456;
// get/set/get pattern (lazy initialization)
let val = this.foo;
if (val === undefined) {
this.foo = 456;
}
return this.foo;
}
}
);

let expectedMessage = backtrackingMessageFor('foo', '.*', {
renderTree: ['\\(result of a `TEST_HELPER` helper\\)'],
});

expectAssertion(() => {
this.render('{{hello}}');
}, expectedMessage);
this.render('{{hello}}');
this.assertText('456');
}
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,24 @@ moduleFor(
);
}

['@test gives helpful assertion when a tracked property is mutated after access in with an autotracking transaction']() {
['@test allows get/set/get (lazy initialization) within the same tracking frame'](assert) {
class MyObject {
@tracked value;
toString() {
return 'MyObject';
}
}

let obj = new MyObject();

track(() => {
obj.value;
obj.value = 123;
assert.strictEqual(obj.value, 123, 'get after set returns the updated value');
});
}

['@test gives helpful assertion when a tracked property is mutated after access without re-read']() {
class MyObject {
@tracked value;
toString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,19 +352,19 @@ class HelperManagerTest extends RenderTest {
this.assertHTML('hello');
}

@test({ skip: !DEBUG }) 'debug name is used for backtracking message'(assert: Assert) {
@test({ skip: !DEBUG }) 'allows get/set within the same tracking frame (lazy initialization)'() {
class Hello extends TestHelper {
@tracked foo = 123;

value() {
consume(this.foo);
this.foo = 456;
return this.foo;
}
}

assert.throws(() => {
this.renderComponent(defineComponent({ hello: Hello }, '{{hello}}'));
}, /You attempted to update `foo` on/u);
this.renderComponent(defineComponent({ hello: Hello }, '{{hello}}'));
this.assertHTML('456');
}

@test({ skip: !DEBUG }) 'asserts against using both `hasValue` and `hasScheduledEffect`'(
Expand Down Expand Up @@ -451,53 +451,46 @@ class HelperManagerTest extends RenderTest {
}

@test({ skip: !DEBUG })
'custom helpers gives helpful assertion when reading then mutating a tracked value within constructor'(
assert: Assert
) {
'custom helpers allows get/set/get (lazy initialization) within constructor'() {
class Hello extends TestHelper {
@tracked foo = 123;
@tracked foo: number | undefined;

constructor(owner: Owner, args: Arguments) {
super(owner, args);

// first read the tracked property

consume(this.foo);

// then attempt to update the tracked property
this.foo = 456;
// get/set/get pattern (lazy initialization)
let val = this.foo;
if (val === undefined) {
this.foo = 456;
}
}

value() {
return this.foo;
}
}

assert.throws(() => {
this.renderComponent(defineComponent({ hello: Hello }, '{{hello}}'));
}, /You attempted to update `foo` on /u);
this.renderComponent(defineComponent({ hello: Hello }, '{{hello}}'));
this.assertHTML('456');
}

@test({ skip: !DEBUG })
'custom helpers gives helpful assertion when reading then mutating a tracked value within value'(
assert: Assert
) {
'custom helpers allows get/set/get (lazy initialization) within value'() {
class Hello extends TestHelper {
@tracked foo = 123;
@tracked foo: number | undefined;

value() {
// first read the tracked property

consume(this.foo);

// then attempt to update the tracked property
this.foo = 456;
// get/set/get pattern (lazy initialization)
let val = this.foo;
if (val === undefined) {
this.foo = 456;
}
return this.foo;
}
}

assert.throws(() => {
this.renderComponent(defineComponent({ hello: Hello }, '{{hello}}'));
}, /You attempted to update `foo` on /u);
this.renderComponent(defineComponent({ hello: Hello }, '{{hello}}'));
this.assertHTML('456');
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,21 +217,19 @@ abstract class ModifierManagerTest extends RenderTest {
}

@test({ skip: !DEBUG })
'provides a helpful deprecation when mutating a tracked value that was consumed already within constructor'(
assert: Assert
) {
'allows get/set (lazy initialization) within modifier constructor'() {
class Foo extends CustomModifier {
@tracked foo = 123;
@tracked foo: number | undefined;

constructor(owner: Owner, args: Arguments) {
super(owner, args);

// first read the tracked property

consume(this.foo);

// then attempt to update the tracked property
this.foo = 456;
// get/set/get pattern (lazy initialization)
let val = this.foo;
if (val === undefined) {
this.foo = 456;
val = this.foo;
}
}

override didInsertElement() {}
Expand All @@ -243,9 +241,8 @@ abstract class ModifierManagerTest extends RenderTest {

let Main = defineComponent({ foo }, '<h1 {{foo}}>hello world</h1>');

assert.throws(() => {
this.renderComponent(Main);
}, /You attempted to update `foo` on `.*`, but it had already been used previously in the same computation/u);
this.renderComponent(Main);
this.assertHTML('<h1>hello world</h1>');
}

@test
Expand Down
Loading
Loading