Skip to content

Commit deefc2e

Browse files
author
Chris Garrett
authored
[BUGFIX release] Ensure tag updates are buffered (#18698)
[BUGFIX release] Ensure tag updates are buffered
2 parents 3196d7a + 2a54362 commit deefc2e

File tree

3 files changed

+284
-101
lines changed

3 files changed

+284
-101
lines changed

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,14 @@
7474
},
7575
"devDependencies": {
7676
"@babel/preset-env": "^7.6.0",
77-
"@glimmer/compiler": "0.38.5-alpha.3",
77+
"@glimmer/compiler": "0.38.5-alpha.4",
7878
"@glimmer/env": "^0.1.7",
79-
"@glimmer/interfaces": "0.38.5-alpha.3",
80-
"@glimmer/node": "0.38.5-alpha.3",
81-
"@glimmer/opcode-compiler": "0.38.5-alpha.3",
82-
"@glimmer/program": "0.38.5-alpha.3",
83-
"@glimmer/reference": "0.38.5-alpha.3",
84-
"@glimmer/runtime": "0.38.5-alpha.3",
79+
"@glimmer/interfaces": "0.38.5-alpha.4",
80+
"@glimmer/node": "0.38.5-alpha.4",
81+
"@glimmer/opcode-compiler": "0.38.5-alpha.4",
82+
"@glimmer/program": "0.38.5-alpha.4",
83+
"@glimmer/reference": "0.38.5-alpha.4",
84+
"@glimmer/runtime": "0.38.5-alpha.4",
8585
"@types/qunit": "^2.5.4",
8686
"@types/rsvp": "^4.0.3",
8787
"@typescript-eslint/parser": "^2.7.0",

packages/@ember/-internals/metal/tests/computed_test.js

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,3 +1042,186 @@ moduleFor(
10421042
}
10431043
}
10441044
);
1045+
1046+
class LazyObject {
1047+
value = 123;
1048+
1049+
@computed('_value')
1050+
get value() {
1051+
return get(this, '_value');
1052+
}
1053+
1054+
set value(value) {
1055+
set(this, '_value', value);
1056+
}
1057+
1058+
static create() {
1059+
let obj = new LazyObject();
1060+
1061+
// ensure a tag exists for the value computed
1062+
get(obj, 'value');
1063+
1064+
return obj;
1065+
}
1066+
}
1067+
1068+
moduleFor(
1069+
'computed - lazy dependencies',
1070+
class extends AbstractTestCase {
1071+
'@test computed properties with lazy dependencies work as expected'(assert) {
1072+
let calledCount = 0;
1073+
let lazyObject = LazyObject.create();
1074+
1075+
class ObjectWithLazyDep {
1076+
@computed('lazyObject.value')
1077+
get someProp() {
1078+
return ++calledCount;
1079+
}
1080+
1081+
@computed('otherProp')
1082+
get lazyObject() {
1083+
return lazyObject;
1084+
}
1085+
}
1086+
1087+
let obj = new ObjectWithLazyDep();
1088+
1089+
// Get someProp and setup the lazy dependency
1090+
assert.equal(obj.someProp, 1, 'called the first time');
1091+
assert.equal(obj.someProp, 1, 'returned cached value the second time');
1092+
1093+
// Finish the lazy dependency
1094+
assert.equal(obj.lazyObject.value, 123, 'lazyObject returns expected value');
1095+
assert.equal(
1096+
obj.someProp,
1097+
1,
1098+
'someProp was not dirtied by propB being calculated for the first time'
1099+
);
1100+
1101+
set(lazyObject, 'value', 456);
1102+
assert.equal(obj.someProp, 2, 'someProp dirtied by lazyObject.value changing');
1103+
1104+
set(lazyObject, 'value', 789);
1105+
assert.equal(
1106+
obj.someProp,
1107+
3,
1108+
'someProp still dirtied by otherProp when lazyObject.value is dirty'
1109+
);
1110+
}
1111+
1112+
'@test computed properties with lazy dependencies do not dirty until dependencies have been read at least once'(
1113+
assert
1114+
) {
1115+
let calledCount = 0;
1116+
let lazyObject = LazyObject.create();
1117+
1118+
class ObjectWithLazyDep {
1119+
@computed('lazyObject.value')
1120+
get someProp() {
1121+
return ++calledCount;
1122+
}
1123+
1124+
@computed('otherProp')
1125+
get lazyObject() {
1126+
return lazyObject;
1127+
}
1128+
}
1129+
1130+
let obj = new ObjectWithLazyDep();
1131+
1132+
assert.equal(obj.someProp, 1, 'called the first time');
1133+
assert.equal(obj.someProp, 1, 'returned cached value the second time');
1134+
1135+
// dirty the object value before the dependency has been finished
1136+
set(lazyObject, 'value', 456);
1137+
1138+
assert.equal(obj.lazyObject.value, 456, 'propB returns expected value');
1139+
assert.equal(
1140+
obj.someProp,
1141+
1,
1142+
'someProp was not dirtied by propB being dirtied before it has been calculated'
1143+
);
1144+
}
1145+
1146+
'@test computed properties with lazy dependencies work correctly if lazy dependency is more recent'(
1147+
assert
1148+
) {
1149+
let calledCount = 0;
1150+
let lazyObject = LazyObject.create();
1151+
1152+
class ObjectWithLazyDep {
1153+
@computed('lazyObject.value')
1154+
get someProp() {
1155+
return ++calledCount;
1156+
}
1157+
1158+
@computed('otherProp')
1159+
get lazyObject() {
1160+
return lazyObject;
1161+
}
1162+
}
1163+
1164+
let obj = new ObjectWithLazyDep();
1165+
1166+
set(lazyObject, 'value', 456);
1167+
1168+
assert.equal(obj.someProp, 1, 'called the first time');
1169+
assert.equal(obj.someProp, 1, 'returned cached value the second time');
1170+
1171+
assert.equal(obj.lazyObject.value, 456, 'lazyObject returns expected value');
1172+
1173+
assert.equal(
1174+
obj.someProp,
1175+
1,
1176+
'someProp was not dirtied by lazyObject being dirtied before it has been calculated'
1177+
);
1178+
}
1179+
}
1180+
);
1181+
1182+
moduleFor(
1183+
'computed - observer interop',
1184+
class extends AbstractTestCase {
1185+
async '@test observers that do not consume computed properties still work'(assert) {
1186+
assert.expect(2);
1187+
1188+
class Foo {
1189+
otherProp = 123;
1190+
1191+
@computed('otherProp')
1192+
get someProp() {
1193+
return this.otherProp;
1194+
}
1195+
}
1196+
1197+
let foo = new Foo();
1198+
1199+
addObserver(
1200+
foo,
1201+
'otherProp',
1202+
foo,
1203+
() => assert.ok(true, 'otherProp observer called when it was changed'),
1204+
false
1205+
);
1206+
1207+
addObserver(
1208+
foo,
1209+
'someProp',
1210+
foo,
1211+
() => assert.ok(false, 'someProp observer called when it was not changed'),
1212+
false
1213+
);
1214+
1215+
set(foo, 'otherProp', 456);
1216+
1217+
await runLoopSettled();
1218+
1219+
assert.equal(get(foo, 'someProp'), 456, '');
1220+
1221+
addObserver(foo, 'anotherProp', foo, () => {}, false);
1222+
set(foo, 'anotherProp', 123);
1223+
1224+
await runLoopSettled();
1225+
}
1226+
}
1227+
);

0 commit comments

Comments
 (0)