pretty-format
Advanced tools
+426
| /** | ||
| * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. | ||
| * | ||
| * This source code is licensed under the BSD-style license found in the | ||
| * LICENSE file in the root directory of this source tree. An additional grant | ||
| * of patent rights can be found in the PATENTS file in the same directory. | ||
| */ | ||
| /* eslint-disable max-len */ | ||
| 'use strict'; | ||
| const style = require('ansi-styles'); | ||
| const printString = require('./printString'); | ||
| const toString = Object.prototype.toString; | ||
| const toISOString = Date.prototype.toISOString; | ||
| const errorToString = Error.prototype.toString; | ||
| const regExpToString = RegExp.prototype.toString; | ||
| const symbolToString = Symbol.prototype.toString; | ||
| const SYMBOL_REGEXP = /^Symbol\((.*)\)(.*)$/; | ||
| const NEWLINE_REGEXP = /\n/ig; | ||
| const getSymbols = Object.getOwnPropertySymbols || (obj => []); | ||
| function isToStringedArrayType(toStringed) { | ||
| return ( | ||
| toStringed === '[object Array]' || | ||
| toStringed === '[object ArrayBuffer]' || | ||
| toStringed === '[object DataView]' || | ||
| toStringed === '[object Float32Array]' || | ||
| toStringed === '[object Float64Array]' || | ||
| toStringed === '[object Int8Array]' || | ||
| toStringed === '[object Int16Array]' || | ||
| toStringed === '[object Int32Array]' || | ||
| toStringed === '[object Uint8Array]' || | ||
| toStringed === '[object Uint8ClampedArray]' || | ||
| toStringed === '[object Uint16Array]' || | ||
| toStringed === '[object Uint32Array]'); | ||
| } | ||
| function printNumber(val) { | ||
| if (val != +val) { | ||
| return 'NaN'; | ||
| } | ||
| const isNegativeZero = val === 0 && 1 / val < 0; | ||
| return isNegativeZero ? '-0' : '' + val; | ||
| } | ||
| function printFunction(val, printFunctionName) { | ||
| if (!printFunctionName) { | ||
| return '[Function]'; | ||
| } else if (val.name === '') { | ||
| return '[Function anonymous]'; | ||
| } else { | ||
| return '[Function ' + val.name + ']'; | ||
| } | ||
| } | ||
| function printSymbol(val) { | ||
| return symbolToString.call(val).replace(SYMBOL_REGEXP, 'Symbol($1)'); | ||
| } | ||
| function printError(val) { | ||
| return '[' + errorToString.call(val) + ']'; | ||
| } | ||
| function printBasicValue(val, printFunctionName, escapeRegex) { | ||
| if (val === true || val === false) { | ||
| return '' + val; | ||
| } | ||
| if (val === undefined) { | ||
| return 'undefined'; | ||
| } | ||
| if (val === null) { | ||
| return 'null'; | ||
| } | ||
| const typeOf = typeof val; | ||
| if (typeOf === 'number') { | ||
| return printNumber(val); | ||
| } | ||
| if (typeOf === 'string') { | ||
| return '"' + printString(val) + '"'; | ||
| } | ||
| if (typeOf === 'function') { | ||
| return printFunction(val, printFunctionName); | ||
| } | ||
| if (typeOf === 'symbol') { | ||
| return printSymbol(val); | ||
| } | ||
| const toStringed = toString.call(val); | ||
| if (toStringed === '[object WeakMap]') { | ||
| return 'WeakMap {}'; | ||
| } | ||
| if (toStringed === '[object WeakSet]') { | ||
| return 'WeakSet {}'; | ||
| } | ||
| if (toStringed === '[object Function]' || toStringed === '[object GeneratorFunction]') { | ||
| return printFunction(val, printFunctionName); | ||
| } | ||
| if (toStringed === '[object Symbol]') { | ||
| return printSymbol(val); | ||
| } | ||
| if (toStringed === '[object Date]') { | ||
| return toISOString.call(val); | ||
| } | ||
| if (toStringed === '[object Error]') { | ||
| return printError(val); | ||
| } | ||
| if (toStringed === '[object RegExp]') { | ||
| if (escapeRegex) { | ||
| return printString(regExpToString.call(val)); | ||
| } | ||
| return regExpToString.call(val); | ||
| } | ||
| if (toStringed === '[object Arguments]' && val.length === 0) { | ||
| return 'Arguments []'; | ||
| } | ||
| if (isToStringedArrayType(toStringed) && val.length === 0) { | ||
| return val.constructor.name + ' []'; | ||
| } | ||
| if (val instanceof Error) { | ||
| return printError(val); | ||
| } | ||
| return false; | ||
| } | ||
| function printList(list, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors) { | ||
| let body = ''; | ||
| if (list.length) { | ||
| body += edgeSpacing; | ||
| const innerIndent = prevIndent + indent; | ||
| for (let i = 0; i < list.length; i++) { | ||
| body += innerIndent + print(list[i], indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| if (i < list.length - 1) { | ||
| body += ',' + spacing; | ||
| } | ||
| } | ||
| body += (min ? '' : ',') + edgeSpacing + prevIndent; | ||
| } | ||
| return '[' + body + ']'; | ||
| } | ||
| function printArguments(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors) { | ||
| return (min ? '' : 'Arguments ') + printList(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| } | ||
| function printArray(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors) { | ||
| return (min ? '' : val.constructor.name + ' ') + printList(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| } | ||
| function printMap(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors) { | ||
| let result = 'Map {'; | ||
| const iterator = val.entries(); | ||
| let current = iterator.next(); | ||
| if (!current.done) { | ||
| result += edgeSpacing; | ||
| const innerIndent = prevIndent + indent; | ||
| while (!current.done) { | ||
| const key = print(current.value[0], indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| const value = print(current.value[1], indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| result += innerIndent + key + ' => ' + value; | ||
| current = iterator.next(); | ||
| if (!current.done) { | ||
| result += ',' + spacing; | ||
| } | ||
| } | ||
| result += (min ? '' : ',') + edgeSpacing + prevIndent; | ||
| } | ||
| return result + '}'; | ||
| } | ||
| function printObject(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors) { | ||
| const constructor = min ? '' : val.constructor ? val.constructor.name + ' ' : 'Object '; | ||
| let result = constructor + '{'; | ||
| let keys = Object.keys(val).sort(); | ||
| const symbols = getSymbols(val); | ||
| if (symbols.length) { | ||
| keys = keys. | ||
| filter(key => !(typeof key === 'symbol' || toString.call(key) === '[object Symbol]')). | ||
| concat(symbols); | ||
| } | ||
| if (keys.length) { | ||
| result += edgeSpacing; | ||
| const innerIndent = prevIndent + indent; | ||
| for (let i = 0; i < keys.length; i++) { | ||
| const key = keys[i]; | ||
| const name = print(key, indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| const value = print(val[key], indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| result += innerIndent + name + ': ' + value; | ||
| if (i < keys.length - 1) { | ||
| result += ',' + spacing; | ||
| } | ||
| } | ||
| result += (min ? '' : ',') + edgeSpacing + prevIndent; | ||
| } | ||
| return result + '}'; | ||
| } | ||
| function printSet(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors) { | ||
| let result = 'Set {'; | ||
| const iterator = val.entries(); | ||
| let current = iterator.next(); | ||
| if (!current.done) { | ||
| result += edgeSpacing; | ||
| const innerIndent = prevIndent + indent; | ||
| while (!current.done) { | ||
| result += innerIndent + print(current.value[1], indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| current = iterator.next(); | ||
| if (!current.done) { | ||
| result += ',' + spacing; | ||
| } | ||
| } | ||
| result += (min ? '' : ',') + edgeSpacing + prevIndent; | ||
| } | ||
| return result + '}'; | ||
| } | ||
| function printComplexValue(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors) { | ||
| refs = refs.slice(); | ||
| if (refs.indexOf(val) > -1) { | ||
| return '[Circular]'; | ||
| } else { | ||
| refs.push(val); | ||
| } | ||
| currentDepth++; | ||
| const hitMaxDepth = currentDepth > maxDepth; | ||
| if (callToJSON && !hitMaxDepth && val.toJSON && typeof val.toJSON === 'function') { | ||
| return print(val.toJSON(), indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| } | ||
| const toStringed = toString.call(val); | ||
| if (toStringed === '[object Arguments]') { | ||
| return hitMaxDepth ? '[Arguments]' : printArguments(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| } else if (isToStringedArrayType(toStringed)) { | ||
| return hitMaxDepth ? '[Array]' : printArray(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| } else if (toStringed === '[object Map]') { | ||
| return hitMaxDepth ? '[Map]' : printMap(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| } else if (toStringed === '[object Set]') { | ||
| return hitMaxDepth ? '[Set]' : printSet(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| } | ||
| return hitMaxDepth ? '[Object]' : printObject(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| } | ||
| function printPlugin(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors) { | ||
| let match = false; | ||
| let plugin; | ||
| for (let p = 0; p < plugins.length; p++) { | ||
| plugin = plugins[p]; | ||
| if (plugin.test(val)) { | ||
| match = true; | ||
| break; | ||
| } | ||
| } | ||
| if (!match) { | ||
| return false; | ||
| } | ||
| function boundPrint(val) { | ||
| return print(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| } | ||
| function boundIndent(str) { | ||
| const indentation = prevIndent + indent; | ||
| return indentation + str.replace(NEWLINE_REGEXP, '\n' + indentation); | ||
| } | ||
| const opts = { | ||
| edgeSpacing, | ||
| spacing }; | ||
| return plugin.print(val, boundPrint, boundIndent, opts, colors); | ||
| } | ||
| function print(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors) { | ||
| const basic = printBasicValue(val, printFunctionName, escapeRegex); | ||
| if (basic) { | ||
| return basic; | ||
| } | ||
| const plugin = printPlugin(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| if (plugin) { | ||
| return plugin; | ||
| } | ||
| return printComplexValue(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex, colors); | ||
| } | ||
| const DEFAULTS = { | ||
| callToJSON: true, | ||
| escapeRegex: false, | ||
| highlight: false, | ||
| indent: 2, | ||
| maxDepth: Infinity, | ||
| min: false, | ||
| plugins: [], | ||
| printFunctionName: true, | ||
| theme: { | ||
| content: 'reset', | ||
| prop: 'yellow', | ||
| tag: 'cyan', | ||
| value: 'green' } }; | ||
| function validateOptions(opts) { | ||
| Object.keys(opts).forEach(key => { | ||
| if (!DEFAULTS.hasOwnProperty(key)) { | ||
| throw new Error('prettyFormat: Invalid option: ' + key); | ||
| } | ||
| }); | ||
| if (opts.min && opts.indent !== undefined && opts.indent !== 0) { | ||
| throw new Error('prettyFormat: Cannot run with min option and indent'); | ||
| } | ||
| } | ||
| function normalizeOptions(opts) { | ||
| const result = {}; | ||
| Object.keys(DEFAULTS).forEach(key => | ||
| result[key] = opts.hasOwnProperty(key) ? opts[key] : DEFAULTS[key]); | ||
| if (result.min) { | ||
| result.indent = 0; | ||
| } | ||
| return result; | ||
| } | ||
| function createIndent(indent) { | ||
| return new Array(indent + 1).join(' '); | ||
| } | ||
| function prettyFormat(val, opts) { | ||
| if (!opts) { | ||
| opts = DEFAULTS; | ||
| } else { | ||
| validateOptions(opts); | ||
| opts = normalizeOptions(opts); | ||
| } | ||
| const colors = {}; | ||
| Object.keys(opts.theme).forEach(key => { | ||
| if (opts.highlight) { | ||
| colors[key] = style[opts.theme[key]]; | ||
| } else { | ||
| colors[key] = { close: '', open: '' }; | ||
| } | ||
| }); | ||
| let indent; | ||
| let refs; | ||
| const prevIndent = ''; | ||
| const currentDepth = 0; | ||
| const spacing = opts.min ? ' ' : '\n'; | ||
| const edgeSpacing = opts.min ? '' : '\n'; | ||
| if (opts && opts.plugins.length) { | ||
| indent = createIndent(opts.indent); | ||
| refs = []; | ||
| const pluginsResult = printPlugin(val, indent, prevIndent, spacing, edgeSpacing, refs, opts.maxDepth, currentDepth, opts.plugins, opts.min, opts.callToJSON, opts.printFunctionName, opts.escapeRegex, colors); | ||
| if (pluginsResult) { | ||
| return pluginsResult; | ||
| } | ||
| } | ||
| const basicResult = printBasicValue(val, opts.printFunctionName, opts.escapeRegex); | ||
| if (basicResult) { | ||
| return basicResult; | ||
| } | ||
| if (!indent) { | ||
| indent = createIndent(opts.indent); | ||
| } | ||
| if (!refs) { | ||
| refs = []; | ||
| } | ||
| return printComplexValue(val, indent, prevIndent, spacing, edgeSpacing, refs, opts.maxDepth, currentDepth, opts.plugins, opts.min, opts.callToJSON, opts.printFunctionName, opts.escapeRegex, colors); | ||
| } | ||
| module.exports = prettyFormat; |
| /** | ||
| * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. | ||
| * | ||
| * This source code is licensed under the BSD-style license found in the | ||
| * LICENSE file in the root directory of this source tree. An additional grant | ||
| * of patent rights can be found in the PATENTS file in the same directory. | ||
| */ | ||
| /* eslint-disable max-len */ | ||
| 'use strict'; | ||
| const printString = require('../printString'); | ||
| const reactElement = Symbol.for('react.element'); | ||
| function traverseChildren(opaqueChildren, cb) { | ||
| if (Array.isArray(opaqueChildren)) { | ||
| opaqueChildren.forEach(child => traverseChildren(child, cb)); | ||
| } else if (opaqueChildren != null && opaqueChildren !== false) { | ||
| cb(opaqueChildren); | ||
| } | ||
| } | ||
| function printChildren(flatChildren, print, indent, colors, opts) { | ||
| return flatChildren.map(node => { | ||
| if (typeof node === 'object') { | ||
| return printElement(node, print, indent, colors, opts); | ||
| } else if (typeof node === 'string') { | ||
| return printString(colors.content.open + node + colors.content.close); | ||
| } else { | ||
| return print(node); | ||
| } | ||
| }).join(opts.edgeSpacing); | ||
| } | ||
| function printProps(props, print, indent, colors, opts) { | ||
| return Object.keys(props).sort().map(name => { | ||
| if (name === 'children') { | ||
| return ''; | ||
| } | ||
| const prop = props[name]; | ||
| let printed = print(prop); | ||
| if (typeof prop !== 'string') { | ||
| if (printed.indexOf('\n') !== -1) { | ||
| printed = '{' + opts.edgeSpacing + indent(indent(printed) + opts.edgeSpacing + '}'); | ||
| } else { | ||
| printed = '{' + printed + '}'; | ||
| } | ||
| } | ||
| return opts.spacing + indent(colors.prop.open + name + colors.prop.close + '=') + colors.value.open + printed + colors.value.close; | ||
| }).join(''); | ||
| } | ||
| function printElement(element, print, indent, colors, opts) { | ||
| let result = colors.tag.open + '<'; | ||
| let elementName; | ||
| if (typeof element.type === 'string') { | ||
| elementName = element.type; | ||
| } else if (typeof element.type === 'function') { | ||
| elementName = element.type.displayName || element.type.name || 'Unknown'; | ||
| } else { | ||
| elementName = 'Unknown'; | ||
| } | ||
| result += elementName + colors.tag.close; | ||
| result += printProps(element.props, print, indent, colors, opts); | ||
| const opaqueChildren = element.props.children; | ||
| if (opaqueChildren) { | ||
| const flatChildren = []; | ||
| traverseChildren(opaqueChildren, child => { | ||
| flatChildren.push(child); | ||
| }); | ||
| const children = printChildren(flatChildren, print, indent, colors, opts); | ||
| result += colors.tag.open + '>' + colors.tag.close + opts.edgeSpacing + indent(children) + opts.edgeSpacing + colors.tag.open + '</' + elementName + '>' + colors.tag.close; | ||
| } else { | ||
| result += colors.tag.open + ' />' + colors.tag.close; | ||
| } | ||
| return result; | ||
| } | ||
| module.exports = { | ||
| print(val, print, indent, opts, colors) { | ||
| return printElement(val, print, indent, colors, opts); | ||
| }, | ||
| test(object) { | ||
| return object && object.$$typeof === reactElement; | ||
| } }; |
| /** | ||
| * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. | ||
| * | ||
| * This source code is licensed under the BSD-style license found in the | ||
| * LICENSE file in the root directory of this source tree. An additional grant | ||
| * of patent rights can be found in the PATENTS file in the same directory. | ||
| */ | ||
| /* eslint-disable max-len */ | ||
| 'use strict'; | ||
| const printString = require('../printString'); | ||
| const reactTestInstance = Symbol.for('react.test.json'); | ||
| function printChildren(children, print, indent, colors, opts) { | ||
| return children.map(child => printInstance(child, print, indent, colors, opts)).join(opts.edgeSpacing); | ||
| } | ||
| function printProps(props, print, indent, colors, opts) { | ||
| return Object.keys(props).sort().map(name => { | ||
| const prop = props[name]; | ||
| let printed = print(prop); | ||
| if (typeof prop !== 'string') { | ||
| if (printed.indexOf('\n') !== -1) { | ||
| printed = '{' + opts.edgeSpacing + indent(indent(printed) + opts.edgeSpacing + '}'); | ||
| } else { | ||
| printed = '{' + printed + '}'; | ||
| } | ||
| } | ||
| return opts.spacing + indent(colors.prop.open + name + colors.prop.close + '=') + colors.value.open + printed + colors.value.close; | ||
| }).join(''); | ||
| } | ||
| function printInstance(instance, print, indent, colors, opts) { | ||
| if (typeof instance == 'number') { | ||
| return print(instance); | ||
| } else if (typeof instance === 'string') { | ||
| return printString(colors.content.open + instance + colors.content.close); | ||
| } | ||
| let result = colors.tag.open + '<' + instance.type + colors.tag.close; | ||
| if (instance.props) { | ||
| result += printProps(instance.props, print, indent, colors, opts); | ||
| } | ||
| if (instance.children) { | ||
| const children = printChildren(instance.children, print, indent, colors, opts); | ||
| result += colors.tag.open + '>' + colors.tag.close + opts.edgeSpacing + indent(children) + opts.edgeSpacing + colors.tag.open + '</' + instance.type + '>' + colors.tag.close; | ||
| } else { | ||
| result += colors.tag.open + ' />' + colors.tag.close; | ||
| } | ||
| return result; | ||
| } | ||
| module.exports = { | ||
| print(val, print, indent, opts, colors) { | ||
| return printInstance(val, print, indent, colors, opts); | ||
| }, | ||
| test(object) { | ||
| return object && object.$$typeof === reactTestInstance; | ||
| } }; |
| /** | ||
| * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. | ||
| * | ||
| * This source code is licensed under the BSD-style license found in the | ||
| * LICENSE file in the root directory of this source tree. An additional grant | ||
| * of patent rights can be found in the PATENTS file in the same directory. | ||
| */ | ||
| 'use strict'; | ||
| const ESCAPED_CHARACTERS = /(\\|\"|\')/g; | ||
| module.exports = val => val.replace(ESCAPED_CHARACTERS, '\\$1'); |
+215
| /** | ||
| * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. | ||
| * | ||
| * This source code is licensed under the BSD-style license found in the | ||
| * LICENSE file in the root directory of this source tree. An additional grant | ||
| * of patent rights can be found in the PATENTS file in the same directory. | ||
| */ | ||
| 'use strict'; | ||
| const prettyFormat = require('../build'); | ||
| const util = require('util'); | ||
| const chalk = require('chalk'); | ||
| const leftPad = require('left-pad'); | ||
| const worldGeoJson = require('./world.geo.json'); | ||
| const React = require('react'); | ||
| const ReactTestRenderer = require('react/lib/ReactTestRenderer'); | ||
| const ReactTestComponent = require('../build/plugins/ReactTestComponent'); | ||
| 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() ', () => { | ||
| return util.inspect(value, { | ||
| depth: null, | ||
| showHidden: true, | ||
| }); | ||
| }); | ||
| const stringified = testCase('JSON.stringify()', () => { | ||
| return JSON.stringify(value, null, ' '); | ||
| }); | ||
| const results = [formatted, inspected, stringified].sort((a, b) => { | ||
| return 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/ig); | ||
| 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); |
Sorry, the diff of this file is too big to display
+10
-17
| { | ||
| "name": "pretty-format", | ||
| "version": "4.3.1", | ||
| "version": "18.0.0", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/facebook/jest.git" | ||
| }, | ||
| "license": "BSD-3-Clause", | ||
| "description": "Stringify any JavaScript value.", | ||
| "license": "MIT", | ||
| "main": "index.js", | ||
| "main": "build/index.js", | ||
| "author": "James Kyle <me@thejameskyle.com>", | ||
| "keywords": [], | ||
| "repository": "https://github.com/thejameskyle/pretty-format.git", | ||
| "bugs": "https://github.com/thejameskyle/pretty-format/issues", | ||
| "homepage": "https://github.com/thejameskle/pretty-format", | ||
| "scripts": { | ||
| "test": "jest", | ||
| "test": "../../packages/jest-cli/bin/jest.js", | ||
| "perf": "node perf/test.js" | ||
| }, | ||
| "jest": { | ||
| "testEnvironment": "node", | ||
| "verbose": true | ||
| }, | ||
| "devDependencies": { | ||
| "chalk": "^1.1.3", | ||
| "jest": "^15.1.1", | ||
| "left-pad": "^1.1.1", | ||
| "react": "15.3.0" | ||
| "dependencies": { | ||
| "ansi-styles": "^2.2.1" | ||
| } | ||
| } |
+53
-14
@@ -1,2 +0,2 @@ | ||
| # pretty-format [](https://travis-ci.org/thejameskyle/pretty-format) | ||
| # pretty-format | ||
@@ -13,3 +13,3 @@ > Stringify any JavaScript value. | ||
| ```sh | ||
| $ npm install pretty-format | ||
| $ yarn add pretty-format | ||
| ``` | ||
@@ -20,3 +20,3 @@ | ||
| ```js | ||
| var prettyFormat = require('pretty-format'); | ||
| const prettyFormat = require('pretty-format'); | ||
@@ -55,2 +55,41 @@ var obj = { property: {} }; | ||
| ### API | ||
| ```js | ||
| console.log(prettyFormat(object)); | ||
| console.log(prettyFormat(object, options)); | ||
| ``` | ||
| Options: | ||
| * **`callToJSON`**<br> | ||
| Type: `boolean`, default: `true`<br> | ||
| Call `toJSON()` on passed object. | ||
| * **`indent`**<br> | ||
| Type: `number`, default: `2`<br> | ||
| Number of spaces for indentation. | ||
| * **`maxDepth`**<br> | ||
| Type: `number`, default: `Infinity`<br> | ||
| Print only this number of levels. | ||
| * **`min`**<br> | ||
| Type: `boolean`, default: `false`<br> | ||
| Print without whitespace. | ||
| * **`plugins`**<br> | ||
| Type: `array`, default: `[]`<br> | ||
| Plugins (see the next section). | ||
| * **`printFunctionName`**<br> | ||
| Type: `boolean`, default: `true`<br> | ||
| Print function names or just `[Function]`. | ||
| * **`escapeRegex`**<br> | ||
| Type: `boolean`, default: `false`<br> | ||
| Escape special characters in regular expressions. | ||
| * **`highlight`**<br> | ||
| Type: `boolean`, default: `false`<br> | ||
| Highlight syntax for terminal (works only with `ReactTestComponent` and `ReactElement` plugins. | ||
| * **`theme`**<br> | ||
| Type: `object`, default: `{tag: 'cyan', content: 'reset'...}`<br> | ||
| Syntax highlight theme.<br> | ||
| Uses [ansi-styles colors](https://github.com/chalk/ansi-styles#colors) + `reset` for no color.<br> | ||
| Available types: `tag`, `content`, `prop` and `value`. | ||
| ### Plugins | ||
@@ -61,7 +100,7 @@ | ||
| ```js | ||
| var fooPlugin = { | ||
| test: function(val) { | ||
| const fooPlugin = { | ||
| test(val) { | ||
| return val && val.hasOwnProperty('foo'); | ||
| }, | ||
| print: function(val, print, indent) { | ||
| print(val, print, indent) { | ||
| return 'Foo: ' + print(val.foo); | ||
@@ -71,3 +110,3 @@ } | ||
| var obj = { foo: { bar: {} } }; | ||
| const obj = {foo: {bar: {}}}; | ||
@@ -85,12 +124,12 @@ prettyFormat(obj, { | ||
| ```js | ||
| var prettyFormat = require('pretty-format'); | ||
| var reactTestPlugin = require('pretty-format/plugins/ReactTestComponent'); | ||
| var reactElementPlugin = require('pretty-format/plugins/ReactElement'); | ||
| const prettyFormat = require('pretty-format'); | ||
| const reactTestPlugin = require('pretty-format/build/plugins/ReactTestComponent'); | ||
| const reactElementPlugin = require('pretty-format/build/plugins/ReactElement'); | ||
| var React = require('react'); | ||
| var renderer = require('react/lib/ReactTestRenderer'); | ||
| const React = require('react'); | ||
| const renderer = require('react-test-renderer'); | ||
| var jsx = React.createElement('h1', null, 'Hello World'); | ||
| const element = React.createElement('h1', null, 'Hello World'); | ||
| prettyFormat(renderer.create(jsx).toJSON(), { | ||
| prettyFormat(renderer.create(element).toJSON(), { | ||
| plugins: [reactTestPlugin, reactElementPlugin] | ||
@@ -97,0 +136,0 @@ }); |
-353
| 'use strict'; | ||
| const printString = require('./printString'); | ||
| const toString = Object.prototype.toString; | ||
| const toISOString = Date.prototype.toISOString; | ||
| const errorToString = Error.prototype.toString; | ||
| const regExpToString = RegExp.prototype.toString; | ||
| const symbolToString = Symbol.prototype.toString; | ||
| const SYMBOL_REGEXP = /^Symbol\((.*)\)(.*)$/; | ||
| const NEWLINE_REGEXP = /\n/ig; | ||
| const getSymbols = Object.getOwnPropertySymbols || (obj => []); | ||
| function isToStringedArrayType(toStringed) { | ||
| return ( | ||
| toStringed === '[object Array]' || | ||
| toStringed === '[object ArrayBuffer]' || | ||
| toStringed === '[object DataView]' || | ||
| toStringed === '[object Float32Array]' || | ||
| toStringed === '[object Float64Array]' || | ||
| toStringed === '[object Int8Array]' || | ||
| toStringed === '[object Int16Array]' || | ||
| toStringed === '[object Int32Array]' || | ||
| toStringed === '[object Uint8Array]' || | ||
| toStringed === '[object Uint8ClampedArray]' || | ||
| toStringed === '[object Uint16Array]' || | ||
| toStringed === '[object Uint32Array]' | ||
| ); | ||
| } | ||
| function printNumber(val) { | ||
| if (val != +val) return 'NaN'; | ||
| const isNegativeZero = val === 0 && (1 / val) < 0; | ||
| return isNegativeZero ? '-0' : '' + val; | ||
| } | ||
| function printFunction(val, printFunctionName) { | ||
| if (!printFunctionName) { | ||
| return '[Function]'; | ||
| } else if (val.name === '') { | ||
| return '[Function anonymous]' | ||
| } else { | ||
| return '[Function ' + val.name + ']'; | ||
| } | ||
| } | ||
| function printSymbol(val) { | ||
| return symbolToString.call(val).replace(SYMBOL_REGEXP, 'Symbol($1)'); | ||
| } | ||
| function printError(val) { | ||
| return '[' + errorToString.call(val) + ']'; | ||
| } | ||
| function printBasicValue(val, printFunctionName, escapeRegex) { | ||
| if (val === true || val === false) return '' + val; | ||
| if (val === undefined) return 'undefined'; | ||
| if (val === null) return 'null'; | ||
| const typeOf = typeof val; | ||
| if (typeOf === 'number') return printNumber(val); | ||
| if (typeOf === 'string') return '"' + printString(val) + '"'; | ||
| if (typeOf === 'function') return printFunction(val, printFunctionName); | ||
| if (typeOf === 'symbol') return printSymbol(val); | ||
| const toStringed = toString.call(val); | ||
| if (toStringed === '[object WeakMap]') return 'WeakMap {}'; | ||
| if (toStringed === '[object WeakSet]') return 'WeakSet {}'; | ||
| if (toStringed === '[object Function]' || toStringed === '[object GeneratorFunction]') return printFunction(val, printFunctionName); | ||
| if (toStringed === '[object Symbol]') return printSymbol(val); | ||
| if (toStringed === '[object Date]') return toISOString.call(val); | ||
| if (toStringed === '[object Error]') return printError(val); | ||
| if (toStringed === '[object RegExp]') { | ||
| if (escapeRegex) { | ||
| return printString(regExpToString.call(val)); | ||
| } | ||
| return regExpToString.call(val); | ||
| }; | ||
| if (toStringed === '[object Arguments]' && val.length === 0) return 'Arguments []'; | ||
| if (isToStringedArrayType(toStringed) && val.length === 0) return val.constructor.name + ' []'; | ||
| if (val instanceof Error) return printError(val); | ||
| return false; | ||
| } | ||
| function printList(list, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex) { | ||
| let body = ''; | ||
| if (list.length) { | ||
| body += edgeSpacing; | ||
| const innerIndent = prevIndent + indent; | ||
| for (let i = 0; i < list.length; i++) { | ||
| body += innerIndent + print(list[i], indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| if (i < list.length - 1) { | ||
| body += ',' + spacing; | ||
| } | ||
| } | ||
| body += (min ? '' : ',') + edgeSpacing + prevIndent; | ||
| } | ||
| return '[' + body + ']'; | ||
| } | ||
| function printArguments(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex) { | ||
| return (min ? '' : 'Arguments ') + printList(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| } | ||
| function printArray(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex) { | ||
| return (min ? '' : val.constructor.name + ' ') + printList(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| } | ||
| function printMap(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex) { | ||
| let result = 'Map {'; | ||
| const iterator = val.entries(); | ||
| let current = iterator.next(); | ||
| if (!current.done) { | ||
| result += edgeSpacing; | ||
| const innerIndent = prevIndent + indent; | ||
| while (!current.done) { | ||
| const key = print(current.value[0], indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| const value = print(current.value[1], indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| result += innerIndent + key + ' => ' + value; | ||
| current = iterator.next(); | ||
| if (!current.done) { | ||
| result += ',' + spacing; | ||
| } | ||
| } | ||
| result += (min ? '' : ',') + edgeSpacing + prevIndent; | ||
| } | ||
| return result + '}'; | ||
| } | ||
| function printObject(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex) { | ||
| const constructor = min ? '' : (val.constructor ? val.constructor.name + ' ' : 'Object '); | ||
| let result = constructor + '{'; | ||
| let keys = Object.keys(val).sort(); | ||
| const symbols = getSymbols(val); | ||
| if (symbols.length) { | ||
| keys = keys | ||
| .filter(key => !(typeof key === 'symbol' || toString.call(key) === '[object Symbol]')) | ||
| .concat(symbols); | ||
| } | ||
| if (keys.length) { | ||
| result += edgeSpacing; | ||
| const innerIndent = prevIndent + indent; | ||
| for (let i = 0; i < keys.length; i++) { | ||
| const key = keys[i]; | ||
| const name = print(key, indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| const value = print(val[key], indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| result += innerIndent + name + ': ' + value; | ||
| if (i < keys.length - 1) { | ||
| result += ',' + spacing; | ||
| } | ||
| } | ||
| result += (min ? '' : ',') + edgeSpacing + prevIndent; | ||
| } | ||
| return result + '}'; | ||
| } | ||
| function printSet(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex) { | ||
| let result = 'Set {'; | ||
| const iterator = val.entries(); | ||
| let current = iterator.next(); | ||
| if (!current.done) { | ||
| result += edgeSpacing; | ||
| const innerIndent = prevIndent + indent; | ||
| while (!current.done) { | ||
| result += innerIndent + print(current.value[1], indent, innerIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| current = iterator.next(); | ||
| if (!current.done) { | ||
| result += ',' + spacing; | ||
| } | ||
| } | ||
| result += (min ? '' : ',') + edgeSpacing + prevIndent; | ||
| } | ||
| return result + '}'; | ||
| } | ||
| function printComplexValue(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex) { | ||
| refs = refs.slice(); | ||
| if (refs.indexOf(val) > -1) { | ||
| return '[Circular]'; | ||
| } else { | ||
| refs.push(val); | ||
| } | ||
| currentDepth++; | ||
| const hitMaxDepth = currentDepth > maxDepth; | ||
| if (callToJSON && !hitMaxDepth && val.toJSON && typeof val.toJSON === 'function') { | ||
| return print(val.toJSON(), indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| } | ||
| const toStringed = toString.call(val); | ||
| if (toStringed === '[object Arguments]') { | ||
| return hitMaxDepth ? '[Arguments]' : printArguments(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| } else if (isToStringedArrayType(toStringed)) { | ||
| return hitMaxDepth ? '[Array]' : printArray(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| } else if (toStringed === '[object Map]') { | ||
| return hitMaxDepth ? '[Map]' : printMap(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| } else if (toStringed === '[object Set]') { | ||
| return hitMaxDepth ? '[Set]' : printSet(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| } else if (typeof val === 'object') { | ||
| return hitMaxDepth ? '[Object]' : printObject(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| } | ||
| } | ||
| function printPlugin(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex) { | ||
| let match = false; | ||
| let plugin; | ||
| for (let p = 0; p < plugins.length; p++) { | ||
| plugin = plugins[p]; | ||
| if (plugin.test(val)) { | ||
| match = true; | ||
| break; | ||
| } | ||
| } | ||
| if (!match) { | ||
| return false; | ||
| } | ||
| function boundPrint(val) { | ||
| return print(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| } | ||
| function boundIndent(str) { | ||
| const indentation = prevIndent + indent; | ||
| return indentation + str.replace(NEWLINE_REGEXP, '\n' + indentation); | ||
| } | ||
| return plugin.print(val, boundPrint, boundIndent, { | ||
| edgeSpacing: edgeSpacing, | ||
| spacing: spacing | ||
| }); | ||
| } | ||
| function print(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex) { | ||
| const basic = printBasicValue(val, printFunctionName, escapeRegex); | ||
| if (basic) return basic; | ||
| const plugin = printPlugin(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| if (plugin) return plugin; | ||
| return printComplexValue(val, indent, prevIndent, spacing, edgeSpacing, refs, maxDepth, currentDepth, plugins, min, callToJSON, printFunctionName, escapeRegex); | ||
| } | ||
| const DEFAULTS = { | ||
| callToJSON: true, | ||
| indent: 2, | ||
| maxDepth: Infinity, | ||
| min: false, | ||
| plugins: [], | ||
| printFunctionName: true, | ||
| escapeRegex: false, | ||
| }; | ||
| function validateOptions(opts) { | ||
| Object.keys(opts).forEach(key => { | ||
| if (!DEFAULTS.hasOwnProperty(key)) { | ||
| throw new Error('prettyFormat: Invalid option: ' + key); | ||
| } | ||
| }); | ||
| if (opts.min && opts.indent !== undefined && opts.indent !== 0) { | ||
| throw new Error('prettyFormat: Cannot run with min option and indent'); | ||
| } | ||
| } | ||
| function normalizeOptions(opts) { | ||
| const result = {}; | ||
| Object.keys(DEFAULTS).forEach(key => | ||
| result[key] = opts.hasOwnProperty(key) ? opts[key] : DEFAULTS[key] | ||
| ); | ||
| if (result.min) { | ||
| result.indent = 0; | ||
| } | ||
| return result; | ||
| } | ||
| function createIndent(indent) { | ||
| return new Array(indent + 1).join(' '); | ||
| } | ||
| function prettyFormat(val, opts) { | ||
| if (!opts) { | ||
| opts = DEFAULTS; | ||
| } else { | ||
| validateOptions(opts) | ||
| opts = normalizeOptions(opts); | ||
| } | ||
| let indent; | ||
| let refs; | ||
| const prevIndent = ''; | ||
| const currentDepth = 0; | ||
| const spacing = opts.min ? ' ' : '\n'; | ||
| const edgeSpacing = opts.min ? '' : '\n'; | ||
| if (opts && opts.plugins.length) { | ||
| indent = createIndent(opts.indent); | ||
| refs = []; | ||
| var pluginsResult = printPlugin(val, indent, prevIndent, spacing, edgeSpacing, refs, opts.maxDepth, currentDepth, opts.plugins, opts.min, opts.callToJSON, opts.printFunctionName, opts.escapeRegex); | ||
| if (pluginsResult) return pluginsResult; | ||
| } | ||
| var basicResult = printBasicValue(val, opts.printFunctionName, opts.escapeRegex); | ||
| if (basicResult) return basicResult; | ||
| if (!indent) indent = createIndent(opts.indent); | ||
| if (!refs) refs = []; | ||
| return printComplexValue(val, indent, prevIndent, spacing, edgeSpacing, refs, opts.maxDepth, currentDepth, opts.plugins, opts.min, opts.callToJSON, opts.printFunctionName, opts.escapeRegex); | ||
| } | ||
| module.exports = prettyFormat; |
-15
| ## ISC License | ||
| Copyright (c) 2016, James Kyle <me@thejameskyle.com> | ||
| Permission to use, copy, modify, and/or distribute this software for any purpose | ||
| with or without fee is hereby granted, provided that the above copyright notice | ||
| and this permission notice appear in all copies. | ||
| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
| REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||
| FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
| INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
| OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
| TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | ||
| THIS SOFTWARE. |
| 'use strict'; | ||
| const printString = require('../printString'); | ||
| const reactElement = Symbol.for('react.element'); | ||
| function traverseChildren(opaqueChildren, cb) { | ||
| if (Array.isArray(opaqueChildren)) { | ||
| opaqueChildren.forEach(child => traverseChildren(child, cb)); | ||
| } else if (opaqueChildren != null && opaqueChildren !== false) { | ||
| cb(opaqueChildren); | ||
| } | ||
| } | ||
| function printChildren(flatChildren, print, indent, opts) { | ||
| return flatChildren.map(node => { | ||
| if (typeof node === 'object') { | ||
| return printElement(node, print, indent, opts); | ||
| } else if (typeof node === 'string') { | ||
| return printString(node); | ||
| } else { | ||
| return print(node); | ||
| } | ||
| }).join(opts.edgeSpacing); | ||
| } | ||
| function printProps(props, print, indent, opts) { | ||
| return Object.keys(props).sort().map(name => { | ||
| if (name === 'children') { | ||
| return ''; | ||
| } | ||
| const prop = props[name]; | ||
| let printed = print(prop); | ||
| if (typeof prop !== 'string') { | ||
| if (printed.indexOf('\n') !== -1) { | ||
| printed = '{' + opts.edgeSpacing + indent(indent(printed) + opts.edgeSpacing + '}'); | ||
| } else { | ||
| printed = '{' + printed + '}'; | ||
| } | ||
| } | ||
| return opts.spacing + indent(name + '=') + printed; | ||
| }).join(''); | ||
| } | ||
| function printElement(element, print, indent, opts) { | ||
| let result = '<'; | ||
| let elementName; | ||
| if (typeof element.type === 'string') { | ||
| elementName = element.type; | ||
| } else if (typeof element.type === 'function') { | ||
| elementName = element.type.displayName || element.type.name || 'Unknown'; | ||
| } else { | ||
| elementName = 'Unknown'; | ||
| } | ||
| result += elementName; | ||
| result += printProps(element.props, print, indent, opts); | ||
| const opaqueChildren = element.props.children; | ||
| if (opaqueChildren) { | ||
| let flatChildren = []; | ||
| traverseChildren(opaqueChildren, child => { | ||
| flatChildren.push(child); | ||
| }); | ||
| const children = printChildren(flatChildren, print, indent, opts); | ||
| result += '>' + opts.edgeSpacing + indent(children) + opts.edgeSpacing + '</' + elementName + '>'; | ||
| } else { | ||
| result += ' />'; | ||
| } | ||
| return result; | ||
| } | ||
| module.exports = { | ||
| test(object) { | ||
| return object && object.$$typeof === reactElement; | ||
| }, | ||
| print(val, print, indent, opts) { | ||
| return printElement(val, print, indent, opts); | ||
| } | ||
| }; |
| 'use strict'; | ||
| const printString = require('../printString'); | ||
| const reactTestInstance = Symbol.for('react.test.json'); | ||
| function printChildren(children, print, indent, opts) { | ||
| return children.map(child => printInstance(child, print, indent, opts)).join(opts.edgeSpacing); | ||
| } | ||
| function printProps(props, print, indent, opts) { | ||
| return Object.keys(props).sort().map(name => { | ||
| const prop = props[name]; | ||
| let printed = print(prop); | ||
| if (typeof prop !== 'string') { | ||
| if (printed.indexOf('\n') !== -1) { | ||
| printed = '{' + opts.edgeSpacing + indent(indent(printed) + opts.edgeSpacing + '}'); | ||
| } else { | ||
| printed = '{' + printed + '}'; | ||
| } | ||
| } | ||
| return opts.spacing + indent(name + '=') + printed; | ||
| }).join(''); | ||
| } | ||
| function printInstance(instance, print, indent, opts) { | ||
| if (typeof instance == 'number') { | ||
| return print(instance); | ||
| } else if (typeof instance === 'string') { | ||
| return printString(instance); | ||
| } | ||
| let result = '<' + instance.type; | ||
| if (instance.props) { | ||
| result += printProps(instance.props, print, indent, opts); | ||
| } | ||
| if (instance.children) { | ||
| const children = printChildren(instance.children, print, indent, opts); | ||
| result += '>' + opts.edgeSpacing + indent(children) + opts.edgeSpacing + '</' + instance.type + '>'; | ||
| } else { | ||
| result += ' />'; | ||
| } | ||
| return result; | ||
| } | ||
| module.exports = { | ||
| test(object) { | ||
| return object && object.$$typeof === reactTestInstance; | ||
| }, | ||
| print(val, print, indent, opts) { | ||
| return printInstance(val, print, indent, opts); | ||
| } | ||
| }; |
| 'use strict'; | ||
| const ESCAPED_CHARACTERS = /(\\|\"|\')/g; | ||
| module.exports = function printString(val) { | ||
| return val.replace(ESCAPED_CHARACTERS, '\\$1'); | ||
| } |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
Mixed license
LicensePackage contains multiple licenses.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
286019
1311.05%0
-100%9
12.5%0
-100%1755
344.3%135
40.63%0
-100%1
Infinity%2
Infinity%+ Added
+ Added