You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							215 lines
						
					
					
						
							5.7 KiB
						
					
					
				
			
		
		
	
	
							215 lines
						
					
					
						
							5.7 KiB
						
					
					
				/** | 
						|
 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. | 
						|
 * | 
						|
 * This source code is licensed under the MIT license found in the | 
						|
 * LICENSE file in the root directory of this source tree. | 
						|
 */ | 
						|
 | 
						|
import util from 'util'; | 
						|
 | 
						|
const chalk = require('chalk'); | 
						|
const React = require('react'); | 
						|
const ReactTestRenderer = require('react-test-renderer'); | 
						|
const leftPad = require('left-pad'); | 
						|
const prettyFormat = require('../build'); | 
						|
const ReactTestComponent = require('../build/plugins/ReactTestComponent'); | 
						|
const worldGeoJson = require('./world.geo.json'); | 
						|
 | 
						|
const NANOSECONDS = 1000000000; | 
						|
let TIMES_TO_RUN = 100000; | 
						|
 | 
						|
function testCase(name, fn) { | 
						|
  let result, error, time, total; | 
						|
 | 
						|
  try { | 
						|
    result = fn(); | 
						|
  } catch (err) { | 
						|
    error = err; | 
						|
  } | 
						|
 | 
						|
  if (!error) { | 
						|
    const start = process.hrtime(); | 
						|
 | 
						|
    for (let i = 0; i < TIMES_TO_RUN; i++) { | 
						|
      fn(); | 
						|
    } | 
						|
 | 
						|
    const diff = process.hrtime(start); | 
						|
 | 
						|
    total = diff[0] * 1e9 + diff[1]; | 
						|
    time = Math.round(total / TIMES_TO_RUN); | 
						|
  } | 
						|
 | 
						|
  return { | 
						|
    error, | 
						|
    name, | 
						|
    result, | 
						|
    time, | 
						|
    total, | 
						|
  }; | 
						|
} | 
						|
 | 
						|
function test(name, value, ignoreResult, prettyFormatOpts) { | 
						|
  const formatted = testCase('prettyFormat()  ', () => | 
						|
    prettyFormat(value, prettyFormatOpts), | 
						|
  ); | 
						|
 | 
						|
  const inspected = testCase('util.inspect()  ', () => | 
						|
    util.inspect(value, { | 
						|
      depth: null, | 
						|
      showHidden: true, | 
						|
    }), | 
						|
  ); | 
						|
 | 
						|
  const stringified = testCase('JSON.stringify()', () => | 
						|
    JSON.stringify(value, null, '  '), | 
						|
  ); | 
						|
 | 
						|
  const results = [formatted, inspected, stringified].sort( | 
						|
    (a, b) => a.time - b.time, | 
						|
  ); | 
						|
 | 
						|
  const winner = results[0]; | 
						|
 | 
						|
  results.forEach((item, index) => { | 
						|
    item.isWinner = index === 0; | 
						|
    item.isLoser = index === results.length - 1; | 
						|
  }); | 
						|
 | 
						|
  function log(current) { | 
						|
    let message = current.name; | 
						|
 | 
						|
    if (current.time) { | 
						|
      message += ' - ' + leftPad(current.time, 6) + 'ns'; | 
						|
    } | 
						|
    if (current.total) { | 
						|
      message += | 
						|
        ' - ' + | 
						|
        current.total / NANOSECONDS + | 
						|
        's total (' + | 
						|
        TIMES_TO_RUN + | 
						|
        ' runs)'; | 
						|
    } | 
						|
    if (current.error) { | 
						|
      message += ' - Error: ' + current.error.message; | 
						|
    } | 
						|
 | 
						|
    if (!ignoreResult && current.result) { | 
						|
      message += ' - ' + JSON.stringify(current.result); | 
						|
    } | 
						|
 | 
						|
    message = ' ' + message + ' '; | 
						|
 | 
						|
    if (current.error) { | 
						|
      message = chalk.dim(message); | 
						|
    } | 
						|
 | 
						|
    const diff = current.time - winner.time; | 
						|
 | 
						|
    if (diff > winner.time * 0.85) { | 
						|
      message = chalk.bgRed.black(message); | 
						|
    } else if (diff > winner.time * 0.65) { | 
						|
      message = chalk.bgYellow.black(message); | 
						|
    } else if (!current.error) { | 
						|
      message = chalk.bgGreen.black(message); | 
						|
    } else { | 
						|
      message = chalk.dim(message); | 
						|
    } | 
						|
 | 
						|
    console.log('  ' + message); | 
						|
  } | 
						|
 | 
						|
  console.log(name + ': '); | 
						|
  results.forEach(log); | 
						|
  console.log(); | 
						|
} | 
						|
 | 
						|
function returnArguments() { | 
						|
  return arguments; | 
						|
} | 
						|
 | 
						|
test('empty arguments', returnArguments()); | 
						|
test('arguments', returnArguments(1, 2, 3)); | 
						|
test('an empty array', []); | 
						|
test('an array with items', [1, 2, 3]); | 
						|
test('a typed array', new Uint32Array(3)); | 
						|
test('an array buffer', new ArrayBuffer(3)); | 
						|
test('a nested array', [[1, 2, 3]]); | 
						|
test('true', true); | 
						|
test('false', false); | 
						|
test('an error', new Error()); | 
						|
test('a typed error with a message', new TypeError('message')); | 
						|
/* eslint-disable no-new-func */ | 
						|
test('a function constructor', new Function()); | 
						|
/* eslint-enable no-new-func */ | 
						|
test('an anonymous function', () => {}); | 
						|
function named() {} | 
						|
test('a named function', named); | 
						|
test('Infinity', Infinity); | 
						|
test('-Infinity', -Infinity); | 
						|
test('an empty map', new Map()); | 
						|
const mapWithValues = new Map(); | 
						|
const mapWithNonStringKeys = new Map(); | 
						|
mapWithValues.set('prop1', 'value1'); | 
						|
mapWithValues.set('prop2', 'value2'); | 
						|
mapWithNonStringKeys.set({prop: 'value'}, {prop: 'value'}); | 
						|
test('a map with values', mapWithValues); | 
						|
test('a map with non-string keys', mapWithNonStringKeys); | 
						|
test('NaN', NaN); | 
						|
test('null', null); | 
						|
test('a number', 123); | 
						|
test('a date', new Date(10e11)); | 
						|
test('an empty object', {}); | 
						|
test('an object with properties', {prop1: 'value1', prop2: 'value2'}); | 
						|
const objectWithPropsAndSymbols = {prop: 'value1'}; | 
						|
objectWithPropsAndSymbols[Symbol('symbol1')] = 'value2'; | 
						|
objectWithPropsAndSymbols[Symbol('symbol2')] = 'value3'; | 
						|
test('an object with properties and symbols', objectWithPropsAndSymbols); | 
						|
test('an object with sorted properties', {a: 2, b: 1}); | 
						|
test('regular expressions from constructors', new RegExp('regexp')); | 
						|
test('regular expressions from literals', /regexp/gi); | 
						|
test('an empty set', new Set()); | 
						|
const setWithValues = new Set(); | 
						|
setWithValues.add('value1'); | 
						|
setWithValues.add('value2'); | 
						|
test('a set with values', setWithValues); | 
						|
test('a string', 'string'); | 
						|
test('a symbol', Symbol('symbol')); | 
						|
test('undefined', undefined); | 
						|
test('a WeakMap', new WeakMap()); | 
						|
test('a WeakSet', new WeakSet()); | 
						|
test('deeply nested objects', {prop: {prop: {prop: 'value'}}}); | 
						|
const circularReferences = {}; | 
						|
circularReferences.prop = circularReferences; | 
						|
test('circular references', circularReferences); | 
						|
const parallelReferencesInner = {}; | 
						|
const parallelReferences = { | 
						|
  prop1: parallelReferencesInner, | 
						|
  prop2: parallelReferencesInner, | 
						|
}; | 
						|
test('parallel references', parallelReferences); | 
						|
test('able to customize indent', {prop: 'value'}); | 
						|
const bigObj = {}; | 
						|
for (let i = 0; i < 50; i++) { | 
						|
  bigObj[i] = i; | 
						|
} | 
						|
test('big object', bigObj); | 
						|
 | 
						|
const element = React.createElement( | 
						|
  'div', | 
						|
  {onClick: () => {}, prop: {a: 1, b: 2}}, | 
						|
  React.createElement('div', {prop: {a: 1, b: 2}}), | 
						|
  React.createElement('div'), | 
						|
  React.createElement( | 
						|
    'div', | 
						|
    {prop: {a: 1, b: 2}}, | 
						|
    React.createElement('div', null, React.createElement('div')), | 
						|
  ), | 
						|
); | 
						|
 | 
						|
test('react', ReactTestRenderer.create(element).toJSON(), false, { | 
						|
  plugins: [ReactTestComponent], | 
						|
}); | 
						|
 | 
						|
TIMES_TO_RUN = 100; | 
						|
test('massive', worldGeoJson, true);
 | 
						|
 |