diff --git a/CHANGELOG.md b/CHANGELOG.md index a05ffa8..e5fcac0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change log +## 3.3.1 (2024-07-18) + +- chore: optimize code to reduce the size by ~600 bytes, +- chore: minify `index.d.ts` to reduce the size by ~200 bytes, +- chore: increase performance, e.g. using chained styles, 70.000.000 -> 80.000.000 ops/sec + ## 3.3.0 (2024-07-14) - feat(BREAKING CHANGE): remove `old` named import DEPRECATED in `v2.0.0` (2023-11-03). diff --git a/README.npm-src.md b/README.npm-src.md new file mode 100644 index 0000000..f4b318e --- /dev/null +++ b/README.npm-src.md @@ -0,0 +1,55 @@ +

+ +
+ ANSI Styling +
+

+ +--- +[![codecov](https://codecov.io/gh/webdiscus/ansis/branch/master/graph/badge.svg?token=H7SFJONX1X)](https://codecov.io/gh/webdiscus/ansis) +[![node](https://img.shields.io/npm/dm/ansis)](https://www.npmjs.com/package/ansis) +[![size](https://img.shields.io/bundlephobia/minzip/ansis)](https://bundlephobia.com/package/ansis) + +Colorize terminal with ANSI colors & styles, smaller and faster alternative to Chalk. + +🚀 [Install and Quick Start](https://github.com/webdiscus/ansis#install) + +✅ [Compare features](https://github.com/webdiscus/ansis#compare) with similar packages + +📊 [Benchmarks](https://github.com/webdiscus/ansis#benchmark) + +📖 [Read full docs on GitHub](https://github.com/webdiscus/ansis) + +## Usage + +```js +import ansis, { red, green, black, ansi256, hex } from 'ansis'; + +ansis.cyan('file') +green('Ok') +red`Error` +black.bgYellow`Warning` +ansi256(214)`Orange` +hex('#E0115F').bold('TrueColor') +``` + +## Highlights + +![ANSI demo](https://github.com/webdiscus/ansis/raw/master/docs/img/ansis-demo.png) + +- Supports ESM, CJS, TypeScript, Bun, Deno, Next.JS +- Named import: `import ansis, { red, bold, hex } from 'ansis'` +- Chained syntax: `red.bold.underline('text')` +- Nested template strings: ``` red`RED ${green`GREEN`} RED` ``` +- ANSI styles: `dim` **`bold`** _`italic`_ `underline` `strikethrough` +- ANSI 16 colors: ``` red`Error!` ``` ``` redBright`Error!` ``` ``` bgRed`Error!` ``` ``` bgRedBright`Error!` ``` +- ANSI 256 colors: ``` fg(56)`violet` ``` ``` bg(208)`orange` ``` +- TrueColor: ``` rgb(224, 17, 95)`Ruby` ``` ``` hex('#96C')`Amethyst` ``` +- Color fallback: TrueColor → 256 colors → 16 colors → no colors +- Raw ANSI codes: ``` `foo ${red.open}bar{red.close} foo` ``` +- Strip ANSI codes: `ansis.strip()` +- Detect color support: `ansis.isSupported()` +- Supports CLI: `NO_COLOR` `FORCE_COLOR` `--no-color` `--color` +- Correct style break at the `end of line` when used `\n` +- Doesn't extend `String.prototype` +- No dependencies diff --git a/README.npm.md b/README.npm.md index f4b318e..7df2811 100644 --- a/README.npm.md +++ b/README.npm.md @@ -20,36 +20,6 @@ Colorize terminal with ANSI colors & styles, smaller and faster alternative to C 📖 [Read full docs on GitHub](https://github.com/webdiscus/ansis) -## Usage - -```js -import ansis, { red, green, black, ansi256, hex } from 'ansis'; - -ansis.cyan('file') -green('Ok') -red`Error` -black.bgYellow`Warning` -ansi256(214)`Orange` -hex('#E0115F').bold('TrueColor') -``` - -## Highlights - -![ANSI demo](https://github.com/webdiscus/ansis/raw/master/docs/img/ansis-demo.png) - -- Supports ESM, CJS, TypeScript, Bun, Deno, Next.JS -- Named import: `import ansis, { red, bold, hex } from 'ansis'` -- Chained syntax: `red.bold.underline('text')` -- Nested template strings: ``` red`RED ${green`GREEN`} RED` ``` -- ANSI styles: `dim` **`bold`** _`italic`_ `underline` `strikethrough` -- ANSI 16 colors: ``` red`Error!` ``` ``` redBright`Error!` ``` ``` bgRed`Error!` ``` ``` bgRedBright`Error!` ``` -- ANSI 256 colors: ``` fg(56)`violet` ``` ``` bg(208)`orange` ``` -- TrueColor: ``` rgb(224, 17, 95)`Ruby` ``` ``` hex('#96C')`Amethyst` ``` -- Color fallback: TrueColor → 256 colors → 16 colors → no colors -- Raw ANSI codes: ``` `foo ${red.open}bar{red.close} foo` ``` -- Strip ANSI codes: `ansis.strip()` -- Detect color support: `ansis.isSupported()` -- Supports CLI: `NO_COLOR` `FORCE_COLOR` `--no-color` `--color` -- Correct style break at the `end of line` when used `\n` -- Doesn't extend `String.prototype` -- No dependencies +--- + +![ANSI demo](https://github.com/webdiscus/ansis/raw/master/docs/img/screenshot-readme-npm.png) diff --git a/bench/index.js b/bench/index.js index 1129011..571e914 100644 --- a/bench/index.js +++ b/bench/index.js @@ -91,6 +91,8 @@ let fixture; log(hex('#F88').inverse.bold` -= Benchmark =- `); bench('Using 1 style (red)'). + add(packages['chalk'], () => chalk.red('foo')). + add(packages['ansis'], () => ansis.red('foo')). add(packages['colors'], () => colorsJs.red('foo')). add(packages['colorette'], () => colorette.red('foo')). add(packages['picocolors'], () => picocolors.red('foo')). @@ -99,11 +101,11 @@ bench('Using 1 style (red)'). add(packages['ansi-colors'], () => ansiColors.red('foo')). add(packages['kleur'], () => kleur.red('foo')). add(packages['kolorist'], () => kolorist.red('foo')). - add(packages['chalk'], () => chalk.red('foo')). - add(packages['ansis'], () => ansis.red('foo')). run(); bench(`Using 2 styles (red, bold)`). + add(packages['chalk'], () => chalk.red.bold('foo')). + add(packages['ansis'], () => ansis.red.bold('foo')). add(packages['colors'], () => colorsJs.red.bold('foo')). add(packages['colorette'], () => colorette.red(colorette.bold('foo'))). add(packages['picocolors'], () => picocolors.red(picocolors.bold('foo'))). @@ -112,11 +114,11 @@ bench(`Using 2 styles (red, bold)`). add(packages['ansi-colors'], () => ansiColors.red.bold('foo')). add(packages['kleur'], () => kleur.red().bold('foo')). add(packages['kolorist'], () => kolorist.red(kolorist.bold('foo'))). - add(packages['chalk'], () => chalk.red.bold('foo')). - add(packages['ansis'], () => ansis.red.bold('foo')). run(); bench(`Using 3 styles (red, bold, underline)`). + add(packages['chalk'], () => chalk.red.bold.underline('foo')). + add(packages['ansis'], () => ansis.red.bold.underline('foo')). add(packages['colors'], () => colorsJs.red.bold.underline('foo')). add(packages['colorette'], () => colorette.red(colorette.bold(colorette.underline('foo')))). add(packages['picocolors'], () => picocolors.red(picocolors.bold(picocolors.underline('foo')))). @@ -125,27 +127,27 @@ bench(`Using 3 styles (red, bold, underline)`). add(packages['ansi-colors'], () => ansiColors.red.bold.underline('foo')). add(packages['kleur'], () => kleur.red().bold().underline('foo')). add(packages['kolorist'], () => kolorist.red(kolorist.bold(kolorist.underline('foo')))). - add(packages['chalk'], () => chalk.red.bold.underline('foo')). - add(packages['ansis'], () => ansis.red.bold.underline('foo')). run(); -bench(`Using 5 styles (bgWhite red, bold, italic, underline)`). - add(packages['colors'], () => colorsJs.bgWhite.red.bold.italic.underline('foo')). - add(packages['colorette'], () => colorette.bgWhite(colorette.red(colorette.bold(colorette.italic(colorette.underline('foo')))))). - add(packages['picocolors'], () => picocolors.bgWhite(picocolors.red(picocolors.bold(picocolors.italic(picocolors.underline('foo')))))). - add(packages['cli-color'], () => cliColor.bgWhite.red.bold.italic.underline('foo')). - add(packages['colors-cli'], () => colorCli.white_b.red.bold.italic.underline('foo')). - add(packages['ansi-colors'], () => ansiColors.bgWhite.red.bold.italic.underline('foo')). - add(packages['kleur'], () => kleur.bgWhite().red().bold().italic().underline()('foo')). - add(packages['kolorist'], () => kolorist.bgWhite(kolorist.red(kolorist.bold(kolorist.italic(kolorist.underline('foo')))))). - add(packages['chalk'], () => chalk.bgWhite.red.bold.italic.underline('foo')). - add(packages['ansis'], () => ansis.bgWhite.red.bold.italic.underline('foo')). +bench(`Using 4 styles (bgWhite red, bold, underline)`). + add(packages['chalk'], () => chalk.bgWhite.red.bold.underline('foo')). + add(packages['ansis'], () => ansis.bgWhite.red.bold.underline('foo')). + add(packages['colors'], () => colorsJs.bgWhite.red.bold.underline('foo')). + add(packages['colorette'], () => colorette.bgWhite(colorette.red(colorette.bold(colorette.underline('foo'))))). + add(packages['picocolors'], () => picocolors.bgWhite(picocolors.red(picocolors.bold(picocolors.underline('foo'))))). + add(packages['cli-color'], () => cliColor.bgWhite.red.bold.underline('foo')). + add(packages['colors-cli'], () => colorCli.white_b.red.bold.underline('foo')). + add(packages['ansi-colors'], () => ansiColors.bgWhite.red.bold.underline('foo')). + add(packages['kleur'], () => kleur.bgWhite().red().bold().underline()('foo')). + add(packages['kolorist'], () => kolorist.bgWhite(kolorist.red(kolorist.bold(kolorist.underline('foo'))))). run(); // Colorette bench // https://github.com/jorgebucaran/colorette/blob/main/bench/index.js fixture = createFixture(vendors, coloretteBench); bench('Colorette bench'). + add(vendors[8].name, () => fixture[8](vendors[8].lib)). + add(vendors[9].name, () => fixture[9](vendors[9].lib)). add(vendors[0].name, () => fixture[0](vendors[0].lib)). add(vendors[1].name, () => fixture[1](vendors[1].lib)). add(vendors[2].name, () => fixture[2](vendors[2].lib)). @@ -154,12 +156,12 @@ bench('Colorette bench'). add(vendors[5].name, () => fixture[5](vendors[5].lib)). add(vendors[6].name, () => fixture[6](vendors[6].lib)). add(vendors[7].name, () => fixture[7](vendors[7].lib)). - add(vendors[8].name, () => fixture[8](vendors[8].lib)). - add(vendors[9].name, () => fixture[9](vendors[9].lib)). run(); // Base colors bench('Base colors'). + add(packages['chalk'], () => baseColors.forEach((style) => chalk[style]('foo'))). + add(packages['ansis'], () => baseColors.forEach((style) => ansis[style]('foo'))). add(packages['colors'], () => baseColors.forEach((style) => colorsJs[style]('foo'))). add(packages['colorette'], () => baseColors.forEach((style) => colorette[style]('foo'))). add(packages['picocolors'], () => baseColors.forEach((style) => picocolors[style]('foo'))). @@ -168,12 +170,12 @@ bench('Base colors'). add(packages['ansi-colors'], () => baseColors.forEach((style) => ansiColors[style]('foo'))). add('kleur/colors', () => baseColors.forEach((style) => kleurColors[style]('foo'))). add(packages['kleur'], () => baseColors.forEach((style) => kleur[style]('foo'))). - add(packages['chalk'], () => baseColors.forEach((style) => chalk[style]('foo'))). - add(packages['ansis'], () => baseColors.forEach((style) => ansis[style]('foo'))). run(); // Chained styles bench('Chained styles'). + add(packages['chalk'], () => baseColors.forEach((style) => chalk[style].bold.underline.italic('foo'))). + add(packages['ansis'], () => baseColors.forEach((style) => ansis[style].bold.underline.italic('foo'))). add(packages['colors'], () => baseColors.forEach((style) => colorsJs[style].bold.underline.italic('foo'))). add('colorette (not supported)', () => baseColors.forEach((style) => colorette[style].bold.underline.italic('foo'))). add('picocolors (not supported)', () => @@ -185,13 +187,13 @@ bench('Chained styles'). add('kleur/colors (not supported)', () => baseColors.forEach((style) => kleurColors[style].bold.underline.italic('foo')), ). - // add(packages['kleur'], () => baseColors.forEach((style) => kleur[style]().bold().underline().italic('foo'))). // alternate syntax - add(packages['chalk'], () => baseColors.forEach((style) => chalk[style].bold.underline.italic('foo'))). - add(packages['ansis'], () => baseColors.forEach((style) => ansis[style].bold.underline.italic('foo'))). + add(packages['kleur'], () => baseColors.forEach((style) => kleur[style]().bold().underline().italic('foo'))). // alternate syntax run(); // Nested calls bench('Nested calls'). + add(packages['chalk'], () => baseColors.forEach((style) => chalk[style](chalk.bold(chalk.underline(chalk.italic('foo')))))). + add(packages['ansis'], () => baseColors.forEach((style) => ansis[style](ansis.bold(ansis.underline(ansis.italic('foo')))))). add(packages['colors'], () => baseColors.forEach((style) => colorsJs[style](colorsJs.bold(colorsJs.underline(colorsJs.italic('foo'))))), ). @@ -216,13 +218,13 @@ bench('Nested calls'). ), ). add(packages['kleur'], () => baseColors.forEach((style) => kleur[style](kleur.bold(kleur.underline(kleur.italic('foo')))))). - add(packages['chalk'], () => baseColors.forEach((style) => chalk[style](chalk.bold(chalk.underline(chalk.italic('foo')))))). - add(packages['ansis'], () => baseColors.forEach((style) => ansis[style](ansis.bold(ansis.underline(ansis.italic('foo')))))). run(); // Nested styles fixture = createFixture(vendors, nestedFixture); bench('Nested styles'). + add(packages['chalk'], () => fixture[7](chalk)). + add(packages['ansis'], () => fixture[8](ansis)). add(packages['colors'], () => fixture[9](colorsJs)). add(packages['colorette'], () => fixture[0](colorette)). add(packages['picocolors'], () => fixture[1](picocolors)). @@ -231,13 +233,13 @@ bench('Nested styles'). add(packages['ansi-colors'], () => fixture[4](ansiColors)). add('kleur/colors', () => fixture[5](kleurColors)). add(packages['kleur'], () => fixture[6](kleur)). - add(packages['chalk'], () => fixture[7](chalk)). - add(packages['ansis'], () => fixture[8](ansis)). run(); // Deep nested styles fixture = createFixture(vendors, deepNestedFixture); bench('Deep nested styles'). + add(packages['chalk'], () => fixture[7](chalk)). + add(packages['ansis'], () => fixture[8](ansis)). add(packages['colors'], () => fixture[9](colorsJs)). add(packages['colorette'], () => fixture[0](colorette)). add(packages['picocolors'], () => fixture[1](picocolors)). @@ -246,8 +248,6 @@ bench('Deep nested styles'). add(packages['ansi-colors'], () => fixture[4](ansiColors)). add('kleur/colors', () => fixture[5](kleurColors)). add(packages['kleur'], () => fixture[6](kleur)). - add(packages['chalk'], () => fixture[7](chalk)). - add(packages['ansis'], () => fixture[8](ansis)). run(); // Check support of correct break style at new line diff --git a/docs/img/screenshot-readme-npm.png b/docs/img/screenshot-readme-npm.png new file mode 100644 index 0000000..6a1e387 Binary files /dev/null and b/docs/img/screenshot-readme-npm.png differ diff --git a/package.json b/package.json index 5bbe62f..455fcd7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ansis", - "version": "3.3.0", + "version": "3.3.1", "description": "Colorize terminal output with ANSI colors & styles", "keywords": [ "ansi", diff --git a/package.npm.json b/package.npm.json index f64ddb6..6516b64 100644 --- a/package.npm.json +++ b/package.npm.json @@ -1,6 +1,6 @@ { "name": "ansis", - "version": "3.3.0", + "version": "3.3.1", "description": "Colorize terminal output with ANSI colors & styles", "keywords": [ "ansi", diff --git a/rollup.config.js b/rollup.config.js index 1b648bf..d04dba8 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -9,6 +9,21 @@ import { minify } from 'terser'; const ecma = 2019; export default [ + // remove comments from d.ts file + { + input: 'src/index.d.ts', + output: [ + { + file: 'dist/index.d.ts', + format: 'es', + }, + ], + plugins: [ + cleanup({ extensions: ['ts'] }), + dts(), + ], + }, + { input: 'src/index.js', output: [ @@ -39,8 +54,16 @@ export default [ { src: 'src/index.mjs', dest: 'dist/', - transform: async (contents, name) => (await minify(contents.toString())).code, + transform: async (contents, name) => (await minify(contents.toString(), { ecma: 2015 })).code, }, + + // minify d.ts file generated after cleanup + { + src: 'dist/index.d.ts', + dest: 'dist/', + transform: (contents, name) => { return contents.toString().replaceAll(/\n/g, '');}, + }, + { src: 'package.npm.json', dest: 'dist/', rename: 'package.json' }, { src: 'README.npm.md', dest: 'dist/', rename: 'README.md' }, { src: 'LICENSE', dest: 'dist/' }, @@ -48,18 +71,4 @@ export default [ }), ], }, - - { - input: 'src/index.d.ts', - output: [ - { - file: 'dist/index.d.ts', - format: 'es', - }, - ], - plugins: [ - cleanup({ extensions: ['ts'] }), - dts(), - ], - }, ]; diff --git a/src/ansi-codes.js b/src/ansi-codes.js index 1d3e91c..a997b6f 100644 --- a/src/ansi-codes.js +++ b/src/ansi-codes.js @@ -9,10 +9,6 @@ const esc = isSupported ? (open, close) => ({ open: `\x1b[${open}m`, close: `\x1 const closeCode = 39; const bgCloseCode = 49; -const ESC = '\x1b'; -const BEL = '\x07'; -const ZWSP = '\u200B'; - // defaults, true color let fnAnsi256 = (code) => esc(`38;5;${code}`, closeCode); let fnBgAnsi256 = (code) => esc(`48;5;${code}`, bgCloseCode); @@ -122,11 +118,6 @@ export const styleMethods = { // note: the `...` operator is too slow //bgHex: (hex) => fnBgRgb(...hexToRgb(hex)), bgHex: createHexFn(fnBgRgb), - - // reserved for future: hyperlink (OSC 8) is not widely supported (works in iTerm) - // link: hasColor - // ? (url) => ({ open: ESC + ']8;;' + url + BEL, close: ESC + ']8;;' + BEL }) - // : (url) => ({ open: '', close: `(${ZWSP}${url}${ZWSP})` }), }; export const rgb = fnRgb; diff --git a/src/index.d.ts b/src/index.d.ts index 4aaf9e3..a081c3a 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1,4 +1,4 @@ -type ColorExtend = Record +type ColorExtend = Record; interface Ansis { /** diff --git a/src/index.js b/src/index.js index 48b3cba..c98183e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ import { baseStyles, styleMethods, rgb, isSupported } from './ansi-codes.js'; -import { hexToRgb, replaceAll } from './utils.js'; +import { hexToRgb } from './utils.js'; /** * @typedef {Object} AnsisProps @@ -17,36 +17,6 @@ const ESC = '\x1b'; const LF = '\x0a'; const styles = {}; -/** - * Wrap the string with styling and reset codes. - * - * @param {string | Array | number} strings A string or template literals. - * @param {Array} values The values of the template literals. - * @param {AnsisProps} props - * @returns {string} - */ -const wrap = (strings, values, props) => { - if (!strings) return ''; - - const { _a: openStack, _b: closeStack } = props; - // convert the number to the string - let string = strings.raw != null ? String.raw(strings, ...values) : strings + ''; - - if (string.includes(ESC)) { - while (props != null) { - string = replaceAll(string, props.close, props.open); // much faster than native replaceAll - //string = string.replaceAll(props.close, props.open); // too slow! - props = props._p; - } - } - - if (string.includes(LF)) { - string = string.replace(regexLFCR, closeStack + '$1' + openStack); - } - - return openStack + string + closeStack; -}; - /** * @param {Object} self * @param {AnsisProps} self._p @@ -56,7 +26,58 @@ const wrap = (strings, values, props) => { * @returns {Ansis} */ const createStyle = ({ _p: props }, { open, close }) => { - const style = (strings, ...values) => wrap(strings, values, style._p); + /** + * Wrap the string with ANSI codes. + * @param {string} strings The normal or template string. + * @param {array} values The values of the template string. + * @return {string} + */ + const style = (strings, ...values) => { + if (!strings) return ''; + + let props = style._p; + let { _a: openStack, _b: closeStack } = props; + + let str = strings.raw != null + // render template strings + ? String.raw(strings, ...values) + // convert the number to the string + : '' + strings; + + // on node.js, the performance of `includes()` and `~indexOf()` is the same, no difference + if (str.includes(ESC)) { + while (props != null) { + // this implementation is over 30% faster than String.replaceAll() + // -- begin replaceAll + let search = props.close; + let searchLength = search.length; + + // the `visible` style has empty open/close props + if (searchLength) { + let lastPos = 0; + let result = ''; + let pos; + + while (~(pos = str.indexOf(search, lastPos))) { + result += str.slice(lastPos, pos) + props.open; + lastPos = pos + searchLength; + } + + if (lastPos) str = result + str.slice(lastPos); + } + // -- end replaceAll + + props = props._p; + } + } + + if (str.includes(LF)) { + str = str.replace(regexLFCR, closeStack + '$1' + openStack); + } + + return openStack + str + closeStack; + }; + let openStack = open; let closeStack = close; @@ -74,7 +95,7 @@ const createStyle = ({ _p: props }, { open, close }) => { }; const Ansis = function() { - const self = (str) => str + ''; + const self = (str) => '' + str; /** * Whether the output supports ANSI color and styles. diff --git a/src/utils.js b/src/utils.js index 6e991f0..718e18b 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,31 +1,5 @@ const { round, floor, max } = Math; -/** - * Replace all matched strings. - * Note: this implementation is over 30% faster than String.replaceAll(). - * - * @param {string} str - * @param {string} searchValue - * @param {string} replaceValue - * @returns {string} - */ -export const replaceAll = (str, searchValue, replaceValue) => { - // visible style has empty open/close props - if (searchValue === '') return str; - - let substringLength = searchValue.length; - let lastPos = 0; - let result = ''; - let pos; - - while (~(pos = str.indexOf(searchValue, lastPos))) { - result += str.slice(lastPos, pos) + replaceValue; - lastPos = pos + substringLength; - } - - return lastPos ? result + str.slice(lastPos) : str; -}; - /** * Convert hex color string to RGB values. * @@ -77,7 +51,6 @@ export const rgbToAnsi256 = (r, g, b) => { + (36 * round(r / 51)) + (6 * round(g / 51)) + round(b / 51); - }; /** @@ -87,7 +60,7 @@ export const rgbToAnsi256 = (r, g, b) => { * @return {number} */ export const ansi256To16 = (code) => { - let r, g, b; + let r, g, b, value, code16, remainder; if (code < 8) return 30 + code; if (code < 16) return 90 + (code - 8); @@ -97,19 +70,18 @@ export const ansi256To16 = (code) => { r = g = b = (((code - 232) * 10) + 8) / 255; } else { code -= 16; - - const remainder = code % 36; + remainder = code % 36; r = floor(code / 36) / 5; g = floor(remainder / 6) / 5; b = (remainder % 6) / 5; } - const value = max(r, g, b) * 2; + value = max(r, g, b) * 2; if (value === 0) return 30; - let code16 = 30 + ((round(b) << 2) | (round(g) << 1) | round(r)); + code16 = 30 + ((round(b) << 2) | (round(g) << 1) | round(r)); return value === 2 ? code16 + 60 : code16; }; diff --git a/test/functional.test.js b/test/functional.test.js index 6f72923..5e92061 100644 --- a/test/functional.test.js +++ b/test/functional.test.js @@ -124,13 +124,13 @@ describe('advanced features tests', () => { expect(esc(received)).toEqual(esc(expected)); }); - test(`nested multi styles`, () => { + test(`nested multi styles using template strings`, () => { const rgb = ansis.rgb(100, 80, 155); - const received = ansis.red( + const received = ansis.red `begin ${rgb.bold('RGB')} ${ansis.yellow('yellow')} red ${ansis.italic.cyan('italic cyan')} red ${ansis.red( 'red')} red ${ansis.underline.green.italic(`underline italic green ${ansis.rgb(80, 120, 200)( 'underline italic blue')} underline italic green`)} red ${ansis.cyan('cyan')} red ${ansis.bold.yellow( - 'bold yellow')} red ${ansis.green('green')} end`); + 'bold yellow')} red ${ansis.green('green')} end`; const expected = '\x1b[31mbegin \x1b[38;2;100;80;155m\x1b[1mRGB\x1b[22m\x1b[31m \x1b[33myellow\x1b[31m red \x1b[3m\x1b[36mitalic cyan\x1b[31m\x1b[23m red \x1b[31mred\x1b[31m red \x1b[4m\x1b[32m\x1b[3munderline italic green \x1b[38;2;80;120;200munderline italic blue\x1b[32m underline italic green\x1b[23m\x1b[31m\x1b[24m red \x1b[36mcyan\x1b[31m red \x1b[1m\x1b[33mbold yellow\x1b[31m\x1b[22m red \x1b[32mgreen\x1b[31m end\x1b[39m'; expect(esc(received)).toEqual(esc(expected));