Skip to content

Commit

Permalink
feat: loupe@2
Browse files Browse the repository at this point in the history
  • Loading branch information
keithamus committed Jan 2, 2019
1 parent 68c4459 commit e11b077
Show file tree
Hide file tree
Showing 56 changed files with 16,269 additions and 1,147 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
npm-debug.log
*.tmp.js
/tmp/
loupe.test.js
loupe.js
.nyc_output/
79 changes: 74 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,75 @@
sudo: false

dist: trusty

language: node_js
node_js:
- 0.8
- 0.10
script:
- make ci

cache:
directories:
- node_modules
- ~/.npm

node_js: 8

jobs:
include:
- stage: lint
script: npm run lint
- stage: test
addons:
chrome: stable
firefox: latest
before_script:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- sleep 3 # give xvfb some time to start
script: npm run test:browser
env:
- QUICKLY_TEST_BROWSERS_AVAILABLE_IN_CI=1 # kept here for easier reading of build log
- stage: test
addons:
sauce_connect:
username: "chaijs-type-detect"
jwt:
secure: "GhkIK785QJbB1G5qwf51zpoJkHibS8wBhibID2jCL6TmQ8ZUHmihN2qnjuRvCI80uosHqkCBi3CeBYZIika5QFsg6LVVf5dnme7Qs0UkG+mw45yO6vcKycxbn1Bo5X8hqdtSjF/x+C91Wr4lelr5w/Sq2X7RokfE0fDVdklE5xQ="
script:
- npm run test:browser
env:
- TEST_BROWSERS_IN_SAUCELABS=1 # kept here for easier reading of build log
- SAUCE_USERNAME="chaijs-type-detect"
- SAUCE_CONNECT_READY_FILE=/tmp/sauce-connect-ready
- stage: test
node_js: 8 # to be removed 2019-12-01
script: npm run test:node
- stage: test
node_js: 7 # to be removed 2017-06-30
before_install: npm i -g npm@5
script: npm run test:node
- stage: test
node_js: 6 # to be removed 2019-04-01
before_install: npm i -g npm@5
script: npm run test:node
- stage: test
node_js: 4 # to be removed 2018-04-01
before_install: npm i -g npm@5
script: npm run test:node
- stage: test
node_js: lts/* # safety net; don't remove
script: npm run test:node
- stage: test
node_js: node # safety net; don't remove
script: npm run test:node
- stage: semantic-release
script:
- if [ "$TRAVIS_PULL_REQUEST" != "false" ] || [ "$TRAVIS_BRANCH" != "master" ]; then echo "the deploy job only runs for the master branch. This build will now exit"; exit 0; fi
- if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then npm run semantic-release; fi
env:
- BUILD_LEADER_ID=10
# GH_TOKEN type-detect travis
- secure: "MPzfTVm7U1Q/eYhHT3DXwZki5Xn4ODNs/uXEM5PB2m+BxbytaAgU+3JSI0ZREv+JLk9CRnj2yWebaQkm+0ompkPRus0pEFuwEsMJ3HqV4ISj6zWGLPNjeJqy6kGa+m1WlkfHM+Spj7vrmk2yclZsmke4xpeQy9W8nnPDEHe6uoQ="
# NPM_TOKEN …7f80442b
- secure: "EM+nNOeL3X6Cz5u5aaBKZU6FqXrQVgKO543zy6CL3+Im/Esz2um9S2Ymgw9nzBH35SczhJh4Avfw7sujRdyHPL5XLbCWj2954TThsO8Ue62Xs/K3lQT6x8+iQc0jRZFtBkwX2sQjWFah04j381sKeTFFH94jifeW8dFOXXtWZfs="

env:
global:
- LOGS_DIR=/tmp/chai-build/logs
21 changes: 21 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
version: '{build}'

skip_tags: true
skip_branch_with_pr: true
clone_depth: 1
deploy: off
build: off

install:
- ps: Install-Product node '8'
- npm i -g npm@5
- npm install

test_script:
- node --version
- npm --version
- npm test

cache:
- node_modules -> package-lock.json
- '%APPDATA%\npm-cache'
17 changes: 17 additions & 0 deletions bench/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"extends": [ "strict/test" ],
"env": {
"node": true,
"browser": true,
"es6": true
},
"rules": {
"no-new-wrappers": 0,
"no-array-constructor": 0,
"no-new-object": 0,
"no-empty-function": 0,
"no-undefined": 0,
"no-console": 0,
"id-length": 0
}
}
63 changes: 63 additions & 0 deletions bench/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const loupe = require('../')
const nodeInspect = require('util').inspect
const Benchmark = require('benchmark')
const benches = []
const mapObjRefA = {}
const mapObjRefB = {}
function getArguments() {
return arguments // eslint-disable-line prefer-rest-params
}
const fixtures = {
'string literal ': 'abc',
'array literal ': [1, 2, 3],
'boolean literal ': true,
'object literal ': { a: 1 },
'object from null ': Object.create(null),
'regex literal ': /^abc$/,
'number literal ': 1,
'null ': null,
'undefined ': undefined,
'buffer ': Buffer.from('hello world'),
'date ': new Date(123),
'map ': new Map().set('a', 1),
'map (complex) ': new Map().set(mapObjRefA, new Map().set(mapObjRefB, 1)),
'regex constructor ': new RegExp('abc'),
'set ': new Set().add(1),
'string constructor ': new String(),
'arguments ': getArguments(1, 2, 3),
}

function prepareBenchMark(test, name, inspect = loupe) {
benches.push(
new Benchmark(name, {
fn() {
inspect(test)
},
onCycle(event) {
process.stdout.clearLine()
process.stdout.cursorTo(0)
process.stdout.write(event.target.toString())
},
})
)
}

const filter = process.argv.slice(2).filter(arg => arg[0] !== '-')[0] || ''
const nodeinspect = process.argv.indexOf('--nodeinspect') !== -1
Object.keys(fixtures)
.filter(key => key.indexOf(filter) !== -1)
.forEach(testName => {
prepareBenchMark(fixtures[testName], `${testName} (loupe)`)
if (nodeinspect) {
prepareBenchMark(fixtures[testName], `${testName} (node)`, nodeInspect)
}
})
Benchmark.invoke(benches, {
name: 'run',
onCycle() {
console.log('')
},
onComplete() {
console.log('~Fin~')
},
})
14 changes: 0 additions & 14 deletions component.json

This file was deleted.

29 changes: 0 additions & 29 deletions hydro.conf.js

This file was deleted.

157 changes: 157 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/* !
* loupe
* Copyright(c) 2013 Jake Luer <[email protected]>
* MIT Licensed
*/

import typeDetect from 'type-detect'

import inspectArray from './lib/array'
import inspectTypedArray from './lib/typedarray'
import inspectDate from './lib/date'
import inspectFunction from './lib/function'
import inspectMap from './lib/map'
import inspectNumber from './lib/number'
import inspectRegExp from './lib/regexp'
import inspectSet from './lib/set'
import inspectString from './lib/string'
import inspectSymbol from './lib/symbol'
import inspectPromise from './lib/promise'
import inspectClass from './lib/class'
import inspectObject from './lib/object'
import inspectArguments from './lib/arguments'
import inspectError from './lib/error'

import { normaliseOptions } from './lib/helpers'

const symbolsSupported = typeof Symbol === 'function' && typeof Symbol.for === 'function'
const chaiInspect = symbolsSupported ? Symbol.for('chai/inspect') : '@@chai/inspect'
let nodeInspect = false
try {
// eslint-disable-next-line global-require
nodeInspect = require('util').inspect.custom
} catch (noNodeInspect) {
nodeInspect = false
}

const constructorMap = new WeakMap()
const stringTagMap = {}
const baseTypesMap = {
undefined: (value, options) => options.stylize('undefined', 'undefined'),
null: (value, options) => options.stylize(null, 'null'),

boolean: (value, options) => options.stylize(value, 'boolean'),
Boolean: (value, options) => options.stylize(value, 'boolean'),

number: inspectNumber,
Number: inspectNumber,

string: inspectString,
String: inspectString,

function: inspectFunction,
Function: inspectFunction,

symbol: inspectSymbol,

Array: inspectArray,
Date: inspectDate,
Map: inspectMap,
Set: inspectSet,
RegExp: inspectRegExp,
Promise: inspectPromise,

// WeakSet, WeakMap are totally opaque to us
WeakSet: (value, options) => options.stylize('WeakSet{…}', 'special'),
WeakMap: (value, options) => options.stylize('WeakMap{…}', 'sepcial'),

Arguments: inspectArguments,
Int8Array: inspectTypedArray,
Uint8Array: inspectTypedArray,
Uint8ClampedArray: inspectTypedArray,
Int16Array: inspectTypedArray,
Uint16Array: inspectTypedArray,
Int32Array: inspectTypedArray,
Uint32Array: inspectTypedArray,
Float32Array: inspectTypedArray,
Float64Array: inspectTypedArray,

Generator: () => '',
DataView: () => '',
ArrayBuffer: () => '',

Error: inspectError,
}

const inspectCustom = (value, options, type) => {
if (chaiInspect in value && typeof value[chaiInspect] === 'function') {
return value[chaiInspect](options)
}

if (nodeInspect && nodeInspect in value && typeof value[nodeInspect] === 'function') {
return value[nodeInspect](options.depth, options)
}

if ('inspect' in value && typeof value.inspect === 'function') {
return value.inspect(options.depth, options)
}

if ('constructor' in value && constructorMap.has(value.constructor)) {
return constructorMap.get(value.constructor)(value, options)
}

if (stringTagMap[type]) {
return stringTagMap[type](value, options)
}

return ''
}

export default function inspect(value, options) {
options = normaliseOptions(options)
options.inspect = inspect
const { customInspect } = options
const type = typeDetect(value)

// If it is a base value that we already support, then use Loupe's inspector
if (baseTypesMap[type]) {
return baseTypesMap[type](value, options)
}

// If its a plain Object then use Loupe's inspector
if (value && Object.getPrototypeOf(value) === Object.prototype) {
return inspectObject(value, options)
}

// If `options.customInspect` is set to true then try to use the custom inspector
if (customInspect && value) {
const output = inspectCustom(value, options, type)
if (output) return output
}

// If it is a class, inspect it like an object but add the constructor name
if ('constructor' in value && value.constructor !== Object) {
return inspectClass(value, options)
}

// We have run out of options! Just stringify the value
return options.stylize(String(value), type)
}

export function registerConstructor(constructor, inspector) {
if (constructorMap.has(constructor)) {
return false
}
constructorMap.add(constructor, inspector)
return true
}

export function registerStringTag(stringTag, inspector) {
if (stringTag in stringTagMap) {
return false
}
stringTagMap[stringTag] = inspector
return true
}

export const custom = chaiInspect
Loading

0 comments on commit e11b077

Please sign in to comment.