Best JavaScript code snippet using playwright-internal
ReactHooksWithNoopRenderer-test.internal.js
Source:ReactHooksWithNoopRenderer-test.internal.js
1/**2 * Copyright (c) 2013-present, Facebook, Inc.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 * @emails react-core8 * @jest-environment node9 */10/* eslint-disable no-func-assign */11'use strict';12let React;13let ReactFeatureFlags;14let ReactNoop;15let SchedulerTracing;16let useState;17let useReducer;18let useEffect;19let useLayoutEffect;20let useCallback;21let useMemo;22let useRef;23let useImperativeMethods;24let forwardRef;25let flushPassiveEffects;26let memo;27// These tests use React Noop Renderer. All new tests should use React Test28// Renderer and go in ReactHooks-test; plan is gradually migrate the noop tests29// to that file.30describe('ReactHooksWithNoopRenderer', () => {31 beforeEach(() => {32 jest.resetModules();33 jest.mock('scheduler', () => {34 let scheduledCallbacks = new Map();35 flushPassiveEffects = () => {36 scheduledCallbacks.forEach(cb => {37 cb();38 });39 scheduledCallbacks = new Map();40 };41 return {42 unstable_scheduleCallback(callback) {43 const handle = {};44 scheduledCallbacks.set(handle, callback);45 return handle;46 },47 unstable_cancelCallback(handle) {48 scheduledCallbacks.delete(handle);49 },50 };51 });52 ReactFeatureFlags = require('shared/ReactFeatureFlags');53 ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;54 ReactFeatureFlags.enableHooks = true;55 ReactFeatureFlags.enableSchedulerTracing = true;56 React = require('react');57 ReactNoop = require('react-noop-renderer');58 SchedulerTracing = require('scheduler/tracing');59 useState = React.useState;60 useReducer = React.useReducer;61 useEffect = React.useEffect;62 useLayoutEffect = React.useLayoutEffect;63 useCallback = React.useCallback;64 useMemo = React.useMemo;65 useRef = React.useRef;66 useImperativeMethods = React.useImperativeMethods;67 forwardRef = React.forwardRef;68 memo = React.memo;69 });70 function span(prop) {71 return {type: 'span', hidden: false, children: [], prop};72 }73 function Text(props) {74 ReactNoop.yield(props.text);75 return <span prop={props.text} />;76 }77 it('resumes after an interruption', () => {78 function Counter(props, ref) {79 const [count, updateCount] = useState(0);80 useImperativeMethods(ref, () => ({updateCount}));81 return <Text text={props.label + ': ' + count} />;82 }83 Counter = forwardRef(Counter);84 // Initial mount85 const counter = React.createRef(null);86 ReactNoop.render(<Counter label="Count" ref={counter} />);87 expect(ReactNoop.flush()).toEqual(['Count: 0']);88 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);89 // Schedule some updates90 counter.current.updateCount(1);91 counter.current.updateCount(count => count + 10);92 // Partially flush without committing93 ReactNoop.flushThrough(['Count: 11']);94 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);95 // Interrupt with a high priority update96 ReactNoop.flushSync(() => {97 ReactNoop.render(<Counter label="Total" />);98 });99 expect(ReactNoop.clearYields()).toEqual(['Total: 0']);100 // Resume rendering101 ReactNoop.flush();102 expect(ReactNoop.getChildren()).toEqual([span('Total: 11')]);103 });104 it('throws inside class components', () => {105 class BadCounter extends React.Component {106 render() {107 const [count] = useState(0);108 return <Text text={this.props.label + ': ' + count} />;109 }110 }111 ReactNoop.render(<BadCounter />);112 expect(() => ReactNoop.flush()).toThrow(113 'Hooks can only be called inside the body of a function component.',114 );115 // Confirm that a subsequent hook works properly.116 function GoodCounter(props, ref) {117 const [count] = useState(props.initialCount);118 return <Text text={count} />;119 }120 ReactNoop.render(<GoodCounter initialCount={10} />);121 expect(ReactNoop.flush()).toEqual([10]);122 });123 it('throws inside module-style components', () => {124 function Counter() {125 return {126 render() {127 const [count] = useState(0);128 return <Text text={this.props.label + ': ' + count} />;129 },130 };131 }132 ReactNoop.render(<Counter />);133 expect(() => ReactNoop.flush()).toThrow(134 'Hooks can only be called inside the body of a function component.',135 );136 // Confirm that a subsequent hook works properly.137 function GoodCounter(props) {138 const [count] = useState(props.initialCount);139 return <Text text={count} />;140 }141 ReactNoop.render(<GoodCounter initialCount={10} />);142 expect(ReactNoop.flush()).toEqual([10]);143 });144 it('throws when called outside the render phase', () => {145 expect(() => useState(0)).toThrow(146 'Hooks can only be called inside the body of a function component.',147 );148 });149 describe('useState', () => {150 it('simple mount and update', () => {151 function Counter(props, ref) {152 const [count, updateCount] = useState(0);153 useImperativeMethods(ref, () => ({updateCount}));154 return <Text text={'Count: ' + count} />;155 }156 Counter = forwardRef(Counter);157 const counter = React.createRef(null);158 ReactNoop.render(<Counter ref={counter} />);159 ReactNoop.flush();160 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);161 counter.current.updateCount(1);162 ReactNoop.flush();163 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);164 counter.current.updateCount(count => count + 10);165 ReactNoop.flush();166 expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]);167 });168 it('lazy state initializer', () => {169 function Counter(props, ref) {170 const [count, updateCount] = useState(() => {171 ReactNoop.yield('getInitialState');172 return props.initialState;173 });174 useImperativeMethods(ref, () => ({updateCount}));175 return <Text text={'Count: ' + count} />;176 }177 Counter = forwardRef(Counter);178 const counter = React.createRef(null);179 ReactNoop.render(<Counter initialState={42} ref={counter} />);180 expect(ReactNoop.flush()).toEqual(['getInitialState', 'Count: 42']);181 expect(ReactNoop.getChildren()).toEqual([span('Count: 42')]);182 counter.current.updateCount(7);183 expect(ReactNoop.flush()).toEqual(['Count: 7']);184 expect(ReactNoop.getChildren()).toEqual([span('Count: 7')]);185 });186 it('multiple states', () => {187 function Counter(props, ref) {188 const [count, updateCount] = useState(0);189 const [label, updateLabel] = useState('Count');190 useImperativeMethods(ref, () => ({updateCount, updateLabel}));191 return <Text text={label + ': ' + count} />;192 }193 Counter = forwardRef(Counter);194 const counter = React.createRef(null);195 ReactNoop.render(<Counter ref={counter} />);196 ReactNoop.flush();197 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);198 counter.current.updateCount(7);199 expect(ReactNoop.flush()).toEqual(['Count: 7']);200 counter.current.updateLabel('Total');201 expect(ReactNoop.flush()).toEqual(['Total: 7']);202 });203 it('returns the same updater function every time', () => {204 let updaters = [];205 function Counter() {206 const [count, updateCount] = useState(0);207 updaters.push(updateCount);208 return <Text text={'Count: ' + count} />;209 }210 ReactNoop.render(<Counter />);211 ReactNoop.flush();212 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);213 updaters[0](1);214 ReactNoop.flush();215 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);216 updaters[0](count => count + 10);217 ReactNoop.flush();218 expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]);219 expect(updaters).toEqual([updaters[0], updaters[0], updaters[0]]);220 });221 it('warns on set after unmount', () => {222 let _updateCount;223 function Counter(props, ref) {224 const [, updateCount] = useState(0);225 _updateCount = updateCount;226 return null;227 }228 ReactNoop.render(<Counter />);229 ReactNoop.flush();230 ReactNoop.render(null);231 ReactNoop.flush();232 expect(() => _updateCount(1)).toWarnDev(233 "Warning: Can't perform a React state update on an unmounted " +234 'component. This is a no-op, but it indicates a memory leak in your ' +235 'application. To fix, cancel all subscriptions and asynchronous ' +236 'tasks in a useEffect cleanup function.\n' +237 ' in Counter (at **)',238 );239 });240 it('works with memo', () => {241 let _updateCount;242 function Counter(props) {243 const [count, updateCount] = useState(0);244 _updateCount = updateCount;245 return <Text text={'Count: ' + count} />;246 }247 Counter = memo(Counter);248 ReactNoop.render(<Counter />);249 expect(ReactNoop.flush()).toEqual(['Count: 0']);250 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);251 ReactNoop.render(<Counter />);252 expect(ReactNoop.flush()).toEqual([]);253 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);254 _updateCount(1);255 expect(ReactNoop.flush()).toEqual(['Count: 1']);256 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);257 });258 });259 describe('updates during the render phase', () => {260 it('restarts the render function and applies the new updates on top', () => {261 function ScrollView({row: newRow}) {262 let [isScrollingDown, setIsScrollingDown] = useState(false);263 let [row, setRow] = useState(null);264 if (row !== newRow) {265 // Row changed since last render. Update isScrollingDown.266 setIsScrollingDown(row !== null && newRow > row);267 setRow(newRow);268 }269 return <Text text={`Scrolling down: ${isScrollingDown}`} />;270 }271 ReactNoop.render(<ScrollView row={1} />);272 ReactNoop.flush();273 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]);274 ReactNoop.render(<ScrollView row={5} />);275 ReactNoop.flush();276 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]);277 ReactNoop.render(<ScrollView row={5} />);278 ReactNoop.flush();279 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]);280 ReactNoop.render(<ScrollView row={10} />);281 ReactNoop.flush();282 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]);283 ReactNoop.render(<ScrollView row={2} />);284 ReactNoop.flush();285 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]);286 ReactNoop.render(<ScrollView row={2} />);287 ReactNoop.flush();288 expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]);289 });290 it('keeps restarting until there are no more new updates', () => {291 function Counter({row: newRow}) {292 let [count, setCount] = useState(0);293 if (count < 3) {294 setCount(count + 1);295 }296 ReactNoop.yield('Render: ' + count);297 return <Text text={count} />;298 }299 ReactNoop.render(<Counter />);300 expect(ReactNoop.flush()).toEqual([301 'Render: 0',302 'Render: 1',303 'Render: 2',304 'Render: 3',305 3,306 ]);307 expect(ReactNoop.getChildren()).toEqual([span(3)]);308 });309 it('updates multiple times within same render function', () => {310 function Counter({row: newRow}) {311 let [count, setCount] = useState(0);312 if (count < 12) {313 setCount(c => c + 1);314 setCount(c => c + 1);315 setCount(c => c + 1);316 }317 ReactNoop.yield('Render: ' + count);318 return <Text text={count} />;319 }320 ReactNoop.render(<Counter />);321 expect(ReactNoop.flush()).toEqual([322 // Should increase by three each time323 'Render: 0',324 'Render: 3',325 'Render: 6',326 'Render: 9',327 'Render: 12',328 12,329 ]);330 expect(ReactNoop.getChildren()).toEqual([span(12)]);331 });332 it('throws after too many iterations', () => {333 function Counter({row: newRow}) {334 let [count, setCount] = useState(0);335 setCount(count + 1);336 ReactNoop.yield('Render: ' + count);337 return <Text text={count} />;338 }339 ReactNoop.render(<Counter />);340 expect(() => ReactNoop.flush()).toThrow(341 'Too many re-renders. React limits the number of renders to prevent ' +342 'an infinite loop.',343 );344 });345 it('works with useReducer', () => {346 function reducer(state, action) {347 return action === 'increment' ? state + 1 : state;348 }349 function Counter({row: newRow}) {350 let [count, dispatch] = useReducer(reducer, 0);351 if (count < 3) {352 dispatch('increment');353 }354 ReactNoop.yield('Render: ' + count);355 return <Text text={count} />;356 }357 ReactNoop.render(<Counter />);358 expect(ReactNoop.flush()).toEqual([359 'Render: 0',360 'Render: 1',361 'Render: 2',362 'Render: 3',363 3,364 ]);365 expect(ReactNoop.getChildren()).toEqual([span(3)]);366 });367 it('uses reducer passed at time of render, not time of dispatch', () => {368 // This test is a bit contrived but it demonstrates a subtle edge case.369 // Reducer A increments by 1. Reducer B increments by 10.370 function reducerA(state, action) {371 switch (action) {372 case 'increment':373 return state + 1;374 case 'reset':375 return 0;376 }377 }378 function reducerB(state, action) {379 switch (action) {380 case 'increment':381 return state + 10;382 case 'reset':383 return 0;384 }385 }386 function Counter({row: newRow}, ref) {387 let [reducer, setReducer] = useState(() => reducerA);388 let [count, dispatch] = useReducer(reducer, 0);389 useImperativeMethods(ref, () => ({dispatch}));390 if (count < 20) {391 dispatch('increment');392 // Swap reducers each time we increment393 if (reducer === reducerA) {394 setReducer(() => reducerB);395 } else {396 setReducer(() => reducerA);397 }398 }399 ReactNoop.yield('Render: ' + count);400 return <Text text={count} />;401 }402 Counter = forwardRef(Counter);403 const counter = React.createRef(null);404 ReactNoop.render(<Counter ref={counter} />);405 expect(ReactNoop.flush()).toEqual([406 // The count should increase by alternating amounts of 10 and 1407 // until we reach 21.408 'Render: 0',409 'Render: 10',410 'Render: 11',411 'Render: 21',412 21,413 ]);414 expect(ReactNoop.getChildren()).toEqual([span(21)]);415 // Test that it works on update, too. This time the log is a bit different416 // because we started with reducerB instead of reducerA.417 counter.current.dispatch('reset');418 ReactNoop.render(<Counter ref={counter} />);419 expect(ReactNoop.flush()).toEqual([420 'Render: 0',421 'Render: 1',422 'Render: 11',423 'Render: 12',424 'Render: 22',425 22,426 ]);427 expect(ReactNoop.getChildren()).toEqual([span(22)]);428 });429 });430 describe('useReducer', () => {431 it('simple mount and update', () => {432 const INCREMENT = 'INCREMENT';433 const DECREMENT = 'DECREMENT';434 function reducer(state, action) {435 switch (action) {436 case 'INCREMENT':437 return state + 1;438 case 'DECREMENT':439 return state - 1;440 default:441 return state;442 }443 }444 function Counter(props, ref) {445 const [count, dispatch] = useReducer(reducer, 0);446 useImperativeMethods(ref, () => ({dispatch}));447 return <Text text={'Count: ' + count} />;448 }449 Counter = forwardRef(Counter);450 const counter = React.createRef(null);451 ReactNoop.render(<Counter ref={counter} />);452 ReactNoop.flush();453 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);454 counter.current.dispatch(INCREMENT);455 ReactNoop.flush();456 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);457 counter.current.dispatch(DECREMENT);458 counter.current.dispatch(DECREMENT);459 counter.current.dispatch(DECREMENT);460 ReactNoop.flush();461 expect(ReactNoop.getChildren()).toEqual([span('Count: -2')]);462 });463 it('accepts an initial action', () => {464 const INCREMENT = 'INCREMENT';465 const DECREMENT = 'DECREMENT';466 function reducer(state, action) {467 switch (action) {468 case 'INITIALIZE':469 return 10;470 case 'INCREMENT':471 return state + 1;472 case 'DECREMENT':473 return state - 1;474 default:475 return state;476 }477 }478 const initialAction = 'INITIALIZE';479 function Counter(props, ref) {480 const [count, dispatch] = useReducer(reducer, 0, initialAction);481 useImperativeMethods(ref, () => ({dispatch}));482 return <Text text={'Count: ' + count} />;483 }484 Counter = forwardRef(Counter);485 const counter = React.createRef(null);486 ReactNoop.render(<Counter ref={counter} />);487 ReactNoop.flush();488 expect(ReactNoop.getChildren()).toEqual([span('Count: 10')]);489 counter.current.dispatch(INCREMENT);490 ReactNoop.flush();491 expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]);492 counter.current.dispatch(DECREMENT);493 counter.current.dispatch(DECREMENT);494 counter.current.dispatch(DECREMENT);495 ReactNoop.flush();496 expect(ReactNoop.getChildren()).toEqual([span('Count: 8')]);497 });498 // Regression test for https://github.com/facebook/react/issues/14360499 it('handles dispatches with mixed priorities', () => {500 const INCREMENT = 'INCREMENT';501 function reducer(state, action) {502 return action === INCREMENT ? state + 1 : state;503 }504 function Counter(props, ref) {505 const [count, dispatch] = useReducer(reducer, 0);506 useImperativeMethods(ref, () => ({dispatch}));507 return <Text text={'Count: ' + count} />;508 }509 Counter = forwardRef(Counter);510 const counter = React.createRef(null);511 ReactNoop.render(<Counter ref={counter} />);512 ReactNoop.flush();513 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);514 counter.current.dispatch(INCREMENT);515 counter.current.dispatch(INCREMENT);516 counter.current.dispatch(INCREMENT);517 ReactNoop.flushSync(() => {518 counter.current.dispatch(INCREMENT);519 });520 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);521 ReactNoop.flush();522 expect(ReactNoop.getChildren()).toEqual([span('Count: 4')]);523 });524 });525 describe('useEffect', () => {526 it('simple mount and update', () => {527 function Counter(props) {528 useEffect(() => {529 ReactNoop.yield(`Did commit [${props.count}]`);530 });531 return <Text text={'Count: ' + props.count} />;532 }533 ReactNoop.render(<Counter count={0} />);534 expect(ReactNoop.flush()).toEqual(['Count: 0']);535 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);536 flushPassiveEffects();537 expect(ReactNoop.clearYields()).toEqual(['Did commit [0]']);538 ReactNoop.render(<Counter count={1} />);539 expect(ReactNoop.flush()).toEqual(['Count: 1']);540 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);541 // Effects are deferred until after the commit542 flushPassiveEffects();543 expect(ReactNoop.clearYields()).toEqual(['Did commit [1]']);544 });545 it('flushes passive effects even with sibling deletions', () => {546 function LayoutEffect(props) {547 useLayoutEffect(() => {548 ReactNoop.yield(`Layout effect`);549 });550 return <Text text="Layout" />;551 }552 function PassiveEffect(props) {553 useEffect(() => {554 ReactNoop.yield(`Passive effect`);555 }, []);556 return <Text text="Passive" />;557 }558 let passive = <PassiveEffect key="p" />;559 ReactNoop.render([<LayoutEffect key="l" />, passive]);560 expect(ReactNoop.flush()).toEqual(['Layout', 'Passive', 'Layout effect']);561 expect(ReactNoop.getChildren()).toEqual([562 span('Layout'),563 span('Passive'),564 ]);565 // Destroying the first child shouldn't prevent the passive effect from566 // being executed567 ReactNoop.render([passive]);568 expect(ReactNoop.flush()).toEqual(['Passive effect']);569 expect(ReactNoop.getChildren()).toEqual([span('Passive')]);570 // (No effects are left to flush.)571 flushPassiveEffects();572 expect(ReactNoop.clearYields()).toEqual(null);573 });574 it('flushes passive effects even if siblings schedule an update', () => {575 function PassiveEffect(props) {576 useEffect(() => {577 ReactNoop.yield('Passive effect');578 });579 return <Text text="Passive" />;580 }581 function LayoutEffect(props) {582 let [count, setCount] = useState(0);583 useLayoutEffect(() => {584 // Scheduling work shouldn't interfere with the queued passive effect585 if (count === 0) {586 setCount(1);587 }588 ReactNoop.yield('Layout effect ' + count);589 });590 return <Text text="Layout" />;591 }592 ReactNoop.render([<PassiveEffect key="p" />, <LayoutEffect key="l" />]);593 expect(ReactNoop.flush()).toEqual([594 'Passive',595 'Layout',596 'Layout effect 0',597 'Passive effect',598 'Layout',599 'Layout effect 1',600 ]);601 expect(ReactNoop.getChildren()).toEqual([602 span('Passive'),603 span('Layout'),604 ]);605 });606 it('flushes passive effects even if siblings schedule a new root', () => {607 function PassiveEffect(props) {608 useEffect(() => {609 ReactNoop.yield('Passive effect');610 }, []);611 return <Text text="Passive" />;612 }613 function LayoutEffect(props) {614 useLayoutEffect(() => {615 ReactNoop.yield('Layout effect');616 // Scheduling work shouldn't interfere with the queued passive effect617 ReactNoop.renderToRootWithID(<Text text="New Root" />, 'root2');618 });619 return <Text text="Layout" />;620 }621 ReactNoop.render([<PassiveEffect key="p" />, <LayoutEffect key="l" />]);622 expect(ReactNoop.flush()).toEqual([623 'Passive',624 'Layout',625 'Layout effect',626 'Passive effect',627 'New Root',628 ]);629 expect(ReactNoop.getChildren()).toEqual([630 span('Passive'),631 span('Layout'),632 ]);633 });634 it(635 'flushes effects serially by flushing old effects before flushing ' +636 "new ones, if they haven't already fired",637 () => {638 function getCommittedText() {639 const children = ReactNoop.getChildren();640 if (children === null) {641 return null;642 }643 return children[0].prop;644 }645 function Counter(props) {646 useEffect(() => {647 ReactNoop.yield(648 `Committed state when effect was fired: ${getCommittedText()}`,649 );650 });651 return <Text text={props.count} />;652 }653 ReactNoop.render(<Counter count={0} />);654 expect(ReactNoop.flush()).toEqual([0]);655 expect(ReactNoop.getChildren()).toEqual([span(0)]);656 // Before the effects have a chance to flush, schedule another update657 ReactNoop.render(<Counter count={1} />);658 expect(ReactNoop.flush()).toEqual([659 // The previous effect flushes before the reconciliation660 'Committed state when effect was fired: 0',661 1,662 ]);663 expect(ReactNoop.getChildren()).toEqual([span(1)]);664 flushPassiveEffects();665 expect(ReactNoop.clearYields()).toEqual([666 'Committed state when effect was fired: 1',667 ]);668 },669 );670 it('updates have async priority', () => {671 function Counter(props) {672 const [count, updateCount] = useState('(empty)');673 useEffect(674 () => {675 ReactNoop.yield(`Schedule update [${props.count}]`);676 updateCount(props.count);677 },678 [props.count],679 );680 return <Text text={'Count: ' + count} />;681 }682 ReactNoop.render(<Counter count={0} />);683 expect(ReactNoop.flush()).toEqual(['Count: (empty)']);684 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);685 flushPassiveEffects();686 expect(ReactNoop.clearYields()).toEqual(['Schedule update [0]']);687 expect(ReactNoop.flush()).toEqual(['Count: 0']);688 ReactNoop.render(<Counter count={1} />);689 expect(ReactNoop.flush()).toEqual(['Count: 0']);690 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);691 flushPassiveEffects();692 expect(ReactNoop.clearYields()).toEqual(['Schedule update [1]']);693 expect(ReactNoop.flush()).toEqual(['Count: 1']);694 });695 it('updates have async priority even if effects are flushed early', () => {696 function Counter(props) {697 const [count, updateCount] = useState('(empty)');698 useEffect(699 () => {700 ReactNoop.yield(`Schedule update [${props.count}]`);701 updateCount(props.count);702 },703 [props.count],704 );705 return <Text text={'Count: ' + count} />;706 }707 ReactNoop.render(<Counter count={0} />);708 expect(ReactNoop.flush()).toEqual(['Count: (empty)']);709 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);710 // Rendering again should flush the previous commit's effects711 ReactNoop.render(<Counter count={1} />);712 ReactNoop.flushThrough(['Schedule update [0]', 'Count: 0']);713 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);714 expect(ReactNoop.flush()).toEqual([]);715 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);716 flushPassiveEffects();717 expect(ReactNoop.flush()).toEqual(['Schedule update [1]', 'Count: 1']);718 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);719 });720 it('flushes serial effects before enqueueing work', () => {721 let _updateCount;722 function Counter(props) {723 const [count, updateCount] = useState(0);724 _updateCount = updateCount;725 useEffect(() => {726 ReactNoop.yield(`Will set count to 1`);727 updateCount(1);728 }, []);729 return <Text text={'Count: ' + count} />;730 }731 ReactNoop.render(<Counter count={0} />);732 expect(ReactNoop.flush()).toEqual(['Count: 0']);733 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);734 // Enqueuing this update forces the passive effect to be flushed --735 // updateCount(1) happens first, so 2 wins.736 _updateCount(2);737 expect(ReactNoop.flush()).toEqual(['Will set count to 1', 'Count: 2']);738 expect(ReactNoop.getChildren()).toEqual([span('Count: 2')]);739 });740 it('flushes serial effects before enqueueing work (with tracing)', () => {741 const onInteractionScheduledWorkCompleted = jest.fn();742 const onWorkCanceled = jest.fn();743 SchedulerTracing.unstable_subscribe({744 onInteractionScheduledWorkCompleted,745 onInteractionTraced: jest.fn(),746 onWorkCanceled,747 onWorkScheduled: jest.fn(),748 onWorkStarted: jest.fn(),749 onWorkStopped: jest.fn(),750 });751 let _updateCount;752 function Counter(props) {753 const [count, updateCount] = useState(0);754 _updateCount = updateCount;755 useEffect(() => {756 expect(SchedulerTracing.unstable_getCurrent()).toMatchInteractions([757 tracingEvent,758 ]);759 ReactNoop.yield(`Will set count to 1`);760 updateCount(1);761 }, []);762 return <Text text={'Count: ' + count} />;763 }764 const tracingEvent = {id: 0, name: 'hello', timestamp: 0};765 SchedulerTracing.unstable_trace(766 tracingEvent.name,767 tracingEvent.timestamp,768 () => {769 ReactNoop.render(<Counter count={0} />);770 },771 );772 expect(ReactNoop.flush()).toEqual(['Count: 0']);773 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);774 expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(0);775 // Enqueuing this update forces the passive effect to be flushed --776 // updateCount(1) happens first, so 2 wins.777 _updateCount(2);778 expect(ReactNoop.flush()).toEqual(['Will set count to 1', 'Count: 2']);779 expect(ReactNoop.getChildren()).toEqual([span('Count: 2')]);780 expect(onInteractionScheduledWorkCompleted).toHaveBeenCalledTimes(1);781 expect(onWorkCanceled).toHaveBeenCalledTimes(0);782 });783 it(784 'in sync mode, useEffect is deferred and updates finish synchronously ' +785 '(in a single batch)',786 () => {787 function Counter(props) {788 const [count, updateCount] = useState('(empty)');789 useEffect(790 () => {791 // Update multiple times. These should all be batched together in792 // a single render.793 updateCount(props.count);794 updateCount(props.count);795 updateCount(props.count);796 updateCount(props.count);797 updateCount(props.count);798 updateCount(props.count);799 },800 [props.count],801 );802 return <Text text={'Count: ' + count} />;803 }804 ReactNoop.renderLegacySyncRoot(<Counter count={0} />);805 // Even in sync mode, effects are deferred until after paint806 expect(ReactNoop.flush()).toEqual(['Count: (empty)']);807 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);808 // Now fire the effects809 flushPassiveEffects();810 // There were multiple updates, but there should only be a811 // single render812 expect(ReactNoop.clearYields()).toEqual(['Count: 0']);813 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);814 },815 );816 it('flushSync is not allowed', () => {817 function Counter(props) {818 const [count, updateCount] = useState('(empty)');819 useEffect(820 () => {821 ReactNoop.yield(`Schedule update [${props.count}]`);822 ReactNoop.flushSync(() => {823 updateCount(props.count);824 });825 },826 [props.count],827 );828 return <Text text={'Count: ' + count} />;829 }830 ReactNoop.render(<Counter count={0} />);831 expect(ReactNoop.flush()).toEqual(['Count: (empty)']);832 expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);833 expect(() => {834 flushPassiveEffects();835 }).toThrow('flushSync was called from inside a lifecycle method');836 });837 it('unmounts previous effect', () => {838 function Counter(props) {839 useEffect(() => {840 ReactNoop.yield(`Did create [${props.count}]`);841 return () => {842 ReactNoop.yield(`Did destroy [${props.count}]`);843 };844 });845 return <Text text={'Count: ' + props.count} />;846 }847 ReactNoop.render(<Counter count={0} />);848 expect(ReactNoop.flush()).toEqual(['Count: 0']);849 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);850 flushPassiveEffects();851 expect(ReactNoop.clearYields()).toEqual(['Did create [0]']);852 ReactNoop.render(<Counter count={1} />);853 expect(ReactNoop.flush()).toEqual(['Count: 1']);854 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);855 flushPassiveEffects();856 expect(ReactNoop.clearYields()).toEqual([857 'Did destroy [0]',858 'Did create [1]',859 ]);860 });861 it('unmounts on deletion', () => {862 function Counter(props) {863 useEffect(() => {864 ReactNoop.yield(`Did create [${props.count}]`);865 return () => {866 ReactNoop.yield(`Did destroy [${props.count}]`);867 };868 });869 return <Text text={'Count: ' + props.count} />;870 }871 ReactNoop.render(<Counter count={0} />);872 expect(ReactNoop.flush()).toEqual(['Count: 0']);873 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);874 flushPassiveEffects();875 expect(ReactNoop.clearYields()).toEqual(['Did create [0]']);876 ReactNoop.render(null);877 expect(ReactNoop.flush()).toEqual(['Did destroy [0]']);878 expect(ReactNoop.getChildren()).toEqual([]);879 });880 it('unmounts on deletion after skipped effect', () => {881 function Counter(props) {882 useEffect(() => {883 ReactNoop.yield(`Did create [${props.count}]`);884 return () => {885 ReactNoop.yield(`Did destroy [${props.count}]`);886 };887 }, []);888 return <Text text={'Count: ' + props.count} />;889 }890 ReactNoop.render(<Counter count={0} />);891 expect(ReactNoop.flush()).toEqual(['Count: 0']);892 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);893 flushPassiveEffects();894 expect(ReactNoop.clearYields()).toEqual(['Did create [0]']);895 ReactNoop.render(<Counter count={1} />);896 expect(ReactNoop.flush()).toEqual(['Count: 1']);897 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);898 flushPassiveEffects();899 expect(ReactNoop.clearYields()).toEqual(null);900 ReactNoop.render(null);901 expect(ReactNoop.flush()).toEqual(['Did destroy [0]']);902 expect(ReactNoop.getChildren()).toEqual([]);903 });904 it('skips effect if constructor has not changed', () => {905 function effect() {906 ReactNoop.yield(`Did mount`);907 return () => {908 ReactNoop.yield(`Did unmount`);909 };910 }911 function Counter(props) {912 useEffect(effect);913 return <Text text={'Count: ' + props.count} />;914 }915 ReactNoop.render(<Counter count={0} />);916 expect(ReactNoop.flush()).toEqual(['Count: 0']);917 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);918 flushPassiveEffects();919 expect(ReactNoop.clearYields()).toEqual(['Did mount']);920 ReactNoop.render(<Counter count={1} />);921 // No effect, because constructor was hoisted outside render922 expect(ReactNoop.flush()).toEqual(['Count: 1']);923 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);924 ReactNoop.render(null);925 expect(ReactNoop.flush()).toEqual(['Did unmount']);926 expect(ReactNoop.getChildren()).toEqual([]);927 });928 it('skips effect if inputs have not changed', () => {929 function Counter(props) {930 const text = `${props.label}: ${props.count}`;931 useEffect(932 () => {933 ReactNoop.yield(`Did create [${text}]`);934 return () => {935 ReactNoop.yield(`Did destroy [${text}]`);936 };937 },938 [props.label, props.count],939 );940 return <Text text={text} />;941 }942 ReactNoop.render(<Counter label="Count" count={0} />);943 expect(ReactNoop.flush()).toEqual(['Count: 0']);944 flushPassiveEffects();945 expect(ReactNoop.clearYields()).toEqual(['Did create [Count: 0]']);946 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);947 ReactNoop.render(<Counter label="Count" count={1} />);948 // Count changed949 expect(ReactNoop.flush()).toEqual(['Count: 1']);950 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);951 flushPassiveEffects();952 expect(ReactNoop.clearYields()).toEqual([953 'Did destroy [Count: 0]',954 'Did create [Count: 1]',955 ]);956 ReactNoop.render(<Counter label="Count" count={1} />);957 // Nothing changed, so no effect should have fired958 expect(ReactNoop.flush()).toEqual(['Count: 1']);959 flushPassiveEffects();960 expect(ReactNoop.clearYields()).toEqual(null);961 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);962 ReactNoop.render(<Counter label="Total" count={1} />);963 // Label changed964 expect(ReactNoop.flush()).toEqual(['Total: 1']);965 expect(ReactNoop.getChildren()).toEqual([span('Total: 1')]);966 flushPassiveEffects();967 expect(ReactNoop.clearYields()).toEqual([968 'Did destroy [Count: 1]',969 'Did create [Total: 1]',970 ]);971 });972 it('multiple effects', () => {973 function Counter(props) {974 useEffect(() => {975 ReactNoop.yield(`Did commit 1 [${props.count}]`);976 });977 useEffect(() => {978 ReactNoop.yield(`Did commit 2 [${props.count}]`);979 });980 return <Text text={'Count: ' + props.count} />;981 }982 ReactNoop.render(<Counter count={0} />);983 expect(ReactNoop.flush()).toEqual(['Count: 0']);984 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);985 flushPassiveEffects();986 expect(ReactNoop.clearYields()).toEqual([987 'Did commit 1 [0]',988 'Did commit 2 [0]',989 ]);990 ReactNoop.render(<Counter count={1} />);991 expect(ReactNoop.flush()).toEqual(['Count: 1']);992 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);993 flushPassiveEffects();994 expect(ReactNoop.clearYields()).toEqual([995 'Did commit 1 [1]',996 'Did commit 2 [1]',997 ]);998 });999 it('unmounts all previous effects before creating any new ones', () => {1000 function Counter(props) {1001 useEffect(() => {1002 ReactNoop.yield(`Mount A [${props.count}]`);1003 return () => {1004 ReactNoop.yield(`Unmount A [${props.count}]`);1005 };1006 });1007 useEffect(() => {1008 ReactNoop.yield(`Mount B [${props.count}]`);1009 return () => {1010 ReactNoop.yield(`Unmount B [${props.count}]`);1011 };1012 });1013 return <Text text={'Count: ' + props.count} />;1014 }1015 ReactNoop.render(<Counter count={0} />);1016 expect(ReactNoop.flush()).toEqual(['Count: 0']);1017 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);1018 flushPassiveEffects();1019 expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']);1020 ReactNoop.render(<Counter count={1} />);1021 expect(ReactNoop.flush()).toEqual(['Count: 1']);1022 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);1023 flushPassiveEffects();1024 expect(ReactNoop.clearYields()).toEqual([1025 'Unmount A [0]',1026 'Unmount B [0]',1027 'Mount A [1]',1028 'Mount B [1]',1029 ]);1030 });1031 it('handles errors on mount', () => {1032 function Counter(props) {1033 useEffect(() => {1034 ReactNoop.yield(`Mount A [${props.count}]`);1035 return () => {1036 ReactNoop.yield(`Unmount A [${props.count}]`);1037 };1038 });1039 useEffect(() => {1040 ReactNoop.yield('Oops!');1041 throw new Error('Oops!');1042 // eslint-disable-next-line no-unreachable1043 ReactNoop.yield(`Mount B [${props.count}]`);1044 return () => {1045 ReactNoop.yield(`Unmount B [${props.count}]`);1046 };1047 });1048 return <Text text={'Count: ' + props.count} />;1049 }1050 ReactNoop.render(<Counter count={0} />);1051 expect(ReactNoop.flush()).toEqual(['Count: 0']);1052 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);1053 expect(() => flushPassiveEffects()).toThrow('Oops');1054 expect(ReactNoop.clearYields()).toEqual([1055 'Mount A [0]',1056 'Oops!',1057 // Clean up effect A. There's no effect B to clean-up, because it1058 // never mounted.1059 'Unmount A [0]',1060 ]);1061 expect(ReactNoop.getChildren()).toEqual([]);1062 });1063 it('handles errors on update', () => {1064 function Counter(props) {1065 useEffect(() => {1066 ReactNoop.yield(`Mount A [${props.count}]`);1067 return () => {1068 ReactNoop.yield(`Unmount A [${props.count}]`);1069 };1070 });1071 useEffect(() => {1072 if (props.count === 1) {1073 ReactNoop.yield('Oops!');1074 throw new Error('Oops!');1075 }1076 ReactNoop.yield(`Mount B [${props.count}]`);1077 return () => {1078 ReactNoop.yield(`Unmount B [${props.count}]`);1079 };1080 });1081 return <Text text={'Count: ' + props.count} />;1082 }1083 ReactNoop.render(<Counter count={0} />);1084 expect(ReactNoop.flush()).toEqual(['Count: 0']);1085 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);1086 flushPassiveEffects();1087 expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']);1088 // This update will trigger an errror1089 ReactNoop.render(<Counter count={1} />);1090 expect(ReactNoop.flush()).toEqual(['Count: 1']);1091 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);1092 expect(() => flushPassiveEffects()).toThrow('Oops');1093 expect(ReactNoop.clearYields()).toEqual([1094 'Unmount A [0]',1095 'Unmount B [0]',1096 'Mount A [1]',1097 'Oops!',1098 // Clean up effect A. There's no effect B to clean-up, because it1099 // never mounted.1100 'Unmount A [1]',1101 ]);1102 expect(ReactNoop.getChildren()).toEqual([]);1103 });1104 it('handles errors on unmount', () => {1105 function Counter(props) {1106 useEffect(() => {1107 ReactNoop.yield(`Mount A [${props.count}]`);1108 return () => {1109 ReactNoop.yield('Oops!');1110 throw new Error('Oops!');1111 // eslint-disable-next-line no-unreachable1112 ReactNoop.yield(`Unmount A [${props.count}]`);1113 };1114 });1115 useEffect(() => {1116 ReactNoop.yield(`Mount B [${props.count}]`);1117 return () => {1118 ReactNoop.yield(`Unmount B [${props.count}]`);1119 };1120 });1121 return <Text text={'Count: ' + props.count} />;1122 }1123 ReactNoop.render(<Counter count={0} />);1124 expect(ReactNoop.flush()).toEqual(['Count: 0']);1125 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);1126 flushPassiveEffects();1127 expect(ReactNoop.clearYields()).toEqual(['Mount A [0]', 'Mount B [0]']);1128 // This update will trigger an errror1129 ReactNoop.render(<Counter count={1} />);1130 expect(ReactNoop.flush()).toEqual(['Count: 1']);1131 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);1132 expect(() => flushPassiveEffects()).toThrow('Oops');1133 expect(ReactNoop.clearYields()).toEqual([1134 'Oops!',1135 // B unmounts even though an error was thrown in the previous effect1136 'Unmount B [0]',1137 ]);1138 expect(ReactNoop.getChildren()).toEqual([]);1139 });1140 it('works with memo', () => {1141 function Counter({count}) {1142 useLayoutEffect(() => {1143 ReactNoop.yield('Mount: ' + count);1144 return () => ReactNoop.yield('Unmount: ' + count);1145 });1146 return <Text text={'Count: ' + count} />;1147 }1148 Counter = memo(Counter);1149 ReactNoop.render(<Counter count={0} />);1150 expect(ReactNoop.flush()).toEqual(['Count: 0', 'Mount: 0']);1151 expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);1152 ReactNoop.render(<Counter count={1} />);1153 expect(ReactNoop.flush()).toEqual(['Count: 1', 'Unmount: 0', 'Mount: 1']);1154 expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);1155 ReactNoop.render(null);1156 expect(ReactNoop.flush()).toEqual(['Unmount: 1']);1157 expect(ReactNoop.getChildren()).toEqual([]);1158 });1159 });1160 describe('useLayoutEffect', () => {1161 it('fires layout effects after the host has been mutated', () => {1162 function getCommittedText() {1163 const children = ReactNoop.getChildren();1164 if (children === null) {1165 return null;1166 }1167 return children[0].prop;1168 }1169 function Counter(props) {1170 useLayoutEffect(() => {1171 ReactNoop.yield(`Current: ${getCommittedText()}`);1172 });1173 return <Text text={props.count} />;1174 }1175 ReactNoop.render(<Counter count={0} />);1176 expect(ReactNoop.flush()).toEqual([0, 'Current: 0']);1177 expect(ReactNoop.getChildren()).toEqual([span(0)]);1178 ReactNoop.render(<Counter count={1} />);1179 expect(ReactNoop.flush()).toEqual([1, 'Current: 1']);1180 expect(ReactNoop.getChildren()).toEqual([span(1)]);1181 });1182 it('force flushes passive effects before firing new layout effects', () => {1183 let committedText = '(empty)';1184 function Counter(props) {1185 useLayoutEffect(() => {1186 // Normally this would go in a mutation effect, but this test1187 // intentionally omits a mutation effect.1188 committedText = props.count + '';1189 ReactNoop.yield(`Mount layout [current: ${committedText}]`);1190 return () => {1191 ReactNoop.yield(`Unmount layout [current: ${committedText}]`);1192 };1193 });1194 useEffect(() => {1195 ReactNoop.yield(`Mount normal [current: ${committedText}]`);1196 return () => {1197 ReactNoop.yield(`Unmount normal [current: ${committedText}]`);1198 };1199 });1200 return null;1201 }1202 ReactNoop.render(<Counter count={0} />);1203 expect(ReactNoop.flush()).toEqual(['Mount layout [current: 0]']);1204 expect(committedText).toEqual('0');1205 ReactNoop.render(<Counter count={1} />);1206 expect(ReactNoop.flush()).toEqual([1207 'Mount normal [current: 0]',1208 'Unmount layout [current: 0]',1209 'Mount layout [current: 1]',1210 ]);1211 expect(committedText).toEqual('1');1212 flushPassiveEffects();1213 expect(ReactNoop.clearYields()).toEqual([1214 'Unmount normal [current: 1]',1215 'Mount normal [current: 1]',1216 ]);1217 });1218 });1219 describe('useCallback', () => {1220 it('memoizes callback by comparing inputs', () => {1221 class IncrementButton extends React.PureComponent {1222 increment = () => {1223 this.props.increment();1224 };1225 render() {1226 return <Text text="Increment" />;1227 }1228 }1229 function Counter({incrementBy}) {1230 const [count, updateCount] = useState(0);1231 const increment = useCallback(() => updateCount(c => c + incrementBy), [1232 incrementBy,1233 ]);1234 return (1235 <React.Fragment>1236 <IncrementButton increment={increment} ref={button} />1237 <Text text={'Count: ' + count} />1238 </React.Fragment>1239 );1240 }1241 const button = React.createRef(null);1242 ReactNoop.render(<Counter incrementBy={1} />);1243 expect(ReactNoop.flush()).toEqual(['Increment', 'Count: 0']);1244 expect(ReactNoop.getChildren()).toEqual([1245 span('Increment'),1246 span('Count: 0'),1247 ]);1248 button.current.increment();1249 expect(ReactNoop.flush()).toEqual([1250 // Button should not re-render, because its props haven't changed1251 // 'Increment',1252 'Count: 1',1253 ]);1254 expect(ReactNoop.getChildren()).toEqual([1255 span('Increment'),1256 span('Count: 1'),1257 ]);1258 // Increase the increment amount1259 ReactNoop.render(<Counter incrementBy={10} />);1260 expect(ReactNoop.flush()).toEqual([1261 // Inputs did change this time1262 'Increment',1263 'Count: 1',1264 ]);1265 expect(ReactNoop.getChildren()).toEqual([1266 span('Increment'),1267 span('Count: 1'),1268 ]);1269 // Callback should have updated1270 button.current.increment();1271 expect(ReactNoop.flush()).toEqual(['Count: 11']);1272 expect(ReactNoop.getChildren()).toEqual([1273 span('Increment'),1274 span('Count: 11'),1275 ]);1276 });1277 });1278 describe('useMemo', () => {1279 it('memoizes value by comparing to previous inputs', () => {1280 function CapitalizedText(props) {1281 const text = props.text;1282 const capitalizedText = useMemo(1283 () => {1284 ReactNoop.yield(`Capitalize '${text}'`);1285 return text.toUpperCase();1286 },1287 [text],1288 );1289 return <Text text={capitalizedText} />;1290 }1291 ReactNoop.render(<CapitalizedText text="hello" />);1292 expect(ReactNoop.flush()).toEqual(["Capitalize 'hello'", 'HELLO']);1293 expect(ReactNoop.getChildren()).toEqual([span('HELLO')]);1294 ReactNoop.render(<CapitalizedText text="hi" />);1295 expect(ReactNoop.flush()).toEqual(["Capitalize 'hi'", 'HI']);1296 expect(ReactNoop.getChildren()).toEqual([span('HI')]);1297 ReactNoop.render(<CapitalizedText text="hi" />);1298 expect(ReactNoop.flush()).toEqual(['HI']);1299 expect(ReactNoop.getChildren()).toEqual([span('HI')]);1300 ReactNoop.render(<CapitalizedText text="goodbye" />);1301 expect(ReactNoop.flush()).toEqual(["Capitalize 'goodbye'", 'GOODBYE']);1302 expect(ReactNoop.getChildren()).toEqual([span('GOODBYE')]);1303 });1304 it('compares function if no inputs are provided', () => {1305 function LazyCompute(props) {1306 const computed = useMemo(props.compute);1307 return <Text text={computed} />;1308 }1309 function computeA() {1310 ReactNoop.yield('compute A');1311 return 'A';1312 }1313 function computeB() {1314 ReactNoop.yield('compute B');1315 return 'B';1316 }1317 ReactNoop.render(<LazyCompute compute={computeA} />);1318 expect(ReactNoop.flush()).toEqual(['compute A', 'A']);1319 ReactNoop.render(<LazyCompute compute={computeA} />);1320 expect(ReactNoop.flush()).toEqual(['A']);1321 ReactNoop.render(<LazyCompute compute={computeA} />);1322 expect(ReactNoop.flush()).toEqual(['A']);1323 ReactNoop.render(<LazyCompute compute={computeB} />);1324 expect(ReactNoop.flush()).toEqual(['compute B', 'B']);1325 });1326 it('should not invoke memoized function during re-renders unless inputs change', () => {1327 function LazyCompute(props) {1328 const computed = useMemo(() => props.compute(props.input), [1329 props.input,1330 ]);1331 const [count, setCount] = useState(0);1332 if (count < 3) {1333 setCount(count + 1);1334 }1335 return <Text text={computed} />;1336 }1337 function compute(val) {1338 ReactNoop.yield('compute ' + val);1339 return val;1340 }1341 ReactNoop.render(<LazyCompute compute={compute} input="A" />);1342 expect(ReactNoop.flush()).toEqual(['compute A', 'A']);1343 ReactNoop.render(<LazyCompute compute={compute} input="A" />);1344 expect(ReactNoop.flush()).toEqual(['A']);1345 ReactNoop.render(<LazyCompute compute={compute} input="B" />);1346 expect(ReactNoop.flush()).toEqual(['compute B', 'B']);1347 });1348 });1349 describe('useRef', () => {1350 it('creates a ref object initialized with the provided value', () => {1351 jest.useFakeTimers();1352 function useDebouncedCallback(callback, ms, inputs) {1353 const timeoutID = useRef(-1);1354 useEffect(() => {1355 return function unmount() {1356 clearTimeout(timeoutID.current);1357 };1358 }, []);1359 const debouncedCallback = useCallback(1360 (...args) => {1361 clearTimeout(timeoutID.current);1362 timeoutID.current = setTimeout(callback, ms, ...args);1363 },1364 [callback, ms],1365 );1366 return useCallback(debouncedCallback, inputs);1367 }1368 let ping;1369 function App() {1370 ping = useDebouncedCallback(1371 value => {1372 ReactNoop.yield('ping: ' + value);1373 },1374 100,1375 [],1376 );1377 return null;1378 }1379 ReactNoop.render(<App />);1380 expect(ReactNoop.flush()).toEqual([]);1381 ping(1);1382 ping(2);1383 ping(3);1384 expect(ReactNoop.flush()).toEqual([]);1385 jest.advanceTimersByTime(100);1386 expect(ReactNoop.flush()).toEqual(['ping: 3']);1387 ping(4);1388 jest.advanceTimersByTime(20);1389 ping(5);1390 ping(6);1391 jest.advanceTimersByTime(80);1392 expect(ReactNoop.flush()).toEqual([]);1393 jest.advanceTimersByTime(20);1394 expect(ReactNoop.flush()).toEqual(['ping: 6']);1395 });1396 it('should return the same ref during re-renders', () => {1397 function Counter() {1398 const ref = useRef('val');1399 const [count, setCount] = useState(0);1400 const [firstRef] = useState(ref);1401 if (firstRef !== ref) {1402 throw new Error('should never change');1403 }1404 if (count < 3) {1405 setCount(count + 1);1406 }1407 return <Text text={ref.current} />;1408 }1409 ReactNoop.render(<Counter />);1410 expect(ReactNoop.flush()).toEqual(['val']);1411 ReactNoop.render(<Counter />);1412 expect(ReactNoop.flush()).toEqual(['val']);1413 });1414 });1415 describe('progressive enhancement', () => {1416 it('mount additional state', () => {1417 let updateA;1418 let updateB;1419 let updateC;1420 function App(props) {1421 const [A, _updateA] = useState(0);1422 const [B, _updateB] = useState(0);1423 updateA = _updateA;1424 updateB = _updateB;1425 let C;1426 if (props.loadC) {1427 const [_C, _updateC] = useState(0);1428 C = _C;1429 updateC = _updateC;1430 } else {1431 C = '[not loaded]';1432 }1433 return <Text text={`A: ${A}, B: ${B}, C: ${C}`} />;1434 }1435 ReactNoop.render(<App loadC={false} />);1436 expect(ReactNoop.flush()).toEqual(['A: 0, B: 0, C: [not loaded]']);1437 expect(ReactNoop.getChildren()).toEqual([1438 span('A: 0, B: 0, C: [not loaded]'),1439 ]);1440 updateA(2);1441 updateB(3);1442 expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: [not loaded]']);1443 expect(ReactNoop.getChildren()).toEqual([1444 span('A: 2, B: 3, C: [not loaded]'),1445 ]);1446 ReactNoop.render(<App loadC={true} />);1447 expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: 0']);1448 expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 0')]);1449 updateC(4);1450 expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: 4']);1451 expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 4')]);1452 });1453 it('unmount state', () => {1454 let updateA;1455 let updateB;1456 let updateC;1457 function App(props) {1458 const [A, _updateA] = useState(0);1459 const [B, _updateB] = useState(0);1460 updateA = _updateA;1461 updateB = _updateB;1462 let C;1463 if (props.loadC) {1464 const [_C, _updateC] = useState(0);1465 C = _C;1466 updateC = _updateC;1467 } else {1468 C = '[not loaded]';1469 }1470 return <Text text={`A: ${A}, B: ${B}, C: ${C}`} />;1471 }1472 ReactNoop.render(<App loadC={true} />);1473 expect(ReactNoop.flush()).toEqual(['A: 0, B: 0, C: 0']);1474 expect(ReactNoop.getChildren()).toEqual([span('A: 0, B: 0, C: 0')]);1475 updateA(2);1476 updateB(3);1477 updateC(4);1478 expect(ReactNoop.flush()).toEqual(['A: 2, B: 3, C: 4']);1479 expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 4')]);1480 ReactNoop.render(<App loadC={false} />);1481 expect(() => ReactNoop.flush()).toThrow(1482 'Rendered fewer hooks than expected. This may be caused by an ' +1483 'accidental early return statement.',1484 );1485 });1486 it('unmount effects', () => {1487 function App(props) {1488 useEffect(() => {1489 ReactNoop.yield('Mount A');1490 return () => {1491 ReactNoop.yield('Unmount A');1492 };1493 }, []);1494 if (props.showMore) {1495 useEffect(() => {1496 ReactNoop.yield('Mount B');1497 return () => {1498 ReactNoop.yield('Unmount B');1499 };1500 }, []);1501 }1502 return null;1503 }1504 ReactNoop.render(<App showMore={false} />);1505 expect(ReactNoop.flush()).toEqual([]);1506 flushPassiveEffects();1507 expect(ReactNoop.clearYields()).toEqual(['Mount A']);1508 ReactNoop.render(<App showMore={true} />);1509 expect(ReactNoop.flush()).toEqual([]);1510 flushPassiveEffects();1511 expect(ReactNoop.clearYields()).toEqual(['Mount B']);1512 ReactNoop.render(<App showMore={false} />);1513 expect(() => ReactNoop.flush()).toThrow(1514 'Rendered fewer hooks than expected. This may be caused by an ' +1515 'accidental early return statement.',1516 );1517 });1518 });...
global_settings.py
Source:global_settings.py
...35# http://www.i18nguy.com/unicode/language-identifiers.html36LANGUAGE_CODE = 'en-us'37# Languages we provide translations for, out of the box.38LANGUAGES = [39 ('af', gettext_noop('Afrikaans')),40 ('ar', gettext_noop('Arabic')),41 ('ast', gettext_noop('Asturian')),42 ('az', gettext_noop('Azerbaijani')),43 ('bg', gettext_noop('Bulgarian')),44 ('be', gettext_noop('Belarusian')),45 ('bn', gettext_noop('Bengali')),46 ('br', gettext_noop('Breton')),47 ('bs', gettext_noop('Bosnian')),48 ('ca', gettext_noop('Catalan')),49 ('cs', gettext_noop('Czech')),50 ('cy', gettext_noop('Welsh')),51 ('da', gettext_noop('Danish')),52 ('de', gettext_noop('German')),53 ('el', gettext_noop('Greek')),54 ('en', gettext_noop('English')),55 ('en-au', gettext_noop('Australian English')),56 ('en-gb', gettext_noop('British English')),57 ('eo', gettext_noop('Esperanto')),58 ('es', gettext_noop('Spanish')),59 ('es-ar', gettext_noop('Argentinian Spanish')),60 ('es-co', gettext_noop('Colombian Spanish')),61 ('es-mx', gettext_noop('Mexican Spanish')),62 ('es-ni', gettext_noop('Nicaraguan Spanish')),63 ('es-ve', gettext_noop('Venezuelan Spanish')),64 ('et', gettext_noop('Estonian')),65 ('eu', gettext_noop('Basque')),66 ('fa', gettext_noop('Persian')),67 ('fi', gettext_noop('Finnish')),68 ('fr', gettext_noop('French')),69 ('fy', gettext_noop('Frisian')),70 ('ga', gettext_noop('Irish')),71 ('gd', gettext_noop('Scottish Gaelic')),72 ('gl', gettext_noop('Galician')),73 ('he', gettext_noop('Hebrew')),74 ('hi', gettext_noop('Hindi')),75 ('hr', gettext_noop('Croatian')),76 ('hu', gettext_noop('Hungarian')),77 ('ia', gettext_noop('Interlingua')),78 ('id', gettext_noop('Indonesian')),79 ('io', gettext_noop('Ido')),80 ('is', gettext_noop('Icelandic')),81 ('it', gettext_noop('Italian')),82 ('ja', gettext_noop('Japanese')),83 ('ka', gettext_noop('Georgian')),84 ('kk', gettext_noop('Kazakh')),85 ('km', gettext_noop('Khmer')),86 ('kn', gettext_noop('Kannada')),87 ('ko', gettext_noop('Korean')),88 ('lb', gettext_noop('Luxembourgish')),89 ('lt', gettext_noop('Lithuanian')),90 ('lv', gettext_noop('Latvian')),91 ('mk', gettext_noop('Macedonian')),92 ('ml', gettext_noop('Malayalam')),93 ('mn', gettext_noop('Mongolian')),94 ('mr', gettext_noop('Marathi')),95 ('my', gettext_noop('Burmese')),96 ('nb', gettext_noop('Norwegian Bokmal')),97 ('ne', gettext_noop('Nepali')),98 ('nl', gettext_noop('Dutch')),99 ('nn', gettext_noop('Norwegian Nynorsk')),100 ('os', gettext_noop('Ossetic')),101 ('pa', gettext_noop('Punjabi')),102 ('pl', gettext_noop('Polish')),103 ('pt', gettext_noop('Portuguese')),104 ('pt-br', gettext_noop('Brazilian Portuguese')),105 ('ro', gettext_noop('Romanian')),106 ('ru', gettext_noop('Russian')),107 ('sk', gettext_noop('Slovak')),108 ('sl', gettext_noop('Slovenian')),109 ('sq', gettext_noop('Albanian')),110 ('sr', gettext_noop('Serbian')),111 ('sr-latn', gettext_noop('Serbian Latin')),112 ('sv', gettext_noop('Swedish')),113 ('sw', gettext_noop('Swahili')),114 ('ta', gettext_noop('Tamil')),115 ('te', gettext_noop('Telugu')),116 ('th', gettext_noop('Thai')),117 ('tr', gettext_noop('Turkish')),118 ('tt', gettext_noop('Tatar')),119 ('udm', gettext_noop('Udmurt')),120 ('uk', gettext_noop('Ukrainian')),121 ('ur', gettext_noop('Urdu')),122 ('vi', gettext_noop('Vietnamese')),123 ('zh-hans', gettext_noop('Simplified Chinese')),124 ('zh-hant', gettext_noop('Traditional Chinese')),125]126# Languages using BiDi (right-to-left) layout127LANGUAGES_BIDI = ["he", "ar", "fa", "ur"]128# If you set this to False, Django will make some optimizations so as not129# to load the internationalization machinery.130USE_I18N = True131LOCALE_PATHS = []132# Settings for language cookie133LANGUAGE_COOKIE_NAME = 'django_language'134LANGUAGE_COOKIE_AGE = None135LANGUAGE_COOKIE_DOMAIN = None136LANGUAGE_COOKIE_PATH = '/'137# If you set this to True, Django will format dates, numbers and calendars138# according to user current locale....
settings.example.py
Source:settings.example.py
...137# Internationalization138# https://docs.djangoproject.com/en/3.0/topics/i18n/139# This is defined here as a do-nothing function because we can't import140# django.utils.translation -- that module depends on the settings.141def gettext_noop(s):142 return s143LANGUAGE_CODE = 'en-us'144LANGUAGES = [145 ('af', gettext_noop('Afrikaans')),146 ('ar', gettext_noop('Arabic')),147 ('ar-dz', gettext_noop('Algerian Arabic')),148 ('ast', gettext_noop('Asturian')),149 ('az', gettext_noop('Azerbaijani')),150 ('bg', gettext_noop('Bulgarian')),151 ('be', gettext_noop('Belarusian')),152 ('bn', gettext_noop('Bengali')),153 ('br', gettext_noop('Breton')),154 ('bs', gettext_noop('Bosnian')),155 ('ca', gettext_noop('Catalan')),156 ('cs', gettext_noop('Czech')),157 ('cy', gettext_noop('Welsh')),158 ('da', gettext_noop('Danish')),159 ('de', gettext_noop('German')),160 ('dsb', gettext_noop('Lower Sorbian')),161 ('el', gettext_noop('Greek')),162 ('en', gettext_noop('English')),163 ('en-au', gettext_noop('Australian English')),164 ('en-gb', gettext_noop('British English')),165 ('eo', gettext_noop('Esperanto')),166 ('es', gettext_noop('Spanish')),167 ('es-ar', gettext_noop('Argentinian Spanish')),168 ('es-co', gettext_noop('Colombian Spanish')),169 ('es-mx', gettext_noop('Mexican Spanish')),170 ('es-ni', gettext_noop('Nicaraguan Spanish')),171 ('es-ve', gettext_noop('Venezuelan Spanish')),172 ('et', gettext_noop('Estonian')),173 ('eu', gettext_noop('Basque')),174 ('fa', gettext_noop('Persian')),175 ('fi', gettext_noop('Finnish')),176 ('fr', gettext_noop('French')),177 ('fy', gettext_noop('Frisian')),178 ('ga', gettext_noop('Irish')),179 ('gd', gettext_noop('Scottish Gaelic')),180 ('gl', gettext_noop('Galician')),181 ('he', gettext_noop('Hebrew')),182 ('hi', gettext_noop('Hindi')),183 ('hr', gettext_noop('Croatian')),184 ('hsb', gettext_noop('Upper Sorbian')),185 ('hu', gettext_noop('Hungarian')),186 ('hy', gettext_noop('Armenian')),187 ('ia', gettext_noop('Interlingua')),188 ('id', gettext_noop('Indonesian')),189 ('ig', gettext_noop('Igbo')),190 ('io', gettext_noop('Ido')),191 ('is', gettext_noop('Icelandic')),192 ('it', gettext_noop('Italian')),193 ('ja', gettext_noop('Japanese')),194 ('ka', gettext_noop('Georgian')),195 ('kab', gettext_noop('Kabyle')),196 ('kk', gettext_noop('Kazakh')),197 ('km', gettext_noop('Khmer')),198 ('kn', gettext_noop('Kannada')),199 ('ko', gettext_noop('Korean')),200 ('ky', gettext_noop('Kyrgyz')),201 ('lb', gettext_noop('Luxembourgish')),202 ('lt', gettext_noop('Lithuanian')),203 ('lv', gettext_noop('Latvian')),204 ('mk', gettext_noop('Macedonian')),205 ('ml', gettext_noop('Malayalam')),206 ('mn', gettext_noop('Mongolian')),207 ('mr', gettext_noop('Marathi')),208 ('my', gettext_noop('Burmese')),209 ('nb', gettext_noop('Norwegian Bokmål')),210 ('ne', gettext_noop('Nepali')),211 ('nl', gettext_noop('Dutch')),212 ('nn', gettext_noop('Norwegian Nynorsk')),213 ('os', gettext_noop('Ossetic')),214 ('pa', gettext_noop('Punjabi')),215 ('pl', gettext_noop('Polish')),216 ('pt', gettext_noop('Portuguese')),217 ('pt-br', gettext_noop('Brazilian Portuguese')),218 ('ro', gettext_noop('Romanian')),219 ('ru', gettext_noop('Russian')),220 ('sk', gettext_noop('Slovak')),221 ('sl', gettext_noop('Slovenian')),222 ('sq', gettext_noop('Albanian')),223 ('sr', gettext_noop('Serbian')),224 ('sr-latn', gettext_noop('Serbian Latin')),225 ('sv', gettext_noop('Swedish')),226 ('sw', gettext_noop('Swahili')),227 ('ta', gettext_noop('Tamil')),228 ('te', gettext_noop('Telugu')),229 ('tg', gettext_noop('Tajik')),230 ('th', gettext_noop('Thai')),231 ('tk', gettext_noop('Turkmen')),232 ('tr', gettext_noop('Turkish')),233 ('tt', gettext_noop('Tatar')),234 ('udm', gettext_noop('Udmurt')),235 ('uk', gettext_noop('Ukrainian')),236 ('ur', gettext_noop('Urdu')),237 ('uz', gettext_noop('Uzbek')),238 ('vi', gettext_noop('Vietnamese')),239 ('zh-hans', gettext_noop('Simplified Chinese')),240 ('zh-hant', gettext_noop('Traditional Chinese')),241]242# Languages using BiDi (right-to-left) layout243LANGUAGES_BIDI = ["he", "ar", "ar-dz", "fa", "ur"]244LOCALE_PATHS = [245 'src/geocurrency/core/locales',246 pycountry.LOCALES_DIR,247]248TIME_ZONE = 'UTC'249USE_I18N = True250USE_L10N = True251USE_TZ = True252# Static files (CSS, JavaScript, Images)253# https://docs.djangoproject.com/en/3.0/howto/static-files/254STATIC_URL = '/static/'...
mock.js
Source:mock.js
1/**2 * Mock implementation for test runners.3 *4 * Example:5 *6 * ```js7 * jest.mock('react-native-a-beep', () => require('react-native-a-beep/mock'));8 * ```9 */1011function NOOP() {12 // noop13}1415const RNBeep = {16 beep: NOOP,17 PlaySysSound: NOOP,1819 AndroidSoundIDs: {20 TONE_CDMA_ABBR_ALERT: NOOP,21 TONE_CDMA_ABBR_INTERCEPT: NOOP,22 TONE_CDMA_ABBR_REORDER: NOOP,23 TONE_CDMA_ALERT_AUTOREDIAL_LITE: NOOP,24 TONE_CDMA_ALERT_CALL_GUARD: NOOP,25 TONE_CDMA_ALERT_INCALL_LITE: NOOP,26 TONE_CDMA_ALERT_NETWORK_LITE: NOOP,27 TONE_CDMA_ANSWER: NOOP,28 TONE_CDMA_CALLDROP_LITE: NOOP,29 TONE_CDMA_CALL_SIGNAL_ISDN_INTERGROUP: NOOP,30 TONE_CDMA_CALL_SIGNAL_ISDN_NORMAL: NOOP,31 TONE_CDMA_CALL_SIGNAL_ISDN_PAT3: NOOP,32 TONE_CDMA_CALL_SIGNAL_ISDN_PAT5: NOOP,33 TONE_CDMA_CALL_SIGNAL_ISDN_PAT6: NOOP,34 TONE_CDMA_CALL_SIGNAL_ISDN_PAT7: NOOP,35 TONE_CDMA_CALL_SIGNAL_ISDN_PING_RING: NOOP,36 TONE_CDMA_CALL_SIGNAL_ISDN_SP_PRI: NOOP,37 TONE_CDMA_CONFIRM: NOOP,38 TONE_CDMA_DIAL_TONE_LITE: NOOP,39 TONE_CDMA_EMERGENCY_RINGBACK: NOOP,40 TONE_CDMA_HIGH_L: NOOP,41 TONE_CDMA_HIGH_PBX_L: NOOP,42 TONE_CDMA_HIGH_PBX_SLS: NOOP,43 TONE_CDMA_HIGH_PBX_SS: NOOP,44 TONE_CDMA_HIGH_PBX_SSL: NOOP,45 TONE_CDMA_HIGH_PBX_S_X4: NOOP,46 TONE_CDMA_HIGH_SLS: NOOP,47 TONE_CDMA_HIGH_SS: NOOP,48 TONE_CDMA_HIGH_SSL: NOOP,49 TONE_CDMA_HIGH_SS_2: NOOP,50 TONE_CDMA_HIGH_S_X4: NOOP,51 TONE_CDMA_INTERCEPT: NOOP,52 TONE_CDMA_KEYPAD_VOLUME_KEY_LITE: NOOP,53 TONE_CDMA_LOW_L: NOOP,54 TONE_CDMA_LOW_PBX_L: NOOP,55 TONE_CDMA_LOW_PBX_SLS: NOOP,56 TONE_CDMA_LOW_PBX_SS: NOOP,57 TONE_CDMA_LOW_PBX_SSL: NOOP,58 TONE_CDMA_LOW_PBX_S_X4: NOOP,59 TONE_CDMA_LOW_SLS: NOOP,60 TONE_CDMA_LOW_SS: NOOP,61 TONE_CDMA_LOW_SSL: NOOP,62 TONE_CDMA_LOW_SS_2: NOOP,63 TONE_CDMA_LOW_S_X4: NOOP,64 TONE_CDMA_MED_L: NOOP,65 TONE_CDMA_MED_PBX_L: NOOP,66 TONE_CDMA_MED_PBX_SLS: NOOP,67 TONE_CDMA_MED_PBX_SS: NOOP,68 TONE_CDMA_MED_PBX_SSL: NOOP,69 TONE_CDMA_MED_PBX_S_X4: NOOP,70 TONE_CDMA_MED_SLS: NOOP,71 TONE_CDMA_MED_SS: NOOP,72 TONE_CDMA_MED_SSL: NOOP,73 TONE_CDMA_MED_SS_2: NOOP,74 TONE_CDMA_MED_S_X4: NOOP,75 TONE_CDMA_NETWORK_BUSY: NOOP,76 TONE_CDMA_NETWORK_BUSY_ONE_SHOT: NOOP,77 TONE_CDMA_NETWORK_CALLWAITING: NOOP,78 TONE_CDMA_NETWORK_USA_RINGBACK: NOOP,79 TONE_CDMA_ONE_MIN_BEEP: NOOP,80 TONE_CDMA_PIP: NOOP,81 TONE_CDMA_PRESSHOLDKEY_LITE: NOOP,82 TONE_CDMA_REORDER: NOOP,83 TONE_CDMA_SIGNAL_OFF: NOOP,84 TONE_CDMA_SOFT_ERROR_LITE: NOOP,85 TONE_DTMF_0: NOOP,86 TONE_DTMF_1: NOOP,87 TONE_DTMF_2: NOOP,88 TONE_DTMF_3: NOOP,89 TONE_DTMF_4: NOOP,90 TONE_DTMF_5: NOOP,91 TONE_DTMF_6: NOOP,92 TONE_DTMF_7: NOOP,93 TONE_DTMF_8: NOOP,94 TONE_DTMF_9: NOOP,95 TONE_DTMF_A: NOOP,96 TONE_DTMF_B: NOOP,97 TONE_DTMF_C: NOOP,98 TONE_DTMF_D: NOOP,99 TONE_DTMF_P: NOOP,100 TONE_DTMF_S: NOOP,101 TONE_PROP_ACK: NOOP,102 TONE_PROP_BEEP: NOOP,103 TONE_PROP_BEEP2: NOOP,104 TONE_PROP_NACK: NOOP,105 TONE_PROP_PROMPT: NOOP,106 TONE_SUP_BUSY: NOOP,107 TONE_SUP_CALL_WAITING: NOOP,108 TONE_SUP_CONFIRM: NOOP,109 TONE_SUP_CONGESTION: NOOP,110 TONE_SUP_CONGESTION_ABBREV: NOOP,111 TONE_SUP_DIAL: NOOP,112 TONE_SUP_ERROR: NOOP,113 TONE_SUP_INTERCEPT: NOOP,114 TONE_SUP_INTERCEPT_ABBREV: NOOP,115 TONE_SUP_PIP: NOOP,116 TONE_SUP_RADIO_ACK: NOOP,117 TONE_SUP_RADIO_NOTAVAIL: NOOP,118 TONE_SUP_RINGTONE: NOOP,119 },120121 iOSSoundIDs: {122 MailReceived: NOOP,123 MailSent: NOOP,124 VoicemailReceived: NOOP,125 SMSReceived: NOOP,126 CalendarAlert: NOOP,127 LowPower: NOOP,128 SMSReceived_Alert1: NOOP,129 SMSReceived_Alert2: NOOP,130 SMSReceived_Alert3: NOOP,131 SMSReceived_Alert4: NOOP,132 SMSReceived_Vibrate: NOOP,133 SMSReceived_Alert5: NOOP,134 SMSReceived_Alert6: NOOP,135 SMSReceived_Alert7: NOOP,136 Voicemail: NOOP,137 SMSSent: NOOP,138 SMSReceived_Alert8: NOOP,139 SMSReceived_Alert9: NOOP,140 SMSReceived_Alert10: NOOP,141 SMSReceived_Alert11: NOOP,142 SMSReceived_Alert12: NOOP,143 SMSReceived_Alert13: NOOP,144 SMSReceived_Alert14: NOOP,145 SMSReceived_Alert15: NOOP,146 SMSReceived_Alert16: NOOP,147 SMSReceived_Alert17: NOOP,148 USSDAlert: NOOP,149 SIMToolkitTone1: NOOP,150 SIMToolkitTone2: NOOP,151 SIMToolkitTone3: NOOP,152 SIMToolkitTone4: NOOP,153 PINKeyPressed: NOOP,154 AudioToneBusy: NOOP,155 AudioToneCongestion: NOOP,156 AudioTonePathAcknowledge: NOOP,157 AudioToneError: NOOP,158 AudioToneCallWaiting: NOOP,159 AudioToneKey2: NOOP,160 ScreenLocked: NOOP,161 ScreenUnlocked: NOOP,162 FailedUnlock: NOOP,163 KeyPressed1: NOOP,164 KeyPressed2: NOOP,165 KeyPressed3: NOOP,166 ConnectedToPower: NOOP,167 RingerSwitchIndication: NOOP,168 CameraShutter: NOOP,169 ShakeToShuffle: NOOP,170 JBL_Begin: NOOP,171 JBL_Confirm: NOOP,172 JBL_Cancel: NOOP,173 BeginRecording: NOOP,174 EndRecording: NOOP,175 JBL_Ambiguous: NOOP,176 JBL_NoMatch: NOOP,177 BeginVideoRecording: NOOP,178 EndVideoRecording: NOOP,179 VCInvitationAccepted: NOOP,180 VCRinging: NOOP,181 VCEnded: NOOP,182 VCCallWaiting: NOOP,183 VCCallUpgrade: NOOP,184 TouchTone1: NOOP,185 TouchTone2: NOOP,186 TouchTone3: NOOP,187 TouchTone4: NOOP,188 TouchTone5: NOOP,189 TouchTone6: NOOP,190 TouchTone7: NOOP,191 TouchTone8: NOOP,192 TouchTone9: NOOP,193 TouchTone10: NOOP,194 TouchTone11: NOOP,195 TouchTone12: NOOP,196 Headset_StartCall: NOOP,197 Headset_Redial: NOOP,198 Headset_AnswerCall: NOOP,199 Headset_EndCall: NOOP,200 Headset_CallWaitingActions: NOOP,201 Headset_TransitionEnd: NOOP,202 SystemSoundPreview1: NOOP,203 SystemSoundPreview2: NOOP,204 SystemSoundPreview3: NOOP,205 SystemSoundPreview4: NOOP,206 SystemSoundPreview5: NOOP,207 SystemSoundPreview6: NOOP,208 KeyPressClickPreview: NOOP,209 SMSReceived_Selection1: NOOP,210 SMSReceived_Selection2: NOOP,211 SMSReceived_Selection3: NOOP,212 SMSReceived_Selection4: NOOP,213 SMSReceived_Selection5: NOOP,214 SMSReceived_Selection6: NOOP,215 SMSReceived_Selection7: NOOP,216 SystemSoundPreview: NOOP,217 SMSReceived_Selection8: NOOP,218 SMSReceived_Selection9: NOOP,219 SMSReceived_Selection10: NOOP,220 SMSReceived_Selection11: NOOP,221 SMSReceived_Selection12: NOOP,222 SMSReceived_Selection13: NOOP,223 SMSReceived_Selection14: NOOP,224 SMSReceived_Selection15: NOOP,225 SMSReceived_Selection16: NOOP,226 SMSReceived_Selection17: NOOP,227 SMSReceived_Selection18: NOOP,228 SMSReceived_Selection19: NOOP,229 SMSReceived_Selection20: NOOP,230 SMSReceived_Selection21: NOOP,231 SMSReceived_Selection22: NOOP,232 SMSReceived_Selection23: NOOP,233 SMSReceived_Selection24: NOOP,234 RingerVibeChanged: NOOP,235 SilentVibeChanged: NOOP,236 Vibrate: NOOP,237 },238};239
...
swfupload.js
Source:swfupload.js
...4 * @since 4.9.05 */6var SWFUpload;7( function () {8 function noop() {}9 if (SWFUpload == undefined) {10 SWFUpload = function (settings) {11 this.initSWFUpload(settings);12 };13 }14 SWFUpload.prototype.initSWFUpload = function ( settings ) {15 function fallback() {16 var $ = window.jQuery;17 var $placeholder = settings.button_placeholder_id ? $( '#' + settings.button_placeholder_id ) : $( settings.button_placeholder );18 if ( ! $placeholder.length ) {19 return;20 }21 var $form = $placeholder.closest( 'form' );22 if ( ! $form.length ) {...
Using AI Code Generation
1(async () => {2 const { chromium } = require('playwright');3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.screenshot({ path: 'google.png' });7 await browser.close();8})();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({ headless: false });4 const page = await browser.newPage();5 await page.evaluate(() => {6 window.playwright._internal.deleteAllCookies();7 });8 await page.screenshot({ path: 'test.png' });9 await browser.close();10})();
Using AI Code Generation
1const { Playwright } = require('playwright');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch({ headless: false });5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.click('text=Sign in');8 await page.waitForTimeout(3000);9 await page.type('input[name="identifier"]', 'testuser');10 await page.click('text=Next');11 await page.waitForTimeout(2000);12 await page.type('input[name="password"]', 'testpassword');13 await page.click('text=Next');14 await page.waitForTimeout(2000);15 await page.click('text=Sign in');16 await page.waitForTimeout(2000);17 await browser.close();18})();
Using AI Code Generation
1const { test, expect } = require('@playwright/test');2test('Playwright Internal API', async ({ page }) => {3 await page.waitForSelector('text=Get started');4 await page.click('text=Get started');5 await page.waitForSelector('text=Test your JavaScript code');6 await page.click('text=Test your JavaScript code');7 await page.waitForSelector('text=Install with npm');8 await page.click('text=Install with npm');9 await page.waitForSelector('text=Create a test file');10 await page.click('text=Create a test file');11 await page.waitForSelector('text=Run the test');12 await page.click('text=Run the test');13 await page.waitForSelector('text=Test your UI code');14 await page.click('text=Test your UI code');15 await page.waitForSelector('text=Install with npm');16 await page.click('text=Install with npm');17 await page.waitForSelector('text=Create a test file');18 await page.click('text=Create a test file');19 await page.waitForSelector('text=Run the test');20 await page.click('text=Run the test');21 await page.waitForSelector('text=Test your browser code');22 await page.click('text=Test your browser code');23 await page.waitForSelector('text=Install with npm');24 await page.click('text=Install with npm');25 await page.waitForSelector('text=Create a test file');26 await page.click('text=Create a test file');27 await page.waitForSelector('text=Run the test');28 await page.click('text=Run the test');29 await page.waitForSelector('text=Test your mobile app');30 await page.click('text=Test your mobile app');31 await page.waitForSelector('text=Install with npm');32 await page.click('text=Install with npm');33 await page.waitForSelector('text=Create a test file');34 await page.click('text=Create a test file');35 await page.waitForSelector('text=Run the test');36 await page.click('text=Run the test');37 await page.waitForSelector('text=Test your Electron app');38 await page.click('text=Test your Electron app');39 await page.waitForSelector('text=Install with npm');40 await page.click('text=Install with npm');41 await page.waitForSelector('text
Using AI Code Generation
1const { test, expect } = require('@playwright/test');2test('noop', async ({ page }) => {3 await page.route('**/*', route => route.fulfill({ body: 'Hello' }));4 expect(await page.textContent('.navbar__inner')).toContain('Hello');5});6MIT © [Rajat Sood](
Using AI Code Generation
1const { _test } = require('@playwright/test');2_test.use({ noOp: true });3const { test } = require('@playwright/test');4test.use({ noOp: true });5const { test } = require('@playwright/test');6test.use({7 browser: async ({}, use) => {8 const browser = await chromium.launch();9 await use(browser);10 await browser.close();11 },12});13test('test 1', async ({ browser }) => {14 const page = await browser.newPage();15});16test('test 2', async ({ browser }) => {17 const page = await browser.newPage();18});19const { test } = require('@playwright/test');20test.use({21 { value: 'chromium', name: 'Chromium' },22 { value: 'firefox', name: 'Firefox' },23 { value: 'webkit', name: 'WebKit' },24});25test('test 1', async ({ browserName }) => {26 const browser = await browsers[browserName].launch();27 const page = await browser.newPage();28 await browser.close();29});
Using AI Code Generation
1const { webkit, devices } = require('playwright');2const iPhone = devices['iPhone 6'];3(async () => {4 const browser = await webkit.launch({5 });6 const context = await browser.newContext({7 geolocation: { longitude: 12.492507, latitude: 41.889938 },8 });9 const page = await context.newPage();10 await page.click('text="Your location"');11 await page.waitForTimeout(10000);12 await browser.close();13})();
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!