import { assert } from 'chai'; import { create, assign } from '../../../../../../lib/core/object'; import { MetaContext, $CONSTRUCTOR, $NAME } from '../../../../../../lib/experimental/meta/MetaContext'; import { $STRINGIFY, withStringify } from '../../../../../../lib/experimental/meta/operations/base/$stringify'; import { withRegisterClass } from '../../../../../../lib/experimental/meta/extensions/registerClass'; import { withRegisterFunction } from '../../../../../../lib/experimental/meta/extensions/registerFunction'; import builtins from '../../../../../../lib/experimental/meta/operations/builtins/$stringify'; const stringify = (function () { const context = new (withRegisterFunction(withRegisterClass(withStringify(MetaContext))))(); context.registerAll(builtins); function stringify(obj: T) { return context[$STRINGIFY](obj); }; stringify.registerClass = function (props: any) { return context.registerClass(props); }; stringify.registerFunction = function (props: any) { return context.registerFunction(props); }; return stringify; })(); describe('experimental.meta.operations.builtins.$stringify', () => { describe('string', () => { test.each([ ['', "''"], ['bar', "'bar'"], ['"bar"', "'\"bar\"'"], ["'bar'", "'\\'bar\\''"], ])('String#%#', (str: string, result: string) => { assert.strictEqual(stringify(str), result); }); }); describe('String', () => { test.each([ ['', "String { '' }"], ['bar', "String { 'bar' }"], ['"bar"', "String { '\"bar\"' }"], ["'bar'", "String { '\\'bar\\'' }"], [123, "String { '123' }"], ])('String#%#', (value: any, result: string) => { const str = new String(value); assert.strictEqual(stringify(str), result); }); }); describe('number', () => { test.each([ [0, '0'], [10000, '10000'], [3.1415, '3.1415'], ])('number#%#', (num: number, result: string) => { assert.strictEqual(stringify(num), result); }); }); describe('Number', () => { test.each([ [0, 'Number { 0 }'], [10000, 'Number { 10000 }'], [3.1415, 'Number { 3.1415 }'], ['123', 'Number { 123 }'], ])('Number#%#', (value: number, result: string) => { const num = new Number(value); assert.strictEqual(stringify(num), result); }); }); describe('boolean', () => { test.each([ [false, 'false'], [true, 'true'] ])('boolean#%#', (bool: boolean, result: string) => { assert.strictEqual(stringify(bool), result); }); }); describe('Boolean', () => { test.each([ [false, 'Boolean { false }'], [true, 'Boolean { true }'], [0, 'Boolean { false }'], [NaN, 'Boolean { false }'], [123, 'Boolean { true }'], [undefined, 'Boolean { false }'], [null, 'Boolean { false }'], ['', 'Boolean { false }'], ['123', 'Boolean { true }'], [{}, 'Boolean { true }'], [[], 'Boolean { true }'], ])('Boolean#%#', (value: boolean, result: string) => { const bool = new Boolean(value); assert.strictEqual(stringify(bool), result); }); }); describe('undefined', () => { it('undefined', () => { assert.strictEqual(stringify(undefined), 'undefined'); }); }); describe('null', () => { it('null', () => { assert.strictEqual(stringify(null), 'null'); }); }); describe('Object', () => { test.each([ [{}, '{}'], [{ x: 1, y: 2 }, '{ x: 1, y: 2 }'], [{ 1: 'a', 2: 'b' }, "{ '1': 'a', '2': 'b' }"], [{ v: [1, 2, 3], str: 'foo', p: { x: 1, y: 2 } }, "{ v: [ 1, 2, 3 ], str: 'foo', p: { x: 1, y: 2 } }"], ])('Object#%#', (obj: any, result: string) => { assert.strictEqual(stringify(obj), result); }); }); describe('object', () => { test.each([ [{}, 'object {}'], [{ x: 1, y: 2 }, 'object { x: 1, y: 2 }'], [{ 1: 'a', 2: 'b' }, "object { '1': 'a', '2': 'b' }"], [{ v: [1, 2, 3], str: 'foo', p: { x: 1, y: 2 } }, "object { v: [ 1, 2, 3 ], str: 'foo', p: { x: 1, y: 2 } }"], ])('object#%#', (value: any, result: string) => { const obj = assign(create(), value); assert.strictEqual(stringify(obj), result); }); }); describe('function', () => { it('function', () => { function add(a: number, b: number) { return a + b; } function mul(a: number, b: number) { return a * b; } stringify.registerFunction({ [$CONSTRUCTOR]: add, [$NAME]: 'add' }); assert.throws(() => { stringify(mul); }); assert.strictEqual(stringify(add), 'add() {}'); }); }); describe('Date', () => { const now = Date.now(); test.each([ [new Date(now), `Date { '${new Date(now).toISOString()}' }`], [new Date('2013-02-01'), `Date { '2013-02-01T00:00:00.000Z' }`], ])('Date#%#', (date: Date, result: string) => { assert.strictEqual(stringify(date), result); }); }); describe('Array', () => { test.each([ [[], '[]'], [[1, 2, 3], '[ 1, 2, 3 ]'], [[1, 'abc', []], "[ 1, 'abc', [] ]"], [[1, 'abc', [1, 'abc']], "[ 1, 'abc', [ 1, 'abc' ] ]"], ])('Array#%#', (array: any[], result: string) => { assert.strictEqual(stringify(array), result); }); }); describe('Map', () => { test.each([ [[], 'Map {}'], [[['a', 1], ['b', 2], ['c', 3]], 'Map { a: 1, b: 2, c: 3 }'], [[['p', { x: 1, y: 2 }], ['v', [1, 2, 3]], ['foo', 'bar']], "Map { p: { x: 1, y: 2 }, v: [ 1, 2, 3 ], foo: 'bar' }"], [[['@foo', 'bar'], [{ x: 1, y: 2 }, 3], ['m', new Map()]], "Map { '@foo': 'bar', { x: 1, y: 2 }: 3, m: Map {} }"], ])('Map#%#', (value: [any, any][], result: string) => { const map = new Map(value); assert.strictEqual(stringify(map), result); }); }); describe('Set', () => { test.each([ [[], 'Set {}'], [[1, 2], 'Set { 1, 2 }'], [[{}], 'Set { {} }'], [[{ x: 1, y: 2 }], 'Set { { x: 1, y: 2 } }'], [[{ x: 1, y: 2 }, [1, 2, 3], 'foo'], "Set { { x: 1, y: 2 }, [ 1, 2, 3 ], 'foo' }"], ])('Set#%#', (value: any[], result: string) => { const set = new Set(value); assert.strictEqual(stringify(set), result); }); }); describe('TypedArrays', () => { describe('Uint8Array', () => { test.each([ [[], 'Uint8Array []'], [[11, 21, 31], 'Uint8Array [ 11, 21, 31 ]'], ])('Uint8Array#%#', (value: number[], result: string) => { const arr = new Uint8Array(value); assert.strictEqual(stringify(arr), result); }); }); }); describe('class', () => { class Point { constructor(public x = 0, public y = 0) { } } class Polygon { constructor(public points: Point[] = []) { } } class Triangle extends Polygon { constructor(p1: Point, p2: Point, p3: Point, public color = 'black') { super([p1, p2, p3]); } } stringify.registerClass({ [$CONSTRUCTOR]: Point, [$NAME]: 'Point' }); stringify.registerClass({ [$CONSTRUCTOR]: Polygon, [$NAME]: 'Polygon' }); stringify.registerClass({ [$CONSTRUCTOR]: Triangle, [$NAME]: 'Triangle' }); describe('Point', () => { test.each([ [ new Point(), 'Point { x: 0, y: 0 }' ], [ new Point(1, 2), 'Point { x: 1, y: 2 }' ] ])('Point#%#', (point: Point, result: string) => { assert.strictEqual(stringify(point), result); }); }); describe('Polygon', () => { test.each([ [ new Polygon(), 'Polygon { points: [] }' ], [ new Polygon([new Point(1, 2), new Point(2, 3), new Point(3, 1)]), 'Polygon { points: [ Point { x: 1, y: 2 }, Point { x: 2, y: 3 }, Point { x: 3, y: 1 } ] }' ] ])('Polygon#%#', (poly: Polygon, result: string) => { assert.strictEqual(stringify(poly), result); }); }); describe('Triangle', () => { test.each([ [ new Triangle(new Point(1, 2), new Point(2, 3), new Point(3, 1), 'red'), "Triangle { points: [ Point { x: 1, y: 2 }, Point { x: 2, y: 3 }, Point { x: 3, y: 1 } ], color: 'red' }" ] ])('Triangle#%#', (tri: Triangle, result: string) => { assert.strictEqual(stringify(tri), result); }); }); }); });