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('textUsing 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!!
