UNPKG

chromafi

Version:

💥 Syntax highlight to console: any function - any - object - any language.

176 lines (151 loc) • 14.3 kB
import test from 'ava' import chalk from 'chalk' import chromafi from '.' // Encode: get escaped, testable string of correct result // const encode = result => { // const json = JSON.stringify(result) // console.log(json.replace(/\'/g, '\\\'')) // } test('JavaScript function', t => { function add (a, b) { return a + b } const result = chromafi(add) t.is(typeof result, 'string') // eslint-disable-next-line unicorn/escape-case t.is(result, '\u001b[37m\u001b[90m 1 \u001b[37m \u001b[37m\u001b[31mfunction\u001b[37m \u001b[32madd\u001b[37m(\u001b[34ma, b\u001b[37m) \u001b[37m{ \u001b[39m\n\u001b[37m\u001b[90m 2 \u001b[37m \u001b[31mreturn\u001b[37m a + b; \u001b[39m\n\u001b[37m\u001b[90m 3 \u001b[37m } \u001b[39m\n\u001b[37m\u001b[39m') }) test('JavaScript object', t => { const obj = { foo: 'bar', baz: 1337, qux: true, zxc: null, // eslint-disable-next-line object-shorthand 'foogle-bork': function (a, b) { return b - a } } const result = chromafi(obj) t.is(typeof result, 'string') // eslint-disable-next-line unicorn/escape-case t.is(result, '\u001b[37m\u001b[90m 1 \u001b[37m { \u001b[39m\n\u001b[37m\u001b[90m 2 \u001b[37m \u001b[33mfoo:\u001b[37m \u001b[33m\'bar\'\u001b[37m, \u001b[39m\n\u001b[37m\u001b[90m 3 \u001b[37m \u001b[33mbaz:\u001b[37m \u001b[32m1337\u001b[37m, \u001b[39m\n\u001b[37m\u001b[90m 4 \u001b[37m \u001b[33mqux:\u001b[37m \u001b[35mtrue\u001b[37m, \u001b[39m\n\u001b[37m\u001b[90m 5 \u001b[37m \u001b[33mzxc:\u001b[37m \u001b[35mnull\u001b[37m, \u001b[39m\n\u001b[37m\u001b[90m 6 \u001b[37m \u001b[36m\'foogle-bork\':\u001b[37m \u001b[37m\u001b[37m\u001b[31mfunction\u001b[37m (\u001b[34ma, b\u001b[37m) \u001b[37m{\u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 7 \u001b[37m \u001b[37m \u001b[31mreturn\u001b[37m b - a;\u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 8 \u001b[37m \u001b[37m }\u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 9 \u001b[37m } \u001b[39m\n\u001b[37m\u001b[39m') }) test('JavaScript code string', t => { const code = ` const a = 2 function abc = (d, e, f) { return 'foo' } const b = 2 const c = (a, b) => { return b - a } var str = "Hello, world!" console.log(true, null, new Date()) const jsObj = { foo: 'bar', baz: 1337, qux: true, 'test-thing': 'cool', zxc: null, spqr: function (a, b) { return b - a } } ` const result = chromafi(code) t.is(typeof result, 'string') // eslint-disable-next-line unicorn/escape-case t.is(result, '\u001b[37m\u001b[90m 1 \u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 2 \u001b[37m \u001b[31mconst\u001b[37m a = \u001b[32m2\u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 3 \u001b[37m \u001b[37m\u001b[31mfunction\u001b[37m \u001b[32mabc\u001b[37m = (\u001b[34md, e, f\u001b[37m) \u001b[37m{ \u001b[31mreturn\u001b[37m \u001b[33m\'foo\'\u001b[37m } \u001b[39m\n\u001b[37m\u001b[90m 4 \u001b[37m \u001b[31mconst\u001b[37m b = \u001b[32m2\u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 5 \u001b[37m \u001b[31mconst\u001b[37m c = \u001b[37m(\u001b[34ma, b\u001b[37m) =>\u001b[37m { \u001b[39m\n\u001b[37m\u001b[90m 6 \u001b[37m \u001b[31mreturn\u001b[37m b - a \u001b[39m\n\u001b[37m\u001b[90m 7 \u001b[37m } \u001b[39m\n\u001b[37m\u001b[90m 8 \u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 9 \u001b[37m \u001b[31mvar\u001b[37m str = \u001b[33m"Hello, world!"\u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 10 \u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 11 \u001b[37m \u001b[34mconsole\u001b[37m.log(\u001b[35mtrue\u001b[37m, \u001b[35mnull\u001b[37m, \u001b[31mnew\u001b[37m \u001b[34mDate\u001b[37m()) \u001b[39m\n\u001b[37m\u001b[90m 12 \u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 13 \u001b[37m \u001b[31mconst\u001b[37m jsObj = { \u001b[39m\n\u001b[37m\u001b[90m 14 \u001b[37m \u001b[33mfoo\u001b[37m: \u001b[33m\'bar\'\u001b[37m, \u001b[39m\n\u001b[37m\u001b[90m 15 \u001b[37m \u001b[33mbaz\u001b[37m: \u001b[32m1337\u001b[37m, \u001b[39m\n\u001b[37m\u001b[90m 16 \u001b[37m \u001b[33mqux\u001b[37m: \u001b[35mtrue\u001b[37m, \u001b[39m\n\u001b[37m\u001b[90m 17 \u001b[37m \u001b[33m\'test-thing\'\u001b[37m: \u001b[33m\'cool\'\u001b[37m, \u001b[39m\n\u001b[37m\u001b[90m 18 \u001b[37m \u001b[33mzxc\u001b[37m: \u001b[35mnull\u001b[37m, \u001b[39m\n\u001b[37m\u001b[90m 19 \u001b[37m \u001b[33mspqr\u001b[37m: \u001b[37m\u001b[31mfunction\u001b[37m (\u001b[34ma, b\u001b[37m) \u001b[37m{ \u001b[39m\n\u001b[37m\u001b[90m 20 \u001b[37m \u001b[31mreturn\u001b[37m b - a \u001b[39m\n\u001b[37m\u001b[90m 21 \u001b[37m } \u001b[39m\n\u001b[37m\u001b[90m 22 \u001b[37m } \u001b[39m\n\u001b[37m\u001b[90m 23 \u001b[37m \u001b[39m\n\u001b[37m\u001b[39m') }) test('Highlights ARM assembler syntax', t => { const asm = ` .text .global connect connect: mov r3, #2 ; s->sin_family = AF_INET strh r3, [sp] ldr r3, =server_port ; s->sin_port = server_port ldr r3, [r3] strh r3, [sp, #2] ldr r3, =server_addr ; s->sin_addr = server_addr ldr r3, [r3] str r3, [sp, #4] mov r3, #0 ; bzero(&s->sin_zero) str r3, [sp, #8] str r3, [sp, #12] mov r1, sp ; const struct sockaddr *addr = sp ldr r7, =connect_call ldr r7, [r7] swi #0 add sp, sp, #16 pop {r0} ; pop sockfd pop {r7} pop {fp, ip, lr} mov sp, ip bx lr .data socket_call: .long 281 connect_call: .long 283 /* all addresses are network byte-order (big-endian) */ server_addr: .long 0x0100007f ; localhost server_port: .hword 0x0b1a ` const result = chromafi(asm) t.is(typeof result, 'string') // eslint-disable-next-line unicorn/escape-case t.is(result, '\u001b[37m\u001b[90m 1 \u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 2 \u001b[37m .text \u001b[39m\n\u001b[37m\u001b[90m 3 \u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 4 \u001b[37m .global connect \u001b[39m\n\u001b[37m\u001b[90m 5 \u001b[37m connect: \u001b[39m\n\u001b[37m\u001b[90m 6 \u001b[37m mov r3, #2 ; s->sin_family = AF_INET \u001b[39m\n\u001b[37m\u001b[90m 7 \u001b[37m strh r3, [sp] \u001b[39m\n\u001b[37m\u001b[90m 8 \u001b[37m ldr r3, =server_port ; s->sin_port = server_port \u001b[39m\n\u001b[37m\u001b[90m 9 \u001b[37m ldr r3, [r3] \u001b[39m\n\u001b[37m\u001b[90m 10 \u001b[37m strh r3, [sp, #2] \u001b[39m\n\u001b[37m\u001b[90m 11 \u001b[37m ldr r3, =server_addr ; s->sin_addr = server_addr \u001b[39m\n\u001b[37m\u001b[90m 12 \u001b[37m ldr r3, [r3] \u001b[39m\n\u001b[37m\u001b[90m 13 \u001b[37m str r3, [sp, #4] \u001b[39m\n\u001b[37m\u001b[90m 14 \u001b[37m mov r3, #0 ; bzero(&s->sin_zero) \u001b[39m\n\u001b[37m\u001b[90m 15 \u001b[37m str r3, [sp, #8] \u001b[39m\n\u001b[37m\u001b[90m 16 \u001b[37m str r3, [sp, #12] \u001b[39m\n\u001b[37m\u001b[90m 17 \u001b[37m mov r1, sp ; const struct sockaddr *addr = sp \u001b[39m\n\u001b[37m\u001b[90m 18 \u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 19 \u001b[37m ldr r7, =connect_call \u001b[39m\n\u001b[37m\u001b[90m 20 \u001b[37m ldr r7, [r7] \u001b[39m\n\u001b[37m\u001b[90m 21 \u001b[37m swi #0 \u001b[39m\n\u001b[37m\u001b[90m 22 \u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 23 \u001b[37m add sp, sp, #16 \u001b[39m\n\u001b[37m\u001b[90m 24 \u001b[37m pop {r0} ; pop sockfd \u001b[39m\n\u001b[37m\u001b[90m 25 \u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 26 \u001b[37m pop {r7} \u001b[39m\n\u001b[37m\u001b[90m 27 \u001b[37m pop {fp, ip, lr} \u001b[39m\n\u001b[37m\u001b[90m 28 \u001b[37m mov sp, ip \u001b[39m\n\u001b[37m\u001b[90m 29 \u001b[37m bx lr \u001b[39m\n\u001b[37m\u001b[90m 30 \u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 31 \u001b[37m .data \u001b[39m\n\u001b[37m\u001b[90m 32 \u001b[37m socket_call: .long 281 \u001b[39m\n\u001b[37m\u001b[90m 33 \u001b[37m connect_call: .long 283 \u001b[39m\n\u001b[37m\u001b[90m 34 \u001b[37m \u001b[39m\n\u001b[37m\u001b[90m 35 \u001b[37m /* all addresses are network byte-order (big-endian) */ \u001b[39m\n\u001b[37m\u001b[90m 36 \u001b[37m server_addr: .long 0x0100007f ; localhost \u001b[39m\n\u001b[37m\u001b[90m 37 \u001b[37m server_port: .hword 0x0b1a \u001b[39m\n\u001b[37m\u001b[90m 38 \u001b[37m \u001b[39m\n\u001b[37m\u001b[39m') }) test('Change colors', t => { const obj = { foo: 'bar', baz: 1337, qux: true, zxc: null, // eslint-disable-next-line object-shorthand 'foogle-bork': function (a, b) { return b - a } } const options = { colors: { base: chalk.bgWhite.black.bold, keyword: chalk.red, number: chalk.blue.dim, function: chalk.black, title: chalk.blue, params: chalk.black, string: chalk.black, // eslint-disable-next-line camelcase built_in: chalk.blue, literal: chalk.blue, attr: chalk.black, // eslint-disable-next-line camelcase trailing_space: chalk, regexp: chalk.blue, // eslint-disable-next-line camelcase line_numbers: chalk.bgBlue.white } } const result = chromafi(obj, options) t.is(typeof result, 'string') // eslint-disable-next-line unicorn/escape-case t.is(result, '\u001b[47m\u001b[30m\u001b[1m\u001b[44m\u001b[37m 1 \u001b[30m\u001b[47m { \u001b[22m\u001b[39m\u001b[49m\n\u001b[47m\u001b[30m\u001b[1m\u001b[44m\u001b[37m 2 \u001b[30m\u001b[47m \u001b[30mfoo:\u001b[30m \u001b[30m\'bar\'\u001b[30m, \u001b[22m\u001b[39m\u001b[49m\n\u001b[47m\u001b[30m\u001b[1m\u001b[44m\u001b[37m 3 \u001b[30m\u001b[47m \u001b[30mbaz:\u001b[30m \u001b[34m\u001b[2m1337\u001b[1m\u001b[30m, \u001b[22m\u001b[39m\u001b[49m\n\u001b[47m\u001b[30m\u001b[1m\u001b[44m\u001b[37m 4 \u001b[30m\u001b[47m \u001b[30mqux:\u001b[30m \u001b[34mtrue\u001b[30m, \u001b[22m\u001b[39m\u001b[49m\n\u001b[47m\u001b[30m\u001b[1m\u001b[44m\u001b[37m 5 \u001b[30m\u001b[47m \u001b[30mzxc:\u001b[30m \u001b[34mnull\u001b[30m, \u001b[22m\u001b[39m\u001b[49m\n\u001b[47m\u001b[30m\u001b[1m\u001b[44m\u001b[37m 6 \u001b[30m\u001b[47m \u001b[36m\'foogle-bork\':\u001b[30m \u001b[30m\u001b[30m\u001b[31mfunction\u001b[30m (\u001b[30ma, b\u001b[30m) \u001b[30m{\u001b[30m \u001b[22m\u001b[39m\u001b[49m\n\u001b[47m\u001b[30m\u001b[1m\u001b[44m\u001b[37m 7 \u001b[30m\u001b[47m \u001b[30m \u001b[31mreturn\u001b[30m b - a;\u001b[30m \u001b[22m\u001b[39m\u001b[49m\n\u001b[47m\u001b[30m\u001b[1m\u001b[44m\u001b[37m 8 \u001b[30m\u001b[47m \u001b[30m }\u001b[30m \u001b[22m\u001b[39m\u001b[49m\n\u001b[47m\u001b[30m\u001b[1m\u001b[44m\u001b[37m 9 \u001b[30m\u001b[47m } \u001b[22m\u001b[39m\u001b[49m\n\u001b[47m\u001b[30m\u001b[1m\u001b[22m\u001b[39m\u001b[49m') }) test('Change options', t => { const obj = {foobar: 1337} const options = { lineNumberPad: 0, codePad: 0, indent: 2, lineNumbers: true, colors: { base: chalk.bgBlack.white.bold, // eslint-disable-next-line camelcase line_numbers: chalk.bgCyan.black } } const result = chromafi(obj, options) t.is(typeof result, 'string') // eslint-disable-next-line unicorn/escape-case t.is(result, '\u001b[40m\u001b[37m\u001b[1m\u001b[46m\u001b[30m1\u001b[37m\u001b[40m{ \u001b[22m\u001b[39m\u001b[49m\n\u001b[40m\u001b[37m\u001b[1m\u001b[46m\u001b[30m2\u001b[37m\u001b[40m \u001b[33mfoobar:\u001b[37m \u001b[32m1337\u001b[37m\u001b[22m\u001b[39m\u001b[49m\n\u001b[40m\u001b[37m\u001b[1m\u001b[46m\u001b[30m3\u001b[37m\u001b[40m} \u001b[22m\u001b[39m\u001b[49m\n\u001b[40m\u001b[37m\u001b[1m\u001b[22m\u001b[39m\u001b[49m') })