Best JavaScript code snippet using playwright-internal
rebase.test.js
Source:rebase.test.js
...39 called++40 }))41 diff(temp, null, [renderer, tracker]);42 expect(called).to.equal(1);43 expect(renderer.tree).to.eql(renderer.renderStatic(copy(temp)));44 expect(events).to.eql([{wA: 0}, {mWA: 0}])45 })46 it("should not mount nodes during cleanup", function(){47 let called = 0;48 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);49 const temp = h(0, hooks("cleanup", f => {50 const res = diff(m(1), null, f);51 expect(res).to.be.false;52 called++53 }))54 const f = diff(temp, null, [renderer, tracker]);55 diff(null, f);56 expect(called).to.equal(1);57 expect(renderer.tree).to.be.null;58 expect(events).to.eql([{wA: 0}, {mWA: 0}, {mWP: 0}])59 })60 it("should not mount nodes during add mutation event", function(){61 let called = 0;62 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);63 diff(h(0), null, [renderer, tracker, {add: f => {64 const res = diff(h(1), null, f);65 expect(res).to.be.false;66 called++67 }}])68 expect(called).to.equal(1);69 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));70 expect(events).to.eql([{wA: 0}, {mWA: 0}])71 })72 it("should not mount nodes during remove mutation event", function(){73 let called = 0;74 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);75 const f = diff(h(0, null, h(1)), null, [renderer, tracker, {remove: (f, p, s, t) => {76 if (t.data.id === 1){77 const res = diff(h(2), null, f);78 expect(res).to.be.false;79 called++80 }81 }}])82 diff(h(0), f);83 expect(called).to.equal(1);84 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));85 expect(events).to.eql([86 {wA: 0}, {wA: 1}, {mWA: 0}, {mWA: 1}, {wU: 0}, {mWP: 1}, {mWR: 0}87 ])88 })89 it("should not mount nodes during temp mutation event", function(){90 let called = 0;91 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);92 const f = diff(h(0), null, [renderer, tracker, {temp: f => {93 const res = diff(h(1), null, f);94 expect(res).to.be.false;95 called++96 }}])97 diff(h(0), f);98 expect(called).to.equal(1);99 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));100 expect(events).to.eql([101 {wA: 0}, {mWA: 0}, {wU: 0}, {mWR: 0},102 ])103 })104 it("should not mount nodes during move mutation event", function(){105 let called = 0;106 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);107 const f = diff(h(0, null, [k(1), k(2)]), null, [renderer, tracker, {move: f => {108 if (f.temp.data.id === 2){109 const res = diff(h(3), null, f);110 expect(res).to.be.false;111 called++112 }113 }}])114 diff(h(0, null, [k(2), k(1)]), f);115 expect(called).to.equal(1);116 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [k(2), k(1)])));117 expect(events).to.eql([118 {wA: 0}, {wA: 1}, {wA: 2}, {mWA: 0}, {mWA: 1}, {mWA: 2},119 {wU: 0}, {wU: 1}, {wU: 2}, {mWR: 0}, {mWR: 2}, {mWM: 2}, {mWR: 1}120 ])121 })122 allHooks.forEach(hook => {123 it(`should immediately return the root's ref during ${hook}`, function(){124 const managedTemp = m(1)125 let called = 0;126 const temp = h(0, hooks(hook, f => {127 const managedNode = diff(managedTemp, null, f);128 expect(managedNode).to.be.an.instanceOf(Frame);129 expect(managedNode.temp).to.equal(managedTemp);130 called++;131 }))132 const f = diff(temp);133 if (has(updateHooks, hook)) diff(copy(temp), f);134 expect(called).to.equal(1);135 })136 it(`should properly mount the node during ${hook}`, function(){137 const managedTemp = m(1)138 const renderer = new LCRSRenderer139 const temp = h(0, hooks(hook, f => {140 diff(managedTemp, null, f)141 }));142 const f = diff(temp, null, renderer);143 if (has(updateHooks, hook)) diff(copy(temp), f);144 expect(renderer.tree).to.eql(renderer.renderStatic(inject(copy(temp), managedTemp)));145 })146 it(`should mount multiple sibling nodes in reverse call order by default during ${hook}`, function(){147 const managedChildren = [m(1), m(2), m(3)], reverse = [...managedChildren].reverse();148 const renderer = new LCRSRenderer149 const temp = h(0, hooks(hook, f => {150 for (let m of managedChildren) diff(m, null, f);151 }));152 const f = diff(temp, null, renderer);153 if (has(updateHooks, hook)) diff(copy(temp), f);154 expect(renderer.tree).to.eql(renderer.renderStatic(inject(copy(temp), reverse)));155 })156 it(`should otherwise mount multiple sibling nodes in a specified order during ${hook}`, function(){157 const managedChildren = [m(1), m(2), m(3)];158 const renderer = new LCRSRenderer159 const temp = h(0, hooks(hook, f => {160 const first = diff(managedChildren[0], null, f); // first is first child161 const second = diff(managedChildren[1], null, f, first); // second after first162 diff(managedChildren[2], null, f, second); // third after second163 }));164 const f = diff(temp, null, renderer);165 if (has(updateHooks, hook)) diff(copy(temp), f);166 expect(renderer.tree).to.eql(renderer.renderStatic(inject(copy(temp), managedChildren)));167 })168 })169 const mount = f => {170 diff(h(3, hooks("willAdd", f => {})), null, f);171 diff(h(4, hooks("willAdd", f => {})), null, f);172 }173 it("should defer rendering new nodes in reverse order until all updates have run during willUpdate", function(){174 const events = [], tracker = new Tracker(events);175 const temp = h(0, null, [176 h(1),177 h(2, hooks("willUpdate", f => mount(f)))178 ])179 const f = diff(temp, null, tracker);180 events.length = 0; // we don't care about initial mount181 diff(copy(temp), f);182 expect(events).to.eql([183 {wU: 0}, {wU: 1}, {wU: 2}, {wA: 4}, {wA: 3}, 184 {mWR: 0}, {mWR: 1}, {mWR: 2}, {mWA: 4}, {mWA: 3}185 ])186 })187 it("should defer rendering new nodes in reverse order until after flush during didUpdate", function(){188 const events = [], tracker = new Tracker(events);189 const temp = h(0, null, [190 h(1),191 h(2, hooks("didUpdate", f => mount(f)))192 ])193 const f = diff(temp, null, tracker);194 events.length = 0; // we don't care about initial mount195 diff(copy(temp), f);196 expect(events).to.eql([197 {wU: 0}, {wU: 1}, {wU: 2}, {mWR: 0}, {mWR: 1}, {mWR: 2}, {dU: 2},198 {wA: 4}, {wA: 3}, {mWA: 4}, {mWA: 3}199 ])200 })201 it("should immediately add new nodes in reverse order during willAdd", function(){202 const events = [], tracker = new Tracker(events);203 const temp = h(0, null, [204 h(1, hooks("willAdd", f => mount(f))),205 h(2)206 ])207 const f = diff(temp, null, tracker);208 expect(events).to.eql([209 {wA: 0}, {wA: 1}, {wA: 4}, {wA: 3}, {wA: 2}, 210 {mWA: 0}, {mWA: 1}, {mWA: 4}, {mWA: 3}, {mWA: 2}211 ])212 })213 it("should defer adding new nodes in reverse order after flush during didAdd", function(){214 const events = [], tracker = new Tracker(events);215 const temp = h(0, null, [216 h(1, hooks("didAdd", f => mount(f))),217 h(2)218 ])219 const f = diff(temp, null, tracker);220 expect(events).to.eql([221 {wA: 0}, {wA: 1}, {wA: 2}, {mWA: 0}, {mWA: 1}, {mWA: 2}, {dA: 1},222 {wA: 4}, {wA: 3}, {mWA: 4}, {mWA: 3},223 ])224 })225 })226 describe("free (unmanaged) nodes", function(){227 it("should not mount nodes during a constructor", function(){228 let called = 0;229 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);230 const temp = h(0, hooks("ctor", f => {231 const res = diff(m(1), null, [renderer, tracker]);232 expect(res).to.be.false;233 called++234 }))235 diff(temp);236 expect(called).to.equal(1);237 expect(renderer.tree).to.be.null;238 expect(events).to.be.empty239 })240 it("should not mount nodes during cleanup", function(){241 let called = 0;242 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);243 const temp = h(0, hooks("cleanup", f => {244 const res = diff(m(1), null, [renderer, tracker]);245 expect(res).to.be.false;246 called++247 }))248 const f = diff(temp);249 diff(null, f);250 expect(called).to.equal(1);251 expect(renderer.tree).to.be.null;252 expect(events).to.be.empty253 })254 it("should not mount nodes during add mutation event", function(){255 let called = 0;256 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);257 diff(h(0), null, {add: f => {258 const res = diff(h(1), null, [renderer, tracker]);259 expect(res).to.be.false;260 called++261 }})262 expect(called).to.equal(1);263 expect(renderer.tree).to.be.null264 expect(events).to.be.empty;265 })266 it("should not mount nodes during remove mutation event", function(){267 let called = 0;268 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);269 const f = diff(h(0, null, h(1)), null, {remove: (f, p, s, t) => {270 if (t.data.id === 1){271 const res = diff(h(2), null, [renderer, tracker]);272 expect(res).to.be.false;273 called++274 }275 }})276 diff(h(0), f);277 expect(called).to.equal(1);278 expect(renderer.tree).to.be.null279 expect(events).to.be.empty280 })281 it("should not mount nodes during temp mutation event", function(){282 let called = 0;283 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);284 const f = diff(h(0), null, {temp: f => {285 const res = diff(h(1), null, [renderer, tracker]);286 expect(res).to.be.false;287 called++288 }})289 diff(h(0), f);290 expect(called).to.equal(1);291 expect(renderer.tree).to.be.null292 expect(events).to.be.empty;293 })294 it("should not mount nodes during move mutation event", function(){295 let called = 0;296 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);297 const f = diff(h(0, null, [k(1), k(2)]), null, {move: f => {298 if (f.temp.data.id === 2){299 const res = diff(h(3), null, [renderer, tracker]);300 expect(res).to.be.false;301 called++302 }303 }})304 diff(h(0, null, [k(2), k(1)]), f);305 expect(called).to.equal(1);306 expect(renderer.tree).to.be.null;307 expect(events).to.be.empty;308 })309 allHooks.forEach(hook => {310 it(`should immediately return the root's ref during ${hook}`, function(){311 const managedTemp = m(1)312 let called = 0;313 const temp = h(0, hooks(hook, f => {314 const managedNode = diff(managedTemp);315 expect(managedNode).to.be.an.instanceOf(Frame);316 expect(managedNode.temp).to.equal(managedTemp);317 called++;318 }))319 const f = diff(temp);320 if (has(updateHooks, hook)) diff(copy(temp), f);321 expect(called).to.equal(1);322 })323 it(`should properly mount the node during ${hook}`, function(){324 const managedTemp = m(1)325 const renderer = new LCRSRenderer326 const temp = h(0, hooks(hook, f => {327 diff(managedTemp)328 }));329 const f = diff(temp, null, renderer);330 if (has(updateHooks, hook)) diff(copy(temp), f);331 expect(renderer.tree).to.eql(renderer.renderStatic(temp));332 })333 it(`should mount multiple nodes in reverse call order during ${hook}`, function(){334 const managedIds = [1, 2, 3];335 let order = [];336 const temp = h(0, hooks(hook, f => {337 for (let id of managedIds) diff(h(id, hooks("willAdd", f => {338 order.push(id);339 })));340 }));341 const f = diff(temp);342 if (has(updateHooks, hook)) diff(copy(temp), f);343 expect(order).to.eql([3,2,1])344 })345 })346 const mount = tracker => {347 diff(h(3, hooks("willAdd", f => {})), null, tracker);348 diff(h(4, hooks("willAdd", f => {})), null, tracker);349 }350 it("should defer rendering new nodes in reverse order until all updates have run during willUpdate", function(){351 const events = [], tracker = new Tracker(events);352 const temp = h(0, null, [353 h(1),354 h(2, hooks("willUpdate", f => mount(tracker)))355 ])356 const f = diff(temp, null, tracker);357 events.length = 0; // we don't care about initial mount358 diff(copy(temp), f);359 expect(events).to.eql([360 {wU: 0}, {wU: 1}, {wU: 2}, {wA: 4}, {wA: 3}, 361 {mWR: 0}, {mWR: 1}, {mWR: 2}, {mWA: 3}, {mWA: 4}362 ])363 })364 it("should defer rendering new nodes in reverse order until after flush during didUpdate", function(){365 const events = [], tracker = new Tracker(events);366 const temp = h(0, null, [367 h(1),368 h(2, hooks("didUpdate", f => mount(tracker)))369 ])370 const f = diff(temp, null, tracker);371 events.length = 0; // we don't care about initial mount372 diff(copy(temp), f);373 expect(events).to.eql([374 {wU: 0}, {wU: 1}, {wU: 2}, {mWR: 0}, {mWR: 1}, {mWR: 2}, {dU: 2},375 {wA: 4}, {wA: 3}, {mWA: 3}, {mWA: 4}376 ])377 })378 it("should immediately render new nodes in reverse order during willAdd", function(){379 const events = [], tracker = new Tracker(events);380 const temp = h(0, null, [381 h(1, hooks("willAdd", f => mount(tracker))),382 h(2)383 ])384 const f = diff(temp, null, tracker);385 expect(events).to.eql([386 {wA: 0}, {wA: 1}, {wA: 4}, {wA: 3}, {wA: 2}, 387 {mWA: 0}, {mWA: 1}, {mWA: 2}, {mWA: 3}, {mWA: 4}388 ])389 })390 it("should defer adding new nodes in reverse order after flush during didAdd", function(){391 const events = [], tracker = new Tracker(events);392 const temp = h(0, null, [393 h(1, hooks("didAdd", f => mount(tracker))),394 h(2)395 ])396 const f = diff(temp, null, tracker);397 expect(events).to.eql([398 {wA: 0}, {wA: 1}, {wA: 2}, {mWA: 0}, {mWA: 1}, {mWA: 2}, {dA: 1},399 {wA: 4}, {wA: 3}, {mWA: 3}, {mWA: 4},400 ])401 })402 })403 })404 describe("unmounting", function(){405 describe("virtual (managed) nodes", function(){406 it("should not unmount nodes during a constructor", function(){407 let called = 0;408 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);409 const r = diff(h(0, null), null, [renderer, tracker]);410 const managedR = diff(h(1), null, r);411 diff(h(2, hooks("ctor", f => {412 const res = diff(null, managedR);413 expect(res).to.be.false;414 called++415 })))416 expect(called).to.equal(1);417 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));418 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])419 })420 it("should not unmount nodes during cleanup", function(){421 let called = 0;422 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);423 const r = diff(h(0, null), null, [renderer, tracker]);424 const managedR = diff(h(1), null, r);425 const f = diff(h(2, hooks("cleanup", f => {426 const res = diff(null, managedR);427 expect(res).to.be.false;428 called++429 })))430 diff(null, f);431 expect(called).to.equal(1);432 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));433 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])434 })435 it("should not unmount nodes during add mutation event", function(){436 let called = 0;437 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);438 const r = diff(h(0, null), null, [renderer, tracker]);439 const m = diff(h(1), null, r);440 diff(h(2), null, {add: f => {441 const res = diff(null, m);442 expect(res).to.be.false;443 called++444 }})445 expect(called).to.equal(1);446 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));447 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])448 })449 it("should not unmount nodes during remove mutation event", function(){450 let called = 0;451 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);452 const r = diff(h(0, null), null, [renderer, tracker]);453 const m = diff(h(1), null, r);454 const f = diff(h(2), null, {remove: f => {455 const res = diff(null, m);456 expect(res).to.be.false;457 called++458 }})459 diff(null, f);460 expect(called).to.equal(1);461 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));462 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])463 })464 it("should not unmount nodes during temp mutation event", function(){465 let called = 0;466 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);467 const r = diff(h(0, null), null, [renderer, tracker]);468 const m = diff(h(1), null, r);469 const f = diff(h(2), null, {temp: f => {470 const res = diff(null, m);471 expect(res).to.be.false;472 called++473 }})474 diff(h(2), f)475 expect(called).to.equal(1);476 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));477 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])478 })479 it("should not unmount nodes during move mutation event", function(){480 let called = 0;481 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);482 const r = diff(h(0, null), null, [renderer, tracker]);483 const m = diff(h(1), null, r);484 const f = diff(h(2, null, [k(3), k(4)]), null, {move: f => {485 if (f.temp.data.id === 4){486 const res = diff(null, m);487 expect(res).to.be.false;488 called++489 }490 }})491 diff(h(2, null, [k(4), k(3)]), f);492 expect(called).to.equal(1);493 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));494 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])495 })496 it("should unmount nodes created during willAdd in the next cycle", function(){497 const managedTemp = h(1);498 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);499 let called = 0;500 const hooks = {501 willAdd: f => {f.managed = diff(managedTemp, null, f)},502 willUpdate: f => {503 expect(f.managed).to.be.an.instanceOf(Frame);504 expect(f.managed.temp).to.equal(managedTemp);505 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, hooks, h(1))))506 const res = diff(null, f.managed)507 expect(res).to.be.true;508 called++;509 }510 }511 const r = diff(h(0, hooks), null, [renderer, tracker]);512 diff(h(0, hooks), r);513 expect(called).to.equal(1);514 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, hooks)))515 expect(events).to.eql([ 516 { wA: 0 }, { wA: 1 }, { mWA: 0 }, { mWA: 1 }, { wU: 0 }, { mWP: 1 }, { mWR: 0 }517 ])518 })519 it("should unmount nodes created during willAdd in didAdd", function(){520 const managedTemp = h(1);521 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);522 let called = 0;523 const hooks = {524 willAdd: f => {f.managed = diff(managedTemp, null, f)},525 didAdd: f => {526 expect(f.managed).to.be.an.instanceOf(Frame);527 expect(f.managed.temp).to.equal(managedTemp);528 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, hooks, h(1))))529 const res = diff(null, f.managed)530 expect(res).to.be.true;531 called++;532 }533 }534 diff(h(0, hooks), null, [renderer, tracker]);535 expect(called).to.equal(1);536 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, hooks)))537 expect(events).to.eql([ 538 { wA: 0 }, { wA: 1 }, { mWA: 0 }, { mWA: 1 }, {dA: 0}, { mWP: 1 }539 ])540 })541 it("should unmount an external node during willAdd", function(){542 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);543 const r1 = diff(h(0, null), null, [renderer, tracker]);544 const managedRoot = diff(h(1), null, r1);545 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))))546 let called = 0;547 const temp = h(2, hooks("willAdd", f => {548 const res = diff(null, managedRoot);549 expect(res).to.be.true;550 called++;551 }));552 diff(temp, null, tracker);553 expect(called).to.equal(1);554 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))555 expect(events).to.eql([556 { wA: 0 }, { mWA: 0 }, {wA: 1}, { mWA: 1 }, {wA: 2}, { mWP: 1 }, {mWA: 2}557 ])558 })559 it("should unmount an external node during didAdd", function(){560 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);561 const r1 = diff(h(0, null), null, [renderer, tracker]);562 const managedRoot = diff(h(1), null, r1);563 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))))564 let called = 0;565 const temp = h(2, hooks("didAdd", f => {566 const res = diff(null, managedRoot);567 expect(res).to.be.true;568 called++;569 }));570 diff(temp, null, tracker);571 expect(called).to.equal(1);572 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))573 expect(events).to.eql([574 { wA: 0 }, { mWA: 0 }, {wA: 1}, { mWA: 1 }, {wA: 2}, {mWA: 2}, {dA: 2}, { mWP: 1 }575 ])576 })577 it("should unmount an external node during willUpdate", function(){578 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);579 const r1 = diff(h(0, null), null, [renderer, tracker]);580 const managedRoot = diff(h(1), null, r1);581 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))))582 let called = 0;583 const temp = h(2, hooks("willUpdate", f => {584 const res = diff(null, managedRoot);585 expect(res).to.be.true;586 called++;587 }));588 const r2 = diff(temp, null, tracker);589 events.length = 0;590 diff(copy(temp), r2);591 expect(called).to.equal(1);592 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))593 expect(events).to.eql([594 {wU: 2}, { mWP: 1 }, {mWR: 2}595 ])596 })597 it("should unmount an external node during didUpdate", function(){598 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);599 const r1 = diff(h(0, null), null, [renderer, tracker]);600 const managedRoot = diff(h(1), null, r1);601 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))))602 let called = 0;603 const temp = h(2, hooks("didUpdate", f => {604 const res = diff(null, managedRoot);605 expect(res).to.be.true;606 called++;607 }));608 const r2 = diff(temp, null, tracker);609 events.length = 0;610 diff(copy(temp), r2);611 expect(called).to.equal(1);612 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))613 expect(events).to.eql([614 {wU: 2}, {mWR: 2}, {dU: 2}, {mWP: 1}615 ])616 })617 it("should unmount a node that has not yet been rendered during willAdd", function(){618 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);619 const t = h(0, hooks("willAdd", f => {620 const r = diff(m(1), null, f);621 diff(null, r);622 }))623 diff(t, null, [renderer, tracker]);624 expect(renderer.tree).to.eql(renderer.renderStatic(copy(t)));625 expect(events).to.eql([{ wA: 0 }, { mWA: 0 }])626 })627 it("should unmount a node that has not yet been rendered during didAdd", function(){628 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);629 const t = h(0, hooks("didAdd", f => {630 const r = diff(m(1), null, f);631 diff(null, r);632 }))633 diff(t, null, [renderer, tracker]);634 expect(renderer.tree).to.eql(renderer.renderStatic(copy(t)));635 expect(events).to.eql([{ wA: 0 }, { mWA: 0 }, {dA: 0}])636 })637 it("should unmount a node that has not yet been rendered during willUpdate", function(){638 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);639 const t = h(0, hooks("willUpdate", f => {640 const r = diff(m(1), null, f);641 diff(null, r);642 }))643 const r = diff(t, null, [renderer, tracker]);644 events.length = 0;645 diff(copy(t), r);646 expect(renderer.tree).to.eql(renderer.renderStatic(copy(t)));647 expect(events).to.eql([{ wU: 0 }, { mWR: 0 }])648 })649 it("should unmount a node that has not yet been rendered during didUpdate", function(){650 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);651 const t = h(0, hooks("didUpdate", f => {652 const r = diff(m(1), null, f);653 diff(null, r);654 }))655 const r = diff(t, null, [renderer, tracker]);656 events.length = 0;657 diff(copy(t), r);658 expect(renderer.tree).to.eql(renderer.renderStatic(copy(t)));659 expect(events).to.eql([{ wU: 0 }, { mWR: 0 }, {dU: 0}])660 })661 it("should properly unmount itself during willAdd", function(){662 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);663 const r = diff(h(0), null, [renderer, tracker]);664 const temp = h(1, hooks("willAdd", f => diff(null, f)));665 diff(temp, null, r);666 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));667 expect(events).to.eql([ { wA: 0 }, { mWA: 0 }, { wA: 1 }])668 })669 it("should properly unmount itself during didAdd", function(){670 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);671 const r = diff(h(0), null, [renderer, tracker]);672 const temp = h(1, hooks("didAdd", f => diff(null, f)));673 diff(temp, null, r);674 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));675 expect(events).to.eql([ { wA: 0 }, { mWA: 0 }, { wA: 1 }, {mWA: 1}, {dA: 1}, {mWP: 1}])676 })677 it("should properly unmount itself during willUpdate", function(){678 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);679 const r = diff(h(0), null, [renderer, tracker]);680 const temp = h(1, hooks("willUpdate", f => diff(null, f)));681 const r2 = diff(temp, null, r);682 events.length = 0;683 diff(copy(temp), r2)684 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));685 expect(events).to.eql([ { wU: 1 }, { mWP: 1 }])686 })687 it("should properly unmount itself during didUpdate", function(){688 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);689 const r = diff(h(0), null, [renderer, tracker]);690 const temp = h(1, hooks("didUpdate", f => diff(null, f)));691 const r2 = diff(temp, null, r);692 events.length = 0;693 diff(copy(temp), r2)694 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));695 expect(events).to.eql([ { wU: 1 }, {mWR: 1}, {dU: 1}, { mWP: 1 }])696 })697 it("should unmount multiple nodes in default order during willAdd", function(){698 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);699 const r1 = diff(h(0, null), null, [renderer, tracker]);700 const managedRoot1 = diff(h(1), null, r1);701 const managedRoot2 = diff(h(2), null, r1, managedRoot1);702 const managedRoot3 = diff(h(3), null, r1, managedRoot2);703 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))704 let called = 0;705 const temp = h(4, hooks("willAdd", f => {706 expect(diff(null, managedRoot1)).to.be.true;707 expect(diff(null, managedRoot2)).to.be.true;708 expect(diff(null, managedRoot3)).to.be.true;709 called++;710 }));711 diff(temp, null, tracker);712 expect(called).to.equal(1);713 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))714 expect(events).to.eql([715 { wA: 0 }, { mWA: 0 }, 716 {wA: 1}, { mWA: 1 }, {wA: 2}, {mWA: 2}, {wA: 3}, { mWA: 3},717 { wA: 4}, {mWP: 1}, {mWP: 2}, {mWP: 3}, {mWA: 4}718 ])719 })720 it("should unmount multiple nodes in default order during didAdd", function(){721 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);722 const r1 = diff(h(0, null), null, [renderer, tracker]);723 const managedRoot1 = diff(h(1), null, r1);724 const managedRoot2 = diff(h(2), null, r1, managedRoot1);725 const managedRoot3 = diff(h(3), null, r1, managedRoot2);726 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))727 let called = 0;728 const temp = h(4, hooks("didAdd", f => {729 expect(diff(null, managedRoot1)).to.be.true;730 expect(diff(null, managedRoot2)).to.be.true;731 expect(diff(null, managedRoot3)).to.be.true;732 called++;733 }));734 diff(temp, null, tracker);735 expect(called).to.equal(1);736 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))737 expect(events).to.eql([738 { wA: 0 }, { mWA: 0 }, 739 {wA: 1}, { mWA: 1 }, {wA: 2}, {mWA: 2}, {wA: 3}, { mWA: 3},740 { wA: 4}, {mWA: 4}, {dA: 4}, {mWP: 1}, {mWP: 2}, {mWP: 3}741 ])742 })743 it("should unmount multiple nodes in default order during willUpdate", function(){744 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);745 const r1 = diff(h(0, null), null, [renderer, tracker]);746 const managedRoot1 = diff(h(1), null, r1);747 const managedRoot2 = diff(h(2), null, r1, managedRoot1);748 const managedRoot3 = diff(h(3), null, r1, managedRoot2);749 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))750 let called = 0;751 const temp = h(4, hooks("willUpdate", f => {752 expect(diff(null, managedRoot1)).to.be.true;753 expect(diff(null, managedRoot2)).to.be.true;754 expect(diff(null, managedRoot3)).to.be.true;755 called++;756 }));757 const r2 = diff(temp, null, tracker);758 events.length = 0;759 diff(copy(temp), r2);760 expect(called).to.equal(1);761 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))762 expect(events).to.eql([763 {wU: 4}, { mWP: 1 }, { mWP: 2 }, { mWP: 3 }, {mWR: 4}764 ])765 })766 it("should unmount multiple nodes in default order during didUpdate", function(){767 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);768 const r1 = diff(h(0, null), null, [renderer, tracker]);769 const managedRoot1 = diff(h(1), null, r1);770 const managedRoot2 = diff(h(2), null, r1, managedRoot1);771 const managedRoot3 = diff(h(3), null, r1, managedRoot2);772 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))773 let called = 0;774 const temp = h(4, hooks("didUpdate", f => {775 expect(diff(null, managedRoot1)).to.be.true;776 expect(diff(null, managedRoot2)).to.be.true;777 expect(diff(null, managedRoot3)).to.be.true;778 called++;779 }));780 const r2 = diff(temp, null, tracker);781 events.length = 0;782 diff(copy(temp), r2);783 expect(called).to.equal(1);784 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))785 expect(events).to.eql([786 {wU: 4}, {mWR: 4}, {dU: 4}, { mWP: 1 }, { mWP: 2 }, { mWP: 3 }787 ])788 })789 it("should unmount multiple nodes in a specified order during willAdd", function(){790 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);791 const r1 = diff(h(0, null), null, [renderer, tracker]);792 const managedRoot1 = diff(h(1), null, r1);793 const managedRoot2 = diff(h(2), null, r1, managedRoot1);794 const managedRoot3 = diff(h(3), null, r1, managedRoot2);795 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))796 let called = 0;797 const temp = h(4, hooks("willAdd", f => {798 expect(diff(null, managedRoot3)).to.be.true;799 expect(diff(null, managedRoot2)).to.be.true;800 expect(diff(null, managedRoot1)).to.be.true;801 called++;802 }));803 diff(temp, null, tracker);804 expect(called).to.equal(1);805 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))806 expect(events).to.eql([807 { wA: 0 }, { mWA: 0 }, 808 {wA: 1}, { mWA: 1 }, {wA: 2}, {mWA: 2}, {wA: 3}, { mWA: 3},809 { wA: 4}, {mWP: 3}, {mWP: 2}, {mWP: 1}, {mWA: 4}810 ])811 })812 it("should unmount multiple nodes in a specified order during didAdd", function(){813 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);814 const r1 = diff(h(0, null), null, [renderer, tracker]);815 const managedRoot1 = diff(h(1), null, r1);816 const managedRoot2 = diff(h(2), null, r1, managedRoot1);817 const managedRoot3 = diff(h(3), null, r1, managedRoot2);818 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))819 let called = 0;820 const temp = h(4, hooks("didAdd", f => {821 expect(diff(null, managedRoot3)).to.be.true;822 expect(diff(null, managedRoot2)).to.be.true;823 expect(diff(null, managedRoot1)).to.be.true;824 called++;825 }));826 diff(temp, null, tracker);827 expect(called).to.equal(1);828 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))829 expect(events).to.eql([830 { wA: 0 }, { mWA: 0 }, 831 {wA: 1}, { mWA: 1 }, {wA: 2}, {mWA: 2}, {wA: 3}, { mWA: 3},832 { wA: 4}, {mWA: 4}, {dA: 4}, {mWP: 3}, {mWP: 2}, {mWP: 1}833 ])834 })835 it("should unmount multiple nodes in a specified order during willUpdate", function(){836 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);837 const r1 = diff(h(0, null), null, [renderer, tracker]);838 const managedRoot1 = diff(h(1), null, r1);839 const managedRoot2 = diff(h(2), null, r1, managedRoot1);840 const managedRoot3 = diff(h(3), null, r1, managedRoot2);841 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))842 let called = 0;843 const temp = h(4, hooks("willUpdate", f => {844 expect(diff(null, managedRoot3)).to.be.true;845 expect(diff(null, managedRoot2)).to.be.true;846 expect(diff(null, managedRoot1)).to.be.true;847 called++;848 }));849 const r2 = diff(temp, null, tracker);850 events.length = 0;851 diff(copy(temp), r2);852 expect(called).to.equal(1);853 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))854 expect(events).to.eql([855 {wU: 4}, { mWP: 3 }, { mWP: 2 }, { mWP: 1 }, {mWR: 4}856 ])857 })858 it("should unmount multiple nodes in a specified order during didUpdate", function(){859 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);860 const r1 = diff(h(0, null), null, [renderer, tracker]);861 const managedRoot1 = diff(h(1), null, r1);862 const managedRoot2 = diff(h(2), null, r1, managedRoot1);863 const managedRoot3 = diff(h(3), null, r1, managedRoot2);864 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))865 let called = 0;866 const temp = h(4, hooks("didUpdate", f => {867 expect(diff(null, managedRoot3)).to.be.true;868 expect(diff(null, managedRoot2)).to.be.true;869 expect(diff(null, managedRoot1)).to.be.true;870 called++;871 }));872 const r2 = diff(temp, null, tracker);873 events.length = 0;874 diff(copy(temp), r2);875 expect(called).to.equal(1);876 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))877 expect(events).to.eql([878 {wU: 4}, {mWR: 4}, {dU: 4}, { mWP: 3 }, { mWP: 2 }, { mWP: 1 }879 ])880 })881 it("should rebase all entangled affects during willAdd", function(){882 const events = [], tracker = new Tracker(events);883 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;884 const r1 = diff(h(0, null), null, [renderer, tracker]);885 const managedRoot = diff(h(1, null, h(2)), null, r1);886 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);887 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);888 affectedRoot1.sub(managedRoot), affectedRoot2.sub(managedRoot.next);889 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, null, h(2)))))890 let called = 0;891 const temp = h(8, hooks("willAdd", f => {892 const res = diff(null, managedRoot);893 expect(res).to.be.true;894 called++;895 }));896 diff(temp, null, tracker);897 expect(called).to.equal(1);898 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))899 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))900 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))901 expect(events).to.eql([902 { wA: 0 }, { mWA: 0 }, 903 {wA: 1}, {wA: 2}, {mWA: 1}, { mWA: 2 }, 904 {wA: 3}, {wA: 4}, {mWA: 3}, {mWA: 4},905 {wA: 5}, {wA: 6}, {wA: 7}, {mWA: 5}, {mWA:6}, {mWA: 7},906 {wA: 8}, {wU: 3}, {wU: 4}, {wU: 5}, {wU: 6}, {wU: 7},907 {mWP: 1}, {mWP: 2}, {mWA: 8}, {mWR: 4}, {mWR: 6}, {mWR: 7}908 ])909 })910 it("should not rebase laggard entangled affects during willAdd", function(){911 const events = [], tracker = new Tracker(events);912 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;913 const r1 = diff(h(0, null), null, [renderer, tracker]);914 const managedRoot = diff(h(1, null, h(2)), null, r1);915 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, null, h(2)))))916 let called = 0;917 const temp = h(8, hooks("willAdd", f => {918 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);919 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);920 affectedRoot1.sub(managedRoot), affectedRoot2.sub(managedRoot.next);921 const res = diff(null, managedRoot);922 expect(res).to.be.true;923 called++;924 }));925 diff(temp, null, tracker);926 expect(called).to.equal(1);927 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))928 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))929 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))930 expect(events).to.eql([931 { wA: 0 }, { mWA: 0 }, 932 {wA: 1}, {wA: 2}, {mWA: 1}, { mWA: 2 },933 {wA: 8}, {wA: 5}, {wA: 6}, {wA: 7}, {wA: 3}, {wA: 4}, 934 {mWP: 1}, {mWP: 2}, {mWA: 8}, {mWA: 3}, {mWA: 4}, {mWA: 5}, {mWA:6}, {mWA: 7}935 ])936 })937 it("should rebase all entangled affects during didAdd", function(){938 const events = [], tracker = new Tracker(events);939 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;940 const r1 = diff(h(0, null), null, [renderer, tracker]);941 const managedRoot = diff(h(1, null, h(2)), null, r1);942 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);943 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);944 affectedRoot1.sub(managedRoot), affectedRoot2.sub(managedRoot.next);945 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, null, h(2)))))946 let called = 0;947 const temp = h(8, hooks("didAdd", f => {948 const res = diff(null, managedRoot);949 expect(res).to.be.true;950 called++;951 }));952 diff(temp, null, tracker);953 expect(called).to.equal(1);954 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))955 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))956 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))957 expect(events).to.eql([958 { wA: 0 }, { mWA: 0 }, 959 {wA: 1}, {wA: 2}, {mWA: 1}, { mWA: 2 }, 960 {wA: 3}, {wA: 4}, {mWA: 3}, {mWA: 4},961 {wA: 5}, {wA: 6}, {wA: 7}, {mWA: 5}, {mWA:6}, {mWA: 7},962 {wA: 8}, {mWA: 8}, {dA: 8}, {wU: 3}, {wU: 4}, {wU: 5}, {wU: 6}, {wU: 7},963 {mWP: 1}, {mWP: 2}, {mWR: 4}, {mWR: 6}, {mWR: 7}964 ])965 })966 it("should rebase all entangled affects during willUpdate", function(){967 const events = [], tracker = new Tracker(events);968 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;969 const r1 = diff(h(0, null), null, [renderer, tracker]);970 const managedRoot = diff(h(1, null, h(2)), null, r1);971 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);972 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);973 affectedRoot1.sub(managedRoot), affectedRoot2.sub(managedRoot.next);974 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, null, h(2)))))975 let called = 0;976 const temp = h(8, hooks("willUpdate", f => {977 const res = diff(null, managedRoot);978 expect(res).to.be.true;979 called++;980 }));981 const r2 = diff(temp, null, tracker);982 events.length = 0;983 diff(copy(temp), r2);984 expect(called).to.equal(1);985 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))986 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))987 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))988 expect(events).to.eql([989 {wU: 8}, {wU: 3}, {wU: 4}, {wU: 5}, {wU: 6}, {wU: 7},990 {mWP: 1}, {mWP: 2}, {mWR: 8}, {mWR: 4}, {mWR: 6}, {mWR: 7}991 ])992 })993 it("should not rebase laggard entangled affects during willUpdate", function(){994 const events = [], tracker = new Tracker(events);995 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;996 const r1 = diff(h(0, null), null, [renderer, tracker]);997 const managedRoot = diff(h(1, null, h(2)), null, r1);998 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, null, h(2)))))999 let called = 0;1000 const temp = h(8, hooks("willUpdate", f => {1001 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);1002 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);1003 affectedRoot1.sub(managedRoot), affectedRoot2.sub(managedRoot.next);1004 const res = diff(null, managedRoot);1005 expect(res).to.be.true;1006 called++;1007 }));1008 const r2 = diff(temp, null, tracker);1009 events.length = 0;1010 diff(copy(temp), r2);1011 expect(called).to.equal(1);1012 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))1013 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))1014 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))1015 expect(events).to.eql([1016 {wU: 8}, {wA: 5}, {wA: 6}, {wA: 7}, {wA: 3}, {wA: 4},1017 {mWP: 1}, {mWP: 2}, {mWR: 8}, {mWA: 3}, {mWA: 4}, {mWA: 5}, {mWA: 6}, {mWA: 7}1018 ])1019 })1020 it("should rebase all entangled affects during didUpdate", function(){1021 const events = [], tracker = new Tracker(events);1022 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;1023 const r1 = diff(h(0, null), null, [renderer, tracker]);1024 const managedRoot = diff(h(1, null, h(2)), null, r1);1025 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);1026 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);1027 affectedRoot1.sub(managedRoot), affectedRoot2.sub(managedRoot.next);1028 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, null, h(2)))))1029 let called = 0;1030 const temp = h(8, hooks("didUpdate", f => {1031 const res = diff(null, managedRoot);1032 expect(res).to.be.true;1033 called++;1034 }));1035 const r2 = diff(temp, null, tracker);1036 events.length = 0;1037 diff(copy(temp), r2);1038 expect(called).to.equal(1);1039 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null)))1040 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))1041 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))1042 expect(events).to.eql([1043 {wU: 8}, {mWR: 8}, {dU: 8}, {wU: 3}, {wU: 4}, {wU: 5}, {wU: 6}, {wU: 7},1044 {mWP: 1}, {mWP: 2}, {mWR: 4}, {mWR: 6}, {mWR: 7}1045 ])1046 })1047 })1048 describe("free (unmanaged) nodes", function(){1049 it("should not unmount nodes during a constructor", function(){1050 let called = 0;1051 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1052 const r = diff(h(0), null, [renderer, tracker]);1053 diff(h(1, hooks("ctor", f => {1054 const res = diff(null, r);1055 expect(res).to.be.false;1056 called++1057 })))1058 expect(called).to.equal(1);1059 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));1060 expect(events).to.eql([{wA: 0}, {mWA: 0}])1061 })1062 it("should not unmount nodes during cleanup", function(){1063 let called = 0;1064 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1065 const r = diff(h(0), null, [renderer, tracker]);1066 const f = diff(h(1, hooks("cleanup", f => {1067 const res = diff(null, r);1068 expect(res).to.be.false;1069 called++1070 })))1071 diff(null, f);1072 expect(called).to.equal(1);1073 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));1074 expect(events).to.eql([{wA: 0}, {mWA: 0}])1075 })1076 it("should not unmount nodes during add mutation event", function(){1077 let called = 0;1078 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1079 const r = diff(h(0), null, [renderer, tracker]);1080 diff(h(1), null, {add: f => {1081 const res = diff(null, r);1082 expect(res).to.be.false;1083 called++1084 }})1085 expect(called).to.equal(1);1086 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));1087 expect(events).to.eql([{wA: 0}, {mWA: 0}])1088 })1089 it("should not unmount nodes during remove mutation event", function(){1090 let called = 0;1091 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1092 const r = diff(h(0), null, [renderer, tracker]);1093 const f = diff(h(1), null, {remove: f => {1094 const res = diff(null, r);1095 expect(res).to.be.false;1096 called++1097 }})1098 diff(null, f);1099 expect(called).to.equal(1);1100 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));1101 expect(events).to.eql([{wA: 0}, {mWA: 0}])1102 })1103 it("should not unmount nodes during temp mutation event", function(){1104 let called = 0;1105 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1106 const r = diff(h(0), null, [renderer, tracker]);1107 const f = diff(h(1), null, {temp: f => {1108 const res = diff(null, r);1109 expect(res).to.be.false;1110 called++1111 }})1112 diff(h(1), f)1113 expect(called).to.equal(1);1114 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));1115 expect(events).to.eql([{wA: 0}, {mWA: 0}])1116 })1117 it("should not unmount nodes during move mutation event", function(){1118 let called = 0;1119 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1120 const r = diff(h(0), null, [renderer, tracker]);1121 const f = diff(h(1, null, [k(2), k(3)]), null, {move: f => {1122 if (f.temp.data.id === 3){1123 const res = diff(null, r);1124 expect(res).to.be.false;1125 called++1126 }1127 }})1128 diff(h(1, null, [k(3), k(2)]), f);1129 expect(called).to.equal(1);1130 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));1131 expect(events).to.eql([{wA: 0}, {mWA: 0}])1132 })1133 it("should unmount nodes created during willAdd in the next cycle", function(){1134 const temp = h(1);1135 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1136 const renderer2 = new LCRSRenderer;1137 let called = 0, mounted;1138 const hooks = {1139 willAdd: f => {mounted = diff(temp, null, [renderer2, tracker])},1140 willUpdate: f => {1141 expect(mounted).to.be.an.instanceOf(Frame);1142 expect(mounted.temp).to.equal(temp);1143 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, hooks)));1144 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(1)));1145 const res = diff(null, mounted)1146 expect(res).to.be.true;1147 called++;1148 }1149 }1150 const r = diff(h(0, hooks), null, [renderer, tracker]);1151 diff(h(0, hooks), r);1152 expect(called).to.equal(1);1153 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, hooks)))1154 expect(renderer2.tree).to.be.null1155 expect(events).to.eql([ 1156 { wA: 0 }, { wA: 1 }, { mWA: 0 }, { mWA: 1 }, { wU: 0 }, { mWP: 1 }, { mWR: 0 }1157 ])1158 })1159 it("should unmount nodes created during willAdd in didAdd", function(){1160 const temp = h(1);1161 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1162 const renderer2 = new LCRSRenderer;1163 let called = 0, mounted;1164 const hooks = {1165 willAdd: f => {mounted = diff(temp, null, [renderer2, tracker])},1166 didAdd: f => {1167 expect(mounted).to.be.an.instanceOf(Frame);1168 expect(mounted.temp).to.equal(temp);1169 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, hooks)));1170 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(1)));1171 const res = diff(null, mounted)1172 expect(res).to.be.true;1173 called++;1174 }1175 }1176 diff(h(0, hooks), null, [renderer, tracker]);1177 expect(called).to.equal(1);1178 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, hooks)))1179 expect(renderer2.tree).to.be.null1180 expect(events).to.eql([ 1181 { wA: 0 }, { wA: 1 }, { mWA: 0 }, { mWA: 1 }, {dA: 0}, { mWP: 1 }1182 ])1183 })1184 it("should unmount an external node during willAdd", function(){1185 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1186 const renderer2 = new LCRSRenderer;1187 const r1 = diff(h(0), null, [renderer, tracker]);1188 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)))1189 let called = 0;1190 const temp = h(1, hooks("willAdd", f => {1191 const res = diff(null, r1);1192 expect(res).to.be.true;1193 called++;1194 }));1195 diff(temp, null, [renderer2, tracker]);1196 expect(called).to.equal(1);1197 expect(renderer.tree).to.be.null1198 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(temp)))1199 expect(events).to.eql([1200 { wA: 0 }, { mWA: 0 }, {wA: 1}, { mWP: 0 }, {mWA: 1}1201 ])1202 })1203 it("should unmount an external node during didAdd", function(){1204 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1205 const renderer2 = new LCRSRenderer;1206 const r1 = diff(h(0), null, [renderer, tracker]);1207 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)))1208 let called = 0;1209 const temp = h(1, hooks("didAdd", f => {1210 const res = diff(null, r1);1211 expect(res).to.be.true;1212 called++;1213 }));1214 diff(temp, null, [renderer2, tracker]);1215 expect(called).to.equal(1);1216 expect(renderer.tree).to.be.null1217 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(temp)))1218 expect(events).to.eql([1219 { wA: 0 }, { mWA: 0 }, {wA: 1}, {mWA: 1}, {dA: 1}, { mWP: 0 }1220 ])1221 })1222 it("should unmount an external node during willUpdate", function(){1223 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1224 const renderer2 = new LCRSRenderer;1225 const r1 = diff(h(0), null, [renderer, tracker]);1226 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)))1227 let called = 0;1228 const temp = h(1, hooks("willUpdate", f => {1229 const res = diff(null, r1);1230 expect(res).to.be.true;1231 called++;1232 }));1233 const r2 = diff(temp, null, [renderer2, tracker]);1234 events.length = 0;1235 diff(copy(temp), r2)1236 expect(called).to.equal(1);1237 expect(renderer.tree).to.be.null1238 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(temp)))1239 expect(events).to.eql([1240 { wU: 1 }, { mWP: 0 }, { mWR: 1 }1241 ])1242 })1243 it("should unmount an external node during didUpdate", function(){1244 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1245 const renderer2 = new LCRSRenderer;1246 const r1 = diff(h(0), null, [renderer, tracker]);1247 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)))1248 let called = 0;1249 const temp = h(1, hooks("didUpdate", f => {1250 const res = diff(null, r1);1251 expect(res).to.be.true;1252 called++;1253 }));1254 const r2 = diff(temp, null, [renderer2, tracker]);1255 events.length = 0;1256 diff(copy(temp), r2)1257 expect(called).to.equal(1);1258 expect(renderer.tree).to.be.null1259 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(temp)))1260 expect(events).to.eql([1261 { wU: 1 }, {mWR: 1}, {dU: 1}, { mWP: 0 }1262 ])1263 })1264 it("should unmount a node that has not yet been rendered during willAdd", function(){1265 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1266 const renderer2 = new LCRSRenderer;1267 const t = h(0, hooks("willAdd", f => {1268 const r = diff(m(1), null, [renderer2, tracker]);1269 diff(null, r);1270 }))1271 diff(t, null, [renderer, tracker]);1272 expect(renderer.tree).to.eql(renderer.renderStatic(copy(t)));1273 expect(renderer2.tree).to.be.null;1274 expect(events).to.eql([{ wA: 0 }, { mWA: 0 }])1275 })1276 it("should unmount a node that has not yet been rendered during didAdd", function(){1277 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1278 const renderer2 = new LCRSRenderer;1279 const t = h(0, hooks("didAdd", f => {1280 const r = diff(m(1), null, [renderer2, tracker]);1281 diff(null, r);1282 }))1283 diff(t, null, [renderer, tracker]);1284 expect(renderer.tree).to.eql(renderer.renderStatic(copy(t)));1285 expect(renderer2.tree).to.be.null;1286 expect(events).to.eql([{ wA: 0 }, { mWA: 0 }, {dA: 0}])1287 })1288 it("should unmount a node that has not yet been rendered during willUpdate", function(){1289 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1290 const renderer2 = new LCRSRenderer;1291 const t = h(0, hooks("willUpdate", f => {1292 const r = diff(m(1), null, [renderer2, tracker]);1293 diff(null, r);1294 }))1295 const r = diff(t, null, [renderer, tracker]);1296 events.length = 0;1297 diff(copy(t), r);1298 expect(renderer.tree).to.eql(renderer.renderStatic(copy(t)));1299 expect(renderer2.tree).to.be.null1300 expect(events).to.eql([{ wU: 0 }, { mWR: 0 }])1301 })1302 it("should unmount a node that has not yet been rendered during didUpdate", function(){1303 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1304 const renderer2 = new LCRSRenderer;1305 const t = h(0, hooks("didUpdate", f => {1306 const r = diff(m(1), null, [renderer2, tracker]);1307 diff(null, r);1308 }))1309 const r = diff(t, null, [renderer, tracker]);1310 events.length = 0;1311 diff(copy(t), r);1312 expect(renderer.tree).to.eql(renderer.renderStatic(copy(t)));1313 expect(renderer2.tree).to.be.null1314 expect(events).to.eql([{ wU: 0 }, { mWR: 0 }, {dU:0}])1315 })1316 it("should properly unmount itself during willAdd", function(){1317 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1318 const r = diff(h(0, hooks("willAdd", f => diff(null, f))), null, [renderer, tracker]);1319 expect(renderer.tree).to.be.null;1320 expect(events).to.eql([ { wA: 0 } ])1321 })1322 it("should properly unmount itself during didAdd", function(){1323 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1324 const r = diff(h(0, hooks("didAdd", f => diff(null, f))), null, [renderer, tracker]);1325 expect(renderer.tree).to.be.null;1326 expect(events).to.eql([ { wA: 0 }, {mWA: 0}, {dA: 0}, {mWP: 0} ])1327 })1328 it("should properly unmount itself during willUpdate", function(){1329 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1330 const temp = h(0, hooks("willUpdate", f => diff(null, f)))1331 const r = diff(temp, null, [renderer, tracker]);1332 events.length = 0;1333 diff(copy(temp), r)1334 expect(renderer.tree).to.be.null1335 expect(events).to.eql([ { wU: 0 }, {mWP: 0} ])1336 })1337 it("should properly unmount itself during didUpdate", function(){1338 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1339 const temp = h(0, hooks("didUpdate", f => diff(null, f)))1340 const r = diff(temp, null, [renderer, tracker]);1341 events.length = 0;1342 diff(copy(temp), r)1343 expect(renderer.tree).to.be.null1344 expect(events).to.eql([ { wU: 0 }, {mWR: 0}, {dU: 0}, {mWP: 0} ])1345 })1346 it("should properly unmount an upstream parent during willAdd", function(){1347 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1348 let r;1349 diff(h(0, hooks("willAdd", f => r = f), [h(1, hooks("willAdd", f => {1350 diff(null, r);1351 }))]), null, [renderer, tracker]);1352 expect(renderer.tree).to.be.null;1353 expect(events).to.eql([1354 { wA: 0 }, { wA: 1 }1355 ])1356 })1357 it("should properly unmount an upstream parent during didAdd", function(){1358 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1359 let r;1360 diff(h(0, hooks("willAdd", f => r = f), [h(1, hooks("didAdd", f => {1361 diff(null, r);1362 }))]), null, [renderer, tracker]);1363 expect(renderer.tree).to.be.null;1364 expect(events).to.eql([1365 { wA: 0 }, { wA: 1 }, {mWA: 0}, {mWA: 1}, {dA: 1}, {mWP: 0}, {mWP: 1}1366 ])1367 })1368 it("should unmount an upstream parent during willAdd without rendering unvisited children", function(){1369 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1370 let r;1371 diff(h(0, hooks("willAdd", f => r = f), [h(1, hooks("willAdd", f => {1372 diff(null, r);1373 }), h(2))]), null, [renderer, tracker]);1374 expect(renderer.tree).to.be.null;1375 expect(events).to.eql([1376 { wA: 0 }, { wA: 1 }1377 ])1378 })1379 it("should unmount an upstream parent during didAdd after rendering unvisited children", function(){1380 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1381 let r;1382 diff(h(0, hooks("willAdd", f => r = f), [h(1, hooks("didAdd", f => {1383 diff(null, r);1384 }), h(2))]), null, [renderer, tracker]);1385 expect(renderer.tree).to.be.null;1386 expect(events).to.eql([1387 { wA: 0 }, { wA: 1 }, {wA: 2}, {mWA: 0}, {mWA: 1}, {mWA: 2}, 1388 {dA: 1}, {mWP: 0}, {mWP: 1}, {mWP: 2}1389 ])1390 })1391 it("should properly unmount an upstream parent during willAdd without rendering unvisited grandchildren", function(){1392 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1393 let r;1394 diff(h(0, hooks("willAdd", f => r = f), [h(1, hooks("willAdd", f => {1395 diff(null, r);1396 })), h(2, null, h(4))]), null, [renderer, tracker]);1397 expect(renderer.tree).to.be.null;1398 expect(events).to.eql([1399 { wA: 0 }, { wA: 1 }1400 ])1401 })1402 it("should properly unmount an upstream parent during didAdd after rendering unvisited grandchildren", function(){1403 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1404 let r;1405 diff(h(0, hooks("willAdd", f => r = f), [h(1, hooks("didAdd", f => {1406 diff(null, r);1407 })), h(2, null, h(4))]), null, [renderer, tracker]);1408 expect(renderer.tree).to.be.null;1409 expect(events).to.eql([1410 { wA: 0 }, { wA: 1 }, {wA: 2}, {wA: 4}, {mWA: 0}, {mWA: 1}, {mWA: 2}, {mWA: 4}, 1411 {dA: 1}, {mWP: 0}, {mWP: 2}, {mWP: 4}, {mWP: 1}1412 ])1413 })1414 it("should properly unmount an upstream parent during willUpdate", function(){1415 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1416 let r, temp; // don't code like this, i'm lazy af1417 diff(temp = h(0, hooks("willAdd", f => r = f), [h(1, hooks("willUpdate", f => {1418 diff(null, r);1419 }))]), null, [renderer, tracker]);1420 events.length = 0;1421 diff(copy(temp), r)1422 expect(renderer.tree).to.be.null;1423 expect(events).to.eql([1424 { wU: 0 }, { wU: 1 }, {mWP: 0}, {mWP: 1}1425 ])1426 })1427 it("should properly unmount an upstream parent during didUpdate", function(){1428 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1429 let r, temp; // don't code like this, i'm lazy af1430 diff(temp = h(0, hooks("willAdd", f => r = f), [h(1, hooks("didUpdate", f => {1431 diff(null, r);1432 }))]), null, [renderer, tracker]);1433 events.length = 0;1434 diff(copy(temp), r)1435 expect(renderer.tree).to.be.null;1436 expect(events).to.eql([1437 { wU: 0 }, { wU: 1 }, {mWR: 0}, {mWR: 1}, {dU: 1}, {mWP: 0}, {mWP: 1}1438 ])1439 })1440 it("should unmount an upstream parent during willUpdate without updating unvisited children", function(){1441 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1442 let r, temp;1443 diff(temp = h(0, hooks("willAdd", f => r = f), [h(1, hooks("willUpdate", f => {1444 diff(null, r);1445 }), h(2))]), null, [renderer, tracker]);1446 events.length = 0;1447 diff(copy(temp), r);1448 expect(renderer.tree).to.be.null;1449 expect(events).to.eql([1450 { wU: 0 }, { wU: 1 },1451 { mWP: 0 }, {mWP: 1}, {mWP: 2}1452 ])1453 })1454 it("should unmount an upstream parent during didUpdate without updating unvisited children", function(){1455 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1456 let r, temp;1457 diff(temp = h(0, hooks("willAdd", f => r = f), [h(1, hooks("didUpdate", f => {1458 diff(null, r);1459 }), h(2))]), null, [renderer, tracker]);1460 events.length = 0;1461 diff(copy(temp), r);1462 expect(renderer.tree).to.be.null;1463 expect(events).to.eql([1464 { wU: 0 }, { wU: 1 }, {wU: 2}, {mWR: 0}, {mWR: 1}, {mWR: 2}, {dU: 1},1465 { mWP: 0 }, {mWP: 1}, {mWP: 2}1466 ])1467 })1468 it("should properly unmount an upstream parent during willUpdate without rendering unvisited grandchildren", function(){1469 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1470 let r, temp;1471 diff(temp = h(0, hooks("willAdd", f => r = f), [h(1, hooks("willUpdate", f => {1472 diff(null, r);1473 })), h(2, null, h(4))]), null, [renderer, tracker]);1474 events.length = 0;1475 diff(copy(temp), r);1476 expect(renderer.tree).to.be.null;1477 expect(events).to.eql([1478 { wU: 0 }, { wU: 1 },1479 { mWP: 0 }, {mWP: 2}, {mWP: 4}, {mWP: 1}1480 ])1481 })1482 it("should properly unmount an upstream parent during didUpdate without rendering unvisited grandchildren", function(){1483 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1484 let r, temp;1485 diff(temp = h(0, hooks("willAdd", f => r = f), [h(1, hooks("didUpdate", f => {1486 diff(null, r);1487 })), h(2, null, h(4))]), null, [renderer, tracker]);1488 events.length = 0;1489 diff(copy(temp), r);1490 expect(renderer.tree).to.be.null;1491 expect(events).to.eql([1492 { wU: 0 }, { wU: 1 }, {wU: 2}, {wU: 4}, {mWR: 0}, {mWR: 1}, {mWR: 2}, {mWR: 4}, {dU: 1},1493 { mWP: 0 }, {mWP: 2}, {mWP: 4}, {mWP: 1}1494 ])1495 })1496 it("should unmount multiple nodes in call order during willAdd", function(){1497 const events = [], tracker = new Tracker(events);1498 const renderer1 = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;1499 const extRoot1 = diff(h(1), null, [renderer1, tracker]);1500 const extRoot2 = diff(h(2), null, [renderer2, tracker]);1501 const extRoot3 = diff(h(3), null, [renderer3, tracker]);1502 expect(renderer1.tree).to.eql(renderer1.renderStatic(h(1)))1503 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(2)))1504 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(3)))1505 let called = 0;1506 const temp = h(4, hooks("willAdd", f => {1507 expect(diff(null, extRoot1)).to.be.true;1508 expect(diff(null, extRoot2)).to.be.true;1509 expect(diff(null, extRoot3)).to.be.true;1510 called++;1511 }));1512 diff(temp, null, tracker);1513 expect(called).to.equal(1);1514 expect(renderer1.tree).to.be.null1515 expect(renderer2.tree).to.be.null1516 expect(renderer3.tree).to.be.null1517 expect(events).to.eql([1518 {wA: 1}, { mWA: 1 }, {wA: 2}, {mWA: 2}, {wA: 3}, { mWA: 3},1519 { wA: 4}, {mWP: 1}, {mWP: 2}, {mWP: 3}, {mWA: 4}1520 ])1521 })1522 it("should unmount multiple nodes in call order during didAdd", function(){1523 const events = [], tracker = new Tracker(events);1524 const renderer1 = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;1525 const extRoot1 = diff(h(1), null, [renderer1, tracker]);1526 const extRoot2 = diff(h(2), null, [renderer2, tracker]);1527 const extRoot3 = diff(h(3), null, [renderer3, tracker]);1528 expect(renderer1.tree).to.eql(renderer1.renderStatic(h(1)))1529 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(2)))1530 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(3)))1531 let called = 0;1532 const temp = h(4, hooks("didAdd", f => {1533 expect(diff(null, extRoot1)).to.be.true;1534 expect(diff(null, extRoot2)).to.be.true;1535 expect(diff(null, extRoot3)).to.be.true;1536 called++;1537 }));1538 diff(temp, null, tracker);1539 expect(called).to.equal(1);1540 expect(renderer1.tree).to.be.null1541 expect(renderer2.tree).to.be.null1542 expect(renderer3.tree).to.be.null1543 expect(events).to.eql([1544 {wA: 1}, { mWA: 1 }, {wA: 2}, {mWA: 2}, {wA: 3}, { mWA: 3},1545 { wA: 4}, {mWA: 4}, {dA: 4}, {mWP: 1}, {mWP: 2}, {mWP: 3}1546 ])1547 })1548 it("should unmount multiple nodes in call order during willUpdate", function(){1549 const events = [], tracker = new Tracker(events);1550 const renderer1 = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;1551 const extRoot1 = diff(h(1), null, [renderer1, tracker]);1552 const extRoot2 = diff(h(2), null, [renderer2, tracker]);1553 const extRoot3 = diff(h(3), null, [renderer3, tracker]);1554 expect(renderer1.tree).to.eql(renderer1.renderStatic(h(1)))1555 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(2)))1556 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(3)))1557 let called = 0;1558 const temp = h(4, hooks("willUpdate", f => {1559 expect(diff(null, extRoot1)).to.be.true;1560 expect(diff(null, extRoot2)).to.be.true;1561 expect(diff(null, extRoot3)).to.be.true;1562 called++;1563 }));1564 const r2 = diff(temp, null, tracker);1565 events.length = 0;1566 diff(copy(temp), r2);1567 expect(called).to.equal(1);1568 expect(renderer1.tree).to.be.null1569 expect(renderer2.tree).to.be.null1570 expect(renderer3.tree).to.be.null1571 expect(events).to.eql([1572 {wU: 4}, { mWP: 1 }, { mWP: 2 }, { mWP: 3 }, {mWR: 4}1573 ])1574 })1575 it("should unmount multiple nodes in call order during didUpdate", function(){1576 const events = [], tracker = new Tracker(events);1577 const renderer1 = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;1578 const extRoot1 = diff(h(1), null, [renderer1, tracker]);1579 const extRoot2 = diff(h(2), null, [renderer2, tracker]);1580 const extRoot3 = diff(h(3), null, [renderer3, tracker]);1581 expect(renderer1.tree).to.eql(renderer1.renderStatic(h(1)))1582 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(2)))1583 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(3)))1584 let called = 0;1585 const temp = h(4, hooks("didUpdate", f => {1586 expect(diff(null, extRoot1)).to.be.true;1587 expect(diff(null, extRoot2)).to.be.true;1588 expect(diff(null, extRoot3)).to.be.true;1589 called++;1590 }));1591 const r2 = diff(temp, null, tracker);1592 events.length = 0;1593 diff(copy(temp), r2);1594 expect(called).to.equal(1);1595 expect(renderer1.tree).to.be.null1596 expect(renderer2.tree).to.be.null1597 expect(renderer3.tree).to.be.null1598 expect(events).to.eql([1599 {wU: 4}, {mWR: 4}, {dU: 4}, { mWP: 1 }, { mWP: 2 }, { mWP: 3 }1600 ])1601 })1602 it("should rebase all entangled affects during willAdd", function(){1603 const events = [], tracker = new Tracker(events);1604 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;1605 const extRoot = diff(h(1, null, h(2)), null, [renderer, tracker]);1606 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);1607 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);1608 affectedRoot1.sub(extRoot), affectedRoot2.sub(extRoot.next);1609 expect(renderer.tree).to.eql(renderer.renderStatic(h(1, null, h(2))))1610 let called = 0;1611 const temp = h(8, hooks("willAdd", f => {1612 const res = diff(null, extRoot);1613 expect(res).to.be.true;1614 called++;1615 }));1616 diff(temp, null, tracker);1617 expect(called).to.equal(1);1618 expect(renderer.tree).to.be.null1619 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))1620 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))1621 expect(events).to.eql([1622 {wA: 1}, {wA: 2}, {mWA: 1}, { mWA: 2 }, 1623 {wA: 3}, {wA: 4}, {mWA: 3}, {mWA: 4},1624 {wA: 5}, {wA: 6}, {wA: 7}, {mWA: 5}, {mWA:6}, {mWA: 7},1625 {wA: 8}, {wU: 3}, {wU: 4}, {wU: 5}, {wU: 6}, {wU: 7},1626 {mWP: 1}, {mWP: 2}, {mWA: 8}, {mWR: 4}, {mWR: 6}, {mWR: 7}1627 ])1628 })1629 it("should not rebase laggard entangled affects during willAdd", function(){1630 const events = [], tracker = new Tracker(events);1631 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;1632 const extRoot = diff(h(1, null, h(2)), null, [renderer, tracker]);1633 expect(renderer.tree).to.eql(renderer.renderStatic(h(1, null, h(2))))1634 let called = 0;1635 const temp = h(8, hooks("willAdd", f => {1636 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);1637 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);1638 affectedRoot1.sub(extRoot), affectedRoot2.sub(extRoot.next);1639 const res = diff(null, extRoot);1640 expect(res).to.be.true;1641 called++;1642 }));1643 diff(temp, null, tracker);1644 expect(called).to.equal(1);1645 expect(renderer.tree).to.be.null1646 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))1647 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))1648 expect(events).to.eql([1649 {wA: 1}, {wA: 2}, {mWA: 1}, { mWA: 2 },1650 {wA: 8}, {wA: 5}, {wA: 6}, {wA: 7}, {wA: 3}, {wA: 4}, 1651 {mWP: 1}, {mWP: 2}, {mWA: 8}, {mWA: 3}, {mWA: 4}, {mWA: 5}, {mWA:6}, {mWA: 7}1652 ])1653 })1654 it("should rebase all entangled affects during didAdd", function(){1655 const events = [], tracker = new Tracker(events);1656 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;1657 const extRoot = diff(h(1, null, h(2)), null, [renderer, tracker]);1658 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);1659 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);1660 affectedRoot1.sub(extRoot), affectedRoot2.sub(extRoot.next);1661 expect(renderer.tree).to.eql(renderer.renderStatic(h(1, null, h(2))))1662 let called = 0;1663 const temp = h(8, hooks("didAdd", f => {1664 const res = diff(null, extRoot);1665 expect(res).to.be.true;1666 called++;1667 }));1668 diff(temp, null, tracker);1669 expect(called).to.equal(1);1670 expect(renderer.tree).to.be.null1671 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))1672 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))1673 expect(events).to.eql([1674 {wA: 1}, {wA: 2}, {mWA: 1}, { mWA: 2 }, 1675 {wA: 3}, {wA: 4}, {mWA: 3}, {mWA: 4},1676 {wA: 5}, {wA: 6}, {wA: 7}, {mWA: 5}, {mWA:6}, {mWA: 7},1677 {wA: 8}, {mWA: 8}, {dA: 8}, {wU: 3}, {wU: 4}, {wU: 5}, {wU: 6}, {wU: 7},1678 {mWP: 1}, {mWP: 2}, {mWR: 4}, {mWR: 6}, {mWR: 7}1679 ])1680 })1681 it("should rebase all entangled affects during willUpdate", function(){1682 const events = [], tracker = new Tracker(events);1683 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;1684 const extRoot = diff(h(1, null, h(2)), null, [renderer, tracker]);1685 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);1686 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);1687 affectedRoot1.sub(extRoot), affectedRoot2.sub(extRoot.next);1688 expect(renderer.tree).to.eql(renderer.renderStatic(h(1, null, h(2))))1689 let called = 0;1690 const temp = h(8, hooks("willUpdate", f => {1691 const res = diff(null, extRoot);1692 expect(res).to.be.true;1693 called++;1694 }));1695 const r2 = diff(temp, null, tracker);1696 events.length = 0;1697 diff(copy(temp), r2);1698 expect(called).to.equal(1);1699 expect(renderer.tree).to.be.null;1700 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))1701 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))1702 expect(events).to.eql([1703 {wU: 8}, {wU: 3}, {wU: 4}, {wU: 5}, {wU: 6}, {wU: 7},1704 {mWP: 1}, {mWP: 2}, {mWR: 8}, {mWR: 4}, {mWR: 6}, {mWR: 7}1705 ])1706 })1707 it("should not rebase laggard entangled affects during willUpdate", function(){1708 const events = [], tracker = new Tracker(events);1709 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;1710 const extRoot = diff(h(1, null, h(2)), null, [renderer, tracker]);1711 expect(renderer.tree).to.eql(renderer.renderStatic(h(1, null, h(2))))1712 let called = 0;1713 const temp = h(8, hooks("willUpdate", f => {1714 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);1715 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);1716 affectedRoot1.sub(extRoot), affectedRoot2.sub(extRoot.next);1717 const res = diff(null, extRoot);1718 expect(res).to.be.true;1719 called++;1720 }));1721 const r2 = diff(temp, null, tracker);1722 events.length = 0;1723 diff(copy(temp), r2);1724 expect(called).to.equal(1);1725 expect(renderer.tree).to.be.null;1726 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))1727 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))1728 expect(events).to.eql([1729 {wU: 8}, {wA: 5}, {wA: 6}, {wA: 7}, {wA: 3}, {wA: 4},1730 {mWP: 1}, {mWP: 2}, {mWR: 8}, {mWA: 3}, {mWA: 4}, {mWA: 5}, {mWA: 6}, {mWA: 7}1731 ])1732 })1733 it("should rebase all entangled affects during didUpdate", function(){1734 const events = [], tracker = new Tracker(events);1735 const renderer = new LCRSRenderer, renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;1736 const extRoot = diff(h(1, null, h(2)), null, [renderer, tracker]);1737 const affectedRoot1 = diff(h(3, null, h(4)), null, [renderer2, tracker]);1738 const affectedRoot2 = diff(h(5, null, [h(6), h(7)]), null, [renderer3, tracker]);1739 affectedRoot1.sub(extRoot), affectedRoot2.sub(extRoot.next);1740 expect(renderer.tree).to.eql(renderer.renderStatic(h(1, null, h(2))))1741 let called = 0;1742 const temp = h(8, hooks("didUpdate", f => {1743 const res = diff(null, extRoot);1744 expect(res).to.be.true;1745 called++;1746 }));1747 const r2 = diff(temp, null, tracker);1748 events.length = 0;1749 diff(copy(temp), r2);1750 expect(called).to.equal(1);1751 expect(renderer.tree).to.be.null;1752 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(3, null, h(4))))1753 expect(renderer3.tree).to.eql(renderer3.renderStatic(h(5, null, [h(6), h(7)])))1754 expect(events).to.eql([1755 {wU: 8}, {mWR: 8}, {dU: 8}, {wU: 3}, {wU: 4}, {wU: 5}, {wU: 6}, {wU: 7},1756 {mWP: 1}, {mWP: 2}, {mWR: 4}, {mWR: 6}, {mWR: 7}1757 ])1758 })1759 })1760 })1761 describe("updating (outer-diffs)", function(){1762 describe("virtual (managed) nodes", function(){1763 it("should not update nodes during a constructor", function(){1764 let called = 0;1765 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1766 const r = diff(h(0, null), null, [renderer, tracker]);1767 const managedR = diff(h(1), null, r);1768 diff(h(1, hooks("ctor", f => {1769 const res = diff(h(1, {some:"data"}), managedR);1770 expect(res).to.be.false;1771 called++1772 })))1773 expect(called).to.equal(1);1774 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));1775 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])1776 })1777 it("should not update nodes during cleanup", function(){1778 let called = 0;1779 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1780 const r = diff(h(0, null), null, [renderer, tracker]);1781 const managedR = diff(h(1), null, r);1782 const f = diff(h(1, hooks("cleanup", f => {1783 const res = diff(h(1, {some:"data"}), managedR);1784 expect(res).to.be.false;1785 called++1786 })))1787 diff(null, f);1788 expect(called).to.equal(1);1789 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));1790 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])1791 })1792 it("should not update nodes during add mutation event", function(){1793 let called = 0;1794 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1795 const r = diff(h(0, null), null, [renderer, tracker]);1796 const m = diff(h(1), null, r);1797 diff(h(2), null, {add: f => {1798 const res = diff(h(1, {some: "data"}), m);1799 expect(res).to.be.false;1800 called++1801 }})1802 expect(called).to.equal(1);1803 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));1804 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])1805 })1806 it("should not update nodes during remove mutation event", function(){1807 let called = 0;1808 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1809 const r = diff(h(0, null), null, [renderer, tracker]);1810 const m = diff(h(1), null, r);1811 const f = diff(h(2), null, {remove: f => {1812 const res = diff(h(1, {some: "data"}), m);1813 expect(res).to.be.false;1814 called++1815 }})1816 diff(null, f);1817 expect(called).to.equal(1);1818 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));1819 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])1820 })1821 it("should not update nodes during temp mutation event", function(){1822 let called = 0;1823 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1824 const r = diff(h(0, null), null, [renderer, tracker]);1825 const m = diff(h(1), null, r);1826 const f = diff(h(2), null, {temp: f => {1827 const res = diff(h(1, {some: "data"}), m);1828 expect(res).to.be.false;1829 called++1830 }})1831 diff(h(2), f)1832 expect(called).to.equal(1);1833 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));1834 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])1835 })1836 it("should not update nodes during move mutation event", function(){1837 let called = 0;1838 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1839 const r = diff(h(0, null), null, [renderer, tracker]);1840 const m = diff(h(1), null, r);1841 const f = diff(h(2, null, [k(3), k(4)]), null, {move: f => {1842 if (f.temp.data.id === 4){1843 const res = diff(h(1, {some: "data"}), m);1844 expect(res).to.be.false;1845 called++1846 }1847 }})1848 diff(h(2, null, [k(4), k(3)]), f);1849 expect(called).to.equal(1);1850 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1))));1851 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}])1852 })1853 it("should rebase itself onto the path when updating itself during willAdd", function(){1854 let called = 0;1855 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1856 const r = diff(h(0, null), null, [renderer, tracker]);1857 const managedTemp = h(1, hooks("willAdd", f => {1858 const temp = h(1, {some: "data"});1859 const res = diff(temp, f);1860 expect(res).to.equal(f);1861 expect(res.temp).to.equal(temp);1862 called++;1863 }))1864 diff(managedTemp, null, r);1865 expect(called).to.equal(1);1866 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}))));1867 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {wU: 1}, {mWA: 1}])1868 })1869 it("should rebase itself onto the path when updating itself during didAdd", function(){1870 let called = 0;1871 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1872 const r = diff(h(0, null), null, [renderer, tracker]);1873 const managedTemp = h(1, hooks("didAdd", f => {1874 const temp = h(1, {some: "data"});1875 const res = diff(temp, f);1876 expect(res).to.equal(f);1877 expect(res.temp).to.equal(temp);1878 called++;1879 }))1880 diff(managedTemp, null, r);1881 expect(called).to.equal(1);1882 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}))));1883 expect(events).to.eql([{wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}, {dA: 1}, {wU: 1}, {mWR: 1}])1884 })1885 it("should call didAdd once and not call didUpdate if rebasing itself during willAdd", function(){1886 let calledAdd = 0, calledUpd = 0, calledDidUpd = 0, calledDidAdd = 0;1887 const events = [], tracker = new Tracker(events);1888 const hooks = {1889 didUpdate: f => {1890 calledDidUpd++;1891 },1892 willAdd: f => {1893 calledAdd++;1894 diff(copy(f.temp), f);1895 },1896 didAdd: f => {1897 calledDidAdd++1898 },1899 willUpdate: f => {1900 calledUpd++;1901 }1902 }1903 const f = diff(h(0, hooks), null, tracker);1904 expect(calledUpd).to.equal(1);1905 expect(calledAdd).to.equal(1);1906 expect(calledDidUpd).to.equal(0);1907 expect(calledDidAdd).to.equal(1);1908 expect(events).to.eql([{wA: 0}, {wU: 0}, {mWA: 0}, {dA: 0}])1909 })1910 it("should rebase its parent and itself onto the path when updating the parent during willAdd", function(){1911 let called = 0;1912 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1913 const r = diff(h(0, null), null, [renderer, tracker]);1914 let parent;1915 const managedTemp = h(1, hooks("ctor", f => parent = f), h(2, hooks("willAdd", f => {1916 const temp = h(1, {some: "data"}, h(2));1917 const res = diff(temp, parent);1918 expect(res).to.equal(parent);1919 expect(res.temp).to.equal(temp);1920 called++;1921 })))1922 diff(managedTemp, null, r);1923 expect(called).to.equal(1);1924 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}, h(2)))));1925 expect(events).to.eql([1926 {wA: 0}, {mWA: 0}, {wA: 1}, {wA: 2},1927 {wU: 1}, {wU: 2}, {mWA: 1}, {mWA: 2}1928 ])1929 })1930 it("should rebase its parent and itself but not laggard siblings when updating the parent during willAdd", function(){1931 let called = 0;1932 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1933 const r = diff(h(0, null), null, [renderer, tracker]);1934 let parent;1935 const managedTemp = h(1, hooks("ctor", f => parent = f), [h(2, hooks("willAdd", f => {1936 const temp = h(1, {some: "data"}, [h(2),h(3)]);1937 const res = diff(temp, parent);1938 expect(res).to.equal(parent);1939 expect(res.temp).to.equal(temp);1940 called++;1941 })), h(3)])1942 diff(managedTemp, null, r);1943 expect(called).to.equal(1);1944 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}, [h(2), h(3)]))));1945 expect(events).to.eql([1946 {wA: 0}, {mWA: 0}, {wA: 1}, {wA: 2},1947 {wU: 1}, {wU: 2}, {wA: 3}, {mWA: 1}, {mWA: 2}, {mWA: 3}1948 ])1949 })1950 it("should rebase its parent and itself onto the path when updating the parent during didAdd", function(){1951 let called = 0;1952 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1953 const r = diff(h(0, null), null, [renderer, tracker]);1954 let parent;1955 const managedTemp = h(1, hooks("ctor", f => parent = f), h(2, hooks("didAdd", f => {1956 const temp = h(1, {some: "data"}, h(2));1957 const res = diff(temp, parent);1958 expect(res).to.equal(parent);1959 expect(res.temp).to.equal(temp);1960 called++;1961 })))1962 diff(managedTemp, null, r);1963 expect(called).to.equal(1);1964 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}, h(2)))));1965 expect(events).to.eql([1966 {wA: 0}, {mWA: 0}, {wA: 1}, {wA: 2}, {mWA: 1}, {mWA: 2}, {dA: 2},1967 {wU: 1}, {wU: 2}, {mWR: 1}, {mWR: 2}1968 ])1969 })1970 it("should rebase an affector and itself onto the path when updating the affector during willAdd", function(){1971 let called = 0;1972 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1973 const renderer2 = new LCRSRenderer;1974 const r = diff(h(0, null), null, [renderer, tracker]);1975 const a = diff(h(1), null, r); // affector1976 const affectTemp = h(2, hooks("willAdd", f => {1977 f.sub(a);1978 const temp = h(1, {some: "data"});1979 const res = diff(temp, a);1980 expect(res).to.equal(a);1981 expect(res.temp).to.equal(temp);1982 called++;1983 }))1984 diff(affectTemp, null, [renderer2, tracker]);1985 expect(called).to.equal(1);1986 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}))));1987 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(affectTemp)))1988 expect(events).to.eql([1989 {wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}, 1990 {wA: 2}, {wU: 1}, {wU: 2}, {mWA: 2}, {mWR: 1}1991 ])1992 })1993 it("should rebase an affector and itself onto the path when updating the affector during didAdd", function(){1994 let called = 0;1995 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);1996 const renderer2 = new LCRSRenderer;1997 const r = diff(h(0, null), null, [renderer, tracker]);1998 const a = diff(h(1), null, r); // affector1999 const affectTemp = h(2, hooks("didAdd", f => {2000 f.sub(a);2001 const temp = h(1, {some: "data"});2002 const res = diff(temp, a);2003 expect(res).to.equal(a);2004 expect(res.temp).to.equal(temp);2005 called++;2006 }))2007 diff(affectTemp, null, [renderer2, tracker]);2008 expect(called).to.equal(1);2009 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}))));2010 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(affectTemp)))2011 expect(events).to.eql([2012 {wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}, 2013 {wA: 2}, {mWA: 2}, {dA: 2}, {wU: 1}, {wU: 2}, {mWR: 1}2014 ])2015 })2016 it("should not rebase laggard nodes, but should update their input temp when updating them during willAdd", function(){2017 let called = 0;2018 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2019 const data = {some: 'data'}2020 const temp = h(0, hooks("willAdd", f => {2021 const managed = diff(h(1, hooks("willAdd", f => {2022 expect(f.temp).to.eql(h(1, data));2023 called++;2024 })), null, f);2025 expect(managed).to.be.an.instanceOf(Frame);2026 const res = diff(h(1, data), managed);2027 expect(res).to.be.an.instanceOf(Frame);2028 }))2029 diff(temp, null, [renderer, tracker])2030 expect(called).to.equal(1);2031 expect(renderer.tree).to.eql(renderer.renderStatic(inject(copy(temp), h(1, data))));2032 expect(events).to.eql([{wA: 0}, {wA: 1}, {mWA: 0}, {mWA: 1}])2033 })2034 it("should not rebase laggard nodes, but should update their input temp when updating them during didAdd", function(){2035 let called = 0;2036 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2037 const data = {some: 'data'}2038 const temp = h(0, hooks("didAdd", f => {2039 const managed = diff(h(1, hooks("willAdd", f => {2040 expect(f.temp).to.eql(h(1, data));2041 called++;2042 })), null, f);2043 expect(managed).to.be.an.instanceOf(Frame);2044 const res = diff(h(1, data), managed);2045 expect(res).to.be.an.instanceOf(Frame);2046 }))2047 diff(temp, null, [renderer, tracker])2048 expect(called).to.equal(1);2049 expect(renderer.tree).to.eql(renderer.renderStatic(inject(copy(temp), h(1, data))));2050 expect(events).to.eql([{wA: 0}, {mWA: 0}, {dA: 0}, {wA: 1}, {mWA: 1}])2051 })2052 it("should rebase nodes that are not in the path when updating them during willAdd", function(){2053 let called = 0;2054 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2055 const renderer2 = new LCRSRenderer;2056 const r1 = diff(h(0, null), null, [renderer, tracker]);2057 const r2 = diff(h(1), null, r1);2058 const newTemp = h(1, {some:"data"});2059 const temp = h(2, hooks("willAdd", f => {2060 const res = diff(newTemp, r2);2061 expect(res).to.equal(r2)2062 expect(res.temp).to.equal(newTemp)2063 called++;2064 }))2065 events.length = 0;2066 diff(temp, null, [renderer2, tracker])2067 expect(called).to.equal(1);2068 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, newTemp)));2069 expect(renderer2.tree).to.eql(renderer2.renderStatic(temp))2070 expect(events).to.eql([{wA: 2}, {wU: 1}, {mWA: 2}, {mWR: 1}])2071 })2072 it("should rebase nodes that are not in the path when updating them during didAdd", function(){2073 let called = 0;2074 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2075 const renderer2 = new LCRSRenderer;2076 const r1 = diff(h(0, null), null, [renderer, tracker]);2077 const r2 = diff(h(1), null, r1);2078 const newTemp = h(1, {some:"data"});2079 const temp = h(2, hooks("didAdd", f => {2080 const res = diff(newTemp, r2);2081 expect(res).to.equal(r2)2082 expect(res.temp).to.equal(newTemp)2083 called++;2084 }))2085 events.length = 0;2086 diff(temp, null, [renderer2, tracker])2087 expect(called).to.equal(1);2088 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, newTemp)));2089 expect(renderer2.tree).to.eql(renderer2.renderStatic(temp))2090 expect(events).to.eql([{wA: 2}, {mWA: 2}, {dA: 2}, {wU: 1}, {mWR: 1}])2091 })2092 it("should rebase itself onto the path when updating itself during willUpdate", function(){2093 let called = 0;2094 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2095 const r = diff(h(0, null), null, [renderer, tracker]);2096 const managedTemp = h(1, hooks("willUpdate", f => {2097 if (called) return;2098 const temp = h(1, {some: "data"});2099 const res = diff(temp, f);2100 expect(res).to.equal(f);2101 expect(res.temp).to.equal(temp);2102 called++;2103 }))2104 const f = diff(managedTemp, null, r);2105 events.length = 0;2106 diff(copy(managedTemp), f);2107 expect(called).to.equal(1);2108 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}))));2109 expect(events).to.eql([{wU: 1}, {wU: 1}, {mWR: 1}])2110 })2111 it("should rebase itself onto the path when updating itself during didUpdate", function(){2112 let called = 0;2113 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2114 const r = diff(h(0, null), null, [renderer, tracker]);2115 const managedTemp = h(1, hooks("didUpdate", f => {2116 if (called) return;2117 const temp = h(1, {some: "data"});2118 const res = diff(temp, f);2119 expect(res).to.equal(f);2120 expect(res.temp).to.equal(temp);2121 called++;2122 }))2123 const f = diff(managedTemp, null, r);2124 events.length = 0;2125 diff(copy(managedTemp), f);2126 expect(called).to.equal(1);2127 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}))));2128 expect(events).to.eql([{wU: 1}, {mWR: 1}, {dU: 1}, {wU: 1}, {mWR: 1}, {dU: 1}])2129 })2130 it("should call didUpdate once and not call didAdd during the update if rebasing itself during willUpdated", function(){2131 let calledAdd = 0, calledUpd = 0, calledDidUpd = 0, calledDidAdd = 0;2132 const events = [], tracker = new Tracker(events);2133 const hooks = {2134 didUpdate: f => {2135 calledDidUpd++;2136 },2137 willAdd: f => {2138 calledAdd++;2139 },2140 didAdd: f => {2141 calledDidAdd++2142 },2143 willUpdate: f => {2144 if (!calledUpd++)2145 diff(copy(f.temp), f);2146 }2147 }2148 const f = diff(h(0, hooks), null, tracker);2149 events.length = 0;2150 diff(copy(f.temp), f);2151 expect(calledUpd).to.equal(2);2152 expect(calledAdd).to.equal(1);2153 expect(calledDidUpd).to.equal(1);2154 expect(calledDidAdd).to.equal(1);2155 expect(events).to.eql([{wU: 0}, {wU: 0}, {mWR: 0}, {dU: 0}])2156 })2157 it("should rebase its parent and itself onto the path when updating the parent during willUpdate", function(){2158 let called = 0;2159 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2160 const r = diff(h(0, null), null, [renderer, tracker]);2161 let parent;2162 const managedTemp = h(1, hooks("ctor", f => parent = f), h(2, hooks("willUpdate", f => {2163 if (called) return;2164 const temp = h(1, {some: "data"}, h(2));2165 const res = diff(temp, parent);2166 expect(res).to.equal(parent);2167 expect(res.temp).to.equal(temp);2168 called++;2169 })))2170 const f = diff(managedTemp, null, r);2171 events.length = 0;2172 diff(copy(managedTemp), f);2173 expect(called).to.equal(1);2174 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}, h(2)))));2175 expect(events).to.eql([2176 {wU: 1}, {wU: 2}, {wU: 1}, {wU: 2},2177 {mWR: 1}, {mWR: 2}2178 ])2179 })2180 it("should rebase its parent and itself but not laggard siblings when updating the parent during willUpdate", function(){2181 let called = 0;2182 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2183 const r = diff(h(0, null), null, [renderer, tracker]);2184 let parent;2185 const managedTemp = h(1, hooks("ctor", f => parent = f), [h(2, hooks("willUpdate", f => {2186 if (called) return;2187 const temp = h(1, {some: "data"}, [h(2), h(3)]);2188 const res = diff(temp, parent);2189 expect(res).to.equal(parent);2190 expect(res.temp).to.equal(temp);2191 called++;2192 }))])2193 const f = diff(managedTemp, null, r);2194 events.length = 0;2195 const temp = copy(managedTemp);2196 temp.next.push(h(3));2197 diff(temp, f);2198 expect(called).to.equal(1);2199 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}, [h(2), h(3)]))));2200 expect(events).to.eql([2201 {wU: 1}, {wU: 2}, {wU: 1}, {wU: 2}, {wA: 3},2202 {mWR: 1}, {mWR: 2}, {mWA: 3}2203 ])2204 })2205 it("should rebase its parent and itself onto the path when updating the parent during didUpdate", function(){2206 let called = 0;2207 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2208 const r = diff(h(0, null), null, [renderer, tracker]);2209 let parent;2210 const managedTemp = h(1, hooks("ctor", f => parent = f), h(2, hooks("didUpdate", f => {2211 if (called) return;2212 const temp = h(1, {some: "data"}, h(2));2213 const res = diff(temp, parent);2214 expect(res).to.equal(parent);2215 expect(res.temp).to.equal(temp);2216 called++;2217 })))2218 const f = diff(managedTemp, null, r);2219 events.length = 0;2220 diff(copy(managedTemp), f);2221 expect(called).to.equal(1);2222 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}, h(2)))));2223 expect(events).to.eql([2224 {wU: 1}, {wU: 2}, {mWR: 1}, {mWR: 2}, {dU: 2},2225 {wU: 1}, {wU: 2}, {mWR: 1}, {mWR: 2}, {dU: 2}2226 ])2227 })2228 it("should rebase an affector and itself onto the path when updating the affector during willUpdate", function(){2229 let called = 0;2230 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2231 const renderer2 = new LCRSRenderer;2232 const r = diff(h(0, null), null, [renderer, tracker]);2233 const a = diff(h(1), null, r); // affector2234 const affectTemp = h(2, hooks("willUpdate", f => {2235 if (called) return;2236 const temp = h(1, {some: "data"});2237 const res = diff(temp, a);2238 expect(res).to.equal(a);2239 expect(res.temp).to.equal(temp);2240 called++;2241 }))2242 const f = diff(affectTemp, null, [renderer2, tracker]);2243 f.sub(a);2244 events.length = 0;2245 diff(h(1), a);2246 expect(called).to.equal(1);2247 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}))));2248 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(affectTemp)))2249 expect(events).to.eql([2250 {wU: 1}, {wU: 2}, {wU: 1}, {wU: 2}, {mWR: 1}2251 ])2252 })2253 it("should rebase an affector and itself onto the path when updating the affector during didUpdate", function(){2254 let called = 0;2255 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2256 const renderer2 = new LCRSRenderer;2257 const r = diff(h(0, null), null, [renderer, tracker]);2258 const a = diff(h(1), null, r); // affector2259 const affectTemp = h(2, hooks("didUpdate", f => {2260 if (called) return;2261 const temp = h(1, {some: "data"});2262 const res = diff(temp, a);2263 expect(res).to.equal(a);2264 expect(res.temp).to.equal(temp);2265 called++;2266 }))2267 const f = diff(affectTemp, null, [renderer2, tracker]);2268 f.sub(a);2269 events.length = 0;2270 diff(h(1), a);2271 expect(called).to.equal(1);2272 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, h(1, {some: "data"}))));2273 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(affectTemp)))2274 expect(events).to.eql([2275 {wU: 1}, {wU: 2}, {mWR: 1}, {dU: 2},2276 {wU: 1}, {wU: 2}, {mWR: 1}, {dU: 2}2277 ])2278 })2279 it("should not rebase laggard nodes, but should update their input temp when updating them during willUpdate", function(){2280 let called = 0;2281 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2282 const data = {some: 'data'}2283 const temp = h(0, hooks("willUpdate", f => {2284 const managed = diff(h(1, hooks("willAdd", f => {2285 expect(f.temp).to.eql(h(1, data));2286 called++;2287 })), null, f);2288 expect(managed).to.be.an.instanceOf(Frame);2289 const res = diff(h(1, data), managed);2290 expect(res).to.be.an.instanceOf(Frame);2291 }))2292 const r1 = diff(temp, null, [renderer, tracker])2293 events.length = 0;2294 diff(copy(temp), r1);2295 expect(called).to.equal(1);2296 expect(renderer.tree).to.eql(renderer.renderStatic(inject(copy(temp), h(1, data))));2297 expect(events).to.eql([{wU: 0}, {wA: 1}, {mWR: 0}, {mWA: 1}])2298 })2299 it("should not rebase laggard nodes, but should update their input temp when updating them during didUpdate", function(){2300 let called = 0;2301 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2302 const data = {some: 'data'}2303 const temp = h(0, hooks("didUpdate", f => {2304 const managed = diff(h(1, hooks("willAdd", f => {2305 expect(f.temp).to.eql(h(1, data));2306 called++;2307 })), null, f);2308 expect(managed).to.be.an.instanceOf(Frame);2309 const res = diff(h(1, data), managed);2310 expect(res).to.be.an.instanceOf(Frame);2311 }))2312 const r1 = diff(temp, null, [renderer, tracker])2313 events.length = 0;2314 diff(copy(temp), r1);2315 expect(called).to.equal(1);2316 expect(renderer.tree).to.eql(renderer.renderStatic(inject(copy(temp), h(1, data))));2317 expect(events).to.eql([{wU: 0}, {mWR: 0}, {dU: 0}, {wA: 1}, {mWA: 1}])2318 })2319 it("should not rebase nodes that are in the path, but should update their input temp when updating them during willUpdate", function(){2320 let called = 0;2321 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2322 const temp1 = h(1, {some: "data"});2323 const temp2 = h(1, {other: "new data"});2324 const hooks = {2325 willAdd: f => {2326 f.managed = diff(h(1), null, f);2327 },2328 willUpdate: f => {2329 const res1 = diff(temp1, f.managed);2330 expect(res1).to.equal(f.managed);2331 expect(res1.temp).to.equal(temp1);2332 const res2 = diff(temp2, f.managed);2333 expect(res2).to.equal(f.managed);2334 expect(res2.temp).to.equal(temp2);2335 called++;2336 }2337 }2338 const temp = h(0, hooks);2339 const r1 = diff(temp, null, [renderer, tracker])2340 events.length = 0;2341 diff(copy(temp), r1);2342 expect(called).to.equal(1);2343 expect(renderer.tree).to.eql(renderer.renderStatic(inject(copy(temp), temp2)));2344 expect(events).to.eql([{wU: 0}, {wU: 1}, {mWR: 0}, {mWR: 1}])2345 })2346 it("should not rebase nodes that are in the path, but should update their input temp when updating them during didUpdate", function(){2347 let called = 0;2348 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2349 const temp1 = h(1, {some: "data"});2350 const temp2 = h(1, {other: "new data"});2351 const hooks = {2352 didUpdate: f => {2353 f.managed = diff(h(1), null, f);2354 const res1 = diff(temp1, f.managed);2355 expect(res1).to.equal(f.managed);2356 expect(res1.temp).to.equal(temp1);2357 const res2 = diff(temp2, f.managed);2358 expect(res2).to.equal(f.managed);2359 expect(res2.temp).to.equal(temp2);2360 called++;2361 }2362 }2363 const temp = h(0, hooks);2364 const r1 = diff(temp, null, [renderer, tracker])2365 events.length = 0;2366 diff(copy(temp), r1);2367 expect(called).to.equal(1);2368 expect(renderer.tree).to.eql(renderer.renderStatic(inject(copy(temp), temp2)));2369 expect(events).to.eql([{wU: 0}, {mWR: 0}, {dU: 0}, {wA: 1}, {mWA: 1}])2370 })2371 it("should rebase nodes that are not in the path when updating them during willUpdate", function(){2372 let called = 0;2373 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2374 const renderer2 = new LCRSRenderer;2375 const r1 = diff(h(0, null), null, [renderer, tracker]);2376 const r2 = diff(h(1), null, r1);2377 const newTemp = h(1, {some:"data"});2378 const temp = h(2, hooks("willUpdate", f => {2379 const res = diff(newTemp, r2);2380 expect(res).to.equal(r2)2381 expect(res.temp).to.equal(newTemp)2382 called++;2383 }))2384 const r3 = diff(temp, null, [renderer2, tracker])2385 events.length = 0;2386 diff(copy(temp), r3);2387 expect(called).to.equal(1);2388 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, newTemp)));2389 expect(renderer2.tree).to.eql(renderer2.renderStatic(temp))2390 expect(events).to.eql([{wU: 2}, {wU: 1}, {mWR: 2}, {mWR: 1}])2391 })2392 it("should rebase nodes that are not in the path when updating them during didUpdate", function(){2393 let called = 0;2394 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2395 const renderer2 = new LCRSRenderer;2396 const r1 = diff(h(0, null), null, [renderer, tracker]);2397 const r2 = diff(h(1), null, r1);2398 const newTemp = h(1, {some:"data"});2399 const temp = h(2, hooks("didUpdate", f => {2400 const res = diff(newTemp, r2);2401 expect(res).to.equal(r2)2402 expect(res.temp).to.equal(newTemp)2403 called++;2404 }))2405 const r3 = diff(temp, null, [renderer2, tracker])2406 events.length = 0;2407 diff(copy(temp), r3);2408 expect(called).to.equal(1);2409 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, newTemp)));2410 expect(renderer2.tree).to.eql(renderer2.renderStatic(temp))2411 expect(events).to.eql([{wU: 2}, {mWR: 2}, {dU: 2}, {wU: 1}, {mWR: 1}])2412 })2413 it("should properly rebase nodes that used to be in the path when updating them during willUpdate", function(){2414 let called = 0;2415 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2416 const newTemp = h(1, {some: "data"});2417 const r1 = diff(h(0, null), null, [renderer, tracker]);2418 const r2 = diff(h(1), null, r1);2419 const temp = h(2, hooks("willUpdate", f => {2420 const res = diff(newTemp, r2);2421 expect(res).to.equal(r2);2422 expect(res.temp).to.equal(newTemp)2423 called++;2424 }))2425 const r3 = diff(temp, null, r1)2426 r2.sub(r1), r3.sub(r1); //order matters here2427 events.length = 0;2428 diff(h(0, null), r1);2429 expect(called).to.equal(1);2430 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [copy(temp), newTemp])));2431 expect(events).to.eql([{wU: 0}, {wU: 1}, {wU: 2}, {wU: 1}, {mWR: 0}, {mWR: 1}])2432 })2433 it("should properly rebase nodes that used to be in the path when updating them during didUpdate", function(){2434 let called = 0;2435 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2436 const newTemp = h(1, {some: "data"});2437 const r1 = diff(h(0, null), null, [renderer, tracker]);2438 const r2 = diff(h(1), null, r1);2439 const temp = h(2, hooks("didUpdate", f => {2440 const res = diff(newTemp, r2);2441 expect(res).to.equal(r2);2442 expect(res.temp).to.equal(newTemp)2443 called++;2444 }))2445 const r3 = diff(temp, null, r1)2446 r2.sub(r1), r3.sub(r1); //order matters here2447 events.length = 0;2448 diff(h(0, null), r1);2449 expect(called).to.equal(1);2450 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [copy(temp), newTemp])));2451 expect(events).to.eql([{wU: 0}, {wU: 1}, {wU: 2}, {mWR: 0}, {dU: 2}, {wU: 1}, {mWR: 1}])2452 })2453 it("should properly rebase portions of a subtree that are not in the path when updating the subtree during willUpdate", function(){2454 let called = 02455 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2456 const newTemp = h(1, {some: "data"}, h(3, {other: "new data"}));2457 const r1 = diff(h(0, null), null, [renderer, tracker]);2458 const r2 = diff(h(1, null, h(3, hooks("willUpdate", f => {2459 expect(f.temp.data).to.equal(newTemp.next.data)2460 called++2461 }))), null, r1);2462 const temp = h(2, hooks("willUpdate", f => {2463 const res = diff(newTemp, r2);2464 expect(res).to.equal(r2);2465 expect(res.temp).to.equal(newTemp)2466 called++2467 }))2468 const r3 = diff(temp, null, r1)2469 r2.sub(r1), r3.sub(r1);2470 r2.next.sub(r3);2471 events.length = 0;2472 diff(h(0, null), r1);2473 expect(called).to.equal(2)2474 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [copy(temp), newTemp])));2475 expect(events).to.eql([2476 {wU: 0}, {wU: 1}, {wU: 2}, {wU: 1}, {wU: 3}, 2477 {mWR: 0}, {mWR: 3}, {mWR: 1}2478 ])2479 })2480 it("should properly rebase portions of a subtree that are not in the path when updating the subtree during didUpdate", function(){2481 let called = 0, calledDidUpd = 0;2482 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2483 const newTemp = h(1, {some: "data"}, h(3, {other: "new data"}));2484 const r1 = diff(h(0, null), null, [renderer, tracker]);2485 const r2 = diff(h(1, null, h(3, hooks("willUpdate", f => {2486 if (called++) expect(f.temp.data).to.equal(newTemp.next.data);2487 }))), null, r1);2488 const temp = h(2, hooks("didUpdate", f => {2489 const res = diff(newTemp, r2);2490 expect(res).to.equal(r2);2491 expect(res.temp).to.equal(newTemp)2492 calledDidUpd++2493 }))2494 const r3 = diff(temp, null, r1)2495 r2.sub(r1), r3.sub(r1);2496 r2.next.sub(r3);2497 events.length = 0;2498 diff(h(0, null), r1);2499 expect(called).to.equal(2)2500 expect(calledDidUpd).to.equal(1);2501 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [copy(temp), newTemp])));2502 expect(events).to.eql([2503 {wU: 0}, {wU: 1}, {wU: 2}, {wU: 3},2504 {mWR: 0}, {mWR: 3}, {dU: 2}, {wU: 1}, {wU: 3}, {mWR: 1}, {mWR: 3}2505 ])2506 })2507 it("should move multiple nodes during willAdd", function(){2508 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2509 const r1 = diff(h(0, null), null, [renderer, tracker]);2510 const managedRoot1 = diff(h(1), null, r1);2511 const managedRoot2 = diff(h(2), null, r1, managedRoot1);2512 const managedRoot3 = diff(h(3), null, r1, managedRoot2);2513 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))2514 let called = 0;2515 const temp = h(4, hooks("willAdd", f => {2516 expect(diff(managedRoot1.temp, managedRoot1, managedRoot3)).to.equal(managedRoot1);2517 expect(diff(managedRoot2.temp, managedRoot2, managedRoot3)).to.equal(managedRoot2);2518 expect(diff(managedRoot3.temp, managedRoot3, managedRoot1)).to.equal(managedRoot3);2519 called++;2520 }));2521 events.length = 0;2522 diff(temp, null, tracker);2523 expect(called).to.equal(1);2524 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(2), h(1), h(3)])))2525 expect(events).to.eql([2526 { wA: 4}, {mWA: 4}, {mWM: 2}2527 ])2528 })2529 it("should move multiple nodes during didAdd", function(){2530 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2531 const r1 = diff(h(0, null), null, [renderer, tracker]);2532 const managedRoot1 = diff(h(1), null, r1);2533 const managedRoot2 = diff(h(2), null, r1, managedRoot1);2534 const managedRoot3 = diff(h(3), null, r1, managedRoot2);2535 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))2536 let called = 0;2537 const temp = h(4, hooks("didAdd", f => {2538 expect(diff(managedRoot1.temp, managedRoot1, managedRoot3)).to.equal(managedRoot1);2539 expect(diff(managedRoot2.temp, managedRoot2, managedRoot3)).to.equal(managedRoot2);2540 expect(diff(managedRoot3.temp, managedRoot3, managedRoot1)).to.equal(managedRoot3);2541 called++;2542 }));2543 events.length = 0;2544 diff(temp, null, tracker);2545 expect(called).to.equal(1);2546 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(2), h(1), h(3)])))2547 expect(events).to.eql([2548 { wA: 4}, {mWA: 4}, {dA: 4}, {mWM: 2}2549 ])2550 })2551 it("should move multiple nodes during willUpdate", function(){2552 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2553 const r1 = diff(h(0, null), null, [renderer, tracker]);2554 const managedRoot1 = diff(h(1), null, r1);2555 const managedRoot2 = diff(h(2), null, r1, managedRoot1);2556 const managedRoot3 = diff(h(3), null, r1, managedRoot2);2557 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))2558 let called = 0;2559 const temp = h(4, hooks("willUpdate", f => {2560 expect(diff(managedRoot1.temp, managedRoot1, managedRoot3)).to.equal(managedRoot1);2561 expect(diff(managedRoot2.temp, managedRoot2, managedRoot3)).to.equal(managedRoot2);2562 expect(diff(managedRoot3.temp, managedRoot3, managedRoot1)).to.equal(managedRoot3);2563 called++;2564 }));2565 const r2 = diff(temp, null, tracker);2566 events.length = 0;2567 diff(copy(temp), r2);2568 expect(called).to.equal(1);2569 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(2), h(1), h(3)])))2570 expect(events).to.eql([2571 { wU: 4}, {mWR: 4}, {mWM: 2}2572 ])2573 })2574 it("should move multiple nodes during didUpdate", function(){2575 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2576 const r1 = diff(h(0, null), null, [renderer, tracker]);2577 const managedRoot1 = diff(h(1), null, r1);2578 const managedRoot2 = diff(h(2), null, r1, managedRoot1);2579 const managedRoot3 = diff(h(3), null, r1, managedRoot2);2580 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(1), h(2), h(3)])))2581 let called = 0;2582 const temp = h(4, hooks("didUpdate", f => {2583 expect(diff(managedRoot1.temp, managedRoot1, managedRoot3)).to.equal(managedRoot1);2584 expect(diff(managedRoot2.temp, managedRoot2, managedRoot3)).to.equal(managedRoot2);2585 expect(diff(managedRoot3.temp, managedRoot3, managedRoot1)).to.equal(managedRoot3);2586 called++;2587 }));2588 const r2 = diff(temp, null, tracker);2589 events.length = 0;2590 diff(copy(temp), r2);2591 expect(called).to.equal(1);2592 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, null, [h(2), h(1), h(3)])))2593 expect(events).to.eql([2594 { wU: 4}, {mWR: 4}, {dU: 4}, {mWM: 2}2595 ])2596 })2597 })2598 describe("free (unmanaged) nodes", function(){2599 it("should not update nodes during a constructor", function(){2600 let called = 0;2601 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2602 const r = diff(h(0), null, [renderer, tracker]);2603 diff(h(1, hooks("ctor", f => {2604 const res = diff(h(0, {some: "data"}), r);2605 expect(res).to.be.false;2606 called++2607 })))2608 expect(called).to.equal(1);2609 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));2610 expect(events).to.eql([{wA: 0}, {mWA: 0}])2611 })2612 it("should not update nodes during cleanup", function(){2613 let called = 0;2614 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2615 const r = diff(h(0), null, [renderer, tracker]);2616 const f = diff(h(1, hooks("ctor", f => {2617 const res = diff(h(0, {some: "data"}), r);2618 expect(res).to.be.false;2619 called++2620 })))2621 diff(null, f);2622 expect(called).to.equal(1);2623 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));2624 expect(events).to.eql([{wA: 0}, {mWA: 0}])2625 })2626 it("should not update nodes during add mutation event", function(){2627 let called = 0;2628 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2629 const r = diff(h(0), null, [renderer, tracker]);2630 diff(h(1), null, {add: f => {2631 const res = diff(h(0, {some: "data"}), r);2632 expect(res).to.be.false;2633 called++2634 }})2635 expect(called).to.equal(1);2636 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));2637 expect(events).to.eql([{wA: 0}, {mWA: 0}])2638 })2639 it("should not update nodes during remove mutation event", function(){2640 let called = 0;2641 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2642 const r = diff(h(0), null, [renderer, tracker]);2643 const f = diff(h(1), null, {remove: f => {2644 const res = diff(h(0, {some: "data"}), r);2645 expect(res).to.be.false;2646 called++2647 }})2648 diff(null, f);2649 expect(called).to.equal(1);2650 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));2651 expect(events).to.eql([{wA: 0}, {mWA: 0}])2652 })2653 it("should not update nodes during temp mutation event", function(){2654 let called = 0;2655 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2656 const r = diff(h(0), null, [renderer, tracker]);2657 const f = diff(h(1), null, {temp: f => {2658 const res = diff(h(0, {some: "data"}), r);2659 expect(res).to.be.false;2660 called++2661 }})2662 diff(h(1), f)2663 expect(called).to.equal(1);2664 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));2665 expect(events).to.eql([{wA: 0}, {mWA: 0}])2666 })2667 it("should not update nodes during move mutation event", function(){2668 let called = 0;2669 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2670 const r = diff(h(0), null, [renderer, tracker]);2671 const f = diff(h(1, null, [k(2), k(3)]), null, {move: f => {2672 if (f.temp.data.id === 3){2673 const res = diff(h(0, {some: "data"}), r);2674 expect(res).to.be.false;2675 called++2676 }2677 }})2678 diff(h(1, null, [k(3), k(2)]), f);2679 expect(called).to.equal(1);2680 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));2681 expect(events).to.eql([{wA: 0}, {mWA: 0}])2682 })2683 it("should rebase itself onto the path when updating itself during willAdd", function(){2684 let called = 0;2685 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2686 const managedTemp = h(0, hooks("willAdd", f => {2687 const temp = h(0, {some: "data"});2688 const res = diff(temp, f);2689 expect(res).to.equal(f);2690 expect(res.temp).to.equal(temp);2691 called++;2692 }))2693 diff(managedTemp, null, [renderer, tracker]);2694 expect(called).to.equal(1);2695 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"})));2696 expect(events).to.eql([{wA: 0}, {wU: 0}, {mWA: 0}])2697 })2698 it("should rebase itself onto the path when updating itself during didAdd", function(){2699 let called = 0;2700 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2701 const managedTemp = h(0, hooks("didAdd", f => {2702 const temp = h(0, {some: "data"});2703 const res = diff(temp, f);2704 expect(res).to.equal(f);2705 expect(res.temp).to.equal(temp);2706 called++;2707 }))2708 diff(managedTemp, null, [renderer, tracker]);2709 expect(called).to.equal(1);2710 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"})));2711 expect(events).to.eql([{wA: 0}, {mWA: 0}, {dA: 0}, {wU: 0}, {mWR: 0}])2712 })2713 it("should rebase its parent and itself onto the path when updating the parent during willAdd", function(){2714 let called = 0, parent;2715 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2716 const r = diff(h(0, hooks("ctor", f => parent = f), h(1, hooks("willAdd", f => {2717 const temp = h(0, {some: "data"}, h(1));2718 const res = diff(temp, parent);2719 expect(res).to.equal(parent);2720 expect(res.temp).to.equal(temp);2721 called++;2722 }))), null, [renderer, tracker]);2723 expect(called).to.equal(1);2724 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"}, h(1))));2725 expect(events).to.eql([2726 {wA: 0}, {wA: 1}, {wU: 0}, {wU: 1},2727 {mWA: 0}, {mWA: 1}2728 ])2729 })2730 it("should rebase its parent and itself but not laggard siblings when updating the parent during willAdd", function(){2731 let called = 0, parent;2732 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2733 const r = diff(h(0, hooks("ctor", f => parent = f), [h(1, hooks("willAdd", f => {2734 const temp = h(0, {some: "data"}, [h(1), h(2)]);2735 const res = diff(temp, parent);2736 expect(res).to.equal(parent);2737 expect(res.temp).to.equal(temp);2738 called++;2739 })), h(2)]), null, [renderer, tracker]);2740 expect(called).to.equal(1);2741 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"}, [h(1), h(2)])));2742 expect(events).to.eql([2743 {wA: 0}, {wA: 1}, {wU: 0}, {wU: 1}, {wA: 2},2744 {mWA: 0}, {mWA: 1}, {mWA: 2}2745 ])2746 })2747 it("should rebase its parent and itself onto the path when updating the parent during didAdd", function(){2748 let called = 0, parent;2749 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2750 const r = diff(h(0, hooks("ctor", f => parent = f), h(1, hooks("didAdd", f => {2751 const temp = h(0, {some: "data"}, h(1));2752 const res = diff(temp, parent);2753 expect(res).to.equal(parent);2754 expect(res.temp).to.equal(temp);2755 called++;2756 }))), null, [renderer, tracker]);2757 expect(called).to.equal(1);2758 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"}, h(1))));2759 expect(events).to.eql([2760 {wA: 0}, {wA: 1}, {mWA: 0}, {mWA: 1}, {dA: 1},2761 {wU: 0}, {wU: 1}, {mWR: 0}, {mWR: 1}2762 ])2763 })2764 it("should rebase an affector and itself onto the path when updating the affector during willAdd", function(){2765 let called = 0;2766 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2767 const renderer2 = new LCRSRenderer;2768 const a = diff(h(0), null, [renderer, tracker]);2769 const affectTemp = h(1, hooks("willAdd", f => {2770 f.sub(a);2771 const temp = h(0, {some: "data"});2772 const res = diff(temp, a);2773 expect(res).to.equal(a);2774 expect(res.temp).to.equal(temp);2775 called++;2776 }));2777 diff(affectTemp, null, [renderer2, tracker])2778 expect(called).to.equal(1);2779 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"})));2780 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(affectTemp)))2781 expect(events).to.eql([2782 {wA: 0}, {mWA: 0}, {wA: 1},2783 {wU: 0}, {wU: 1}, {mWA: 1}, {mWR: 0}2784 ])2785 })2786 it("should rebase an affector and itself onto the path when updating the affector during didAdd", function(){2787 let called = 0;2788 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2789 const renderer2 = new LCRSRenderer;2790 const a = diff(h(0), null, [renderer, tracker]);2791 const affectTemp = h(1, hooks("didAdd", f => {2792 f.sub(a);2793 const temp = h(0, {some: "data"});2794 const res = diff(temp, a);2795 expect(res).to.equal(a);2796 expect(res.temp).to.equal(temp);2797 called++;2798 }));2799 diff(affectTemp, null, [renderer2, tracker])2800 expect(called).to.equal(1);2801 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"})));2802 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(affectTemp)))2803 expect(events).to.eql([2804 {wA: 0}, {mWA: 0}, {wA: 1}, {mWA: 1}, {dA: 1},2805 {wU: 0}, {wU: 1}, {mWR: 0}2806 ])2807 })2808 it("should not rebase laggard nodes, but should update their input temp when updating them during willAdd", function(){2809 let called = 0;2810 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2811 const renderer2 = new LCRSRenderer2812 const data = {some: 'data'}2813 const temp = h(0, hooks("willAdd", f => {2814 const r = diff(h(1, hooks("willAdd", f => {2815 expect(f.temp).to.eql(h(1, data));2816 called++;2817 })), null, [renderer2, tracker]);2818 expect(r).to.be.an.instanceOf(Frame);2819 const res = diff(h(1, data), r);2820 expect(res).to.be.an.instanceOf(Frame);2821 }))2822 diff(temp, null, [renderer, tracker])2823 expect(called).to.equal(1);2824 expect(renderer.tree).to.eql(renderer.renderStatic(copy(temp)));2825 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(1, data)))2826 expect(events).to.eql([{wA: 0}, {wA: 1}, {mWA: 0}, {mWA: 1}])2827 })2828 it("should not rebase laggard nodes, but should update their input temp when updating them during didAdd", function(){2829 let called = 0;2830 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2831 const renderer2 = new LCRSRenderer2832 const data = {some: 'data'}2833 const temp = h(0, hooks("didAdd", f => {2834 const r = diff(h(1, hooks("willAdd", f => {2835 expect(f.temp).to.eql(h(1, data));2836 called++;2837 })), null, [renderer2, tracker]);2838 expect(r).to.be.an.instanceOf(Frame);2839 const res = diff(h(1, data), r);2840 expect(res).to.be.an.instanceOf(Frame);2841 }))2842 diff(temp, null, [renderer, tracker])2843 expect(called).to.equal(1);2844 expect(renderer.tree).to.eql(renderer.renderStatic(copy(temp)));2845 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(1, data)))2846 expect(events).to.eql([{wA: 0}, {mWA: 0}, {dA: 0}, {wA: 1}, {mWA: 1}])2847 })2848 it("should rebase nodes that are not in the path when updating them during willAdd", function(){2849 let called = 0;2850 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2851 const renderer2 = new LCRSRenderer;2852 const r1 = diff(h(0), null, [renderer, tracker]);2853 const newTemp = h(0, {some:"data"});2854 const temp = h(1, hooks("willAdd", f => {2855 const res = diff(newTemp, r1);2856 expect(res).to.equal(r1)2857 expect(res.temp).to.equal(newTemp)2858 called++;2859 }))2860 events.length = 0;2861 diff(temp, null, [renderer2, tracker])2862 expect(called).to.equal(1);2863 expect(renderer.tree).to.eql(renderer.renderStatic(newTemp));2864 expect(renderer2.tree).to.eql(renderer2.renderStatic(temp))2865 expect(events).to.eql([{wA: 1}, {wU: 0}, {mWA: 1}, {mWR: 0}])2866 })2867 it("should rebase nodes that are not in the path when updating them during didAdd", function(){2868 let called = 0;2869 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2870 const renderer2 = new LCRSRenderer;2871 const r1 = diff(h(0), null, [renderer, tracker]);2872 const newTemp = h(0, {some:"data"});2873 const temp = h(1, hooks("didAdd", f => {2874 const res = diff(newTemp, r1);2875 expect(res).to.equal(r1)2876 expect(res.temp).to.equal(newTemp)2877 called++;2878 }))2879 events.length = 0;2880 diff(temp, null, [renderer2, tracker])2881 expect(called).to.equal(1);2882 expect(renderer.tree).to.eql(renderer.renderStatic(newTemp));2883 expect(renderer2.tree).to.eql(renderer2.renderStatic(temp))2884 expect(events).to.eql([{wA: 1}, {mWA: 1}, {dA: 1}, {wU: 0}, {mWR: 0}])2885 })2886 it("should rebase itself onto the path when updating itself during willUpdate", function(){2887 let called = 0;2888 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2889 const temp = h(0, hooks("willUpdate", f => {2890 if (called) return;2891 const temp = h(0, {some: "data"});2892 const res = diff(temp, f);2893 expect(res).to.equal(f);2894 expect(res.temp).to.equal(temp);2895 called++;2896 }))2897 const f = diff(temp, null, [renderer, tracker]);2898 events.length = 0;2899 diff(copy(temp), f);2900 expect(called).to.equal(1);2901 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"})));2902 expect(events).to.eql([{wU: 0}, {wU: 0}, {mWR: 0}])2903 })2904 it("should rebase itself onto the path when updating itself during didUpdate", function(){2905 let called = 0;2906 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2907 const temp = h(0, hooks("didUpdate", f => {2908 if (called) return;2909 const temp = h(0, {some: "data"});2910 const res = diff(temp, f);2911 expect(res).to.equal(f);2912 expect(res.temp).to.equal(temp);2913 called++;2914 }))2915 const f = diff(temp, null, [renderer, tracker]);2916 events.length = 0;2917 diff(copy(temp), f);2918 expect(called).to.equal(1);2919 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"})));2920 expect(events).to.eql([{wU: 0}, {mWR: 0}, {dU: 0}, {wU: 0}, {mWR: 0}, {dU: 0}])2921 })2922 it("should rebase its parent and itself onto the path when updating the parent during willUpdate", function(){2923 let called = 0, parent;2924 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2925 const temp = h(0, hooks("ctor", f => parent = f), h(1, hooks("willUpdate", f => {2926 if (called) return;2927 const temp = h(0, {some: "data"}, h(1));2928 const res = diff(temp, parent);2929 expect(res).to.equal(parent);2930 expect(res.temp).to.equal(temp);2931 called++;2932 })))2933 const f = diff(temp, null, [renderer, tracker]);2934 events.length = 0;2935 diff(copy(temp), f);2936 expect(called).to.equal(1);2937 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"}, h(1))));2938 expect(events).to.eql([2939 {wU: 0}, {wU: 1}, {wU: 0}, {wU: 1},2940 {mWR: 0}, {mWR: 1}2941 ])2942 })2943 it("should rebase its parent and itself but not laggard siblings when updating the parent during willUpdate", function(){2944 let called = 0, parent;2945 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2946 const temp = h(0, hooks("ctor", f => parent = f), [h(1, hooks("willUpdate", f => {2947 if (called) return;2948 const temp = h(0, {some: "data"}, [h(1), h(2)]);2949 const res = diff(temp, parent);2950 expect(res).to.equal(parent);2951 expect(res.temp).to.equal(temp);2952 called++;2953 }))])2954 const f = diff(temp, null, [renderer, tracker]);2955 events.length = 0;2956 const copyTemp = copy(temp);2957 copyTemp.next.push(h(2));2958 diff(copyTemp, f);2959 expect(called).to.equal(1);2960 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"}, [h(1), h(2)])));2961 expect(events).to.eql([2962 {wU: 0}, {wU: 1}, {wU: 0}, {wU: 1}, {wA: 2},2963 {mWR: 0}, {mWR: 1}, {mWA: 2}2964 ])2965 })2966 it("should rebase its parent and itself onto the path when updating the parent during didUpdate", function(){2967 let called = 0, parent;2968 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2969 const temp = h(0, hooks("ctor", f => parent = f), h(1, hooks("didUpdate", f => {2970 if (called) return;2971 const temp = h(0, {some: "data"}, h(1));2972 const res = diff(temp, parent);2973 expect(res).to.equal(parent);2974 expect(res.temp).to.equal(temp);2975 called++;2976 })))2977 const f = diff(temp, null, [renderer, tracker]);2978 events.length = 0;2979 diff(copy(temp), f);2980 expect(called).to.equal(1);2981 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"}, h(1))));2982 expect(events).to.eql([2983 {wU: 0}, {wU: 1}, {mWR: 0}, {mWR: 1}, {dU: 1},2984 {wU: 0}, {wU: 1}, {mWR: 0}, {mWR: 1}, {dU: 1}2985 ])2986 })2987 it("should rebase an affector and itself onto the path when updating the affector during willUpdate", function(){2988 let called = 0;2989 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);2990 const renderer2 = new LCRSRenderer;2991 const a = diff(h(0), null, [renderer, tracker]); // affector2992 const affectTemp = h(1, hooks("willUpdate", f => {2993 if (called) return;2994 const temp = h(0, {some: "data"});2995 const res = diff(temp, a);2996 expect(res).to.equal(a);2997 expect(res.temp).to.equal(temp);2998 called++;2999 }))3000 const f = diff(affectTemp, null, [renderer2, tracker]);3001 f.sub(a);3002 events.length = 0;3003 diff(h(0), a);3004 expect(called).to.equal(1);3005 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"})));3006 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(affectTemp)))3007 expect(events).to.eql([3008 {wU: 0}, {wU: 1}, {wU: 0}, {wU: 1}, {mWR: 0}3009 ])3010 })3011 it("should rebase an affector and itself onto the path when updating the affector during didUpdate", function(){3012 let called = 0;3013 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);3014 const renderer2 = new LCRSRenderer;3015 const a = diff(h(0), null, [renderer, tracker]); // affector3016 const affectTemp = h(1, hooks("didUpdate", f => {3017 if (called) return;3018 const temp = h(0, {some: "data"});3019 const res = diff(temp, a);3020 expect(res).to.equal(a);3021 expect(res.temp).to.equal(temp);3022 called++;3023 }))3024 const f = diff(affectTemp, null, [renderer2, tracker]);3025 f.sub(a);3026 events.length = 0;3027 diff(h(0), a);3028 expect(called).to.equal(1);3029 expect(renderer.tree).to.eql(renderer.renderStatic(h(0, {some: "data"})));3030 expect(renderer2.tree).to.eql(renderer2.renderStatic(copy(affectTemp)))3031 expect(events).to.eql([3032 {wU: 0}, {wU: 1}, {mWR: 0}, {dU: 1},3033 {wU: 0}, {wU: 1}, {mWR: 0}, {dU: 1}3034 ])3035 })3036 it("should not rebase laggard nodes, but should update their input temp when updating them during willUpdate", function(){3037 let called = 0;3038 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);3039 const renderer2 = new LCRSRenderer3040 const data = {some: 'data'}3041 const temp = h(0, hooks("willUpdate", f => {3042 const r = diff(h(1, hooks("willAdd", f => {3043 expect(f.temp).to.eql(h(1, data));3044 called++;3045 })), null, [renderer2, tracker]);3046 expect(r).to.be.an.instanceOf(Frame);3047 const res = diff(h(1, data), r);3048 expect(res).to.be.an.instanceOf(Frame);3049 }))3050 const r1 = diff(temp, null, [renderer, tracker])3051 events.length = 0;3052 diff(copy(temp), r1);3053 expect(called).to.equal(1);3054 expect(renderer.tree).to.eql(renderer.renderStatic(copy(temp)));3055 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(1, data)))3056 expect(events).to.eql([{wU: 0}, {wA: 1}, {mWR: 0}, {mWA: 1}])3057 })3058 it("should not rebase laggard nodes, but should update their input temp when updating them during didUpdate", function(){3059 let called = 0;3060 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);3061 const renderer2 = new LCRSRenderer3062 const data = {some: 'data'}3063 const temp = h(0, hooks("didUpdate", f => {3064 const r = diff(h(1, hooks("willAdd", f => {3065 expect(f.temp).to.eql(h(1, data));3066 called++;3067 })), null, [renderer2, tracker]);3068 expect(r).to.be.an.instanceOf(Frame);3069 const res = diff(h(1, data), r);3070 expect(res).to.be.an.instanceOf(Frame);3071 }))3072 const r1 = diff(temp, null, [renderer, tracker])3073 events.length = 0;3074 diff(copy(temp), r1);3075 expect(called).to.equal(1);3076 expect(renderer.tree).to.eql(renderer.renderStatic(copy(temp)));3077 expect(renderer2.tree).to.eql(renderer2.renderStatic(h(1, data)))3078 expect(events).to.eql([{wU: 0}, {mWR: 0}, {dU: 0}, {wA: 1}, {mWA: 1}])3079 })3080 it("should not rebase nodes that are in the path, but should update their input temp when updating them during willUpdate", function(){3081 let called = 0, r;3082 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);3083 const renderer2 = new LCRSRenderer;3084 const temp1 = h(1, {some: "data"});3085 const temp2 = h(1, {other: "new data"});3086 const hooks = {3087 willAdd: f => {3088 r = diff(h(1), null, [renderer2, tracker]);3089 },3090 willUpdate: f => {3091 const res1 = diff(temp1, r);3092 expect(res1).to.equal(r);3093 expect(res1.temp).to.equal(temp1);3094 const res2 = diff(temp2, r);3095 expect(res2).to.equal(r);3096 expect(res2.temp).to.equal(temp2);3097 called++;3098 }3099 }3100 const temp = h(0, hooks);3101 const r1 = diff(temp, null, [renderer, tracker])3102 events.length = 0;3103 diff(copy(temp), r1);3104 expect(called).to.equal(1);3105 expect(renderer.tree).to.eql(renderer.renderStatic(copy(temp)));3106 expect(renderer2.tree).to.eql(renderer2.renderStatic(temp2));3107 expect(events).to.eql([{wU: 0}, {wU: 1}, {mWR: 0}, {mWR: 1}])3108 })3109 it("should not rebase nodes that are in the path, but should update their input temp when updating them during didUpdate", function(){3110 let called = 0, r;3111 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);3112 const renderer2 = new LCRSRenderer;3113 const temp1 = h(1, {some: "data"});3114 const temp2 = h(1, {other: "new data"});3115 const hooks = {3116 didUpdate: f => {3117 const r = diff(h(1), null, [renderer2, tracker]);3118 const res1 = diff(temp1, r);3119 expect(res1).to.equal(r);3120 expect(res1.temp).to.equal(temp1);3121 const res2 = diff(temp2, r);3122 expect(res2).to.equal(r);3123 expect(res2.temp).to.equal(temp2);3124 called++;3125 }3126 }3127 const temp = h(0, hooks);3128 const r1 = diff(temp, null, [renderer, tracker])3129 events.length = 0;3130 diff(copy(temp), r1);3131 expect(called).to.equal(1);3132 expect(renderer.tree).to.eql(renderer.renderStatic(copy(temp)));3133 expect(renderer2.tree).to.eql(renderer2.renderStatic(temp2));3134 expect(events).to.eql([{wU: 0}, {mWR: 0}, {dU: 0}, {wA: 1}, {mWA: 1}])3135 })3136 it("should rebase nodes that are not in the path when updating them during willUpdate", function(){3137 let called = 0;3138 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);3139 const renderer2 = new LCRSRenderer;3140 const r1 = diff(h(0), null, [renderer, tracker]);3141 const newTemp = h(0, {some:"data"});3142 const temp = h(1, hooks("willUpdate", f => {3143 const res = diff(newTemp, r1);3144 expect(res).to.equal(r1)3145 expect(res.temp).to.equal(newTemp)3146 called++;3147 }))3148 const f = diff(temp, null, [renderer2, tracker])3149 events.length = 0;3150 diff(copy(temp), f);3151 expect(called).to.equal(1);3152 expect(renderer.tree).to.eql(renderer.renderStatic(newTemp));3153 expect(renderer2.tree).to.eql(renderer2.renderStatic(temp))3154 expect(events).to.eql([{wU: 1}, {wU: 0}, {mWR: 1}, {mWR: 0}])3155 })3156 it("should rebase nodes that are not in the path when updating them during didUpdate", function(){3157 let called = 0;3158 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);3159 const renderer2 = new LCRSRenderer;3160 const r1 = diff(h(0), null, [renderer, tracker]);3161 const newTemp = h(0, {some:"data"});3162 const temp = h(1, hooks("didUpdate", f => {3163 const res = diff(newTemp, r1);3164 expect(res).to.equal(r1)3165 expect(res.temp).to.equal(newTemp)3166 called++;3167 }))3168 const f = diff(temp, null, [renderer2, tracker])3169 events.length = 0;3170 diff(copy(temp), f);3171 expect(called).to.equal(1);3172 expect(renderer.tree).to.eql(renderer.renderStatic(newTemp));3173 expect(renderer2.tree).to.eql(renderer2.renderStatic(temp))3174 expect(events).to.eql([{wU: 1}, {mWR: 1}, {dU: 1}, {wU: 0}, {mWR: 0}])3175 })3176 it("should properly rebase nodes that used to be in the path when updating them during willUpdate", function(){3177 let called = 0;3178 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);3179 const renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;3180 const newTemp = h(1, {some: "data"});3181 const r1 = diff(h(0), null, [renderer, tracker]);3182 const r2 = diff(h(1), null, [renderer2, tracker]);3183 const temp = h(2, hooks("willUpdate", f => {3184 const res = diff(newTemp, r2);3185 expect(res).to.equal(r2);3186 expect(res.temp).to.equal(newTemp)3187 called++;3188 }))3189 const r3 = diff(temp, null, [renderer3, tracker])3190 r2.sub(r1), r3.sub(r1);3191 events.length = 0;3192 diff(h(0), r1);3193 expect(called).to.equal(1);3194 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));3195 expect(renderer2.tree).to.eql(renderer2.renderStatic(newTemp));3196 expect(renderer3.tree).to.eql(renderer3.renderStatic(copy(temp)));3197 expect(events).to.eql([{wU: 0}, {wU: 1}, {wU: 2}, {wU: 1}, {mWR: 0}, {mWR: 1}])3198 })3199 it("should properly rebase nodes that used to be in the path when updating them during didUpdate", function(){3200 let called = 0;3201 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);3202 const renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;3203 const newTemp = h(1, {some: "data"});3204 const r1 = diff(h(0), null, [renderer, tracker]);3205 const r2 = diff(h(1), null, [renderer2, tracker]);3206 const temp = h(2, hooks("didUpdate", f => {3207 const res = diff(newTemp, r2);3208 expect(res).to.equal(r2);3209 expect(res.temp).to.equal(newTemp)3210 called++;3211 }))3212 const r3 = diff(temp, null, [renderer3, tracker])3213 r2.sub(r1), r3.sub(r1);3214 events.length = 0;3215 diff(h(0), r1);3216 expect(called).to.equal(1);3217 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));3218 expect(renderer2.tree).to.eql(renderer2.renderStatic(newTemp));3219 expect(renderer3.tree).to.eql(renderer3.renderStatic(copy(temp)));3220 expect(events).to.eql([{wU: 0}, {wU: 1}, {wU: 2}, {mWR: 0}, {dU: 2}, {wU: 1}, {mWR: 1}])3221 })3222 it("should properly rebase portions of a subtree that are not in the path when updating the subtree during willUpdate", function(){3223 let calledUpd = 0, calledUpd2 = 0;3224 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);3225 const renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;3226 const newTemp = h(1, {some: "data"}, h(3, {other: "new data"}));3227 const r1 = diff(h(0), null, [renderer, tracker]);3228 const r2 = diff(h(1, null, h(3, hooks("willUpdate", f => {3229 expect(f.temp.data).to.equal(newTemp.next.data)3230 calledUpd++3231 }))), null, [renderer2, tracker]);3232 const temp = h(2, hooks("willUpdate", f => {3233 const res = diff(newTemp, r2);3234 expect(res).to.equal(r2);3235 expect(res.temp).to.equal(newTemp)3236 calledUpd2++3237 }))3238 const r3 = diff(temp, null, [renderer3, tracker])3239 r2.sub(r1), r3.sub(r1);3240 r2.next.sub(r3);3241 events.length = 0;3242 diff(h(0), r1);3243 expect(calledUpd).to.equal(1);3244 expect(calledUpd2).to.equal(1);3245 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));3246 expect(renderer2.tree).to.eql(renderer2.renderStatic(newTemp));3247 expect(renderer3.tree).to.eql(renderer3.renderStatic(copy(temp)));3248 expect(events).to.eql([3249 {wU: 0}, {wU: 1}, {wU: 2}, {wU: 1}, {wU: 3}, 3250 {mWR: 0}, {mWR: 3}, {mWR: 1}3251 ])3252 })3253 it("should properly rebase portions of a subtree that are not in the path when updating the subtree during willUpdate", function(){3254 let calledUpd = 0, calledUpd2 = 0;3255 const events = [], renderer = new LCRSRenderer, tracker = new Tracker(events);3256 const renderer2 = new LCRSRenderer, renderer3 = new LCRSRenderer;3257 const newTemp = h(1, {some: "data"}, h(3, {other: "new data"}));3258 const r1 = diff(h(0), null, [renderer, tracker]);3259 const r2 = diff(h(1, null, h(3, hooks("willUpdate", f => {3260 if (calledUpd++) expect(f.temp.data).to.equal(newTemp.next.data)3261 }))), null, [renderer2, tracker]);3262 const temp = h(2, hooks("didUpdate", f => {3263 const res = diff(newTemp, r2);3264 expect(res).to.equal(r2);3265 expect(res.temp).to.equal(newTemp)3266 calledUpd2++3267 }))3268 const r3 = diff(temp, null, [renderer3, tracker])3269 r2.sub(r1), r3.sub(r1);3270 r2.next.sub(r3);3271 events.length = 0;3272 diff(h(0), r1);3273 expect(calledUpd).to.equal(2);3274 expect(calledUpd2).to.equal(1);3275 expect(renderer.tree).to.eql(renderer.renderStatic(h(0)));3276 expect(renderer2.tree).to.eql(renderer2.renderStatic(newTemp));3277 expect(renderer3.tree).to.eql(renderer3.renderStatic(copy(temp)));3278 expect(events).to.eql([3279 {wU: 0}, {wU: 1}, {wU: 2}, {wU: 3}, 3280 {mWR: 0}, {mWR: 3}, {dU: 2}, {wU: 1}, {wU: 3}, {mWR: 1}, {mWR: 3}3281 ])3282 })3283 })3284 })3285 describe("updating (sync inner-diffs)", function(){3286 it("should not update nodes during a constructor", function(){3287 let called = 0;3288 const events = [], tracker = new Tracker(events);3289 const r = diff(h(0), null, tracker);3290 diff(h(1, hooks("ctor", f => {3291 expect(r.setState({n: 0})).to.be.false;...
server.js
Source:server.js
...35});36// Getting "/"37server.get("/", (req, res) => {38 console.log("get request to /");39 // Incorporate Aphrodite's StyleSheetServer.renderStatic() function into the standard ReactDomServer function40 const { html, css } = StyleSheetServer.renderStatic(() => {41 return ReactDOMServer.renderToString(42 <>43 <Navbar />44 <Bio />45 </>46 );47 });48 res.send(`49<html>50<head>51<title>SSR React App</title>52<style data-aphrodite>${css.content}</style>53</head>54<body style="margin:0px;font-family:Helvetica Neue" id="body">55<div id="mountNode">${html}</div>56<script src="../dist/main.js"></script>57</body>58</html>59`);60});61// Getting "/experience"62server.get("/experience", (req, res) => {63 console.log("get request to /experience");64 // Incorporate Aphrodite's StyleSheetServer.renderStatic() function into the standard ReactDomServer function65 const { html, css } = StyleSheetServer.renderStatic(() => {66 return ReactDOMServer.renderToString(67 <>68 <Navbar />69 <Experience />70 </>71 );72 });73 res.send(`74<html>75<head>76<title>SSR React App</title>77<style data-aphrodite>${css.content}</style>78</head>79<body style="margin:0px;font-family:Helvetica Neue" id="body">80<div id="mountNode">${html}</div>81<script src="../dist/main.js"></script>82</body>83</html>84`);85});86// Getting "/skills"87server.get("/skills", (req, res) => {88 console.log("get request to /skills");89 // Incorporate Aphrodite's StyleSheetServer.renderStatic() function into the standard ReactDomServer function90 const { html, css } = StyleSheetServer.renderStatic(() => {91 return ReactDOMServer.renderToString(92 <>93 <Navbar />94 <Skills />95 </>96 );97 });98 res.send(`99<html>100<head>101<title>SSR React App</title>102<style data-aphrodite>${css.content}</style>103</head>104<body style="margin:0px;font-family:Helvetica Neue" id="body">105<div id="mountNode">${html}</div>106<script src="../dist/main.js"></script>107</body>108</html>109`);110});111// Getting "/education"112server.get("/education", (req, res) => {113 console.log("get request to /education");114 // Incorporate Aphrodite's StyleSheetServer.renderStatic() function into the standard ReactDomServer function115 const { html, css } = StyleSheetServer.renderStatic(() => {116 return ReactDOMServer.renderToString(117 <>118 <Navbar />119 <Education />120 </>121 );122 });123 res.send(`124 <html>125 <head>126 <title>SSR React App</title>127 </head>128 <body style="margin:0px;font-family:Helvetica Neue" id="body">129 <div id="mountNode">${html}</div>130 <script src="dist/main.js"></script>131 </body>132 </html>133 `);134});135// Getting "/education"136server.get("/portfolio", (req, res) => {137 console.log("get request to /portfolio");138 res.redirect("https://yuri-dubler-portfolio.herokuapp.com");139});140// Getting "/resume"141server.get("/resume", (req, res) => {142 console.log("get request to /resume");143 // Incorporate Aphrodite's StyleSheetServer.renderStatic() function into the standard ReactDomServer function144 // const { html, css } = StyleSheetServer.renderStatic(() => {145 // return ReactDOMServer.renderToString(146 // <>147 // <Navbar />148 // <Resume />149 // </>150 // );151 // });152 // res.send(`153 // <html>154 // <head>155 // <title>SSR React App</title>156 // </head>157 // <body style="margin:0px;font-family:Helvetica Neue" id="body">158 // <div id="mountNode">${html}</div>159 // <script src="dist/main.js"></script>160 // </body>161 // </html>162 // `);163 //GOOD;164 var file = fs.createReadStream(__dirname + "/public/Resume-Yuri-Dubler.pdf");165 var stat = fs.statSync(__dirname + "/public/Resume-Yuri-Dubler.pdf");166 res.setHeader("Content-Length", stat.size);167 res.setHeader("Content-Type", "application/pdf");168 res.setHeader(169 "Content-Disposition",170 "attachment; filename=Resume-Yuri-Dubler.pdf"171 );172 file.pipe(res);173 // BAD174 // var path = require("path");175 // var file = path.join(__dirname, "/public/testResume.pdf");176 // res.setHeader("Content-Type", "application/pdf");177 // res.download(file);178 // res.download(__dirname + "/public/testResume.pdf");179});180// Getting "/articles"181server.get("/articles", (req, res) => {182 console.log("get request to /articles");183 // Incorporate Aphrodite's StyleSheetServer.renderStatic() function into the standard ReactDomServer function184 const { html, css } = StyleSheetServer.renderStatic(() => {185 return ReactDOMServer.renderToString(186 <>187 <Navbar />188 <Articles />189 </>190 );191 });192 res.send(`193 <html>194 <head>195 <title>SSR React App</title>196 <style data-aphrodite>${css.content}</style>197 </head>198 <body style="margin:0px;font-family:Helvetica Neue" id="body">199 <div id="mountNode">${html}</div>200 <script src="dist/main.js"></script>201 </body>202 </html>203 `);204});205// Getting "/3d-models"206server.get("/3dmodels", (req, res) => {207 console.log("get request to /3dmodels");208 // Incorporate Aphrodite's StyleSheetServer.renderStatic() function into the standard ReactDomServer function209 const { html, css } = StyleSheetServer.renderStatic(() => {210 return ReactDOMServer.renderToString(211 <>212 <Navbar />213 <ThreeDModels />214 </>215 );216 });217 res.send(`218 <html>219 <head>220 <title>SSR React App</title>221 <style data-aphrodite>${css.content}</style>222 </head>223 <body style="margin:0px;font-family:Helvetica Neue" id="body">224 <div id="mountNode">${html}</div>225 <script src="dist/main.js"></script>226 </body>227 </html>228 `);229});230// Getting "/contact"231server.get("/contact", (req, res) => {232 console.log("get request to /contact");233 // Incorporate Aphrodite's StyleSheetServer.renderStatic() function into the standard ReactDomServer function234 const { html, css } = StyleSheetServer.renderStatic(() => {235 return ReactDOMServer.renderToString(236 <>237 <Navbar />238 <Contact />239 </>240 );241 });242 res.send(`243 <html>244 <head>245 <title>SSR React App</title>246 <style data-aphrodite>${css.content}</style>247 </head>248 <body style="margin:0px;font-family:Helvetica Neue" id="body">249 <div id="mountNode">${html}</div>250 <script src="dist/main.js"></script>251 </body>252 </html>253 `);254});255// Getting "/articles/insertion-sort"256server.get("/articles/insertion-sort", (req, res) => {257 console.log("get request to /articles/insertion-sort");258 // Incorporate Aphrodite's StyleSheetServer.renderStatic() function into the standard ReactDomServer function259 const { html, css } = StyleSheetServer.renderStatic(() => {260 return ReactDOMServer.renderToString(261 <>262 <Navbar />263 <InsertionSort />264 </>265 );266 });267 res.send(`268 <html>269 <head>270 <title>SSR React App</title>271 <style data-aphrodite>${css.content}</style>272 </head>273 <body style="margin:0px;font-family:Helvetica Neue" id="body">...
build.js
Source:build.js
...112 urls,113 async location => {114 debug(`'${location}': prepend file and deps`);115 try {116 const files = await renderStatic({117 app,118 assets,119 location,120 });121 debug(`'${location}': files & deps collected`, files);122 return Promise.all(123 files.map(file =>124 writeFile(125 path.join(config.outdir, decodeURIComponent(file.path)),126 file.contents,127 ),128 ),129 );130 } catch (e) {...
index.js
Source:index.js
...12 localAlias: ['Nunito', 'Nunito Bold', 'Nunito-Bold'],13 unicodeRange:14 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD',15 })16 renderer.renderStatic(17 {18 boxSizing: 'border-box',19 },20 '*'21 )22 renderer.renderStatic(23 {24 margin: 0,25 fontFamily:26 "'Nunito', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif",27 WebkitFontSmoothing: 'antialiased',28 MozOsxFontSmoothing: 'grayscale',29 backgroundImage: "url('/assets/images/background.jpg')",30 backgroundRepeat: 'repeat',31 backgroundColor: '#101f26',32 color: 'var(--white)',33 },34 'body'35 )36 renderer.renderStatic(37 {38 scrollPaddingTop: '2em',39 // Game colors40 '--beige': '#e2d7af',41 '--dark-beige': '#9b8e70',42 '--light-blue': '#2e5662',43 '--dark-blue': '#20353f',44 '--green': '#36786d',45 '--black': '#101f26',46 '--white': '#f5f2e5',47 '--yellow': '#d0b84c',48 // Faction colors49 '--neutral': '#4e5659',50 '--swarm': '#604830',51 '--ironclad': '#824648',52 '--shadowfen': '#30655d',53 '--winter': '#405477',54 '--light-swarm': '#b89571',55 '--light-ironclad': '#b6787a',56 '--light-shadowfen': '#56afa1',57 '--light-winter': '#6680ad',58 // Card colors59 '--affordable': '#6be79c',60 '--upgradable': '#e7d146',61 // Battle sim colors62 '--player-red': '#cb2b43',63 '--player-blue': '#195d9c',64 '--poison': '#700470',65 '--freeze': '#60adc7',66 '--confused': '#c59948',67 '--vitalized': '#24e071',68 '--disabled': '#a52086',69 // League colors70 '--starter': 'currentcolor',71 '--iron': '#d3d1cc',72 '--bronze': '#e2c3b7',73 '--silver': '#d6d9e2',74 '--gold': '#f1e0be',75 '--platinum': '#c0e0cf',76 '--diamond': '#c8c0df',77 '--heroes': '#caf9ff',78 // Rarity colors79 '--common': '#f5f1e5',80 '--common-bright': '#97927b',81 '--rare': '#95d7f9',82 '--rare-bright': '#1faee0',83 '--epic': '#dba8f5',84 '--epic-bright': '#c45de6',85 '--legendary': '#f5c79f',86 '--legendary-bright': '#e88931',87 // Spacing variables88 '--s-smallest': SPACING_TOKENS.SMALLEST,89 '--s-smaller': SPACING_TOKENS.SMALLER,90 '--s-small': SPACING_TOKENS.SMALL,91 '--s-base': SPACING_TOKENS.BASE,92 '--s-large': SPACING_TOKENS.LARGE,93 '--s-larger': SPACING_TOKENS.LARGER,94 '--s-largest': SPACING_TOKENS.LARGEST,95 // Typically injected by @reach/tooltip96 '--reach-tooltip': 1,97 },98 ':root'99 )100 renderer.renderStatic(101 {102 minHeight: '100%',103 overflowX: 'hidden',104 },105 'html'106 )107 renderer.renderStatic(108 {109 font: 'inherit',110 },111 'button'112 )113 renderer.renderStatic(114 {115 display: 'flex',116 flexDirection: 'column',117 flex: '1 1 auto',118 },119 'html, body, #__next'120 )121 renderer.renderStatic(122 {123 display: 'none !important',124 },125 '[hidden]'126 )127 renderer.renderStatic(128 {129 marginTop: 0,130 marginBottom: 'var(--s-base)',131 },132 'p'133 )134 // This will hide the focus indicator if the element receives focus via the135 // mouse, but it will still show up on keyboard focus.136 renderer.renderStatic(137 {138 outline: 'none',139 },140 '.js-focus-visible :focus:not(.focus-visible)'141 )142 renderer.renderStatic(143 {144 color: 'var(--black)',145 },146 'option'147 )148 renderer.renderStatic(149 {150 padding: 0,151 margin: 0,152 border: 0,153 },154 'fieldset'155 )156 renderer.renderStatic(157 {158 color: 'var(--beige)',159 fontWeight: 'normal',160 },161 '.Highlight'162 )163 renderer.renderStatic(164 {165 color: 'var(--beige)',166 fontSize: '110%',167 },168 'code'169 )170 renderer.renderStatic(171 {172 borderBottom: '1px dotted',173 textDecoration: 'none',174 cursor: 'help',175 },176 'abbr[title]'177 )178 renderer.renderStatic(179 {180 cursor: 'pointer',181 borderBottom: '1px solid transparent',182 display: 'inline-block',183 transition: '250ms',184 },185 'summary'186 )187 renderer.renderStatic(188 {189 display: 'none',190 },191 'summary::-webkit-details-marker'192 )193 renderer.renderStatic(194 {195 color: 'var(--beige)',196 borderBottomColor: 'currentcolor',197 },198 'summary:hover'199 )200 renderer.renderStatic(201 {202 color: 'var(--beige)',203 },204 '.EditorialContent p:not([class]) strong, .EditorialContent li:not([class]) strong'205 )206 renderer.renderStatic(207 {208 color: 'var(--beige)',209 marginTop: 'var(--s-large)',210 },211 '.EditorialContent h3:not([class])'212 )213 renderer.renderStatic(214 {215 marginTop: 'var(--s-smaller)',216 marginBottom: 0,217 },218 '.EditorialContent ol ul:not([class])'219 )220 renderer.renderStatic(221 {222 padding: 0,223 listStylePosition: 'inside',224 },225 '.EditorialContent ol:not([class]), .EditorialContent ul:not([class])'226 )227 renderer.renderStatic(228 {229 paddingLeft: '1.1em',230 textIndent: '-1.1em',231 marginBottom: 'var(--s-smaller)',232 },233 '.EditorialContent ol li:not([class])'234 )235 renderer.renderStatic(236 {237 paddingLeft: '1.1em',238 textIndent: '-1.1em',239 marginBottom: 'var(--s-smaller)',240 },241 '.EditorialContent ul li:not([class])'242 )243 renderer.renderStatic(244 {245 marginTop: 'var(--s-smaller)',246 marginBottom: 0,247 },248 '.EditorialContent li ul'249 )250}...
slide.js
Source:slide.js
...104 this.color = color105 this.font = size + "px " + font106 }107108 renderStatic(ctx){109 let goon = false110 if(Slide.currentScreen == -1 && this.master){111 goon = true112 }113 if (Slide.currentScreen == 1 && this.alter){114 goon = true115 }116 if(!goon){return}117 if(!this.isText){118 this.drawToCanvas(ctx)119 }else{120 var tempColor = ctx.fillStyle121 var tempFont = ctx.font122 ctx.fillStyle = this.fillStyle123 ctx.font = this.font124 ctx.fillText(this.text,this.x,this.y)125 ctx.fillStyle = tempColor126 ctx.font = tempFont127 }128 }129130 render(ctx){131 if(!this.isMoving){132 //ä¸å¨åæ¢ä¸å°±ç´æ¥æ¸²æ133 this.renderStatic(ctx)134 return135 }136 //å¦å就渲ææ»å¨137 if(this.stage <= -1){138 //å¤çåæ¢å°å¯å±139 if(this.stage == -1){140 this.step++141 this.x = this.x - (screenWidth/this.speed)*this.step142 this.renderStatic(ctx)143 if(this.x < -1 * screenWidth){144 this.step = 0145 this.stage = -2146 Slide.currentScreen = 1147 }148 }else{149 this.step++150 this.x = this.originX + screenWidth - (screenWidth/this.speed)*this.step151 this.renderStatic(ctx)152 if(Math.abs(this.originX-this.x) < 10){153 this.step = 0154 this.stage = 0155 this.x = this.originX156 this.y = this.originY157 this.isMoving = false158 }159 }160 }else{161 //å¤çæ»å¨å°ä¸»å±162 if(this.stage == 1){163 this.step++164 this.x = this.x + (screenWidth/this.speed)*this.step165 this.renderStatic(ctx)166 if(this.x > screenWidth){167 this.step = 0168 this.stage = 2169 Slide.currentScreen = -1170 }171 }else{172 this.step++173 this.x = this.originX - screenWidth + (screenWidth/this.speed)*this.step174 this.renderStatic(ctx)175 if(Math.abs(this.originX-this.x) < 10){176 this.step = 0177 this.stage = 0178 this.x = this.originX179 this.y = this.originY180 this.isMoving = false181 }182 }183 }184185 }186187188
...
wrap-page.test.js
Source:wrap-page.test.js
...18 siteUrl: 'http://my-site.com',19 }20 );21 ReactDOMServer.renderToString(element);22 const link = Helmet.renderStatic().link.toComponent();23 expect(link.length).toBe(1);24 expect(link[0].props.href).toBe('http://my-site.com/pathname/?search#hash');25});26it('should use a slash as pathname, if it is falsy', () => {27 const element = wrap(28 {29 element: 'element',30 props: {31 location: {32 pathname: '',33 search: '?search',34 hash: '#hash',35 },36 },37 },38 {39 siteUrl: 'http://my-site.com',40 }41 );42 ReactDOMServer.renderToString(element);43 const link = Helmet.renderStatic().link.toComponent();44 expect(link.length).toBe(1);45 expect(link[0].props.href).toBe('http://my-site.com/?search#hash');46});47it('should element set canonial, it should use it', () => {48 const canonical = 'https://this-is-a.canonical.test/more-test';49 const element = wrap(50 {51 element: React.createElement(Helmet, {52 link: [{ rel: 'canonical', key: canonical, href: canonical }],53 }),54 props: {55 location: {56 pathname: '/example/',57 search: '?search',58 hash: '#hash',59 },60 },61 },62 {63 siteUrl: 'http://my-site.com',64 }65 );66 ReactDOMServer.renderToString(element);67 const link = Helmet.renderStatic().link.toComponent();68 expect(link.length).toBe(1);69 expect(link[0].props.href).toBe('https://this-is-a.canonical.test/more-test');70});71it('should remove trailing slash, if `noTrailingSlash` option is used', () => {72 const element = wrap(73 {74 element: 'element',75 props: {76 location: {77 pathname: '/pathname/',78 search: '?search',79 hash: '#hash',80 },81 },82 },83 {84 siteUrl: 'http://my-site.com',85 noTrailingSlash: true,86 }87 );88 ReactDOMServer.renderToString(element);89 const link = Helmet.renderStatic().link.toComponent();90 expect(link.length).toBe(1);91 expect(link[0].props.href).toBe('http://my-site.com/pathname?search#hash');92});93it('should remove query string, if `noQueryString` option is used', () => {94 const element = wrap(95 {96 element: 'element',97 props: {98 location: {99 pathname: '/pathname/',100 search: '?search',101 hash: '#hash',102 },103 },104 },105 {106 siteUrl: 'http://my-site.com',107 noQueryString: true,108 }109 );110 ReactDOMServer.renderToString(element);111 const link = Helmet.renderStatic().link.toComponent();112 expect(link.length).toBe(1);113 expect(link[0].props.href).toBe('http://my-site.com/pathname/#hash');114});115it('should remove hash, if `noHash` option is used', () => {116 const element = wrap(117 {118 element: 'element',119 props: {120 location: {121 pathname: '/pathname/',122 search: '?search',123 hash: '#hash',124 },125 },126 },127 {128 siteUrl: 'http://my-site.com',129 noHash: true,130 }131 );132 ReactDOMServer.renderToString(element);133 const link = Helmet.renderStatic().link.toComponent();134 expect(link.length).toBe(1);135 expect(link[0].props.href).toBe('http://my-site.com/pathname/?search');136});137it('should not set canonical if no options is passed', () => {138 const element = wrap({139 element: 'element',140 props: {141 location: {},142 },143 });144 ReactDOMServer.renderToString(element);145 const link = Helmet.renderStatic().link.toComponent();146 expect(link.length).toBe(0);147});148it('should not set canonical if no siteUrl option is passed', () => {149 const element = wrap(150 {151 element: 'element',152 props: {153 location: {},154 },155 },156 {}157 );158 ReactDOMServer.renderToString(element);159 const link = Helmet.renderStatic().link.toComponent();160 expect(link.length).toBe(0);161});162test.each([163 [['/my-pathname']],164 [['/something', '/my-pathname']],165 [[/pathname/]],166 [[/^not/, /pathname/]],167 [[new RegExp('pathname')]],168])('should not set canonical if pathname is excluded: %p', exclude => {169 const element = wrap(170 {171 element: 'element',172 props: {173 location: {174 pathname: '/my-pathname/',175 search: '',176 hash: '',177 },178 },179 },180 {181 siteUrl: 'http://my-site.com',182 exclude,183 }184 );185 ReactDOMServer.renderToString(element);186 const link = Helmet.renderStatic().link.toComponent();187 expect(link.length).toBe(0);...
static.js
Source:static.js
...13);14describe('static', () => {15 describe('# normal render', () => {16 it('## index.html', () => {17 expect(renderStatic([{18 component: './lib/__tests__/utils/TestReact',19 name: 'index',20 template: 'test.html'21 }])).toMatchObject([{22 filename: 'index.html',23 content: renderContent('<div>test react</div>')24 }]);25 });26 it('## test/index.html', () => {27 expect(renderStatic([{28 component: './lib/__tests__/utils/TestReact',29 name: 'test',30 template: 'test.html'31 }])).toMatchObject([{32 filename: 'test/index.html',33 content: renderContent('<div>test react</div>')34 }]);35 });36 });37 it('# default template path', () => {38 expect(renderStatic([{39 component: './lib/__tests__/utils/TestReact',40 name: 'index'41 }])).toMatchObject([{42 filename: 'index.html',43 content: minify(nunjucks.render(44 'template.html', {45 content: '<div>test react</div>',46 ENV: false47 }48 ))49 }]);50 });51 describe('# render redux', () => {52 it('## just reducer', () => {53 expect(renderStatic([{54 component: './lib/__tests__/utils/TestRedux',55 name: 'index',56 template: 'test.html',57 props: {58 redux: {59 reducer: combineReducers({testReducer})60 }61 }62 }])).toMatchObject([{63 content: renderContent('<div>test redux(origin state)</div>')64 }]);65 });66 describe('## add preloadedState', () => {67 expect(renderStatic([{68 component: './lib/__tests__/utils/TestRedux',69 name: 'index',70 template: 'test.html',71 props: {72 redux: {73 reducer: combineReducers({testReducer}),74 preloadedState: {testReducer: 'preloaded state'}75 }76 }77 }])).toMatchObject([{78 content: renderContent('<div>test redux(preloaded state)</div>')79 }]);80 });81 });82 describe('# render router', () => {83 const urls = ['/', '/about/'];84 useUrls(urls, {85 component: './lib/__tests__/utils/TestRouter',86 name: 'index',87 template: 'test.html'88 }).forEach((config, index) => {89 it(`## render '${urls[index]}'`, () => {90 expect(renderStatic([config]))91 .toMatchObject([{92 content: renderContent(`<div data-radium="true"><div>router render ${93 urls[index] === '/' ? 'index' : 'about'94 }</div></div>`)95 }]);96 });97 });98 });...
render.js
Source:render.js
...36 renderedFrontPost = true37 fs.writeFileSync(outDir + '/blog/index.html', dom.html())38 }39})40renderStatic(templates.splash, 'index')41renderStatic(templates.about, 'about')42renderStatic(templates.team, 'team')43renderStatic(templates.docs, 'docs')44// copy static stuff45cptar('./static', outDir + '/static', function (err) {46 if (err) throw err47})48function renderStatic (template, target) {49 var dom = cheerio.load(templates.index)50 dom('#content').html(template)51 dom('a[href="/' + target + '"]').addClass('active')52 fs.writeFileSync(outDir + '/' + target + '.html', dom.html())...
Using AI Code Generation
1const path = require('path');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 const { html, css, js } = await page.context().renderStatic();7 await browser.close();8})();9const { chromium } = require('playwright');10(async () => {11 const browser = await chromium.launch();12 const page = await browser.newPage();13 const { html, css, js } = await page.context().renderStatic();14 await browser.close();15})();
Using AI Code Generation
1const { chromium } = require('playwright');2const path = require('path');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 const html = await page.evaluate(() => {7 return renderStatic({8 css: 'body { background: red; }',9 });10 });11 await page.setContent(html);12 await page.screenshot({ path: path.resolve(__dirname, 'screenshot.png') });13 await browser.close();14})();15const { chromium } = require('playwright');16const path = require('path');17(async () => {18 const browser = await chromium.launch();19 const page = await browser.newPage();20 const pdf = await page.evaluate(() => {21 return renderStatic({22 css: 'body { background: red; }',23 });24 });25 await page.setContent(pdf);26 await page.pdf({ path: path.resolve(__dirname, 'screenshot.pdf') });27 await browser.close();28})();
Using AI Code Generation
1const { renderStatic } = require('playwright/lib/server/frames');2const { chromium } = require('playwright');3const fs = require('fs');4(async () => {5 const browser = await chromium.launch();6 const context = await browser.newContext();7 const page = await context.newPage();8 const { html, css } = await renderStatic(page, 'body');9 fs.writeFileSync('output.html', html);10 fs.writeFileSync('output.css', css);11 await browser.close();12})();
Using AI Code Generation
1const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderApp');2const { parse } = require('playwright/lib/server/supplements/recorder/recorderUtils');3const { parseTest } = require('playwright/lib/server/supplements/recorder/recorderTestParser');4const { generateTest } = require('playwright/lib/server/supplements/recorder/recorderTestGenerator');5 const { test } = pwt;6 test('test', async ({ page }) => {7 });8`;9(async () => {10 const { html, js } = await renderStatic();11 const testFile = parseTest(test);12 const testFileWithHtml = parse(testFile, html);13 const testFileWithHtmlAndJs = parse(testFileWithHtml, js);14 const generatedTest = generateTest(testFileWithHtmlAndJs);15 console.log(generatedTest);16})();17const { test } = pwt;18test('test', async ({ page }) => {19 await page.click('text=Get started');20 await page.click('text=Docs');21 await page.click('text=API');22 await page.click('text=Blog');23 await page.click('text=GitHub');24 await page.click('text=Twitter');25 await page.click('text=Playwright');26});27### `renderStatic(options)`
Using AI Code Generation
1const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderApp');2const { html, css, js } = renderStatic();3const { html, css, js } = await renderStatic();4const { html, css, js } = await renderStatic();5const { html, css, js } = renderStatic();6const { html, css, js } = renderStatic();7const { html, css, js } = renderStatic();8const { html, css, js } = renderStatic();9const { html, css, js } = renderStatic();10const { html, css, js } = renderStatic();11const { html, css, js } = renderStatic();12const { html, css, js } = renderStatic();13const { html, css, js } = renderStatic();14const { html, css, js } = renderStatic();15const { html, css, js } = renderStatic();16const { html, css, js } = renderStatic();17const { html, css, js } = renderStatic();18const { html, css, js } = renderStatic();19const { html, css, js } = renderStatic();20const { html, css, js } = renderStatic();21const { html, css
Using AI Code Generation
1const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderApp');2const { renderToStaticMarkup } = require('react-dom/server');3const { React } = require('react');4const result = renderStatic((props) => renderToStaticMarkup(React.createElement(RecorderApp, props)));5console.log(result.html);6console.log(result.css);7console.log(result.js);8const handle = await page.evaluateHandle(() => {9 const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderApp');10 const { renderToStaticMarkup } = require('react-dom/server');11 const { React } = require('react');12 return renderStatic((props) => renderToStaticMarkup(React.createElement(RecorderApp, props)));13});14const html = await handle.getProperty('html').jsonValue();15const css = await handle.getProperty('css').jsonValue();16const js = await handle.getProperty('js').jsonValue();
Using AI Code Generation
1const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderSupplement');2const html = await renderStatic(page, { selector: 'body' });3const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderSupplement');4const html = await renderStatic(page, { selector: 'body' });5const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderSupplement');6const html = await renderStatic(page, { selector: 'body' });7const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderSupplement');8const html = await renderStatic(page, { selector: 'body' });9const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderSupplement');10const html = await renderStatic(page, { selector: 'body' });11const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderSupplement');12const html = await renderStatic(page, { selector: 'body' });13const { renderStatic }
Using AI Code Generation
1const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderApp');2const { html } = renderStatic({3});4const { renderStatic } = require('playwright/lib/server/supplements/recorder/recorderApp');5const { html } = renderStatic({6});7const { render } = require('playwright/lib/server/supplements/recorder/recorderApp');8const { html } = render({9});10const { render } = require('playwright/lib/server/supplements/recorder/recorderApp');11const { html } = render({12});13const { html } = render({14});
Using AI Code Generation
1const { renderStatic } = require('playwright/lib/server/supplements/recorder/frames');2const frames = await page.frames();3const html = renderStatic(frames, 'html');4const { renderStatic } = require('playwright');5const frames = await page.frames();6const html = renderStatic(frames, 'html');7import { renderStatic } from 'playwright';8const frames = await page.frames();9const html = renderStatic(frames, 'html');10import { renderStatic } from 'playwright';11const frames = await page.frames();12const html = renderStatic(frames, 'html');13import { renderStatic } from 'playwright';14const frames = await page.frames();15const html = renderStatic(frames, 'html');16import { renderStatic } from 'playwright';17const frames = await page.frames();18const html = renderStatic(frames, 'html');19import { renderStatic } from 'playwright';20const frames = await page.frames();21const html = renderStatic(frames, 'html');22import { renderStatic } from 'playwright';23const frames = await page.frames();24const html = renderStatic(frames, 'html');25import { renderStatic } from 'playwright';26const frames = await page.frames();27const html = renderStatic(frames, 'html');28import { renderStatic } from 'playwright';29const frames = await page.frames();30const html = renderStatic(frames, 'html');31import { renderStatic } from 'playwright';32const frames = await page.frames();33const html = renderStatic(frames, 'html');34import { renderStatic } from 'playwright';35const frames = await page.frames();36const html = renderStatic(frames, 'html');
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!