Skip to content

Commit

Permalink
feat: use custom colors implementation instead of picocolors
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Mar 7, 2023
1 parent 1bdcc21 commit 427b062
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 46 deletions.
2 changes: 1 addition & 1 deletion packages/expect/src/index.ts
Expand Up @@ -5,4 +5,4 @@ export * from './types'
export { getState, setState } from './state'
export { JestChaiExpect } from './jest-expect'
export { JestExtend } from './jest-extend'
export { setColors as setupColors } from '@vitest/utils'
export { setupColors } from '@vitest/utils'
1 change: 0 additions & 1 deletion packages/utils/package.json
Expand Up @@ -40,7 +40,6 @@
"cli-truncate": "^3.1.0",
"diff": "^5.1.0",
"loupe": "^2.3.6",
"picocolors": "^1.0.0",
"pretty-format": "^27.5.1"
},
"devDependencies": {
Expand Down
81 changes: 74 additions & 7 deletions packages/utils/src/colors.ts
@@ -1,7 +1,7 @@
import type p from 'picocolors'
import type { Formatter } from 'picocolors/types'
import { SAFE_COLORS_SYMBOL } from './constants'

type Colors = ReturnType<typeof createColors>

const colors = [
'reset',
'bold',
Expand Down Expand Up @@ -30,17 +30,84 @@ const colors = [
'bgWhite',
] as const

const formatter: Formatter = str => String(str)
const string = (str: unknown) => String(str)
string.open = ''
string.close = ''

const defaultColors = colors.reduce((acc, key) => {
acc[key] = formatter
acc[key] = string
return acc
}, { isColorSupported: false } as typeof p)
}, {} as Colors)

export function getDefaultColors(): Colors {
return { ...defaultColors }
}

export function getColors(): typeof p {
export function getColors(): Colors {
return (globalThis as any)[SAFE_COLORS_SYMBOL] || defaultColors
}

export function setColors(colors: typeof p) {
export function createColors(isTTY = false) {
const enabled = typeof process !== 'undefined'
&& !('NO_COLOR' in process.env || process.argv.includes('--no-color'))
&& !('GITHUB_ACTIONS' in process.env)
&& ('FORCE_COLOR' in process.env
|| process.argv.includes('--color')
|| process.platform === 'win32'
|| (isTTY && process.env.TERM !== 'dumb')
|| 'CI' in process.env)

const replaceClose = (string: string, close: string, replace: string, index: number): string => {
const start = string.substring(0, index) + replace
const end = string.substring(index + close.length)
const nextIndex = end.indexOf(close)
return ~nextIndex ? start + replaceClose(end, close, replace, nextIndex) : start + end
}

const formatter = (open: string, close: string, replace = open) => {
const fn = (input: unknown) => {
const string = `${input}`
const index = string.indexOf(close, open.length)
return ~index
? open + replaceClose(string, close, replace, index) + close
: open + string + close
}
fn.open = open
fn.close = close
return fn
}

// based on "https://github.com/alexeyraspopov/picocolors", but browser-friendly
return {
isColorSupported: enabled,
reset: enabled ? (s: string) => `\x1B[0m${s}\x1B[0m` : string,
bold: enabled ? formatter('\x1B[1m', '\x1B[22m', '\x1B[22m\x1B[1m') : string,
dim: enabled ? formatter('\x1B[2m', '\x1B[22m', '\x1B[22m\x1B[2m') : string,
italic: enabled ? formatter('\x1B[3m', '\x1B[23m') : string,
underline: enabled ? formatter('\x1B[4m', '\x1B[24m') : string,
inverse: enabled ? formatter('\x1B[7m', '\x1B[27m') : string,
hidden: enabled ? formatter('\x1B[8m', '\x1B[28m') : string,
strikethrough: enabled ? formatter('\x1B[9m', '\x1B[29m') : string,
black: enabled ? formatter('\x1B[30m', '\x1B[39m') : string,
red: enabled ? formatter('\x1B[31m', '\x1B[39m') : string,
green: enabled ? formatter('\x1B[32m', '\x1B[39m') : string,
yellow: enabled ? formatter('\x1B[33m', '\x1B[39m') : string,
blue: enabled ? formatter('\x1B[34m', '\x1B[39m') : string,
magenta: enabled ? formatter('\x1B[35m', '\x1B[39m') : string,
cyan: enabled ? formatter('\x1B[36m', '\x1B[39m') : string,
white: enabled ? formatter('\x1B[37m', '\x1B[39m') : string,
gray: enabled ? formatter('\x1B[90m', '\x1B[39m') : string,
bgBlack: enabled ? formatter('\x1B[40m', '\x1B[49m') : string,
bgRed: enabled ? formatter('\x1B[41m', '\x1B[49m') : string,
bgGreen: enabled ? formatter('\x1B[42m', '\x1B[49m') : string,
bgYellow: enabled ? formatter('\x1B[43m', '\x1B[49m') : string,
bgBlue: enabled ? formatter('\x1B[44m', '\x1B[49m') : string,
bgMagenta: enabled ? formatter('\x1B[45m', '\x1B[49m') : string,
bgCyan: enabled ? formatter('\x1B[46m', '\x1B[49m') : string,
bgWhite: enabled ? formatter('\x1B[47m', '\x1B[49m') : string,
}
}

export function setupColors(colors: Colors) {
(globalThis as any)[SAFE_COLORS_SYMBOL] = colors
}
14 changes: 7 additions & 7 deletions packages/vitest/src/runtime/setup.node.ts
@@ -1,7 +1,7 @@
import { createRequire } from 'node:module'
import p from 'picocolors'
import { isatty } from 'node:tty'
import { installSourcemapsSupport } from 'vite-node/source-map'
import { setColors } from '@vitest/utils'
import { createColors, setupColors } from '@vitest/utils'
import { environments } from '../integrations/env'
import type { Environment, ResolvedConfig } from '../types'
import { getSafeTimers, getWorkerState } from '../utils'
Expand Down Expand Up @@ -29,13 +29,13 @@ export async function setupGlobalEnv(config: ResolvedConfig) {

globalSetup = true
setupSnapshotEnvironment(new NodeSnapshotEnvironment())
setColors(p)
setupColors(createColors(isatty(1)))

const require = createRequire(import.meta.url)
const _require = createRequire(import.meta.url)
// always mock "required" `css` files, because we cannot process them
require.extensions['.css'] = () => ({})
require.extensions['.scss'] = () => ({})
require.extensions['.sass'] = () => ({})
_require.extensions['.css'] = () => ({})
_require.extensions['.scss'] = () => ({})
_require.extensions['.sass'] = () => ({})

const state = getWorkerState()

Expand Down
58 changes: 28 additions & 30 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 427b062

Please sign in to comment.