Skip to content

Commit 8278d81

Browse files
committed
active expressions expose new Promise gotDisposed
SQUASHED: AUTO-COMMIT-src-client-reactive-active-expression-active-expression.js,AUTO-COMMIT-src-client-reactive-test-active-expression-utility-methods.spec.js,
1 parent ce4b96b commit 8278d81

File tree

2 files changed

+151
-56
lines changed

2 files changed

+151
-56
lines changed

src/client/reactive/active-expression/active-expression.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,20 @@ export class BaseActiveExpression {
427427
return this;
428428
}
429429

430+
gotDisposed() {
431+
if (this._disposedPromise) {
432+
return this._disposedPromise;
433+
}
434+
435+
return this._disposedPromise = new Promise(resolve => {
436+
if (this.isDisposed()) {
437+
resolve();
438+
} else {
439+
this.on('dispose', resolve);
440+
}
441+
});
442+
}
443+
430444
/*MD ## Reflection Information MD*/
431445
meta(annotation) {
432446
if(annotation) {
@@ -472,6 +486,40 @@ export class BaseActiveExpression {
472486
then(...args) {
473487
return this.nextValue().then(...args);
474488
}
489+
490+
values() {
491+
492+
const disposed = new Promise(resolve => {
493+
if (this.isDisposed()) {
494+
resolve()
495+
} else {
496+
this.on('')
497+
}
498+
});
499+
500+
Promise.race([
501+
this.nextValue().then(v => ({ value: v, done: false })),
502+
])
503+
504+
function newResult(v, done) {
505+
506+
}
507+
508+
return {
509+
[Symbol.asyncIterator]() {
510+
return {
511+
i: 0,
512+
next() {
513+
if (this.i < 3) {
514+
return Promise.resolve({ value: ++this.i, done: false });
515+
}
516+
517+
return Promise.resolve({ done: true });
518+
}
519+
};
520+
}
521+
};
522+
}
475523
}
476524

477525
export function aexpr(func, ...args) {

src/client/reactive/test/active-expression/utility-methods.spec.js

Lines changed: 103 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,86 +6,133 @@ import sinonChai from 'src/external/sinon-chai.js';
66
chai.use(sinonChai);
77

88
describe('Iterators and Utility Methods for Active Expressions', () => {
9-
it("chainable", () => {
10-
let obj = {a: 2},
11-
spy = sinon.spy();
129

13-
aexpr(() => obj.a > 5)
14-
.onBecomeFalse(spy)
15-
.onBecomeTrue(spy)
16-
.onBecomeFalse(spy)
17-
.onBecomeTrue(spy);
10+
describe('.gotDisposed', () => {
1811

19-
expect(spy).to.be.calledTwice;
20-
});
12+
it("aexprs define .gotDisposed", () => {
13+
expect(aexpr(() => {})).to.respondTo('gotDisposed');
14+
});
15+
16+
it("caches its Promise", () => {
17+
const ae = aexpr(() => {});
18+
expect(ae.gotDisposed()).to.equal(ae.gotDisposed());
19+
});
2120

22-
it("flank up", () => {
23-
let obj = {a: 2},
24-
spy = sinon.spy();
21+
it("Promise resolved if already disposed", async () => {
22+
const ae = aexpr(() => {});
23+
ae.dispose();
24+
const prom = ae.gotDisposed();
2525

26-
let axp = aexpr(() => obj.a > 5);
27-
axp.onBecomeTrue(spy);
28-
expect(spy).not.to.be.called;
26+
// promise resolved
27+
await prom;
28+
});
2929

30-
obj.a = 10;
31-
expect(spy).to.be.calledOnce;
30+
it("Promise resolves later when ae gets disposed", async () => {
31+
const ae = aexpr(() => {});
32+
const prom = ae.gotDisposed();
3233

33-
obj.a = 0;
34-
expect(spy).to.be.calledOnce;
34+
lively.sleep(30).then(() => ae.dispose());
35+
36+
await lively.sleep(15);
37+
expect(ae.isDisposed()).to.be.false;
38+
39+
// promise resolved
40+
await prom;
41+
});
3542

36-
obj.a = 10;
37-
expect(spy).to.be.calledTwice;
3843
});
3944

40-
it("immediately triggers onBecomeTrue", () => {
41-
let obj = {a: 7},
42-
spy = sinon.spy();
45+
describe('.values', () => {
4346

44-
let axp = aexpr(() => obj.a > 5);
45-
axp.onBecomeTrue(spy);
46-
expect(spy).to.be.calledOnce;
47+
it("aexprs define .values", () => {
48+
expect(aexpr(() => {})).to.respondTo('values');
49+
});
4750

48-
obj.a = 0;
49-
expect(spy).to.be.calledOnce;
51+
it(".values", async () => {
52+
let val = 0,
53+
spy = sinon.spy();
5054

51-
obj.a = 10;
52-
expect(spy).to.be.calledTwice;
53-
});
55+
const ae = aexpr(() => val);
5456

55-
it("flank down", () => {
56-
let obj = {a: 2},
57-
spy = sinon.spy();
57+
(async () => {
58+
lively.sleep(10);
59+
val++;
60+
lively.sleep(10);
61+
val++;
62+
lively.sleep(10);
63+
val++;
5864

59-
let axp = aexpr(() => obj.a > 0);
60-
axp.onBecomeFalse(spy);
61-
expect(spy).not.to.be.called;
65+
lively.sleep(10);
66+
ae.dispose();
6267

63-
obj.a = -2;
64-
expect(spy).to.be.calledOnce;
68+
lively.sleep(10);
69+
val++;
70+
})();
71+
72+
let j = 0;
73+
for await (let v of ae.values()) {
74+
j++;
75+
expect(v).to.equal(j);
76+
}
77+
expect(j).to.equal(3);
78+
});
6579

66-
obj.a = 2;
67-
expect(spy).to.be.calledOnce;
80+
describe('understanding generators', () => {
6881

69-
obj.a = -2;
70-
expect(spy).to.be.calledTwice;
71-
});
82+
it("plain generators", () => {
83+
function* gen() {
84+
yield 1;
85+
yield 2;
86+
yield 3;
87+
}
88+
89+
const iter = gen()
90+
91+
expect(iter.next().value).to.equal(1);
92+
expect(iter.next().value).to.equal(2);
93+
expect(iter.next().value).to.equal(3);
94+
expect(iter.next().done).to.equal(true);
95+
});
96+
97+
it("generators and for loops", () => {
98+
function* gen() {
99+
yield 1;
100+
yield 2;
101+
yield 3;
102+
}
103+
104+
let j = 0;
105+
for (let i of gen()) {
106+
j++;
107+
expect(i).to.equal(j);
108+
}
109+
expect(j).to.equal(3);
110+
});
72111

73-
it("immediately triggers onBecomeFalse", () => {
74-
let obj = {a: -2},
75-
spy = sinon.spy();
112+
it("async generators and for await loops", async () => {
113+
async function* gen() {
114+
lively.sleep(1);
115+
yield 1;
116+
lively.sleep(1);
117+
yield Promise.resolve(2);
118+
lively.sleep(1);
119+
yield 3;
120+
}
76121

77-
let axp = aexpr(() => obj.a > 0);
78-
axp.onBecomeFalse(spy);
79-
expect(spy).to.be.calledOnce;
122+
let j = 0;
123+
for await (let i of gen()) {
124+
j++;
125+
expect(i).to.equal(j);
126+
}
127+
expect(j).to.equal(3);
128+
});
80129

81-
obj.a = 2;
82-
expect(spy).to.be.calledOnce;
130+
});
83131

84-
obj.a = -2;
85-
expect(spy).to.be.calledTwice;
86132
});
87133

88134
describe('nextValue', () => {
135+
89136
it("aexprs define nextValue", () => {
90137
expect(aexpr(() => {})).to.respondTo('nextValue');
91138
});

0 commit comments

Comments
 (0)