2018-02-14 18:30:01 -08:00
/* eslint-disable unicorn/no-hex-escape */
2017-07-23 22:17:33 +02:00
import test from 'ava' ;
// Spoof supports-color
require ( './_supports-color' ) ( _ _dirname ) ;
2019-07-12 13:51:07 +07:00
const chalk = require ( '../source' ) ;
2017-07-23 22:17:33 +02:00
test ( 'return an empty string for an empty literal' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` ` , '' ) ;
2017-07-23 22:17:33 +02:00
} ) ;
test ( 'return a regular string for a literal with no templates' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 0 } ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` hello ` , 'hello' ) ;
2017-07-23 22:17:33 +02:00
} ) ;
test ( 'correctly perform template parsing' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 0 } ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` {bold Hello, {cyan World!} This is a} test. {green Woo!} ` ,
instance . bold ( 'Hello,' , instance . cyan ( 'World!' ) , 'This is a' ) + ' test. ' + instance . green ( 'Woo!' ) ) ;
2017-07-23 22:17:33 +02:00
} ) ;
test ( 'correctly perform template substitutions' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 0 } ) ;
2017-07-23 22:17:33 +02:00
const name = 'Sindre' ;
const exclamation = 'Neat' ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` {bold Hello, {cyan.inverse ${ name } !} This is a} test. {green ${ exclamation } !} ` ,
instance . bold ( 'Hello,' , instance . cyan . inverse ( name + '!' ) , 'This is a' ) + ' test. ' + instance . green ( exclamation + '!' ) ) ;
2017-07-23 22:17:33 +02:00
} ) ;
test ( 'correctly parse and evaluate color-convert functions' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 3 } ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` {bold.rgb(144,10,178).inverse Hello, {~inverse there!}} ` ,
2017-07-30 22:36:59 -07:00
'\u001B[1m\u001B[38;2;144;10;178m\u001B[7mHello, ' +
'\u001B[27m\u001B[39m\u001B[22m\u001B[1m' +
'\u001B[38;2;144;10;178mthere!\u001B[39m\u001B[22m' ) ;
2017-07-23 22:17:33 +02:00
2018-09-18 14:05:08 +07:00
t . is ( instance ` {bold.bgRgb(144,10,178).inverse Hello, {~inverse there!}} ` ,
2017-07-30 22:36:59 -07:00
'\u001B[1m\u001B[48;2;144;10;178m\u001B[7mHello, ' +
'\u001B[27m\u001B[49m\u001B[22m\u001B[1m' +
'\u001B[48;2;144;10;178mthere!\u001B[49m\u001B[22m' ) ;
2017-07-23 22:17:33 +02:00
} ) ;
test ( 'properly handle escapes' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 3 } ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` {bold hello \{ in brackets \} } ` ,
2017-07-30 22:36:59 -07:00
'\u001B[1mhello {in brackets}\u001B[22m' ) ;
2017-07-23 22:17:33 +02:00
} ) ;
test ( 'throw if there is an unclosed block' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 3 } ) ;
2017-07-23 22:17:33 +02:00
try {
2018-09-18 14:05:08 +07:00
console . log ( instance ` {bold this shouldn't appear ever \} ` ) ;
2017-07-23 22:17:33 +02:00
t . fail ( ) ;
2018-09-18 14:05:08 +07:00
} catch ( error ) {
t . is ( error . message , 'Chalk template literal is missing 1 closing bracket (`}`)' ) ;
2017-07-30 22:36:59 -07:00
}
try {
2018-09-18 14:05:08 +07:00
console . log ( instance ` {bold this shouldn't {inverse appear {underline ever \} :) \} ` ) ;
2017-07-30 22:36:59 -07:00
t . fail ( ) ;
2018-09-18 14:05:08 +07:00
} catch ( error ) {
t . is ( error . message , 'Chalk template literal is missing 3 closing brackets (`}`)' ) ;
2017-07-23 22:17:33 +02:00
}
} ) ;
test ( 'throw if there is an invalid style' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 3 } ) ;
2017-07-23 22:17:33 +02:00
try {
2018-09-18 14:05:08 +07:00
console . log ( instance ` {abadstylethatdoesntexist this shouldn't appear ever} ` ) ;
2017-07-23 22:17:33 +02:00
t . fail ( ) ;
2018-09-18 14:05:08 +07:00
} catch ( error ) {
t . is ( error . message , 'Unknown Chalk style: abadstylethatdoesntexist' ) ;
2017-07-23 22:17:33 +02:00
}
} ) ;
test ( 'properly style multiline color blocks' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 3 } ) ;
2017-07-23 22:17:33 +02:00
t . is (
2018-09-18 14:05:08 +07:00
instance ` {bold
2017-07-23 22:17:33 +02:00
Hello ! This is a
$ { 'multiline' } block !
: )
} { underline
I hope you enjoy
} ` ,
2017-07-30 22:36:59 -07:00
'\u001B[1m\u001B[22m\n' +
'\u001B[1m\t\t\tHello! This is a\u001B[22m\n' +
'\u001B[1m\t\t\tmultiline block!\u001B[22m\n' +
'\u001B[1m\t\t\t:)\u001B[22m\n' +
'\u001B[1m\t\t\u001B[22m \u001B[4m\u001B[24m\n' +
'\u001B[4m\t\t\tI hope you enjoy\u001B[24m\n' +
'\u001B[4m\t\t\u001B[24m'
2017-07-23 22:17:33 +02:00
) ;
} ) ;
test ( 'escape interpolated values' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 0 } ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` Hello {bold hi} ` , 'Hello hi' ) ;
t . is ( instance ` Hello ${ '{bold hi}' } ` , 'Hello {bold hi}' ) ;
2017-07-23 22:17:33 +02:00
} ) ;
2017-07-30 22:41:15 -07:00
test ( 'allow custom colors (themes) on custom contexts' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 3 } ) ;
2018-09-18 14:05:08 +07:00
instance . rose = instance . hex ( '#F6D9D9' ) ;
t . is ( instance ` Hello, {rose Rose}. ` , 'Hello, \u001B[38;2;246;217;217mRose\u001B[39m.' ) ;
2017-07-30 22:41:15 -07:00
} ) ;
test ( 'correctly parse newline literals (bug #184)' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 0 } ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` Hello
2017-07-30 22:41:15 -07:00
{ red there } ` , 'Hello \n there');
} ) ;
test ( 'correctly parse newline escapes (bug #177)' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 0 } ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` Hello \n there! ` , 'Hello\nthere!' ) ;
2017-07-30 22:41:15 -07:00
} ) ;
test ( 'correctly parse escape in parameters (bug #177 comment 318622809)' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 0 } ) ;
2020-04-02 15:56:21 +08:00
const string = '\\' ;
t . is ( instance ` {blue ${ string } } ` , '\\' ) ;
2017-07-30 22:41:15 -07:00
} ) ;
2017-07-30 22:36:59 -07:00
test ( 'correctly parses unicode/hex escapes' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 0 } ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` \u 0078ylophones are fo \x 78y! {magenta.inverse \u 0078ylophones are fo \x 78y!} ` ,
2017-07-30 22:36:59 -07:00
'xylophones are foxy! xylophones are foxy!' ) ;
} ) ;
test ( 'correctly parses string arguments' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 3 } ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` {keyword('black').bold can haz cheezburger} ` , '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m' ) ;
t . is ( instance ` {keyword('blac \x 6B').bold can haz cheezburger} ` , '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m' ) ;
t . is ( instance ` {keyword('blac \u 006B').bold can haz cheezburger} ` , '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m' ) ;
2017-07-30 22:36:59 -07:00
} ) ;
test ( 'throws if a bad argument is encountered' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 3 } ) ; // Keep level at least 1 in case we optimize for disabled chalk instances
2017-07-30 22:36:59 -07:00
try {
2018-09-18 14:05:08 +07:00
console . log ( instance ` {keyword(????) hi} ` ) ;
2017-07-30 22:36:59 -07:00
t . fail ( ) ;
2018-09-18 14:05:08 +07:00
} catch ( error ) {
t . is ( error . message , 'Invalid Chalk template style argument: ???? (in style \'keyword\')' ) ;
2017-07-30 22:36:59 -07:00
}
} ) ;
test ( 'throws if an extra unescaped } is found' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 0 } ) ;
2017-07-30 22:36:59 -07:00
try {
2018-09-18 14:05:08 +07:00
console . log ( instance ` {red hi!}} ` ) ;
2017-07-30 22:36:59 -07:00
t . fail ( ) ;
2018-09-18 14:05:08 +07:00
} catch ( error ) {
t . is ( error . message , 'Found extraneous } in Chalk template literal' ) ;
2017-07-30 22:36:59 -07:00
}
} ) ;
test ( 'should not parse upper-case escapes' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 0 } ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` \N \n \T \t \X 07 \x 07 \U 000A \u 000A \U 000a \u 000a ` , 'N\nT\tX07\x07U000A\u000AU000a\u000A' ) ;
2017-07-30 22:36:59 -07:00
} ) ;
2017-08-01 18:55:54 -07:00
test ( 'should properly handle undefined template interpolated values' , t => {
2019-03-12 12:53:03 +00:00
const instance = new chalk . Instance ( { level : 0 } ) ;
2018-09-18 14:05:08 +07:00
t . is ( instance ` hello ${ undefined } ` , 'hello undefined' ) ;
t . is ( instance ` hello ${ null } ` , 'hello null' ) ;
2017-08-01 18:55:54 -07:00
} ) ;
2019-07-12 08:35:11 +02:00
test ( 'should allow bracketed Unicode escapes' , t => {
const instance = new chalk . Instance ( { level : 3 } ) ;
t . is ( instance ` \u {AB} ` , '\u{AB}' ) ;
t . is ( instance ` This is a {bold \u {AB681}} test ` , 'This is a \u001B[1m\u{AB681}\u001B[22m test' ) ;
t . is ( instance ` This is a {bold \u {10FFFF}} test ` , 'This is a \u001B[1m\u{10FFFF}\u001B[22m test' ) ;
} ) ;
2020-04-27 13:37:30 +02:00
test ( 'should support nested calls' , t => {
const instance = new chalk . Instance ( { level : 3 } ) ;
const name = 'Sindre' ;
const exclamation = 'Neat' ;
const result = instance . bold ` {bold Hello, {cyan.inverse ${ name } !} This is a test. {green ${ exclamation } !}} ` ;
t . is ( result , '\u001B[1mHello, \u001B[22m\u001B[1m\u001B[36m\u001B[7mSindre!\u001B[27m\u001B[39m\u001B[22m\u001B[1m This is a test. \u001B[22m\u001B[1m\u001B[32mNeat!\u001B[39m\u001B[22m' ) ;
} ) ;