Best JavaScript code snippet using cypress
storeStressTestConcurrent-test.js
Source:storeStressTestConcurrent-test.js
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9describe('StoreStressConcurrent', () => {10 let React;11 let ReactDOM;12 let act;13 let actAsync;14 let bridge;15 let store;16 let print;17 beforeEach(() => {18 bridge = global.bridge;19 store = global.store;20 store.collapseNodesByDefault = false;21 React = require('react');22 ReactDOM = require('react-dom');23 act = require('./utils').act;24 // TODO: Figure out recommendation for concurrent mode tests, then replace25 // this helper with the real thing.26 actAsync = require('./utils').actAsync;27 print = require('./storeSerializer').print;28 });29 // TODO: Remove this in favor of @gate pragma30 if (!__EXPERIMENTAL__) {31 it("empty test so Jest doesn't complain", () => {});32 return;33 }34 // This is a stress test for the tree mount/update/unmount traversal.35 // It renders different trees that should produce the same output.36 it('should handle a stress test with different tree operations (Concurrent Mode)', () => {37 let setShowX;38 const A = () => 'a';39 const B = () => 'b';40 const C = () => {41 // We'll be manually flipping this component back and forth in the test.42 // We only do this for a single node in order to verify that DevTools43 // can handle a subtree switching alternates while other subtrees are memoized.44 const [showX, _setShowX] = React.useState(false);45 setShowX = _setShowX;46 return showX ? <X /> : 'c';47 };48 const D = () => 'd';49 const E = () => 'e';50 const X = () => 'x';51 const a = <A key="a" />;52 const b = <B key="b" />;53 const c = <C key="c" />;54 const d = <D key="d" />;55 const e = <E key="e" />;56 function Parent({children}) {57 return children;58 }59 // 1. Render a normal version of [a, b, c, d, e].60 let container = document.createElement('div');61 // $FlowFixMe62 let root = ReactDOM.createRoot(container);63 act(() => root.render(<Parent>{[a, b, c, d, e]}</Parent>));64 expect(store).toMatchInlineSnapshot(65 `66 [root]67 â¾ <Parent>68 <A key="a">69 <B key="b">70 <C key="c">71 <D key="d">72 <E key="e">73 `,74 );75 expect(container.textContent).toMatch('abcde');76 const snapshotForABCDE = print(store);77 // 2. Render a version where <C /> renders an <X /> child instead of 'c'.78 // This is how we'll test an update to a single component.79 act(() => {80 setShowX(true);81 });82 expect(store).toMatchInlineSnapshot(83 `84 [root]85 â¾ <Parent>86 <A key="a">87 <B key="b">88 â¾ <C key="c">89 <X>90 <D key="d">91 <E key="e">92 `,93 );94 expect(container.textContent).toMatch('abxde');95 const snapshotForABXDE = print(store);96 // 3. Verify flipping it back produces the original result.97 act(() => {98 setShowX(false);99 });100 expect(container.textContent).toMatch('abcde');101 expect(print(store)).toBe(snapshotForABCDE);102 // 4. Clean up.103 act(() => root.unmount());104 expect(print(store)).toBe('');105 // Now comes the interesting part.106 // All of these cases are equivalent to [a, b, c, d, e] in output.107 // We'll verify that DevTools produces the same snapshots for them.108 // These cases are picked so that rendering them sequentially in the same109 // container results in a combination of mounts, updates, unmounts, and reorders.110 // prettier-ignore111 const cases = [112 [a, b, c, d, e],113 [[a], b, c, d, e],114 [[a, b], c, d, e],115 [[a, b], c, [d, e]],116 [[a, b], c, [d, '', e]],117 [[a], b, c, d, [e]],118 [a, b, [[c]], d, e],119 [[a, ''], [b], [c], [d], [e]],120 [a, b, [c, [d, ['', e]]]],121 [a, b, c, d, e],122 [<div key="0">{a}</div>, b, c, d, e],123 [<div key="0">{a}{b}</div>, c, d, e],124 [<div key="0">{a}{b}</div>, c, <div key="1">{d}{e}</div>],125 [<div key="1">{a}{b}</div>, c, <div key="0">{d}{e}</div>],126 [<div key="0">{a}{b}</div>, c, <div key="1">{d}{e}</div>],127 [<div key="2">{a}{b}</div>, c, <div key="3">{d}{e}</div>],128 [<span key="0">{a}</span>, b, c, d, [e]],129 [a, b, <span key="0"><span>{c}</span></span>, d, e],130 [<div key="0">{a}</div>, [b], <span key="1">{c}</span>, [d], <div key="2">{e}</div>],131 [a, b, [c, <div key="0">{d}<span>{e}</span></div>], ''],132 [a, [[]], b, c, [d, [[]], e]],133 [[[a, b, c, d], e]],134 [a, b, c, d, e],135 ];136 // 5. Test fresh mount for each case.137 for (let i = 0; i < cases.length; i++) {138 // Ensure fresh mount.139 container = document.createElement('div');140 // $FlowFixMe141 root = ReactDOM.createRoot(container);142 // Verify mounting 'abcde'.143 act(() => root.render(<Parent>{cases[i]}</Parent>));144 expect(container.textContent).toMatch('abcde');145 expect(print(store)).toEqual(snapshotForABCDE);146 // Verify switching to 'abxde'.147 act(() => {148 setShowX(true);149 });150 expect(container.textContent).toMatch('abxde');151 expect(print(store)).toBe(snapshotForABXDE);152 // Verify switching back to 'abcde'.153 act(() => {154 setShowX(false);155 });156 expect(container.textContent).toMatch('abcde');157 expect(print(store)).toBe(snapshotForABCDE);158 // Clean up.159 act(() => root.unmount());160 expect(print(store)).toBe('');161 }162 // 6. Verify *updates* by reusing the container between iterations.163 // There'll be no unmounting until the very end.164 container = document.createElement('div');165 // $FlowFixMe166 root = ReactDOM.createRoot(container);167 for (let i = 0; i < cases.length; i++) {168 // Verify mounting 'abcde'.169 act(() => root.render(<Parent>{cases[i]}</Parent>));170 expect(container.textContent).toMatch('abcde');171 expect(print(store)).toEqual(snapshotForABCDE);172 // Verify switching to 'abxde'.173 act(() => {174 setShowX(true);175 });176 expect(container.textContent).toMatch('abxde');177 expect(print(store)).toBe(snapshotForABXDE);178 // Verify switching back to 'abcde'.179 act(() => {180 setShowX(false);181 });182 expect(container.textContent).toMatch('abcde');183 expect(print(store)).toBe(snapshotForABCDE);184 // Don't unmount. Reuse the container between iterations.185 }186 act(() => root.unmount());187 expect(print(store)).toBe('');188 });189 it('should handle stress test with reordering (Concurrent Mode)', () => {190 const A = () => 'a';191 const B = () => 'b';192 const C = () => 'c';193 const D = () => 'd';194 const E = () => 'e';195 const a = <A key="a" />;196 const b = <B key="b" />;197 const c = <C key="c" />;198 const d = <D key="d" />;199 const e = <E key="e" />;200 // prettier-ignore201 const steps = [202 a,203 b,204 c,205 d,206 e,207 [a],208 [b],209 [c],210 [d],211 [e],212 [a, b],213 [b, a],214 [b, c],215 [c, b],216 [a, c],217 [c, a],218 ];219 const Root = ({children}) => {220 return children;221 };222 // 1. Capture the expected render result.223 const snapshots = [];224 let container = document.createElement('div');225 // $FlowFixMe226 let root = ReactDOM.createRoot(container);227 for (let i = 0; i < steps.length; i++) {228 act(() => root.render(<Root>{steps[i]}</Root>));229 // We snapshot each step once so it doesn't regress.230 snapshots.push(print(store));231 act(() => root.unmount());232 expect(print(store)).toBe('');233 }234 expect(snapshots).toMatchInlineSnapshot(`235 Array [236 "[root]237 â¾ <Root>238 <A key=\\"a\\">",239 "[root]240 â¾ <Root>241 <B key=\\"b\\">",242 "[root]243 â¾ <Root>244 <C key=\\"c\\">",245 "[root]246 â¾ <Root>247 <D key=\\"d\\">",248 "[root]249 â¾ <Root>250 <E key=\\"e\\">",251 "[root]252 â¾ <Root>253 <A key=\\"a\\">",254 "[root]255 â¾ <Root>256 <B key=\\"b\\">",257 "[root]258 â¾ <Root>259 <C key=\\"c\\">",260 "[root]261 â¾ <Root>262 <D key=\\"d\\">",263 "[root]264 â¾ <Root>265 <E key=\\"e\\">",266 "[root]267 â¾ <Root>268 <A key=\\"a\\">269 <B key=\\"b\\">",270 "[root]271 â¾ <Root>272 <B key=\\"b\\">273 <A key=\\"a\\">",274 "[root]275 â¾ <Root>276 <B key=\\"b\\">277 <C key=\\"c\\">",278 "[root]279 â¾ <Root>280 <C key=\\"c\\">281 <B key=\\"b\\">",282 "[root]283 â¾ <Root>284 <A key=\\"a\\">285 <C key=\\"c\\">",286 "[root]287 â¾ <Root>288 <C key=\\"c\\">289 <A key=\\"a\\">",290 ]291 `);292 // 2. Verify that we can update from every step to every other step and back.293 for (let i = 0; i < steps.length; i++) {294 for (let j = 0; j < steps.length; j++) {295 container = document.createElement('div');296 // $FlowFixMe297 root = ReactDOM.createRoot(container);298 act(() => root.render(<Root>{steps[i]}</Root>));299 expect(print(store)).toMatch(snapshots[i]);300 act(() => root.render(<Root>{steps[j]}</Root>));301 expect(print(store)).toMatch(snapshots[j]);302 act(() => root.render(<Root>{steps[i]}</Root>));303 expect(print(store)).toMatch(snapshots[i]);304 act(() => root.unmount());305 expect(print(store)).toBe('');306 }307 }308 // 3. Same test as above, but this time we wrap children in a host component.309 for (let i = 0; i < steps.length; i++) {310 for (let j = 0; j < steps.length; j++) {311 container = document.createElement('div');312 // $FlowFixMe313 root = ReactDOM.createRoot(container);314 act(() =>315 root.render(316 <Root>317 <div>{steps[i]}</div>318 </Root>,319 ),320 );321 expect(print(store)).toMatch(snapshots[i]);322 act(() =>323 root.render(324 <Root>325 <div>{steps[j]}</div>326 </Root>,327 ),328 );329 expect(print(store)).toMatch(snapshots[j]);330 act(() =>331 root.render(332 <Root>333 <div>{steps[i]}</div>334 </Root>,335 ),336 );337 expect(print(store)).toMatch(snapshots[i]);338 act(() => root.unmount());339 expect(print(store)).toBe('');340 }341 }342 });343 it('should handle a stress test for Suspense (Concurrent Mode)', async () => {344 const A = () => 'a';345 const B = () => 'b';346 const C = () => 'c';347 const X = () => 'x';348 const Y = () => 'y';349 const Z = () => 'z';350 const a = <A key="a" />;351 const b = <B key="b" />;352 const c = <C key="c" />;353 const z = <Z key="z" />;354 // prettier-ignore355 const steps = [356 a,357 [a],358 [a, b, c],359 [c, b, a],360 [c, null, a],361 <React.Fragment>{c}{a}</React.Fragment>,362 <div>{c}{a}</div>,363 <div><span>{a}</span>{b}</div>,364 [[a]],365 null,366 b,367 a,368 ];369 const Never = () => {370 throw new Promise(() => {});371 };372 const Root = ({children}) => {373 return children;374 };375 // 1. For each step, check Suspense can render them as initial primary content.376 // This is the only step where we use Jest snapshots.377 const snapshots = [];378 let container = document.createElement('div');379 // $FlowFixMe380 let root = ReactDOM.createRoot(container);381 for (let i = 0; i < steps.length; i++) {382 act(() =>383 root.render(384 <Root>385 <X />386 <React.Suspense fallback={z}>{steps[i]}</React.Suspense>387 <Y />388 </Root>,389 ),390 );391 // We snapshot each step once so it doesn't regress.d392 snapshots.push(print(store));393 act(() => root.unmount());394 expect(print(store)).toBe('');395 }396 expect(snapshots).toMatchInlineSnapshot(`397 Array [398 "[root]399 â¾ <Root>400 <X>401 â¾ <Suspense>402 <A key=\\"a\\">403 <Y>",404 "[root]405 â¾ <Root>406 <X>407 â¾ <Suspense>408 <A key=\\"a\\">409 <Y>",410 "[root]411 â¾ <Root>412 <X>413 â¾ <Suspense>414 <A key=\\"a\\">415 <B key=\\"b\\">416 <C key=\\"c\\">417 <Y>",418 "[root]419 â¾ <Root>420 <X>421 â¾ <Suspense>422 <C key=\\"c\\">423 <B key=\\"b\\">424 <A key=\\"a\\">425 <Y>",426 "[root]427 â¾ <Root>428 <X>429 â¾ <Suspense>430 <C key=\\"c\\">431 <A key=\\"a\\">432 <Y>",433 "[root]434 â¾ <Root>435 <X>436 â¾ <Suspense>437 <C key=\\"c\\">438 <A key=\\"a\\">439 <Y>",440 "[root]441 â¾ <Root>442 <X>443 â¾ <Suspense>444 <C key=\\"c\\">445 <A key=\\"a\\">446 <Y>",447 "[root]448 â¾ <Root>449 <X>450 â¾ <Suspense>451 <A key=\\"a\\">452 <B key=\\"b\\">453 <Y>",454 "[root]455 â¾ <Root>456 <X>457 â¾ <Suspense>458 <A key=\\"a\\">459 <Y>",460 "[root]461 â¾ <Root>462 <X>463 <Suspense>464 <Y>",465 "[root]466 â¾ <Root>467 <X>468 â¾ <Suspense>469 <B key=\\"b\\">470 <Y>",471 "[root]472 â¾ <Root>473 <X>474 â¾ <Suspense>475 <A key=\\"a\\">476 <Y>",477 ]478 `);479 // 2. Verify check Suspense can render same steps as initial fallback content.480 for (let i = 0; i < steps.length; i++) {481 act(() =>482 root.render(483 <Root>484 <X />485 <React.Suspense fallback={steps[i]}>486 <Z />487 <Never />488 <Z />489 </React.Suspense>490 <Y />491 </Root>,492 ),493 );494 expect(print(store)).toEqual(snapshots[i]);495 act(() => root.unmount());496 expect(print(store)).toBe('');497 }498 // 3. Verify we can update from each step to each step in primary mode.499 for (let i = 0; i < steps.length; i++) {500 for (let j = 0; j < steps.length; j++) {501 // Always start with a fresh container and steps[i].502 container = document.createElement('div');503 // $FlowFixMe504 root = ReactDOM.createRoot(container);505 act(() =>506 root.render(507 <Root>508 <X />509 <React.Suspense fallback={z}>{steps[i]}</React.Suspense>510 <Y />511 </Root>,512 ),513 );514 expect(print(store)).toEqual(snapshots[i]);515 // Re-render with steps[j].516 act(() =>517 root.render(518 <Root>519 <X />520 <React.Suspense fallback={z}>{steps[j]}</React.Suspense>521 <Y />522 </Root>,523 ),524 );525 // Verify the successful transition to steps[j].526 expect(print(store)).toEqual(snapshots[j]);527 // Check that we can transition back again.528 act(() =>529 root.render(530 <Root>531 <X />532 <React.Suspense fallback={z}>{steps[i]}</React.Suspense>533 <Y />534 </Root>,535 ),536 );537 expect(print(store)).toEqual(snapshots[i]);538 // Clean up after every iteration.539 act(() => root.unmount());540 expect(print(store)).toBe('');541 }542 }543 // 4. Verify we can update from each step to each step in fallback mode.544 for (let i = 0; i < steps.length; i++) {545 for (let j = 0; j < steps.length; j++) {546 // Always start with a fresh container and steps[i].547 container = document.createElement('div');548 // $FlowFixMe549 root = ReactDOM.createRoot(container);550 act(() =>551 root.render(552 <Root>553 <X />554 <React.Suspense fallback={steps[i]}>555 <Z />556 <Never />557 <Z />558 </React.Suspense>559 <Y />560 </Root>,561 ),562 );563 expect(print(store)).toEqual(snapshots[i]);564 // Re-render with steps[j].565 act(() =>566 root.render(567 <Root>568 <X />569 <React.Suspense fallback={steps[j]}>570 <Z />571 <Never />572 <Z />573 </React.Suspense>574 <Y />575 </Root>,576 ),577 );578 // Verify the successful transition to steps[j].579 expect(print(store)).toEqual(snapshots[j]);580 // Check that we can transition back again.581 act(() =>582 root.render(583 <Root>584 <X />585 <React.Suspense fallback={steps[i]}>586 <Z />587 <Never />588 <Z />589 </React.Suspense>590 <Y />591 </Root>,592 ),593 );594 expect(print(store)).toEqual(snapshots[i]);595 // Clean up after every iteration.596 act(() => root.unmount());597 expect(print(store)).toBe('');598 }599 }600 // 5. Verify we can update from each step to each step when moving primary -> fallback.601 for (let i = 0; i < steps.length; i++) {602 for (let j = 0; j < steps.length; j++) {603 // Always start with a fresh container and steps[i].604 container = document.createElement('div');605 // $FlowFixMe606 root = ReactDOM.createRoot(container);607 act(() =>608 root.render(609 <Root>610 <X />611 <React.Suspense fallback={z}>{steps[i]}</React.Suspense>612 <Y />613 </Root>,614 ),615 );616 expect(print(store)).toEqual(snapshots[i]);617 // Re-render with steps[j].618 act(() =>619 root.render(620 <Root>621 <X />622 <React.Suspense fallback={steps[j]}>623 <Z />624 <Never />625 <Z />626 </React.Suspense>627 <Y />628 </Root>,629 ),630 );631 // Verify the successful transition to steps[j].632 expect(print(store)).toEqual(snapshots[j]);633 // Check that we can transition back again.634 act(() =>635 root.render(636 <Root>637 <X />638 <React.Suspense fallback={z}>{steps[i]}</React.Suspense>639 <Y />640 </Root>,641 ),642 );643 expect(print(store)).toEqual(snapshots[i]);644 // Clean up after every iteration.645 act(() => root.unmount());646 expect(print(store)).toBe('');647 }648 }649 // 6. Verify we can update from each step to each step when moving fallback -> primary.650 for (let i = 0; i < steps.length; i++) {651 for (let j = 0; j < steps.length; j++) {652 // Always start with a fresh container and steps[i].653 container = document.createElement('div');654 // $FlowFixMe655 root = ReactDOM.createRoot(container);656 act(() =>657 root.render(658 <Root>659 <X />660 <React.Suspense fallback={steps[i]}>661 <Z />662 <Never />663 <Z />664 </React.Suspense>665 <Y />666 </Root>,667 ),668 );669 expect(print(store)).toEqual(snapshots[i]);670 // Re-render with steps[j].671 act(() =>672 root.render(673 <Root>674 <X />675 <React.Suspense fallback={z}>{steps[j]}</React.Suspense>676 <Y />677 </Root>,678 ),679 );680 // Verify the successful transition to steps[j].681 expect(print(store)).toEqual(snapshots[j]);682 // Check that we can transition back again.683 act(() =>684 root.render(685 <Root>686 <X />687 <React.Suspense fallback={steps[i]}>688 <Z />689 <Never />690 <Z />691 </React.Suspense>692 <Y />693 </Root>,694 ),695 );696 expect(print(store)).toEqual(snapshots[i]);697 // Clean up after every iteration.698 act(() => root.unmount());699 expect(print(store)).toBe('');700 }701 }702 // 7. Verify we can update from each step to each step when toggling Suspense.703 for (let i = 0; i < steps.length; i++) {704 for (let j = 0; j < steps.length; j++) {705 // Always start with a fresh container and steps[i].706 container = document.createElement('div');707 // $FlowFixMe708 root = ReactDOM.createRoot(container);709 act(() =>710 root.render(711 <Root>712 <X />713 <React.Suspense fallback={steps[j]}>{steps[i]}</React.Suspense>714 <Y />715 </Root>,716 ),717 );718 // We get ID from the index in the tree above:719 // Root, X, Suspense, ...720 // ^ (index is 2)721 const suspenseID = store.getElementIDAtIndex(2);722 // Force fallback.723 expect(print(store)).toEqual(snapshots[i]);724 await actAsync(async () => {725 bridge.send('overrideSuspense', {726 id: suspenseID,727 rendererID: store.getRendererIDForElement(suspenseID),728 forceFallback: true,729 });730 });731 expect(print(store)).toEqual(snapshots[j]);732 // Stop forcing fallback.733 await actAsync(async () => {734 bridge.send('overrideSuspense', {735 id: suspenseID,736 rendererID: store.getRendererIDForElement(suspenseID),737 forceFallback: false,738 });739 });740 expect(print(store)).toEqual(snapshots[i]);741 // Trigger actual fallback.742 act(() =>743 root.render(744 <Root>745 <X />746 <React.Suspense fallback={steps[j]}>747 <Z />748 <Never />749 <Z />750 </React.Suspense>751 <Y />752 </Root>,753 ),754 );755 expect(print(store)).toEqual(snapshots[j]);756 // Force fallback while we're in fallback mode.757 act(() => {758 bridge.send('overrideSuspense', {759 id: suspenseID,760 rendererID: store.getRendererIDForElement(suspenseID),761 forceFallback: true,762 });763 });764 // Keep seeing fallback content.765 expect(print(store)).toEqual(snapshots[j]);766 // Switch to primary mode.767 act(() =>768 root.render(769 <Root>770 <X />771 <React.Suspense fallback={steps[j]}>{steps[i]}</React.Suspense>772 <Y />773 </Root>,774 ),775 );776 // Fallback is still forced though.777 expect(print(store)).toEqual(snapshots[j]);778 // Stop forcing fallback. This reverts to primary content.779 await actAsync(async () => {780 bridge.send('overrideSuspense', {781 id: suspenseID,782 rendererID: store.getRendererIDForElement(suspenseID),783 forceFallback: false,784 });785 });786 // Now we see primary content.787 expect(print(store)).toEqual(snapshots[i]);788 // Clean up after every iteration.789 await actAsync(async () => root.unmount());790 expect(print(store)).toBe('');791 }792 }793 });794 it('should handle a stress test for Suspense without type change (Concurrent Mode)', async () => {795 const A = () => 'a';796 const B = () => 'b';797 const C = () => 'c';798 const X = () => 'x';799 const Y = () => 'y';800 const Z = () => 'z';801 const a = <A key="a" />;802 const b = <B key="b" />;803 const c = <C key="c" />;804 const z = <Z key="z" />;805 // prettier-ignore806 const steps = [807 a,808 [a],809 [a, b, c],810 [c, b, a],811 [c, null, a],812 <React.Fragment>{c}{a}</React.Fragment>,813 <div>{c}{a}</div>,814 <div><span>{a}</span>{b}</div>,815 [[a]],816 null,817 b,818 a,819 ];820 const Never = () => {821 throw new Promise(() => {});822 };823 const MaybeSuspend = ({children, suspend}) => {824 if (suspend) {825 return (826 <div>827 {children}828 <Never />829 <X />830 </div>831 );832 }833 return (834 <div>835 {children}836 <Z />837 </div>838 );839 };840 const Root = ({children}) => {841 return children;842 };843 // 1. For each step, check Suspense can render them as initial primary content.844 // This is the only step where we use Jest snapshots.845 const snapshots = [];846 let container = document.createElement('div');847 // $FlowFixMe848 let root = ReactDOM.createRoot(container);849 for (let i = 0; i < steps.length; i++) {850 act(() =>851 root.render(852 <Root>853 <X />854 <React.Suspense fallback={z}>855 <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>856 </React.Suspense>857 <Y />858 </Root>,859 ),860 );861 // We snapshot each step once so it doesn't regress.862 snapshots.push(print(store));863 act(() => root.unmount());864 expect(print(store)).toBe('');865 }866 // 2. Verify check Suspense can render same steps as initial fallback content.867 // We don't actually assert here because the tree includes <MaybeSuspend>868 // which is different from the snapshots above. So we take more snapshots.869 const fallbackSnapshots = [];870 for (let i = 0; i < steps.length; i++) {871 act(() =>872 root.render(873 <Root>874 <X />875 <React.Suspense fallback={steps[i]}>876 <Z />877 <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>878 <Z />879 </React.Suspense>880 <Y />881 </Root>,882 ),883 );884 // We snapshot each step once so it doesn't regress.885 fallbackSnapshots.push(print(store));886 act(() => root.unmount());887 expect(print(store)).toBe('');888 }889 expect(snapshots).toMatchInlineSnapshot(`890 Array [891 "[root]892 â¾ <Root>893 <X>894 â¾ <Suspense>895 â¾ <MaybeSuspend>896 <A key=\\"a\\">897 <Z>898 <Y>",899 "[root]900 â¾ <Root>901 <X>902 â¾ <Suspense>903 â¾ <MaybeSuspend>904 <A key=\\"a\\">905 <Z>906 <Y>",907 "[root]908 â¾ <Root>909 <X>910 â¾ <Suspense>911 â¾ <MaybeSuspend>912 <A key=\\"a\\">913 <B key=\\"b\\">914 <C key=\\"c\\">915 <Z>916 <Y>",917 "[root]918 â¾ <Root>919 <X>920 â¾ <Suspense>921 â¾ <MaybeSuspend>922 <C key=\\"c\\">923 <B key=\\"b\\">924 <A key=\\"a\\">925 <Z>926 <Y>",927 "[root]928 â¾ <Root>929 <X>930 â¾ <Suspense>931 â¾ <MaybeSuspend>932 <C key=\\"c\\">933 <A key=\\"a\\">934 <Z>935 <Y>",936 "[root]937 â¾ <Root>938 <X>939 â¾ <Suspense>940 â¾ <MaybeSuspend>941 <C key=\\"c\\">942 <A key=\\"a\\">943 <Z>944 <Y>",945 "[root]946 â¾ <Root>947 <X>948 â¾ <Suspense>949 â¾ <MaybeSuspend>950 <C key=\\"c\\">951 <A key=\\"a\\">952 <Z>953 <Y>",954 "[root]955 â¾ <Root>956 <X>957 â¾ <Suspense>958 â¾ <MaybeSuspend>959 <A key=\\"a\\">960 <B key=\\"b\\">961 <Z>962 <Y>",963 "[root]964 â¾ <Root>965 <X>966 â¾ <Suspense>967 â¾ <MaybeSuspend>968 <A key=\\"a\\">969 <Z>970 <Y>",971 "[root]972 â¾ <Root>973 <X>974 â¾ <Suspense>975 â¾ <MaybeSuspend>976 <Z>977 <Y>",978 "[root]979 â¾ <Root>980 <X>981 â¾ <Suspense>982 â¾ <MaybeSuspend>983 <B key=\\"b\\">984 <Z>985 <Y>",986 "[root]987 â¾ <Root>988 <X>989 â¾ <Suspense>990 â¾ <MaybeSuspend>991 <A key=\\"a\\">992 <Z>993 <Y>",994 ]995 `);996 // 3. Verify we can update from each step to each step in primary mode.997 for (let i = 0; i < steps.length; i++) {998 for (let j = 0; j < steps.length; j++) {999 // Always start with a fresh container and steps[i].1000 container = document.createElement('div');1001 // $FlowFixMe1002 root = ReactDOM.createRoot(container);1003 act(() =>1004 root.render(1005 <Root>1006 <X />1007 <React.Suspense fallback={z}>1008 <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1009 </React.Suspense>1010 <Y />1011 </Root>,1012 ),1013 );1014 expect(print(store)).toEqual(snapshots[i]);1015 // Re-render with steps[j].1016 act(() =>1017 root.render(1018 <Root>1019 <X />1020 <React.Suspense fallback={z}>1021 <MaybeSuspend suspend={false}>{steps[j]}</MaybeSuspend>1022 </React.Suspense>1023 <Y />1024 </Root>,1025 ),1026 );1027 // Verify the successful transition to steps[j].1028 expect(print(store)).toEqual(snapshots[j]);1029 // Check that we can transition back again.1030 act(() =>1031 root.render(1032 <Root>1033 <X />1034 <React.Suspense fallback={z}>1035 <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1036 </React.Suspense>1037 <Y />1038 </Root>,1039 ),1040 );1041 expect(print(store)).toEqual(snapshots[i]);1042 // Clean up after every iteration.1043 act(() => root.unmount());1044 expect(print(store)).toBe('');1045 }1046 }1047 // 4. Verify we can update from each step to each step in fallback mode.1048 for (let i = 0; i < steps.length; i++) {1049 for (let j = 0; j < steps.length; j++) {1050 // Always start with a fresh container and steps[i].1051 container = document.createElement('div');1052 // $FlowFixMe1053 root = ReactDOM.createRoot(container);1054 act(() =>1055 root.render(1056 <Root>1057 <X />1058 <React.Suspense fallback={steps[i]}>1059 <Z />1060 <MaybeSuspend suspend={true}>1061 <X />1062 <Y />1063 </MaybeSuspend>1064 <Z />1065 </React.Suspense>1066 <Y />1067 </Root>,1068 ),1069 );1070 expect(print(store)).toEqual(fallbackSnapshots[i]);1071 // Re-render with steps[j].1072 act(() =>1073 root.render(1074 <Root>1075 <X />1076 <React.Suspense fallback={steps[j]}>1077 <Z />1078 <MaybeSuspend suspend={true}>1079 <Y />1080 <X />1081 </MaybeSuspend>1082 <Z />1083 </React.Suspense>1084 <Y />1085 </Root>,1086 ),1087 );1088 // Verify the successful transition to steps[j].1089 expect(print(store)).toEqual(fallbackSnapshots[j]);1090 // Check that we can transition back again.1091 act(() =>1092 root.render(1093 <Root>1094 <X />1095 <React.Suspense fallback={steps[i]}>1096 <Z />1097 <MaybeSuspend suspend={true}>1098 <X />1099 <Y />1100 </MaybeSuspend>1101 <Z />1102 </React.Suspense>1103 <Y />1104 </Root>,1105 ),1106 );1107 expect(print(store)).toEqual(fallbackSnapshots[i]);1108 // Clean up after every iteration.1109 act(() => root.unmount());1110 expect(print(store)).toBe('');1111 }1112 }1113 // 5. Verify we can update from each step to each step when moving primary -> fallback.1114 for (let i = 0; i < steps.length; i++) {1115 for (let j = 0; j < steps.length; j++) {1116 // Always start with a fresh container and steps[i].1117 container = document.createElement('div');1118 // $FlowFixMe1119 root = ReactDOM.createRoot(container);1120 act(() =>1121 root.render(1122 <Root>1123 <X />1124 <React.Suspense fallback={z}>1125 <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1126 </React.Suspense>1127 <Y />1128 </Root>,1129 ),1130 );1131 expect(print(store)).toEqual(snapshots[i]);1132 // Re-render with steps[j].1133 act(() =>1134 root.render(1135 <Root>1136 <X />1137 <React.Suspense fallback={steps[j]}>1138 <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>1139 </React.Suspense>1140 <Y />1141 </Root>,1142 ),1143 );1144 // Verify the successful transition to steps[j].1145 expect(print(store)).toEqual(fallbackSnapshots[j]);1146 // Check that we can transition back again.1147 act(() =>1148 root.render(1149 <Root>1150 <X />1151 <React.Suspense fallback={z}>1152 <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1153 </React.Suspense>1154 <Y />1155 </Root>,1156 ),1157 );1158 expect(print(store)).toEqual(snapshots[i]);1159 // Clean up after every iteration.1160 act(() => root.unmount());1161 expect(print(store)).toBe('');1162 }1163 }1164 // 6. Verify we can update from each step to each step when moving fallback -> primary.1165 for (let i = 0; i < steps.length; i++) {1166 for (let j = 0; j < steps.length; j++) {1167 // Always start with a fresh container and steps[i].1168 container = document.createElement('div');1169 // $FlowFixMe1170 root = ReactDOM.createRoot(container);1171 act(() =>1172 root.render(1173 <Root>1174 <X />1175 <React.Suspense fallback={steps[i]}>1176 <MaybeSuspend suspend={true}>{steps[j]}</MaybeSuspend>1177 </React.Suspense>1178 <Y />1179 </Root>,1180 ),1181 );1182 expect(print(store)).toEqual(fallbackSnapshots[i]);1183 // Re-render with steps[j].1184 act(() =>1185 root.render(1186 <Root>1187 <X />1188 <React.Suspense fallback={steps[i]}>1189 <MaybeSuspend suspend={false}>{steps[j]}</MaybeSuspend>1190 </React.Suspense>1191 <Y />1192 </Root>,1193 ),1194 );1195 // Verify the successful transition to steps[j].1196 expect(print(store)).toEqual(snapshots[j]);1197 // Check that we can transition back again.1198 act(() =>1199 root.render(1200 <Root>1201 <X />1202 <React.Suspense fallback={steps[i]}>1203 <MaybeSuspend suspend={true}>{steps[j]}</MaybeSuspend>1204 </React.Suspense>1205 <Y />1206 </Root>,1207 ),1208 );1209 expect(print(store)).toEqual(fallbackSnapshots[i]);1210 // Clean up after every iteration.1211 act(() => root.unmount());1212 expect(print(store)).toBe('');1213 }1214 }1215 // 7. Verify we can update from each step to each step when toggling Suspense.1216 for (let i = 0; i < steps.length; i++) {1217 for (let j = 0; j < steps.length; j++) {1218 // Always start with a fresh container and steps[i].1219 container = document.createElement('div');1220 // $FlowFixMe1221 root = ReactDOM.createRoot(container);1222 act(() =>1223 root.render(1224 <Root>1225 <X />1226 <React.Suspense fallback={steps[j]}>1227 <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1228 </React.Suspense>1229 <Y />1230 </Root>,1231 ),1232 );1233 // We get ID from the index in the tree above:1234 // Root, X, Suspense, ...1235 // ^ (index is 2)1236 const suspenseID = store.getElementIDAtIndex(2);1237 // Force fallback.1238 expect(print(store)).toEqual(snapshots[i]);1239 await actAsync(async () => {1240 bridge.send('overrideSuspense', {1241 id: suspenseID,1242 rendererID: store.getRendererIDForElement(suspenseID),1243 forceFallback: true,1244 });1245 });1246 expect(print(store)).toEqual(fallbackSnapshots[j]);1247 // Stop forcing fallback.1248 await actAsync(async () => {1249 bridge.send('overrideSuspense', {1250 id: suspenseID,1251 rendererID: store.getRendererIDForElement(suspenseID),1252 forceFallback: false,1253 });1254 });1255 expect(print(store)).toEqual(snapshots[i]);1256 // Trigger actual fallback.1257 act(() =>1258 root.render(1259 <Root>1260 <X />1261 <React.Suspense fallback={steps[j]}>1262 <MaybeSuspend suspend={true}>{steps[i]}</MaybeSuspend>1263 </React.Suspense>1264 <Y />1265 </Root>,1266 ),1267 );1268 expect(print(store)).toEqual(fallbackSnapshots[j]);1269 // Force fallback while we're in fallback mode.1270 act(() => {1271 bridge.send('overrideSuspense', {1272 id: suspenseID,1273 rendererID: store.getRendererIDForElement(suspenseID),1274 forceFallback: true,1275 });1276 });1277 // Keep seeing fallback content.1278 expect(print(store)).toEqual(fallbackSnapshots[j]);1279 // Switch to primary mode.1280 act(() =>1281 root.render(1282 <Root>1283 <X />1284 <React.Suspense fallback={steps[j]}>1285 <MaybeSuspend suspend={false}>{steps[i]}</MaybeSuspend>1286 </React.Suspense>1287 <Y />1288 </Root>,1289 ),1290 );1291 // Fallback is still forced though.1292 expect(print(store)).toEqual(fallbackSnapshots[j]);1293 // Stop forcing fallback. This reverts to primary content.1294 await actAsync(async () => {1295 bridge.send('overrideSuspense', {1296 id: suspenseID,1297 rendererID: store.getRendererIDForElement(suspenseID),1298 forceFallback: false,1299 });1300 });1301 // Now we see primary content.1302 expect(print(store)).toEqual(snapshots[i]);1303 // Clean up after every iteration.1304 act(() => root.unmount());1305 expect(print(store)).toBe('');1306 }1307 }1308 });...
DependencyGraph-test.js
Source:DependencyGraph-test.js
1'use strict';2jest3 .dontMock('../index')4 .dontMock('q')5 .dontMock('path')6 .dontMock('absolute-path')7 .dontMock('../docblock')8 .setMock('../../../ModuleDescriptor', function(data) {return data;});9describe('DependencyGraph', function() {10 var DependencyGraph;11 var fileWatcher;12 var fs;13 beforeEach(function() {14 fs = require('fs');15 DependencyGraph = require('../index');16 fileWatcher = {17 on: function() {18 return this;19 }20 };21 });22 describe('getOrderedDependencies', function() {23 pit('should get dependencies', function() {24 var root = '/root';25 fs.__setMockFilesystem({26 'root': {27 'index.js': [28 '/**',29 ' * @providesModule index',30 ' */',31 'require("a")'32 ].join('\n'),33 'a.js': [34 '/**',35 ' * @providesModule a',36 ' */',37 ].join('\n'),38 }39 });40 var dgraph = new DependencyGraph({41 roots: [root],42 fileWatcher: fileWatcher43 });44 return dgraph.load().then(function() {45 expect(dgraph.getOrderedDependencies('/root/index.js'))46 .toEqual([47 {id: 'index', path: '/root/index.js', dependencies: ['a']},48 {id: 'a', path: '/root/a.js', dependencies: []},49 ]);50 });51 });52 pit('should get dependencies', function() {53 var root = '/root';54 fs.__setMockFilesystem({55 'root': {56 'index.js': [57 '/**',58 ' * @providesModule index',59 ' */',60 'require("image!a")'61 ].join('\n'),62 'imgs': {63 'a.png': ''64 },65 }66 });67 var dgraph = new DependencyGraph({68 roots: [root],69 fileWatcher: fileWatcher,70 assetRoots: ['/root/imgs']71 });72 return dgraph.load().then(function() {73 expect(dgraph.getOrderedDependencies('/root/index.js'))74 .toEqual([75 {id: 'index', path: '/root/index.js', dependencies: ['image!a']},76 { id: 'image!a',77 path: '/root/imgs/a.png',78 dependencies: [],79 isAsset: true80 },81 ]);82 });83 });84 pit('should get recursive dependencies', function() {85 var root = '/root';86 fs.__setMockFilesystem({87 'root': {88 'index.js': [89 '/**',90 ' * @providesModule index',91 ' */',92 'require("a")',93 ].join('\n'),94 'a.js': [95 '/**',96 ' * @providesModule a',97 ' */',98 'require("index")',99 ].join('\n'),100 }101 });102 var dgraph = new DependencyGraph({103 roots: [root],104 fileWatcher: fileWatcher105 });106 return dgraph.load().then(function() {107 expect(dgraph.getOrderedDependencies('/root/index.js'))108 .toEqual([109 {id: 'index', path: '/root/index.js', dependencies: ['a']},110 {id: 'a', path: '/root/a.js', dependencies: ['index']},111 ]);112 });113 });114 pit('should work with packages', function() {115 var root = '/root';116 fs.__setMockFilesystem({117 'root': {118 'index.js': [119 '/**',120 ' * @providesModule index',121 ' */',122 'require("aPackage")',123 ].join('\n'),124 'aPackage': {125 'package.json': JSON.stringify({126 name: 'aPackage',127 main: 'main.js'128 }),129 'main.js': 'lol'130 }131 }132 });133 var dgraph = new DependencyGraph({134 roots: [root],135 fileWatcher: fileWatcher136 });137 return dgraph.load().then(function() {138 expect(dgraph.getOrderedDependencies('/root/index.js'))139 .toEqual([140 {id: 'index', path: '/root/index.js', dependencies: ['aPackage']},141 { id: 'aPackage/main',142 path: '/root/aPackage/main.js',143 dependencies: []144 },145 ]);146 });147 });148 pit('should ignore malformed packages', function() {149 var root = '/root';150 fs.__setMockFilesystem({151 'root': {152 'index.js': [153 '/**',154 ' * @providesModule index',155 ' */',156 'require("aPackage")',157 ].join('\n'),158 'aPackage': {159 'package.json': 'lol',160 'main.js': 'lol'161 }162 }163 });164 var dgraph = new DependencyGraph({165 roots: [root],166 fileWatcher: fileWatcher167 });168 return dgraph.load().then(function() {169 expect(dgraph.getOrderedDependencies('/root/index.js'))170 .toEqual([171 {id: 'index', path: '/root/index.js', dependencies: ['aPackage']},172 ]);173 });174 });175 pit('can have multiple modules with the same name', function() {176 var root = '/root';177 fs.__setMockFilesystem({178 'root': {179 'index.js': [180 '/**',181 ' * @providesModule index',182 ' */',183 'require("b")',184 ].join('\n'),185 'b.js': [186 '/**',187 ' * @providesModule b',188 ' */',189 ].join('\n'),190 'c.js': [191 '/**',192 ' * @providesModule c',193 ' */',194 ].join('\n'),195 'somedir': {196 'somefile.js': [197 '/**',198 ' * @providesModule index',199 ' */',200 'require("c")',201 ].join('\n')202 }203 }204 });205 var dgraph = new DependencyGraph({206 roots: [root],207 fileWatcher: fileWatcher208 });209 return dgraph.load().then(function() {210 expect(dgraph.getOrderedDependencies('/root/somedir/somefile.js'))211 .toEqual([212 { id: 'index',213 path: '/root/somedir/somefile.js',214 dependencies: ['c']215 },216 { id: 'c',217 path: '/root/c.js',218 dependencies: []219 },220 ]);221 });222 });223 pit('providesModule wins when conflict with package', function() {224 var root = '/root';225 fs.__setMockFilesystem({226 'root': {227 'index.js': [228 '/**',229 ' * @providesModule index',230 ' */',231 'require("aPackage")',232 ].join('\n'),233 'b.js': [234 '/**',235 ' * @providesModule aPackage',236 ' */',237 ].join('\n'),238 'aPackage': {239 'package.json': JSON.stringify({240 name: 'aPackage',241 main: 'main.js'242 }),243 'main.js': 'lol'244 }245 }246 });247 var dgraph = new DependencyGraph({248 roots: [root],249 fileWatcher: fileWatcher250 });251 return dgraph.load().then(function() {252 expect(dgraph.getOrderedDependencies('/root/index.js'))253 .toEqual([254 { id: 'index',255 path: '/root/index.js',256 dependencies: ['aPackage']257 },258 { id: 'aPackage',259 path: '/root/b.js',260 dependencies: []261 },262 ]);263 });264 });265 pit('should be forgiving with missing requires', function() {266 var root = '/root';267 fs.__setMockFilesystem({268 'root': {269 'index.js': [270 '/**',271 ' * @providesModule index',272 ' */',273 'require("lolomg")',274 ].join('\n')275 }276 });277 var dgraph = new DependencyGraph({278 roots: [root],279 fileWatcher: fileWatcher280 });281 return dgraph.load().then(function() {282 expect(dgraph.getOrderedDependencies('/root/index.js'))283 .toEqual([284 { id: 'index',285 path: '/root/index.js',286 dependencies: ['lolomg']287 }288 ]);289 });290 });291 pit('should work with packages with subdirs', function() {292 var root = '/root';293 fs.__setMockFilesystem({294 'root': {295 'index.js': [296 '/**',297 ' * @providesModule index',298 ' */',299 'require("aPackage/subdir/lolynot")',300 ].join('\n'),301 'aPackage': {302 'package.json': JSON.stringify({303 name: 'aPackage',304 main: 'main.js'305 }),306 'main.js': 'lol',307 'subdir': {308 'lolynot.js': 'lolynot'309 }310 }311 }312 });313 var dgraph = new DependencyGraph({314 roots: [root],315 fileWatcher: fileWatcher316 });317 return dgraph.load().then(function() {318 expect(dgraph.getOrderedDependencies('/root/index.js'))319 .toEqual([320 { id: 'index',321 path: '/root/index.js',322 dependencies: ['aPackage/subdir/lolynot']323 },324 { id: 'aPackage/subdir/lolynot',325 path: '/root/aPackage/subdir/lolynot.js',326 dependencies: []327 },328 ]);329 });330 });331 pit('should work with packages with symlinked subdirs', function() {332 var root = '/root';333 fs.__setMockFilesystem({334 'symlinkedPackage': {335 'package.json': JSON.stringify({336 name: 'aPackage',337 main: 'main.js'338 }),339 'main.js': 'lol',340 'subdir': {341 'lolynot.js': 'lolynot'342 }343 },344 'root': {345 'index.js': [346 '/**',347 ' * @providesModule index',348 ' */',349 'require("aPackage/subdir/lolynot")',350 ].join('\n'),351 'aPackage': { SYMLINK: '/symlinkedPackage' },352 }353 });354 var dgraph = new DependencyGraph({355 roots: [root],356 fileWatcher: fileWatcher357 });358 return dgraph.load().then(function() {359 expect(dgraph.getOrderedDependencies('/root/index.js'))360 .toEqual([361 { id: 'index',362 path: '/root/index.js',363 dependencies: ['aPackage/subdir/lolynot']364 },365 { id: 'aPackage/subdir/lolynot',366 path: '/symlinkedPackage/subdir/lolynot.js',367 dependencies: []368 },369 ]);370 });371 });372 pit('should work with relative modules in packages', function() {373 var root = '/root';374 fs.__setMockFilesystem({375 'root': {376 'index.js': [377 '/**',378 ' * @providesModule index',379 ' */',380 'require("aPackage")',381 ].join('\n'),382 'aPackage': {383 'package.json': JSON.stringify({384 name: 'aPackage',385 main: 'main.js'386 }),387 'main.js': 'require("./subdir/lolynot")',388 'subdir': {389 'lolynot.js': 'require("../other")'390 },391 'other.js': 'some code'392 }393 }394 });395 var dgraph = new DependencyGraph({396 roots: [root],397 fileWatcher: fileWatcher398 });399 return dgraph.load().then(function() {400 expect(dgraph.getOrderedDependencies('/root/index.js'))401 .toEqual([402 { id: 'index',403 path: '/root/index.js',404 dependencies: ['aPackage']405 },406 { id: 'aPackage/main',407 path: '/root/aPackage/main.js',408 dependencies: ['./subdir/lolynot']409 },410 { id: 'aPackage/subdir/lolynot',411 path: '/root/aPackage/subdir/lolynot.js',412 dependencies: ['../other']413 },414 { id: 'aPackage/other',415 path: '/root/aPackage/other.js',416 dependencies: []417 },418 ]);419 });420 });421 });422 describe('file watch updating', function() {423 var triggerFileChange;424 beforeEach(function() {425 fileWatcher = {426 on: function(eventType, callback) {427 if (eventType !== 'all') {428 throw new Error('Can only handle "all" event in watcher.');429 }430 triggerFileChange = callback;431 return this;432 }433 };434 });435 pit('updates module dependencies', function() {436 var root = '/root';437 var filesystem = fs.__setMockFilesystem({438 'root': {439 'index.js': [440 '/**',441 ' * @providesModule index',442 ' */',443 'require("aPackage")',444 'require("foo")'445 ].join('\n'),446 'foo': [447 '/**',448 ' * @providesModule foo',449 ' */',450 'require("aPackage")'451 ].join('\n'),452 'aPackage': {453 'package.json': JSON.stringify({454 name: 'aPackage',455 main: 'main.js'456 }),457 'main.js': 'main',458 }459 }460 });461 var dgraph = new DependencyGraph({462 roots: [root],463 fileWatcher: fileWatcher464 });465 return dgraph.load().then(function() {466 filesystem.root['index.js'] =467 filesystem.root['index.js'].replace('require("foo")', '');468 triggerFileChange('change', 'index.js', root);469 return dgraph.load().then(function() {470 expect(dgraph.getOrderedDependencies('/root/index.js'))471 .toEqual([472 { id: 'index',473 path: '/root/index.js',474 dependencies: ['aPackage']475 },476 { id: 'aPackage/main',477 path: '/root/aPackage/main.js',478 dependencies: []479 },480 ]);481 });482 });483 });484 pit('updates module dependencies on file change', function() {485 var root = '/root';486 var filesystem = fs.__setMockFilesystem({487 'root': {488 'index.js': [489 '/**',490 ' * @providesModule index',491 ' */',492 'require("aPackage")',493 'require("foo")'494 ].join('\n'),495 'foo.js': [496 '/**',497 ' * @providesModule foo',498 ' */',499 'require("aPackage")'500 ].join('\n'),501 'aPackage': {502 'package.json': JSON.stringify({503 name: 'aPackage',504 main: 'main.js'505 }),506 'main.js': 'main',507 }508 }509 });510 var dgraph = new DependencyGraph({511 roots: [root],512 fileWatcher: fileWatcher513 });514 return dgraph.load().then(function() {515 filesystem.root['index.js'] =516 filesystem.root['index.js'].replace('require("foo")', '');517 triggerFileChange('change', 'index.js', root);518 return dgraph.load().then(function() {519 expect(dgraph.getOrderedDependencies('/root/index.js'))520 .toEqual([521 { id: 'index',522 path: '/root/index.js',523 dependencies: ['aPackage']524 },525 { id: 'aPackage/main',526 path: '/root/aPackage/main.js',527 dependencies: []528 },529 ]);530 });531 });532 });533 pit('updates module dependencies on file delete', function() {534 var root = '/root';535 var filesystem = fs.__setMockFilesystem({536 'root': {537 'index.js': [538 '/**',539 ' * @providesModule index',540 ' */',541 'require("aPackage")',542 'require("foo")'543 ].join('\n'),544 'foo.js': [545 '/**',546 ' * @providesModule foo',547 ' */',548 'require("aPackage")'549 ].join('\n'),550 'aPackage': {551 'package.json': JSON.stringify({552 name: 'aPackage',553 main: 'main.js'554 }),555 'main.js': 'main',556 }557 }558 });559 var dgraph = new DependencyGraph({560 roots: [root],561 fileWatcher: fileWatcher562 });563 return dgraph.load().then(function() {564 delete filesystem.root.foo;565 triggerFileChange('delete', 'foo.js', root);566 return dgraph.load().then(function() {567 expect(dgraph.getOrderedDependencies('/root/index.js'))568 .toEqual([569 { id: 'index',570 path: '/root/index.js',571 dependencies: ['aPackage', 'foo']572 },573 { id: 'aPackage/main',574 path: '/root/aPackage/main.js',575 dependencies: []576 },577 ]);578 });579 });580 });581 pit('updates module dependencies on file add', function() {582 var root = '/root';583 var filesystem = fs.__setMockFilesystem({584 'root': {585 'index.js': [586 '/**',587 ' * @providesModule index',588 ' */',589 'require("aPackage")',590 'require("foo")'591 ].join('\n'),592 'foo.js': [593 '/**',594 ' * @providesModule foo',595 ' */',596 'require("aPackage")'597 ].join('\n'),598 'aPackage': {599 'package.json': JSON.stringify({600 name: 'aPackage',601 main: 'main.js'602 }),603 'main.js': 'main',604 }605 }606 });607 var dgraph = new DependencyGraph({608 roots: [root],609 fileWatcher: fileWatcher610 });611 return dgraph.load().then(function() {612 filesystem.root['bar.js'] = [613 '/**',614 ' * @providesModule bar',615 ' */',616 'require("foo")'617 ].join('\n');618 triggerFileChange('add', 'bar.js', root);619 filesystem.root.aPackage['main.js'] = 'require("bar")';620 triggerFileChange('change', 'aPackage/main.js', root);621 return dgraph.load().then(function() {622 expect(dgraph.getOrderedDependencies('/root/index.js'))623 .toEqual([624 { id: 'index',625 path: '/root/index.js',626 dependencies: ['aPackage', 'foo']627 },628 { id: 'aPackage/main',629 path: '/root/aPackage/main.js',630 dependencies: ['bar']631 },632 { id: 'bar',633 path: '/root/bar.js',634 dependencies: ['foo']635 },636 { id: 'foo',637 path: '/root/foo.js',638 dependencies: ['aPackage']639 },640 ]);641 });642 });643 });644 pit('runs changes through ignore filter', function() {645 var root = '/root';646 var filesystem = fs.__setMockFilesystem({647 'root': {648 'index.js': [649 '/**',650 ' * @providesModule index',651 ' */',652 'require("aPackage")',653 'require("foo")'654 ].join('\n'),655 'foo.js': [656 '/**',657 ' * @providesModule foo',658 ' */',659 'require("aPackage")'660 ].join('\n'),661 'aPackage': {662 'package.json': JSON.stringify({663 name: 'aPackage',664 main: 'main.js'665 }),666 'main.js': 'main',667 }668 }669 });670 var dgraph = new DependencyGraph({671 roots: [root],672 fileWatcher: fileWatcher,673 ignoreFilePath: function(filePath) {674 if (filePath === '/root/bar.js') {675 return true;676 }677 return false;678 }679 });680 return dgraph.load().then(function() {681 filesystem.root['bar.js'] = [682 '/**',683 ' * @providesModule bar',684 ' */',685 'require("foo")'686 ].join('\n');687 triggerFileChange('add', 'bar.js', root);688 filesystem.root.aPackage['main.js'] = 'require("bar")';689 triggerFileChange('change', 'aPackage/main.js', root);690 return dgraph.load().then(function() {691 expect(dgraph.getOrderedDependencies('/root/index.js'))692 .toEqual([693 { id: 'index',694 path: '/root/index.js',695 dependencies: ['aPackage', 'foo']696 },697 { id: 'aPackage/main',698 path: '/root/aPackage/main.js',699 dependencies: ['bar']700 },701 { id: 'foo',702 path: '/root/foo.js',703 dependencies: ['aPackage']704 },705 ]);706 });707 });708 });709 pit('should ignore directory updates', function() {710 var root = '/root';711 fs.__setMockFilesystem({712 'root': {713 'index.js': [714 '/**',715 ' * @providesModule index',716 ' */',717 'require("aPackage")',718 'require("foo")'719 ].join('\n'),720 'foo.js': [721 '/**',722 ' * @providesModule foo',723 ' */',724 'require("aPackage")'725 ].join('\n'),726 'aPackage': {727 'package.json': JSON.stringify({728 name: 'aPackage',729 main: 'main.js'730 }),731 'main.js': 'main',732 }733 }734 });735 var dgraph = new DependencyGraph({736 roots: [root],737 fileWatcher: fileWatcher738 });739 return dgraph.load().then(function() {740 triggerFileChange('change', 'aPackage', '/root', {741 isDirectory: function(){ return true; }742 });743 return dgraph.load().then(function() {744 expect(dgraph.getOrderedDependencies('/root/index.js'))745 .toEqual([746 { id: 'index',747 path: '/root/index.js',748 dependencies: ['aPackage', 'foo']749 },750 { id: 'aPackage/main',751 path: '/root/aPackage/main.js',752 dependencies: []753 },754 { id: 'foo',755 path: '/root/foo.js',756 dependencies: ['aPackage']757 },758 ]);759 });760 });761 });762 });...
Node.js
Source:Node.js
1module("tinymce.html.Node");2test('construction', function() {3 var node;4 expect(15);5 node = new tinymce.html.Node('#text', 3);6 equal(node.name, '#text');7 equal(node.type, 3);8 node = new tinymce.html.Node('#comment', 8);9 equal(node.name, '#comment');10 equal(node.type, 8);11 node = new tinymce.html.Node('b', 1);12 equal(node.name, 'b');13 equal(node.type, 1);14 deepEqual(node.attributes, []);15 node = new tinymce.html.Node('#pi', 7);16 equal(node.name, '#pi');17 equal(node.type, 7);18 node = new tinymce.html.Node('#doctype', 10);19 equal(node.name, '#doctype');20 equal(node.type, 10);21 node = new tinymce.html.Node('#cdata', 4);22 equal(node.name, '#cdata');23 equal(node.type, 4);24 node = new tinymce.html.Node('#frag', 11);25 equal(node.name, '#frag');26 equal(node.type, 11);27});28test('append inside empty node', function() {29 var root, node;30 expect(10);31 root = new tinymce.html.Node('#frag', 11);32 node = root.append(new tinymce.html.Node('b', 1));33 ok(root.firstChild.parent === root);34 equal(root.firstChild.next, undefined);35 equal(root.firstChild.prev, undefined);36 equal(root.firstChild.firstChild, undefined);37 equal(root.firstChild.lastChild, undefined);38 ok(node.parent === root);39 equal(node.next, undefined);40 equal(node.prev, undefined);41 equal(node.firstChild, undefined);42 equal(node.lastChild, undefined);43});44test('append node after node', function() {45 var root, node, node2;46 expect(17);47 root = new tinymce.html.Node('#frag', 11);48 node2 = root.append(new tinymce.html.Node('a', 1));49 node = root.append(new tinymce.html.Node('b', 1));50 ok(root.firstChild.parent === root, 'root.firstChild.parent === root');51 ok(root.firstChild === node2, 'root.firstChild');52 ok(root.lastChild === node, 'root.firstChild');53 ok(root.firstChild.next === node, 'root.firstChild.next');54 equal(root.firstChild.prev, undefined, 'root.firstChild.prev');55 equal(root.firstChild.firstChild, undefined, 'root.firstChild.firstChild');56 equal(root.firstChild.lastChild, undefined, 'root.firstChild.lastChild');57 ok(node2.parent === root, 'node2.parent === root');58 ok(node2.next === node, 'node2.next');59 equal(node2.prev, undefined, 'node2.prev');60 equal(node2.firstChild, undefined, 'node2.firstChild');61 equal(node2.lastChild, undefined, 'node2.lastChild');62 ok(node.parent === root, 'node.parent === root');63 equal(node.next, undefined, 'node.next');64 ok(node.prev === node2, 'node.prev');65 equal(node.firstChild, undefined, 'node.firstChild');66 equal(node.lastChild, undefined, 'node.lastChild');67});68test('append existing node before other existing node', function() {69 var root, node, node2;70 expect(8);71 root = new tinymce.html.Node('#frag', 11);72 node = root.append(new tinymce.html.Node('a', 1));73 node2 = root.append(new tinymce.html.Node('b', 1));74 root.append(node);75 ok(root.firstChild === node2, 'root.firstChild');76 ok(root.lastChild === node, 'root.lastChild');77 equal(node.next, undefined, 'node.next');78 ok(node.prev === node2, 'node.prev');79 ok(node.parent === root, 'node.parent');80 ok(node2.parent === root, 'node2.parent');81 equal(node2.prev, undefined, 'node2.prev');82 ok(node2.next === node, 'node2.next');83});84test('remove unattached node', function() {85 expect(1);86 ok(!new tinymce.html.Node('#text', 3).remove().parent);87});88test('remove single child', function() {89 var root, node;90 expect(6);91 root = new tinymce.html.Node('#frag', 11);92 node = root.append(new tinymce.html.Node('p', 1));93 node = root.firstChild.remove();94 equal(root.firstChild, undefined);95 equal(root.lastChild, undefined);96 equal(node.parent, undefined);97 equal(node.next, undefined);98 equal(node.prev, undefined);99 equal(node.name, 'p');100});101test('remove middle node', function() {102 var root, node, node2, node3;103 expect(9);104 root = new tinymce.html.Node('#frag', 11);105 node = root.append(new tinymce.html.Node('a', 1));106 node2 = root.append(new tinymce.html.Node('b', 1));107 node3 = root.append(new tinymce.html.Node('c', 1));108 node2.remove();109 equal(node2.parent, undefined);110 equal(node2.next, undefined);111 equal(node2.prev, undefined);112 ok(root.firstChild === node, 'root.firstChild');113 ok(root.lastChild === node3, 'root.lastChild');114 ok(node.next === node3, 'node.next');115 equal(node.prev, undefined, 'node.prev');116 ok(node3.prev, node, 'node3.prev');117 equal(node3.next, undefined, 'node3.next');118});119test('insert after last', function() {120 var fragment, root, node, node2;121 expect(5);122 fragment = new tinymce.html.Node('#frag', 11);123 root = fragment.append(new tinymce.html.Node('body', 1));124 node = root.append(new tinymce.html.Node('a', 1));125 node2 = root.insert(new tinymce.html.Node('x', 1), node);126 ok(root.firstChild === node, 'root.firstChild');127 ok(root.lastChild === node2, 'root.lastChild');128 ok(node.next === node2, 'node.next');129 ok(node2.prev === node, 'node2.prev');130 ok(node2.parent === root, 'node3.next');131});132test('insert before first', function() {133 var fragment, root, node, node2;134 expect(8);135 fragment = new tinymce.html.Node('#frag', 11);136 root = fragment.append(new tinymce.html.Node('body', 1));137 node = root.append(new tinymce.html.Node('a', 1));138 node2 = root.insert(new tinymce.html.Node('x', 1), node, true);139 ok(root.firstChild === node2, 'root.firstChild');140 ok(root.lastChild === node, 'root.lastChild');141 ok(node2.parent === root, 'node2.lastChild');142 ok(node2.next === node, 'node2.next');143 ok(node2.prev === undefined, 'node2.prev');144 ok(node.parent === root, 'node.lastChild');145 ok(node.next === undefined, 'node.next');146 ok(node.prev === node2, 'node.prev');147});148test('insert before second', function() {149 var fragment, root, node, node2, node3;150 expect(5);151 fragment = new tinymce.html.Node('#frag', 11);152 root = fragment.append(new tinymce.html.Node('body', 1));153 node = root.append(new tinymce.html.Node('a', 1));154 node2 = root.append(new tinymce.html.Node('b', 1));155 node3 = root.insert(new tinymce.html.Node('x', 1), node2, true);156 ok(root.firstChild === node, 'root.firstChild');157 ok(root.lastChild === node2, 'root.lastChild');158 ok(node3.parent === root, 'node3.parent');159 ok(node3.next === node2, 'node3.next');160 ok(node3.prev === node, 'node3.prev');161});162test('insert after and between two nodes', function() {163 var root, node, node2, node3, fragment;164 expect(7);165 fragment = new tinymce.html.Node('#frag', 11);166 root = fragment.append(new tinymce.html.Node('body', 1));167 node = root.append(new tinymce.html.Node('a', 1));168 node2 = root.append(new tinymce.html.Node('b', 1));169 node3 = root.insert(new tinymce.html.Node('x', 1), node);170 ok(root.firstChild === node, 'root.firstChild');171 ok(root.lastChild === node2, 'root.lastChild');172 ok(node.next === node3, 'node.next');173 ok(node2.prev === node3, 'node2.prev');174 ok(node3.parent === root, 'node3.next');175 ok(node3.next === node2, 'node3.next');176 ok(node3.prev === node, 'node3.prev');177});178test('replace single child', function() {179 var root, node1, node2;180 expect(5);181 root = new tinymce.html.Node('#frag', 11);182 node1 = root.append(new tinymce.html.Node('b', 1));183 node2 = root.append(new tinymce.html.Node('em', 1));184 node1.replace(node2);185 ok(root.firstChild === node2, 'root.firstChild');186 ok(root.lastChild === node2, 'root.lastChild');187 ok(node2.parent === root, 'node2.parent');188 ok(!node2.next, 'node2.next');189 ok(!node2.prev, 'node2.prev');190});191test('replace first child', function() {192 var root, node1, node2, node3;193 expect(5);194 root = new tinymce.html.Node('#frag', 11);195 node1 = root.append(new tinymce.html.Node('b', 1));196 node2 = root.append(new tinymce.html.Node('em', 1));197 node3 = root.append(new tinymce.html.Node('b', 1));198 node1.replace(node2);199 ok(root.firstChild === node2, 'root.firstChild');200 ok(root.lastChild === node3, 'root.lastChild');201 ok(node2.parent === root, 'node2.parent');202 ok(node2.next === node3, 'node2.next');203 ok(!node2.prev, 'node2.prev');204});205test('replace last child', function() {206 var root, node1, node2, node3;207 expect(5);208 root = new tinymce.html.Node('#frag', 11);209 node1 = root.append(new tinymce.html.Node('b', 1));210 node3 = root.append(new tinymce.html.Node('b', 1));211 node2 = root.append(new tinymce.html.Node('em', 1));212 node3.replace(node2);213 ok(root.firstChild === node1, 'root.firstChild');214 ok(root.lastChild === node2, 'root.lastChild');215 ok(node2.parent === root, 'node2.parent');216 ok(!node2.next, 'node2.next');217 ok(node2.prev === node1, 'node2.prev');218});219test('replace middle child', function() {220 var root, node1, node2, node3, node4;221 expect(5);222 root = new tinymce.html.Node('#frag', 11);223 node1 = root.append(new tinymce.html.Node('b', 1));224 node2 = root.append(new tinymce.html.Node('b', 1));225 node3 = root.append(new tinymce.html.Node('b', 1));226 node4 = root.append(new tinymce.html.Node('em', 1));227 node2.replace(node4);228 ok(root.firstChild === node1, 'root.firstChild');229 ok(root.lastChild === node3, 'root.lastChild');230 ok(node4.parent === root, 'node4.parent');231 ok(node4.next === node3, 'node4.next');232 ok(node4.prev === node1, 'node4.prev');233});234test('attr', 22, function() {235 var node;236 node = new tinymce.html.Node('b', 1);237 deepEqual(node.attributes, []);238 node.attr('attr1', 'value1');239 equal(node.attr('attr1'), 'value1');240 equal(node.attr('attr2'), undefined);241 deepEqual(node.attributes, [{name: 'attr1', value: 'value1'}]);242 deepEqual(node.attributes.map, {'attr1': 'value1'});243 node = new tinymce.html.Node('b', 1);244 deepEqual(node.attributes, []);245 node.attr('attr1', 'value1');246 node.attr('attr1', 'valueX');247 equal(node.attr('attr1'), 'valueX');248 deepEqual(node.attributes, [{name: 'attr1', value: 'valueX'}]);249 deepEqual(node.attributes.map, {'attr1': 'valueX'});250 node = new tinymce.html.Node('b', 1);251 deepEqual(node.attributes, []);252 node.attr('attr1', 'value1');253 node.attr('attr2', 'value2');254 equal(node.attr('attr1'), 'value1');255 equal(node.attr('attr2'), 'value2');256 deepEqual(node.attributes, [{name: 'attr1', value: 'value1'}, {name: 'attr2', value: 'value2'}]);257 deepEqual(node.attributes.map, {'attr1': 'value1', 'attr2': 'value2'});258 node = new tinymce.html.Node('b', 1);259 deepEqual(node.attributes, []);260 node.attr('attr1', 'value1');261 node.attr('attr1', null);262 equal(node.attr('attr1'), undefined);263 deepEqual(node.attributes, []);264 deepEqual(node.attributes.map, {});265 node = new tinymce.html.Node('b', 1);266 node.attr({a:'1', b:'2'});267 deepEqual(node.attributes, [{name: 'a', value: '1'}, {name: 'b', value: '2'}]);268 deepEqual(node.attributes.map, {a:'1', b:'2'});269 node = new tinymce.html.Node('b', 1);270 node.attr(null);271 deepEqual(node.attributes, []);272 deepEqual(node.attributes.map, {});273});274test('clone', function() {275 var root, node, clone;276 expect(16);277 node = new tinymce.html.Node('#text', 3);278 node.value = 'value';279 clone = node.clone();280 equal(clone.name, '#text');281 equal(clone.type, 3);282 equal(clone.value, 'value');283 equal(clone.parent, undefined);284 equal(clone.next, undefined);285 equal(clone.prev, undefined);286 root = new tinymce.html.Node('#frag', 11);287 node = new tinymce.html.Node('#text', 3);288 node.value = 'value';289 root.append(node);290 equal(clone.name, '#text');291 equal(clone.type, 3);292 equal(clone.value, 'value');293 equal(clone.parent, undefined);294 equal(clone.next, undefined);295 equal(clone.prev, undefined);296 node = new tinymce.html.Node('b', 1);297 node.attr('id', 'id');298 node.attr('class', 'class');299 node.attr('title', 'title');300 clone = node.clone();301 equal(clone.name, 'b');302 equal(clone.type, 1);303 deepEqual(clone.attributes, [{name: 'class', value: 'class'}, {name: 'title', value: 'title'}]);304 deepEqual(clone.attributes.map, {'class': 'class', 'title': 'title'});305});306test('unwrap', function() {307 var root, node1, node2, node3;308 expect(7);309 root = new tinymce.html.Node('#frag', 11);310 node1 = root.append(new tinymce.html.Node('b', 1));311 node2 = node1.append(new tinymce.html.Node('em', 1));312 node1.unwrap();313 ok(root.firstChild === node2, 'root.firstChild');314 ok(root.lastChild === node2, 'root.lastChild');315 ok(node2.parent === root, 'node2.parent');316 root = new tinymce.html.Node('#frag', 11);317 node1 = root.append(new tinymce.html.Node('b', 1));318 node2 = node1.append(new tinymce.html.Node('em', 1));319 node3 = node1.append(new tinymce.html.Node('span', 1));320 node1.unwrap();321 ok(root.firstChild === node2, 'root.firstChild');322 ok(root.lastChild === node3, 'root.lastChild');323 ok(node2.parent === root, 'node2.parent');324 ok(node3.parent === root, 'node3.parent');325});326test('empty', function() {327 var root, node1, node2;328 expect(4);329 root = new tinymce.html.Node('#frag', 11);330 node1 = root.append(new tinymce.html.Node('b', 1));331 node2 = node1.append(new tinymce.html.Node('em', 1));332 node1.empty();333 ok(root.firstChild === node1, 'root.firstChild');334 ok(root.lastChild === node1, 'root.firstChild');335 ok(!node1.firstChild, 'node1.firstChild');336 ok(!node1.lastChild, 'node1.firstChild');337});338test('isEmpty', function() {339 var root, node1, node2;340 expect(9);341 root = new tinymce.html.Node('#frag', 11);342 node1 = root.append(new tinymce.html.Node('p', 1));343 node2 = node1.append(new tinymce.html.Node('b', 1));344 ok(root.isEmpty({img: 1}), 'Is empty 1');345 ok(node1.isEmpty({img: 1}), 'Is empty 2');346 root = new tinymce.html.Node('#frag', 11);347 node1 = root.append(new tinymce.html.Node('p', 1));348 node2 = node1.append(new tinymce.html.Node('img', 1));349 ok(!root.isEmpty({img: 1}), 'Is not empty 1');350 ok(!node1.isEmpty({img: 1}), 'Is not empty 2');351 root = new tinymce.html.Node('#frag', 11);352 node1 = root.append(new tinymce.html.Node('p', 1));353 node2 = node1.append(new tinymce.html.Node('#text', 3));354 node2.value = 'X';355 ok(!root.isEmpty({img: 1}), 'Is not empty 3');356 ok(!node1.isEmpty({img: 1}), 'Is not empty 4');357 root = new tinymce.html.Node('#frag', 11);358 node1 = root.append(new tinymce.html.Node('p', 1));359 node2 = node1.append(new tinymce.html.Node('#text', 3));360 node2.value = '';361 ok(root.isEmpty({img: 1}), 'Is empty 4');362 ok(node1.isEmpty({img: 1}), 'Is empty 5');363 root = new tinymce.html.Node('#frag', 11);364 node1 = root.append(new tinymce.html.Node('a', 1)).attr('name', 'x');365 ok(!root.isEmpty({img: 1}), 'Contains anchor with name attribute.');...
CaretBookmark.js
Source:CaretBookmark.js
1ModuleLoader.require([2 'tinymce/caret/CaretBookmark',3 'tinymce/caret/CaretPosition'4], function(CaretBookmark, CaretPosition) {5 var assertCaretPosition = Utils.assertCaretPosition;6 module('tinymce.caret.CaretBookmark');7 function getRoot() {8 return document.getElementById('view');9 }10 function setupHtml(html) {11 getRoot().innerHTML = html;12 }13 function createTextPos(textNode, offset) {14 return new CaretPosition(textNode, offset);15 }16 test('create element index', function() {17 setupHtml('<b></b><i></i><b></b>');18 equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().childNodes[0])), 'b[0],before');19 equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().childNodes[1])), 'i[0],before');20 equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().childNodes[2])), 'b[1],before');21 equal(CaretBookmark.create(getRoot(), CaretPosition.after(getRoot().childNodes[2])), 'b[1],after');22 });23 test('create text index', function() {24 setupHtml('a<b></b>b<b></b>ccc');25 equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[0], 0)), 'text()[0],0');26 equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[2], 1)), 'text()[1],1');27 equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[4], 3)), 'text()[2],3');28 });29 test('create text index on fragmented text nodes', function() {30 setupHtml('a');31 getRoot().appendChild(document.createTextNode('b'));32 getRoot().appendChild(document.createTextNode('c'));33 getRoot().appendChild(document.createElement('b'));34 getRoot().appendChild(document.createTextNode('d'));35 getRoot().appendChild(document.createTextNode('e'));36 equal(getRoot().childNodes.length, 6);37 equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[0], 0)), 'text()[0],0');38 equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[1], 0)), 'text()[0],1');39 equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[2], 0)), 'text()[0],2');40 equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[4], 0)), 'text()[1],0');41 equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[5], 0)), 'text()[1],1');42 });43 test('create br element index', function() {44 setupHtml('<p><br data-mce-bogus="1"></p><p><br></p>');45 equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().firstChild.firstChild)), 'p[0]/br[0],before');46 equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().lastChild.firstChild)), 'p[1]/br[0],before');47 });48 test('create deep element index', function() {49 setupHtml('<p><span>a</span><span><b id="a"></b><b id="b"></b><b id="c"></b></span></p>');50 equal(CaretBookmark.create(getRoot(), CaretPosition.before(document.getElementById('a'))), 'p[0]/span[1]/b[0],before');51 equal(CaretBookmark.create(getRoot(), CaretPosition.before(document.getElementById('b'))), 'p[0]/span[1]/b[1],before');52 equal(CaretBookmark.create(getRoot(), CaretPosition.before(document.getElementById('c'))), 'p[0]/span[1]/b[2],before');53 equal(CaretBookmark.create(getRoot(), CaretPosition.after(document.getElementById('c'))), 'p[0]/span[1]/b[2],after');54 });55 test('create deep text index', function() {56 setupHtml('<p><span>a</span><span id="x">a<b></b>b<b></b>ccc</span></p>');57 equal(CaretBookmark.create(getRoot(), createTextPos(document.getElementById('x').childNodes[0], 0)), 'p[0]/span[1]/text()[0],0');58 equal(CaretBookmark.create(getRoot(), createTextPos(document.getElementById('x').childNodes[2], 1)), 'p[0]/span[1]/text()[1],1');59 equal(CaretBookmark.create(getRoot(), createTextPos(document.getElementById('x').childNodes[4], 3)), 'p[0]/span[1]/text()[2],3');60 });61 test('create element index from bogus', function() {62 setupHtml('<b></b><span data-mce-bogus="1"><b></b><span data-mce-bogus="1"><b></b><b></b></span></span>');63 equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().lastChild.lastChild.childNodes[1])), 'b[3],before');64 });65 test('resolve element index', function() {66 setupHtml('<b></b><i></i><b></b>');67 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'b[0],before'), CaretPosition.before(getRoot().childNodes[0]));68 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'b[1],before'), CaretPosition.before(getRoot().childNodes[2]));69 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'b[1],after'), CaretPosition.after(getRoot().childNodes[2]));70 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'i[0],before'), CaretPosition.before(getRoot().childNodes[1]));71 });72 test('resolve odd element names', function() {73 setupHtml('<h-2X>abc</h-2X>');74 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'h-2X[0]/text()[0],2'), createTextPos(getRoot().childNodes[0].firstChild, 2));75 });76 test('resolve deep element index', function() {77 setupHtml('<p><span>a</span><span><b id="a"></b><b id="b"></b><b id="c"></b></span></p>');78 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[0],before'), CaretPosition.before(document.getElementById('a')));79 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[1],before'), CaretPosition.before(document.getElementById('b')));80 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[2],before'), CaretPosition.before(document.getElementById('c')));81 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[2],after'), CaretPosition.after(document.getElementById('c')));82 });83 test('resolve text index', function() {84 setupHtml('a<b></b>b<b></b>ccc');85 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],0'), createTextPos(getRoot().childNodes[0], 0));86 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],1'), createTextPos(getRoot().childNodes[2], 1));87 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[2],3'), createTextPos(getRoot().childNodes[4], 3));88 });89 test('resolve text index on fragmented text nodes', function() {90 setupHtml('a');91 getRoot().appendChild(document.createTextNode('b'));92 getRoot().appendChild(document.createTextNode('c'));93 getRoot().appendChild(document.createElement('b'));94 getRoot().appendChild(document.createTextNode('d'));95 getRoot().appendChild(document.createTextNode('e'));96 equal(getRoot().childNodes.length, 6);97 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],0'), createTextPos(getRoot().childNodes[0], 0));98 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],1'), createTextPos(getRoot().childNodes[0], 1));99 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],2'), createTextPos(getRoot().childNodes[1], 1));100 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],3'), createTextPos(getRoot().childNodes[2], 1));101 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],4'), createTextPos(getRoot().childNodes[2], 1));102 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],0'), createTextPos(getRoot().childNodes[4], 0));103 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],1'), createTextPos(getRoot().childNodes[4], 1));104 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],2'), createTextPos(getRoot().childNodes[5], 1));105 });106 test('resolve text index with to high offset', function() {107 setupHtml('abc');108 assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],10'), createTextPos(getRoot().childNodes[0], 3));109 });110 test('resolve invalid paths', function() {111 setupHtml('<b><i></i></b>');112 equal(CaretBookmark.resolve(getRoot(), 'x[0]/y[1]/z[2]'), null);113 equal(CaretBookmark.resolve(getRoot(), 'b[0]/i[2]'), null);114 equal(CaretBookmark.resolve(getRoot(), 'x'), null);115 equal(CaretBookmark.resolve(getRoot(), null), null);116 });...
rootattributeoperation.js
Source:rootattributeoperation.js
1/**2 * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.3 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license4 */5import Model from '../../../src/model/model';6import DocumentFragment from '../../../src/model/documentfragment';7import Element from '../../../src/model/element';8import RootAttributeOperation from '../../../src/model/operation/rootattributeoperation';9import { expectToThrowCKEditorError } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';10describe( 'RootAttributeOperation', () => {11 let model, doc, root;12 beforeEach( () => {13 model = new Model();14 doc = model.document;15 root = doc.createRoot();16 } );17 describe( 'type', () => {18 it( 'should be addRootAttribute for adding attribute', () => {19 const op = new RootAttributeOperation(20 root,21 'key',22 null,23 'newValue',24 doc.version25 );26 expect( op.type ).to.equal( 'addRootAttribute' );27 } );28 it( 'should be removeRootAttribute for removing attribute', () => {29 const op = new RootAttributeOperation(30 root,31 'key',32 'oldValue',33 null,34 doc.version35 );36 expect( op.type ).to.equal( 'removeRootAttribute' );37 } );38 it( 'should be changeRootAttribute for removing attribute', () => {39 const op = new RootAttributeOperation(40 root,41 'key',42 'oldValue',43 'newValue',44 doc.version45 );46 expect( op.type ).to.equal( 'changeRootAttribute' );47 } );48 } );49 it( 'should add attribute on the root element', () => {50 model.applyOperation(51 new RootAttributeOperation(52 root,53 'isNew',54 null,55 true,56 doc.version57 )58 );59 expect( doc.version ).to.equal( 1 );60 expect( root.hasAttribute( 'isNew' ) ).to.be.true;61 } );62 it( 'should change attribute on the root element', () => {63 root._setAttribute( 'isNew', false );64 model.applyOperation(65 new RootAttributeOperation(66 root,67 'isNew',68 false,69 true,70 doc.version71 )72 );73 expect( doc.version ).to.equal( 1 );74 expect( root.getAttribute( 'isNew' ) ).to.be.true;75 } );76 it( 'should remove attribute from the root element', () => {77 root._setAttribute( 'x', true );78 model.applyOperation(79 new RootAttributeOperation(80 root,81 'x',82 true,83 null,84 doc.version85 )86 );87 expect( doc.version ).to.equal( 1 );88 expect( root.hasAttribute( 'x' ) ).to.be.false;89 } );90 it( 'should create a RootAttributeOperation as a reverse', () => {91 const operation = new RootAttributeOperation( root, 'x', 'old', 'new', doc.version );92 const reverse = operation.getReversed();93 expect( reverse ).to.be.an.instanceof( RootAttributeOperation );94 expect( reverse.baseVersion ).to.equal( 1 );95 expect( reverse.root ).to.equal( root );96 expect( reverse.key ).to.equal( 'x' );97 expect( reverse.oldValue ).to.equal( 'new' );98 expect( reverse.newValue ).to.equal( 'old' );99 } );100 it( 'should undo adding attribute by applying reverse operation', () => {101 const operation = new RootAttributeOperation(102 root,103 'isNew',104 null,105 true,106 doc.version107 );108 const reverse = operation.getReversed();109 model.applyOperation( operation );110 model.applyOperation( reverse );111 expect( doc.version ).to.equal( 2 );112 expect( root.hasAttribute( 'x' ) ).to.be.false;113 } );114 it( 'should undo changing attribute by applying reverse operation', () => {115 root._setAttribute( 'isNew', false );116 const operation = new RootAttributeOperation(117 root,118 'isNew',119 false,120 true,121 doc.version122 );123 const reverse = operation.getReversed();124 model.applyOperation( operation );125 model.applyOperation( reverse );126 expect( doc.version ).to.equal( 2 );127 expect( root.getAttribute( 'isNew' ) ).to.be.false;128 } );129 it( 'should undo remove attribute by applying reverse operation', () => {130 root._setAttribute( 'foo', true );131 const operation = new RootAttributeOperation(132 root,133 'foo',134 true,135 null,136 doc.version137 );138 const reverse = operation.getReversed();139 model.applyOperation( operation );140 model.applyOperation( reverse );141 expect( doc.version ).to.equal( 2 );142 expect( root.getAttribute( 'foo' ) ).to.be.true;143 } );144 describe( '_validate()', () => {145 it( 'should throw an error when trying to change non-root element', () => {146 const child = new Element( 'p' );147 const parent = new Element( 'p' );148 parent._appendChild( child );149 expectToThrowCKEditorError( () => {150 const op = new RootAttributeOperation(151 child,152 'foo',153 null,154 'bar',155 null156 );157 op._validate();158 }, /rootattribute-operation-not-a-root/ );159 } );160 it( 'should throw an error when trying to change document fragment', () => {161 expectToThrowCKEditorError( () => {162 const op = new RootAttributeOperation(163 new DocumentFragment(),164 'foo',165 null,166 'bar',167 null168 );169 op._validate();170 }, /rootattribute-operation-not-a-root/ );171 } );172 it( 'should throw an error when trying to remove an attribute that does not exists', () => {173 expectToThrowCKEditorError( () => {174 const op = new RootAttributeOperation(175 root,176 'foo',177 true,178 null,179 doc.version180 );181 op._validate();182 }, /rootattribute-operation-wrong-old-value/, model );183 } );184 it( 'should throw an error when trying to add an attribute that already exists', () => {185 root._setAttribute( 'x', 1 );186 expectToThrowCKEditorError( () => {187 const op = new RootAttributeOperation(188 root,189 'x',190 null,191 2,192 doc.version193 );194 op._validate();195 }, /rootattribute-operation-attribute-exists/, model );196 } );197 } );198 it( 'should create a RootAttributeOperation with the same parameters when cloned', () => {199 const baseVersion = doc.version;200 const op = new RootAttributeOperation( root, 'foo', 'old', 'new', baseVersion );201 const clone = op.clone();202 // New instance rather than a pointer to the old instance.203 expect( clone ).not.to.equal( op );204 expect( clone ).to.be.instanceof( RootAttributeOperation );205 expect( clone.root ).to.equal( root );206 expect( clone.key ).to.equal( 'foo' );207 expect( clone.oldValue ).to.equal( 'old' );208 expect( clone.newValue ).to.equal( 'new' );209 expect( clone.baseVersion ).to.equal( baseVersion );210 } );211 describe( 'toJSON', () => {212 it( 'should create proper serialized object', () => {213 const op = new RootAttributeOperation(214 root,215 'key',216 null,217 'newValue',218 doc.version219 );220 const serialized = op.toJSON();221 expect( serialized.__className ).to.equal( 'RootAttributeOperation' );222 expect( serialized ).to.deep.equal( {223 __className: 'RootAttributeOperation',224 baseVersion: 0,225 key: 'key',226 newValue: 'newValue',227 oldValue: null,228 root: 'main'229 } );230 } );231 } );232 describe( 'fromJSON', () => {233 it( 'should create proper RootAttributeOperation from json object', () => {234 const op = new RootAttributeOperation( root, 'key', null, 'newValue', doc.version );235 const serialized = op.toJSON();236 const deserialized = RootAttributeOperation.fromJSON( serialized, doc );237 expect( deserialized ).to.deep.equal( op );238 } );239 it( 'should throw an error when root does not exists', () => {240 const op = new RootAttributeOperation(241 root,242 'key',243 null,244 'newValue',245 doc.version246 );247 const serialized = op.toJSON();248 serialized.root = 'no-root';249 expectToThrowCKEditorError( () => {250 RootAttributeOperation.fromJSON( serialized, doc );251 }, /rootattribute-operation-fromjson-no-root/ );252 } );253 } );...
api.js
Source:api.js
1// 以ä¸æ¯ä¸å¡æå¡å¨APIå°å2// æ¬æºå¼åæ¶ä½¿ç¨3 var WxApiRoot = 'http://localhost:8080/wx/';4// å±åç½æµè¯ä½¿ç¨5// var WxApiRoot = 'http://192.168.0.101:8080/wx/';6// äºå¹³å°é¨ç½²æ¶ä½¿ç¨7// var WxApiRoot = 'http://122.152.206.172:8080/wx/';8// äºå¹³å°ä¸çº¿æ¶ä½¿ç¨9// var WxApiRoot = 'https://www.menethil.com.cn/wx/';10module.exports = {11 IndexUrl: WxApiRoot + 'home/index', //é¦é¡µæ°æ®æ¥å£12 CatalogList: WxApiRoot + 'catalog/index', //åç±»ç®å½å
¨é¨åç±»æ°æ®æ¥å£13 CatalogCurrent: WxApiRoot + 'catalog/current', //åç±»ç®å½å½ååç±»æ°æ®æ¥å£14 AuthLoginByWeixin: WxApiRoot + 'auth/login_by_weixin', //微信ç»å½15 AuthLoginByAccount: WxApiRoot + 'auth/login', //è´¦å·ç»å½16 AuthRegister: WxApiRoot + 'auth/register', //è´¦å·æ³¨å17 AuthReset: WxApiRoot + 'auth/reset', //è´¦å·å¯ç éç½®18 AuthRegisterCaptcha: WxApiRoot + 'auth/regCaptcha', //éªè¯ç 19 AuthBindPhone: WxApiRoot + 'auth/bindPhone', //ç»å®å¾®ä¿¡ææºå·20 GoodsCount: WxApiRoot + 'goods/count', //ç»è®¡ååæ»æ°21 GoodsList: WxApiRoot + 'goods/list', //è·å¾ååå表22 GoodsCategory: WxApiRoot + 'goods/category', //è·å¾åç±»æ°æ®23 GoodsDetail: WxApiRoot + 'goods/detail', //è·å¾ååç详æ
24 GoodsNew: WxApiRoot + 'goods/new', //æ°å25 GoodsHot: WxApiRoot + 'goods/hot', //çé¨26 GoodsRelated: WxApiRoot + 'goods/related', //åå详æ
页çå
³èååï¼å¤§å®¶é½å¨çï¼27 BrandList: WxApiRoot + 'brand/list', //åçå表28 BrandDetail: WxApiRoot + 'brand/detail', //åç详æ
29 CartList: WxApiRoot + 'cart/index', //è·åè´ç©è½¦çæ°æ®30 CartAdd: WxApiRoot + 'cart/add', // æ·»å ååå°è´ç©è½¦31 CartFastAdd: WxApiRoot + 'cart/fastadd', // ç«å³è´ä¹°åå32 CartUpdate: WxApiRoot + 'cart/update', // æ´æ°è´ç©è½¦çåå33 CartDelete: WxApiRoot + 'cart/delete', // å é¤è´ç©è½¦çåå34 CartChecked: WxApiRoot + 'cart/checked', // éæ©æåæ¶éæ©åå35 CartGoodsCount: WxApiRoot + 'cart/goodscount', // è·åè´ç©è½¦åå件æ°36 CartCheckout: WxApiRoot + 'cart/checkout', // ä¸ååä¿¡æ¯ç¡®è®¤37 CollectList: WxApiRoot + 'collect/list', //æ¶èå表38 CollectAddOrDelete: WxApiRoot + 'collect/addordelete', //æ·»å æåæ¶æ¶è39 CommentList: WxApiRoot + 'comment/list', //è¯è®ºå表40 CommentCount: WxApiRoot + 'comment/count', //è¯è®ºæ»æ°41 CommentPost: WxApiRoot + 'comment/post', //å表è¯è®º42 TopicList: WxApiRoot + 'topic/list', //ä¸é¢å表43 TopicDetail: WxApiRoot + 'topic/detail', //ä¸é¢è¯¦æ
44 TopicRelated: WxApiRoot + 'topic/related', //ç¸å
³ä¸é¢45 SearchIndex: WxApiRoot + 'search/index', //æç´¢å
³é®å46 SearchResult: WxApiRoot + 'search/result', //æç´¢ç»æ47 SearchHelper: WxApiRoot + 'search/helper', //æ索帮å©48 SearchClearHistory: WxApiRoot + 'search/clearhistory', //æç´¢åå²æ¸
æ¥49 AddressList: WxApiRoot + 'address/list', //æ¶è´§å°åå表50 AddressDetail: WxApiRoot + 'address/detail', //æ¶è´§å°å详æ
51 AddressSave: WxApiRoot + 'address/save', //ä¿åæ¶è´§å°å52 AddressDelete: WxApiRoot + 'address/delete', //ä¿åæ¶è´§å°å53 ExpressQuery: WxApiRoot + 'express/query', //ç©æµæ¥è¯¢54 RegionList: WxApiRoot + 'region/list', //è·ååºåå表55 OrderSubmit: WxApiRoot + 'order/submit', // æ交订å56 OrderPrepay: WxApiRoot + 'order/prepay', // 订åçé¢æ¯ä»ä¼è¯57 OrderList: WxApiRoot + 'order/list', //订åå表58 OrderDetail: WxApiRoot + 'order/detail', //订å详æ
59 OrderCancel: WxApiRoot + 'order/cancel', //åæ¶è®¢å60 OrderRefund: WxApiRoot + 'order/refund', //é款åæ¶è®¢å61 OrderDelete: WxApiRoot + 'order/delete', //å é¤è®¢å62 OrderConfirm: WxApiRoot + 'order/confirm', //确认æ¶è´§63 OrderComment: WxApiRoot + 'order/comment', // 代è¯ä»·ååä¿¡æ¯64 FootprintList: WxApiRoot + 'footprint/list', //足迹å表65 FootprintDelete: WxApiRoot + 'footprint/delete', //å é¤è¶³è¿¹66 UserFormIdCreate: WxApiRoot + 'formid/create', //ç¨æ·FromIdï¼ç¨äºåé模çæ¶æ¯67 GroupOn: WxApiRoot + 'groupon/query', //å¢è´API-æ¥è¯¢68 GroupOnMy: WxApiRoot + 'groupon/my', //å¢è´API-æçå¢è´69 GroupOnDetail: WxApiRoot + 'groupon/detail', //å¢è´API-详æ
70 GroupOnJoin: WxApiRoot + 'groupon/join', //å¢è´API-详æ
71 StorageUpload: WxApiRoot + 'storage/upload' //å¾çä¸ä¼ ...
binaryTree.js
Source:binaryTree.js
1'use strict';2class Node {3 constructor(value) {4 this.value = value;5 this.left = null;6 this.right = null;7 }8}9class BinaryTree {10 constructor() {11 this.root = null;12 }13 preOrder() {14 let resultArr = [];15 let _preOrder = (root) => {16 if (root !== null) {17 resultArr.push(root.value);18 if (root.left !== null) {19 _preOrder(root.left);20 }21 if (root.right !== null) {22 _preOrder(root.right);23 }24 }25 };26 _preOrder(this.root);27 return resultArr;28 }29 inOrder() {30 let resultArr = [];31 let _inOrder = (root) => {32 if (root !== null) {33 if (root.left !== null) {34 _inOrder(root.left);35 }36 resultArr.push(root.value);37 if (root.right !== null) {38 _inOrder(root.right);39 }40 }41 };42 _inOrder(this.root);43 return resultArr;44 }45 postOrder() {46 let resultArr = [];47 let _postOrder = (root) => {48 if (root !== null) {49 if (root.left !== null) {50 _postOrder(root.left);51 }52 if (root.right !== null) {53 _postOrder(root.right);54 }55 resultArr.push(root.value);56 }57 };58 _postOrder(this.root);59 return resultArr;60 }61 addBinarySearch(value) {62 let _add = (inputValue, root) => {63 if (root === null) {64 root = new Node(inputValue);65 }66 else if (root.value === inputValue) {67 throw `Binary Search Tree already contains ${inputValue}. Nothing was added to the tree`;68 }69 else if (inputValue < root.value) {70 root.left = _add(inputValue, root.left);71 }72 else if (inputValue > root.value) {73 root.right = _add(inputValue, root.right);74 }75 return root;76 };77 try {78 this.root = _add(value, this.root);79 } catch (error) {80 console.log(error);81 }82 }83 findMax() {84 if (this.root === null) {85 throw 'Error: Binary Tree is empty';86 }87 else {88 let max = null;89 let _preOrderMax = (root, maxValue) => {90 if (root !== null) {91 if (root.value > maxValue) {92 maxValue = root.value;93 }94 if (root.left !== null) {95 maxValue = _preOrderMax(root.left, maxValue);96 }97 if (root.right !== null) {98 maxValue = _preOrderMax(root.right, maxValue);99 }100 }101 return maxValue;102 };103 max = this.root.value;104 return _preOrderMax(this.root, max);105 }106 }107}...
rootelement.js
Source:rootelement.js
1/**2 * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.3 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license4 */5import Model from '../../src/model/model';6import Element from '../../src/model/element';7import RootElement from '../../src/model/rootelement';8import count from '@ckeditor/ckeditor5-utils/src/count';9describe( 'RootElement', () => {10 describe( 'constructor()', () => {11 it( 'should create root element without attributes', () => {12 const model = new Model();13 const doc = model.document;14 const root = new RootElement( doc );15 expect( root ).to.be.an.instanceof( Element );16 expect( root ).to.have.property( 'document' ).that.equals( doc );17 expect( count( root.getAttributes() ) ).to.equal( 0 );18 expect( root.childCount ).to.equal( 0 );19 } );20 } );21 describe( 'is()', () => {22 let root;23 before( () => {24 const model = new Model();25 const doc = model.document;26 root = new RootElement( doc, '$root' );27 } );28 it( 'should return true for rootElement, element, element with same name and element name', () => {29 expect( root.is( 'element', '$root' ) ).to.be.true;30 expect( root.is( 'model:element', '$root' ) ).to.be.true;31 expect( root.is( 'element' ) ).to.be.true;32 expect( root.is( 'model:element' ) ).to.be.true;33 expect( root.is( 'rootElement', '$root' ) ).to.be.true;34 expect( root.is( 'model:rootElement', '$root' ) ).to.be.true;35 expect( root.is( 'rootElement' ) ).to.be.true;36 expect( root.is( 'model:rootElement' ) ).to.be.true;37 expect( root.is( 'node' ) ).to.be.true;38 expect( root.is( 'model:node' ) ).to.be.true;39 } );40 it( 'should return false for other accept values', () => {41 expect( root.is( 'element', '$graveyard' ) ).to.be.false;42 expect( root.is( 'model:element', '$graveyard' ) ).to.be.false;43 expect( root.is( 'rootElement', '$graveyard' ) ).to.be.false;44 expect( root.is( 'model:rootElement', '$graveyard' ) ).to.be.false;45 expect( root.is( '$graveyard' ) ).to.be.false;46 expect( root.is( '$text' ) ).to.be.false;47 expect( root.is( '$textProxy' ) ).to.be.false;48 expect( root.is( 'documentFragment' ) ).to.be.false;49 expect( root.is( 'view:element' ) ).to.be.false;50 expect( root.is( '$root' ) ).to.be.false;51 expect( root.is( 'model:$root' ) ).to.be.false;52 expect( root.is( 'node', '$root' ) ).to.be.false;53 expect( root.is( 'model:node', '$root' ) ).to.be.false;54 } );55 } );...
Using AI Code Generation
1describe('My first test suite', function() {2 it('My first test case', function() {3 cy.get('.search-keyword').type('ca')4 cy.wait(2000)5 cy.get('.products').as('productLocator')6 cy.get('@productLocator').find('.product').should('have.length',5)7 cy.get('@productLocator').find('.product').eq(2).contains('ADD TO CART').click().then(function()8 {9 console.log('sf')10 })11 cy.get('@productLocator').find('.product').each(($el, index, $list) => {12 const textVeg=$el.find('h4.product-name').text()13 if(textVeg.includes('Cashews'))14 {15 $el.find('button').click()16 }17 })18 cy.get('.brand').should('have.text','GREENKART')19 cy.get('.brand').then(function(logoelement){20 cy.log(logoelement.text())21 })22 cy.get('.brand').then(function(logoelement){23 cy.log(logoelement.text())24 })25 cy.get('.brand').then(function(logoelement){26 cy.log(logoelement.text())27 })28 cy.get('.brand').then(function(logoelement){29 cy.log(logoelement.text())30 })31 cy.get('.brand').then(function(logoelement){32 cy.log(logoelement.text())33 })34 cy.get('.brand').then(function(logoelement){35 cy.log(logoelement.text())36 })37 cy.get('.brand').then(function(logoelement){38 cy.log(logoelement.text())39 })40 cy.get('.brand').then(function(logoelement){41 cy.log(logoelement.text())42 })43 cy.get('.brand').then(function(logoelement){44 cy.log(logoelement.text())45 })46 cy.get('.brand').then(function(logoelement){47 cy.log(logoelement.text())48 })49 })50})
Using AI Code Generation
1describe('My First Test', function() {2 it('Does not do much!', function() {3 cy.contains('type').click()4 cy.url().should('include', '/commands/actions')5 cy.get('.action-email')6 .type('
Using AI Code Generation
1describe('My First Test', () => {2 it('Does not do much!', () => {3 expect(true).to.equal(true)4 })5})6describe('My First Test', () => {7 it('Does not do much!', () => {8 cy.contains('type').click()9 cy.url().should('include', '/commands/actions')10 })11})12describe('My First Test', () => {13 it('Does not do much!', () => {14 cy.contains('type').click()15 cy.url().should('include', '/commands/actions')16 })17})18describe('My First Test', () => {19 it('Does not do much!', () => {20 cy.contains('type').click()21 cy.url().should('include', '/commands/actions')22 })23})24describe('My First Test', () => {25 it('Does not do much!', () => {26 cy.contains('type').click()27 cy.url().should('include', '/commands/actions')28 })29})30describe('My First Test', () => {31 it('Does not do much!', () => {32 cy.contains('type').click()33 cy.url().should('include', '/commands/actions')34 })35})36describe('My First Test', () => {37 it('Does not do much!', () => {38 cy.contains('type').click()39 cy.url().should('include', '/commands/actions')40 })41})42describe('My First Test', () => {43 it('Does not do much!', () => {44 cy.contains('type').click()45 cy.url().should('include', '/commands/actions')46 })47})48describe('My First Test', () => {49 it('Does not do much!', ()
Using AI Code Generation
1describe("My First Test", () => {2 it("Visits the Kitchen Sink", () => {3 });4});5describe("My First Test", () => {6 it("Visits the Kitchen Sink", () => {7 cy.contains("type");8 });9});10describe("My First Test", () => {11 it("Visits the Kitchen Sink", () => {12 cy.contains("type").click();13 });14});15describe("My First Test", () => {16 it("Visits the Kitchen Sink", () => {17 cy.contains("type").click();18 cy.url().should("include", "/commands/actions");19 });20});21describe("My First Test", () => {22 it("Visits the Kitchen Sink", () => {23 cy.contains("type").click();24 cy.url().should("include", "/commands/actions");25 cy.get(".action-email")26 .type("
Using AI Code Generation
1describe('My First Test', () => {2 it('Visits the Kitchen Sink', () => {3 })4})5describe('My First Test', () => {6 it('Visits the Kitchen Sink', () => {7 })8})9describe('My First Test', () => {10 it('Visits the Kitchen Sink', () => {11 })12})13describe('My First Test', () => {14 it('Visits the Kitchen Sink', () => {15 })16})17describe('My First Test', () => {18 it('Visits the Kitchen Sink', () => {19 })20})21describe('My First Test', () => {22 it('Visits the Kitchen Sink', () => {23 })24})25describe('My First Test', () => {26 it('Visits the Kitchen Sink', () => {27 })28})29describe('My First Test', () => {30 it('Visits the Kitchen Sink', () => {31 })32})33describe('My First Test', () => {34 it('Visits the Kitchen Sink', () => {35 })36})
Using AI Code Generation
1describe('My First Test Suite', function() 2{3 it('My FirstTest case', function() {4 cy.get('.search-keyword').type('ca')5 cy.wait(2000)6 cy.get('.products').as('productLocator')7 cy.get('@productLocator').find('.product').should('have.length',5)8 cy.get(':nth-child(3) > .product-action > button').click()9 cy.get('@productLocator').find('.product').should('have.length',4)10 cy.get('@productLocator').contains('ADD TO CART').click().should('have.length',4)11 cy.get('@productLocator').find('.product').eq(2).contains('ADD TO CART').click()12 cy.get('.brand').should('have.text','GREENKART')13 cy.get('.brand').then(function(logoelement){14 cy.log(logoelement.text())15 })16 cy.get('.brand').then(function(logoelement){17 cy.log(logoelement.text())18 })19 cy.get('.brand').then(function(logoelement){20 cy.log(logoelement.text())21 })22 cy.get('.brand').then(function(logoelement){23 cy.log(logoelement.text())24 })25 cy.get('.brand').then(function(logoelement){
Using AI Code Generation
1it('should navigate to the homepage', () => {2 cy.visit('/')3})4it('should navigate to the homepage', () => {5 cy.visit('/')6 cy.contains('h1', 'Welcome to our store')7})8it('should navigate to the homepage', () => {9 cy.visit('/')10 cy.contains('h1', 'Welcome to our store')11 cy.get('nav a').should('have.length', 3)12})13it('should navigate to the homepage', () => {14 cy.visit('/')15 cy.contains('h1', 'Welcome to our store')16 cy.get('nav a').should('have.length', 3)17 cy.get('nav a').eq(1).click()18 cy.contains('h2', 'Products')19})20it('should navigate to the homepage', () => {21 cy.visit('/')22 cy.contains('h1', 'Welcome to our store')23 cy.get('nav a').should('have.length', 3)24 cy.get('nav a').eq(1).click()25 cy.contains('h2', 'Products')26 cy.get('nav a').eq(2).click()27 cy.contains('h2', 'Cart')28})29it('should navigate to the homepage', () => {30 cy.visit('/')31 cy.contains('h1', 'Welcome to our store')32 cy.get('nav a').should('have.length', 3)33 cy.get('nav a').eq(1).click()34 cy.contains('h2', 'Products')35 cy.get('nav a').eq(2).click()36 cy.contains('h2', 'Cart')37 cy.get('nav a').eq(0).click()38 cy.contains('h1', 'Welcome to our store')39})40it('should navigate to the homepage', () => {41 cy.visit('/')42 cy.contains('h1', 'Welcome to our store')43 cy.get('nav a').should('have.length', 3)44 cy.get('nav a').eq(1).click()45 cy.contains('h2', 'Products')46 cy.get('nav a').eq(2).click()47 cy.contains('h2', 'Cart')
Using AI Code Generation
1describe('Root', () => {2 it('works', () => {3 cy.visit('/')4 })5})6describe('Homepage', () => {7 it('has a title', () => {8 cy.visit('/')9 cy.get('h1').contains('Home')10 })11})12describe('About page', () => {13 it('has a title', () => {14 cy.visit('/about')15 cy.get('h1').contains('About')16 })17})18describe('Contact page', () => {19 it('has a title', () => {20 cy.visit('/contact')21 cy.get('h1').contains('Contact')22 })23})24describe('Contact page', () => {25 it('has a title', () => {26 cy.visit('/contact')27 cy.get('h1').contains('Contact')28 })29})30 and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.
You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.
Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.
Get 100 minutes of automation test minutes FREE!!