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. let React;
    
  13. let ReactDOM;
    
  14. 
    
  15. describe('Component stack trace displaying', () => {
    
  16.   beforeEach(() => {
    
  17.     React = require('react');
    
  18.     ReactDOM = require('react-dom');
    
  19.   });
    
  20. 
    
  21.   // @gate !enableComponentStackLocations || !__DEV__
    
  22.   it('should provide filenames in stack traces', () => {
    
  23.     class Component extends React.Component {
    
  24.       render() {
    
  25.         return [<span>a</span>, <span>b</span>];
    
  26.       }
    
  27.     }
    
  28. 
    
  29.     spyOnDev(console, 'error');
    
  30.     const container = document.createElement('div');
    
  31.     const fileNames = {
    
  32.       '': '',
    
  33.       '/': '',
    
  34.       '\\': '',
    
  35.       Foo: 'Foo',
    
  36.       'Bar/Foo': 'Foo',
    
  37.       'Bar\\Foo': 'Foo',
    
  38.       'Baz/Bar/Foo': 'Foo',
    
  39.       'Baz\\Bar\\Foo': 'Foo',
    
  40. 
    
  41.       'Foo.js': 'Foo.js',
    
  42.       'Foo.jsx': 'Foo.jsx',
    
  43.       '/Foo.js': 'Foo.js',
    
  44.       '/Foo.jsx': 'Foo.jsx',
    
  45.       '\\Foo.js': 'Foo.js',
    
  46.       '\\Foo.jsx': 'Foo.jsx',
    
  47.       'Bar/Foo.js': 'Foo.js',
    
  48.       'Bar/Foo.jsx': 'Foo.jsx',
    
  49.       'Bar\\Foo.js': 'Foo.js',
    
  50.       'Bar\\Foo.jsx': 'Foo.jsx',
    
  51.       '/Bar/Foo.js': 'Foo.js',
    
  52.       '/Bar/Foo.jsx': 'Foo.jsx',
    
  53.       '\\Bar\\Foo.js': 'Foo.js',
    
  54.       '\\Bar\\Foo.jsx': 'Foo.jsx',
    
  55.       'Bar/Baz/Foo.js': 'Foo.js',
    
  56.       'Bar/Baz/Foo.jsx': 'Foo.jsx',
    
  57.       'Bar\\Baz\\Foo.js': 'Foo.js',
    
  58.       'Bar\\Baz\\Foo.jsx': 'Foo.jsx',
    
  59.       '/Bar/Baz/Foo.js': 'Foo.js',
    
  60.       '/Bar/Baz/Foo.jsx': 'Foo.jsx',
    
  61.       '\\Bar\\Baz\\Foo.js': 'Foo.js',
    
  62.       '\\Bar\\Baz\\Foo.jsx': 'Foo.jsx',
    
  63.       'C:\\funny long (path)/Foo.js': 'Foo.js',
    
  64.       'C:\\funny long (path)/Foo.jsx': 'Foo.jsx',
    
  65. 
    
  66.       'index.js': 'index.js',
    
  67.       'index.jsx': 'index.jsx',
    
  68.       '/index.js': 'index.js',
    
  69.       '/index.jsx': 'index.jsx',
    
  70.       '\\index.js': 'index.js',
    
  71.       '\\index.jsx': 'index.jsx',
    
  72.       'Bar/index.js': 'Bar/index.js',
    
  73.       'Bar/index.jsx': 'Bar/index.jsx',
    
  74.       'Bar\\index.js': 'Bar/index.js',
    
  75.       'Bar\\index.jsx': 'Bar/index.jsx',
    
  76.       '/Bar/index.js': 'Bar/index.js',
    
  77.       '/Bar/index.jsx': 'Bar/index.jsx',
    
  78.       '\\Bar\\index.js': 'Bar/index.js',
    
  79.       '\\Bar\\index.jsx': 'Bar/index.jsx',
    
  80.       'Bar/Baz/index.js': 'Baz/index.js',
    
  81.       'Bar/Baz/index.jsx': 'Baz/index.jsx',
    
  82.       'Bar\\Baz\\index.js': 'Baz/index.js',
    
  83.       'Bar\\Baz\\index.jsx': 'Baz/index.jsx',
    
  84.       '/Bar/Baz/index.js': 'Baz/index.js',
    
  85.       '/Bar/Baz/index.jsx': 'Baz/index.jsx',
    
  86.       '\\Bar\\Baz\\index.js': 'Baz/index.js',
    
  87.       '\\Bar\\Baz\\index.jsx': 'Baz/index.jsx',
    
  88.       'C:\\funny long (path)/index.js': 'funny long (path)/index.js',
    
  89.       'C:\\funny long (path)/index.jsx': 'funny long (path)/index.jsx',
    
  90.     };
    
  91.     Object.keys(fileNames).forEach((fileName, i) => {
    
  92.       Component.displayName = 'Component ' + i;
    
  93.       ReactDOM.render(
    
  94.         <Component __source={{fileName, lineNumber: i}} />,
    
  95.         container,
    
  96.       );
    
  97.     });
    
  98.     if (__DEV__) {
    
  99.       let i = 0;
    
  100.       expect(console.error).toHaveBeenCalledTimes(
    
  101.         Object.keys(fileNames).length,
    
  102.       );
    
  103.       for (const fileName in fileNames) {
    
  104.         if (!fileNames.hasOwnProperty(fileName)) {
    
  105.           continue;
    
  106.         }
    
  107.         const args = console.error.mock.calls[i];
    
  108.         const stack = args[args.length - 1];
    
  109.         const expected = fileNames[fileName];
    
  110.         expect(stack).toContain(`at ${expected}:`);
    
  111.         i++;
    
  112.       }
    
  113.     }
    
  114.   });
    
  115. });