Best JavaScript code snippet using storybook-root
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
1import { noopDecorator } from 'storybook-root-decorator';2import { themeDecorator } from 'storybook-root-decorator';3import { withInfo } from '@storybook/addon-info';4import { withKnobs } from '@storybook/addon-knobs';5storiesOf('Button', module)6  .addDecorator(noopDecorator)7  .addDecorator(themeDecorator)8  .addDecorator(withInfo)9  .addDecorator(withKnobs)10  .add('with text', () => <Button>Hello Button</Button>)11  .add('with some emoji', () => <Button>😀 😎 👍 💯</Button>);12MIT © [shubham-singh](Using AI Code Generation
1import { noopDecorator } from 'storybook-root-decorator';2export default {3};4export const Test = () => <div>Test</div>;5module.exports = {6  stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],7};8MIT © [iamogbz](Using AI Code Generation
1import { noopDecorator } from 'storybook-root-decorator';2import { storiesOf } from '@storybook/react';3import { action } from '@storybook/addon-actions';4import { withKnobs, text, select } from '@storybook/addon-knobs';5import { withInfo } from '@storybook/addon-info';6import Button from './Button';7storiesOf('Button', module)8  .addDecorator(withKnobs)9  .add(10    withInfo('A very simple button')(() => (11      <Button onClick={action('clicked')}>12        {text('Label', 'Hello Button')}13  .add(14    withInfo('A very simple button')(() => (15      <Button onClick={action('clicked')}>16        {text('Label', '😀 😎 👍 💯')}17  .add(18    withInfo('A very simple button')(() => (19      <Button onClick={action('clicked')}>20        {text('Label', 'Button')}21  .add(22    withInfo('A very simple button')(() => (23      <Button onClick={action('clicked')}>24        {text('Label', 'Link')}25  .add(26    withInfo('A very simple button')(() => (27        onClick={action('clicked')}28        color={select('Color', ['primary', 'secondary'], 'primary')}29        {text('Label', 'Button')}30  );31MIT © [shubhamjha97](Using AI Code Generation
1import { noop } from "storybook-root";2import { noop } from "storybook-root";3import { noop } from "storybook-root";4import { noop } from "storybook-root";5import { noop } from "storybook-root";6import { noop } from "storybook-root";7import { noop } from "storybook-root";8import { noop } from "storybook-root";9import { noop } from "storybook-root";10import { noop } from "storybook-root";11import { noop } from "storybook-root";12import { noop } from "storybook-root";13import { noop } from "storybook-root";14import { noop } from "storybook-root";15import { noop } from "storybook-root";16import { noop } from "storybook-root";17import { noop } from "storybook-root";18import { noop } from "storybook-root";19import { noop } from "storybook-root";20import { noop } from "storybook-root";21import { noop } from "storybook-root";22import { noop } from "storybook-root";Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
