1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @emails react-core
    
  8.  */
    
  9. 
    
  10. 'use strict';
    
  11. 
    
  12. describe('toErrorDev', () => {
    
  13.   it('does not fail if a warning contains a stack', () => {
    
  14.     expect(() => {
    
  15.       if (__DEV__) {
    
  16.         console.error('Hello\n    in div');
    
  17.       }
    
  18.     }).toErrorDev('Hello');
    
  19.   });
    
  20. 
    
  21.   it('does not fail if all warnings contain a stack', () => {
    
  22.     expect(() => {
    
  23.       if (__DEV__) {
    
  24.         console.error('Hello\n    in div');
    
  25.         console.error('Good day\n    in div');
    
  26.         console.error('Bye\n    in div');
    
  27.       }
    
  28.     }).toErrorDev(['Hello', 'Good day', 'Bye']);
    
  29.   });
    
  30. 
    
  31.   it('does not fail if warnings without stack explicitly opt out', () => {
    
  32.     expect(() => {
    
  33.       if (__DEV__) {
    
  34.         console.error('Hello');
    
  35.       }
    
  36.     }).toErrorDev('Hello', {withoutStack: true});
    
  37.     expect(() => {
    
  38.       if (__DEV__) {
    
  39.         console.error('Hello');
    
  40.         console.error('Good day');
    
  41.         console.error('Bye');
    
  42.       }
    
  43.     }).toErrorDev(['Hello', 'Good day', 'Bye'], {withoutStack: true});
    
  44.   });
    
  45. 
    
  46.   it('does not fail when expected stack-less warning number matches the actual one', () => {
    
  47.     expect(() => {
    
  48.       if (__DEV__) {
    
  49.         console.error('Hello\n    in div');
    
  50.         console.error('Good day');
    
  51.         console.error('Bye\n    in div');
    
  52.       }
    
  53.     }).toErrorDev(['Hello', 'Good day', 'Bye'], {withoutStack: 1});
    
  54.   });
    
  55. 
    
  56.   if (__DEV__) {
    
  57.     // Helper methods avoids invalid toWarn().toThrow() nesting
    
  58.     // See no-to-warn-dev-within-to-throw
    
  59.     const expectToWarnAndToThrow = (expectBlock, expectedErrorMessage) => {
    
  60.       let caughtError;
    
  61.       try {
    
  62.         expectBlock();
    
  63.       } catch (error) {
    
  64.         caughtError = error;
    
  65.       }
    
  66.       expect(caughtError).toBeDefined();
    
  67.       expect(caughtError.message).toContain(expectedErrorMessage);
    
  68.     };
    
  69. 
    
  70.     it('fails if a warning does not contain a stack', () => {
    
  71.       expectToWarnAndToThrow(() => {
    
  72.         expect(() => {
    
  73.           console.error('Hello');
    
  74.         }).toErrorDev('Hello');
    
  75.       }, 'Received warning unexpectedly does not include a component stack');
    
  76.     });
    
  77. 
    
  78.     it('fails if some warnings do not contain a stack', () => {
    
  79.       expectToWarnAndToThrow(() => {
    
  80.         expect(() => {
    
  81.           console.error('Hello\n    in div');
    
  82.           console.error('Good day\n    in div');
    
  83.           console.error('Bye');
    
  84.         }).toErrorDev(['Hello', 'Good day', 'Bye']);
    
  85.       }, 'Received warning unexpectedly does not include a component stack');
    
  86.       expectToWarnAndToThrow(() => {
    
  87.         expect(() => {
    
  88.           console.error('Hello');
    
  89.           console.error('Good day\n    in div');
    
  90.           console.error('Bye\n    in div');
    
  91.         }).toErrorDev(['Hello', 'Good day', 'Bye']);
    
  92.       }, 'Received warning unexpectedly does not include a component stack');
    
  93.       expectToWarnAndToThrow(() => {
    
  94.         expect(() => {
    
  95.           console.error('Hello\n    in div');
    
  96.           console.error('Good day');
    
  97.           console.error('Bye\n    in div');
    
  98.         }).toErrorDev(['Hello', 'Good day', 'Bye']);
    
  99.       }, 'Received warning unexpectedly does not include a component stack');
    
  100.       expectToWarnAndToThrow(() => {
    
  101.         expect(() => {
    
  102.           console.error('Hello');
    
  103.           console.error('Good day');
    
  104.           console.error('Bye');
    
  105.         }).toErrorDev(['Hello', 'Good day', 'Bye']);
    
  106.       }, 'Received warning unexpectedly does not include a component stack');
    
  107.     });
    
  108. 
    
  109.     it('fails if warning is expected to not have a stack, but does', () => {
    
  110.       expectToWarnAndToThrow(() => {
    
  111.         expect(() => {
    
  112.           console.error('Hello\n    in div');
    
  113.         }).toErrorDev('Hello', {withoutStack: true});
    
  114.       }, 'Received warning unexpectedly includes a component stack');
    
  115.       expectToWarnAndToThrow(() => {
    
  116.         expect(() => {
    
  117.           console.error('Hello\n    in div');
    
  118.           console.error('Good day');
    
  119.           console.error('Bye\n    in div');
    
  120.         }).toErrorDev(['Hello', 'Good day', 'Bye'], {withoutStack: true});
    
  121.       }, 'Received warning unexpectedly includes a component stack');
    
  122.     });
    
  123. 
    
  124.     it('fails if expected stack-less warning number does not match the actual one', () => {
    
  125.       expectToWarnAndToThrow(() => {
    
  126.         expect(() => {
    
  127.           console.error('Hello\n    in div');
    
  128.           console.error('Good day');
    
  129.           console.error('Bye\n    in div');
    
  130.         }).toErrorDev(['Hello', 'Good day', 'Bye'], {withoutStack: 4});
    
  131.       }, 'Expected 4 warnings without a component stack but received 1');
    
  132.     });
    
  133. 
    
  134.     it('fails if withoutStack is invalid', () => {
    
  135.       expectToWarnAndToThrow(() => {
    
  136.         expect(() => {
    
  137.           console.error('Hi');
    
  138.         }).toErrorDev('Hi', {withoutStack: null});
    
  139.       }, 'Instead received object');
    
  140.       expectToWarnAndToThrow(() => {
    
  141.         expect(() => {
    
  142.           console.error('Hi');
    
  143.         }).toErrorDev('Hi', {withoutStack: {}});
    
  144.       }, 'Instead received object');
    
  145.       expectToWarnAndToThrow(() => {
    
  146.         expect(() => {
    
  147.           console.error('Hi');
    
  148.         }).toErrorDev('Hi', {withoutStack: 'haha'});
    
  149.       }, 'Instead received string');
    
  150.     });
    
  151. 
    
  152.     it('fails if the argument number does not match', () => {
    
  153.       expectToWarnAndToThrow(() => {
    
  154.         expect(() => {
    
  155.           console.error('Hi %s', 'Sara', 'extra');
    
  156.         }).toErrorDev('Hi', {withoutStack: true});
    
  157.       }, 'Received 2 arguments for a message with 1 placeholders');
    
  158. 
    
  159.       expectToWarnAndToThrow(() => {
    
  160.         expect(() => {
    
  161.           console.error('Hi %s');
    
  162.         }).toErrorDev('Hi', {withoutStack: true});
    
  163.       }, 'Received 0 arguments for a message with 1 placeholders');
    
  164.     });
    
  165. 
    
  166.     it('fails if stack is passed twice', () => {
    
  167.       expectToWarnAndToThrow(() => {
    
  168.         expect(() => {
    
  169.           console.error('Hi %s%s', '\n    in div', '\n    in div');
    
  170.         }).toErrorDev('Hi');
    
  171.       }, 'Received more than one component stack for a warning');
    
  172.     });
    
  173. 
    
  174.     it('fails if multiple strings are passed without an array wrapper', () => {
    
  175.       expectToWarnAndToThrow(() => {
    
  176.         expect(() => {
    
  177.           console.error('Hi \n    in div');
    
  178.         }).toErrorDev('Hi', 'Bye');
    
  179.       }, 'toErrorDev() second argument, when present, should be an object');
    
  180.       expectToWarnAndToThrow(() => {
    
  181.         expect(() => {
    
  182.           console.error('Hi \n    in div');
    
  183.           console.error('Bye \n    in div');
    
  184.         }).toErrorDev('Hi', 'Bye');
    
  185.       }, 'toErrorDev() second argument, when present, should be an object');
    
  186.       expectToWarnAndToThrow(() => {
    
  187.         expect(() => {
    
  188.           console.error('Hi \n    in div');
    
  189.           console.error('Wow \n    in div');
    
  190.           console.error('Bye \n    in div');
    
  191.         }).toErrorDev('Hi', 'Bye');
    
  192.       }, 'toErrorDev() second argument, when present, should be an object');
    
  193.       expectToWarnAndToThrow(() => {
    
  194.         expect(() => {
    
  195.           console.error('Hi \n    in div');
    
  196.           console.error('Wow \n    in div');
    
  197.           console.error('Bye \n    in div');
    
  198.         }).toErrorDev('Hi', 'Wow', 'Bye');
    
  199.       }, 'toErrorDev() second argument, when present, should be an object');
    
  200.     });
    
  201. 
    
  202.     it('fails on more than two arguments', () => {
    
  203.       expectToWarnAndToThrow(() => {
    
  204.         expect(() => {
    
  205.           console.error('Hi \n    in div');
    
  206.           console.error('Wow \n    in div');
    
  207.           console.error('Bye \n    in div');
    
  208.         }).toErrorDev('Hi', undefined, 'Bye');
    
  209.       }, 'toErrorDev() received more than two arguments.');
    
  210.     });
    
  211.   }
    
  212. });
    
  213. 
    
  214. describe('toWarnDev', () => {
    
  215.   it('does not fail if a warning contains a stack', () => {
    
  216.     expect(() => {
    
  217.       if (__DEV__) {
    
  218.         console.warn('Hello\n    in div');
    
  219.       }
    
  220.     }).toWarnDev('Hello');
    
  221.   });
    
  222. 
    
  223.   it('does not fail if all warnings contain a stack', () => {
    
  224.     expect(() => {
    
  225.       if (__DEV__) {
    
  226.         console.warn('Hello\n    in div');
    
  227.         console.warn('Good day\n    in div');
    
  228.         console.warn('Bye\n    in div');
    
  229.       }
    
  230.     }).toWarnDev(['Hello', 'Good day', 'Bye']);
    
  231.   });
    
  232. 
    
  233.   it('does not fail if warnings without stack explicitly opt out', () => {
    
  234.     expect(() => {
    
  235.       if (__DEV__) {
    
  236.         console.warn('Hello');
    
  237.       }
    
  238.     }).toWarnDev('Hello', {withoutStack: true});
    
  239.     expect(() => {
    
  240.       if (__DEV__) {
    
  241.         console.warn('Hello');
    
  242.         console.warn('Good day');
    
  243.         console.warn('Bye');
    
  244.       }
    
  245.     }).toWarnDev(['Hello', 'Good day', 'Bye'], {withoutStack: true});
    
  246.   });
    
  247. 
    
  248.   it('does not fail when expected stack-less warning number matches the actual one', () => {
    
  249.     expect(() => {
    
  250.       if (__DEV__) {
    
  251.         console.warn('Hello\n    in div');
    
  252.         console.warn('Good day');
    
  253.         console.warn('Bye\n    in div');
    
  254.       }
    
  255.     }).toWarnDev(['Hello', 'Good day', 'Bye'], {withoutStack: 1});
    
  256.   });
    
  257. 
    
  258.   if (__DEV__) {
    
  259.     // Helper methods avoids invalid toWarn().toThrow() nesting
    
  260.     // See no-to-warn-dev-within-to-throw
    
  261.     const expectToWarnAndToThrow = (expectBlock, expectedErrorMessage) => {
    
  262.       let caughtError;
    
  263.       try {
    
  264.         expectBlock();
    
  265.       } catch (error) {
    
  266.         caughtError = error;
    
  267.       }
    
  268.       expect(caughtError).toBeDefined();
    
  269.       expect(caughtError.message).toContain(expectedErrorMessage);
    
  270.     };
    
  271. 
    
  272.     it('fails if a warning does not contain a stack', () => {
    
  273.       expectToWarnAndToThrow(() => {
    
  274.         expect(() => {
    
  275.           console.warn('Hello');
    
  276.         }).toWarnDev('Hello');
    
  277.       }, 'Received warning unexpectedly does not include a component stack');
    
  278.     });
    
  279. 
    
  280.     it('fails if some warnings do not contain a stack', () => {
    
  281.       expectToWarnAndToThrow(() => {
    
  282.         expect(() => {
    
  283.           console.warn('Hello\n    in div');
    
  284.           console.warn('Good day\n    in div');
    
  285.           console.warn('Bye');
    
  286.         }).toWarnDev(['Hello', 'Good day', 'Bye']);
    
  287.       }, 'Received warning unexpectedly does not include a component stack');
    
  288.       expectToWarnAndToThrow(() => {
    
  289.         expect(() => {
    
  290.           console.warn('Hello');
    
  291.           console.warn('Good day\n    in div');
    
  292.           console.warn('Bye\n    in div');
    
  293.         }).toWarnDev(['Hello', 'Good day', 'Bye']);
    
  294.       }, 'Received warning unexpectedly does not include a component stack');
    
  295.       expectToWarnAndToThrow(() => {
    
  296.         expect(() => {
    
  297.           console.warn('Hello\n    in div');
    
  298.           console.warn('Good day');
    
  299.           console.warn('Bye\n    in div');
    
  300.         }).toWarnDev(['Hello', 'Good day', 'Bye']);
    
  301.       }, 'Received warning unexpectedly does not include a component stack');
    
  302.       expectToWarnAndToThrow(() => {
    
  303.         expect(() => {
    
  304.           console.warn('Hello');
    
  305.           console.warn('Good day');
    
  306.           console.warn('Bye');
    
  307.         }).toWarnDev(['Hello', 'Good day', 'Bye']);
    
  308.       }, 'Received warning unexpectedly does not include a component stack');
    
  309.     });
    
  310. 
    
  311.     it('fails if warning is expected to not have a stack, but does', () => {
    
  312.       expectToWarnAndToThrow(() => {
    
  313.         expect(() => {
    
  314.           console.warn('Hello\n    in div');
    
  315.         }).toWarnDev('Hello', {withoutStack: true});
    
  316.       }, 'Received warning unexpectedly includes a component stack');
    
  317.       expectToWarnAndToThrow(() => {
    
  318.         expect(() => {
    
  319.           console.warn('Hello\n    in div');
    
  320.           console.warn('Good day');
    
  321.           console.warn('Bye\n    in div');
    
  322.         }).toWarnDev(['Hello', 'Good day', 'Bye'], {
    
  323.           withoutStack: true,
    
  324.         });
    
  325.       }, 'Received warning unexpectedly includes a component stack');
    
  326.     });
    
  327. 
    
  328.     it('fails if expected stack-less warning number does not match the actual one', () => {
    
  329.       expectToWarnAndToThrow(() => {
    
  330.         expect(() => {
    
  331.           console.warn('Hello\n    in div');
    
  332.           console.warn('Good day');
    
  333.           console.warn('Bye\n    in div');
    
  334.         }).toWarnDev(['Hello', 'Good day', 'Bye'], {
    
  335.           withoutStack: 4,
    
  336.         });
    
  337.       }, 'Expected 4 warnings without a component stack but received 1');
    
  338.     });
    
  339. 
    
  340.     it('fails if withoutStack is invalid', () => {
    
  341.       expectToWarnAndToThrow(() => {
    
  342.         expect(() => {
    
  343.           console.warn('Hi');
    
  344.         }).toWarnDev('Hi', {withoutStack: null});
    
  345.       }, 'Instead received object');
    
  346.       expectToWarnAndToThrow(() => {
    
  347.         expect(() => {
    
  348.           console.warn('Hi');
    
  349.         }).toWarnDev('Hi', {withoutStack: {}});
    
  350.       }, 'Instead received object');
    
  351.       expectToWarnAndToThrow(() => {
    
  352.         expect(() => {
    
  353.           console.warn('Hi');
    
  354.         }).toWarnDev('Hi', {withoutStack: 'haha'});
    
  355.       }, 'Instead received string');
    
  356.     });
    
  357. 
    
  358.     it('fails if the argument number does not match', () => {
    
  359.       expectToWarnAndToThrow(() => {
    
  360.         expect(() => {
    
  361.           console.warn('Hi %s', 'Sara', 'extra');
    
  362.         }).toWarnDev('Hi', {withoutStack: true});
    
  363.       }, 'Received 2 arguments for a message with 1 placeholders');
    
  364. 
    
  365.       expectToWarnAndToThrow(() => {
    
  366.         expect(() => {
    
  367.           console.warn('Hi %s');
    
  368.         }).toWarnDev('Hi', {withoutStack: true});
    
  369.       }, 'Received 0 arguments for a message with 1 placeholders');
    
  370.     });
    
  371. 
    
  372.     it('fails if stack is passed twice', () => {
    
  373.       expectToWarnAndToThrow(() => {
    
  374.         expect(() => {
    
  375.           console.warn('Hi %s%s', '\n    in div', '\n    in div');
    
  376.         }).toWarnDev('Hi');
    
  377.       }, 'Received more than one component stack for a warning');
    
  378.     });
    
  379. 
    
  380.     it('fails if multiple strings are passed without an array wrapper', () => {
    
  381.       expectToWarnAndToThrow(() => {
    
  382.         expect(() => {
    
  383.           console.warn('Hi \n    in div');
    
  384.         }).toWarnDev('Hi', 'Bye');
    
  385.       }, 'toWarnDev() second argument, when present, should be an object');
    
  386.       expectToWarnAndToThrow(() => {
    
  387.         expect(() => {
    
  388.           console.warn('Hi \n    in div');
    
  389.           console.warn('Bye \n    in div');
    
  390.         }).toWarnDev('Hi', 'Bye');
    
  391.       }, 'toWarnDev() second argument, when present, should be an object');
    
  392.       expectToWarnAndToThrow(() => {
    
  393.         expect(() => {
    
  394.           console.warn('Hi \n    in div');
    
  395.           console.warn('Wow \n    in div');
    
  396.           console.warn('Bye \n    in div');
    
  397.         }).toWarnDev('Hi', 'Bye');
    
  398.       }, 'toWarnDev() second argument, when present, should be an object');
    
  399.       expectToWarnAndToThrow(() => {
    
  400.         expect(() => {
    
  401.           console.warn('Hi \n    in div');
    
  402.           console.warn('Wow \n    in div');
    
  403.           console.warn('Bye \n    in div');
    
  404.         }).toWarnDev('Hi', 'Wow', 'Bye');
    
  405.       }, 'toWarnDev() second argument, when present, should be an object');
    
  406.     });
    
  407. 
    
  408.     it('fails on more than two arguments', () => {
    
  409.       expectToWarnAndToThrow(() => {
    
  410.         expect(() => {
    
  411.           console.warn('Hi \n    in div');
    
  412.           console.warn('Wow \n    in div');
    
  413.           console.warn('Bye \n    in div');
    
  414.         }).toWarnDev('Hi', undefined, 'Bye');
    
  415.       }, 'toWarnDev() received more than two arguments.');
    
  416.     });
    
  417.   }
    
  418. });