import { expect } from 'chai';
import { describe, it } from 'mocha';
import { inspect } from '../inspect.js';
describe('inspect', () => {
it('undefined', () => {
expect(inspect(undefined)).to.equal('undefined');
});
it('null', () => {
expect(inspect(null)).to.equal('null');
});
it('boolean', () => {
expect(inspect(true)).to.equal('true');
expect(inspect(false)).to.equal('false');
});
it('string', () => {
expect(inspect('')).to.equal('""');
expect(inspect('abc')).to.equal('"abc"');
expect(inspect('"')).to.equal('"\\""');
});
it('number', () => {
expect(inspect(0.0)).to.equal('0');
expect(inspect(3.14)).to.equal('3.14');
expect(inspect(NaN)).to.equal('NaN');
expect(inspect(Infinity)).to.equal('Infinity');
expect(inspect(-Infinity)).to.equal('-Infinity');
});
it('function', () => {
const unnamedFuncStr = inspect(
() => expect.fail('Should not be called'),
);
expect(unnamedFuncStr).to.equal('[function]');
function namedFunc() {
expect.fail('Should not be called');
}
expect(inspect(namedFunc)).to.equal('[function namedFunc]');
});
it('array', () => {
expect(inspect([])).to.equal('[]');
expect(inspect([null])).to.equal('[null]');
expect(inspect([1, NaN])).to.equal('[1, NaN]');
expect(inspect([['a', 'b'], 'c'])).to.equal('[["a", "b"], "c"]');
expect(inspect([[[]]])).to.equal('[[[]]]');
expect(inspect([[['a']]])).to.equal('[[[Array]]]');
expect(inspect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])).to.equal(
'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]',
);
expect(inspect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])).to.equal(
'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ... 1 more item]',
);
expect(inspect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])).to.equal(
'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ... 2 more items]',
);
});
it('object', () => {
expect(inspect({})).to.equal('{}');
expect(inspect({ a: 1 })).to.equal('{ a: 1 }');
expect(inspect({ a: 1, b: 2 })).to.equal('{ a: 1, b: 2 }');
expect(inspect({ array: [null, 0] })).to.equal('{ array: [null, 0] }');
expect(inspect({ a: { b: {} } })).to.equal('{ a: { b: {} } }');
expect(inspect({ a: { b: { c: 1 } } })).to.equal('{ a: { b: [Object] } }');
const map = Object.create(null);
map.a = true;
map.b = null;
expect(inspect(map)).to.equal('{ a: true, b: null }');
});
it('use toJSON if provided', () => {
const object = {
toJSON() {
return '<json value>';
},
};
expect(inspect(object)).to.equal('<json value>');
});
it('handles toJSON that return `this` should work', () => {
const object = {
toJSON() {
return this;
},
};
expect(inspect(object)).to.equal('{ toJSON: [function toJSON] }');
});
it('handles toJSON returning object values', () => {
const object = {
toJSON() {
return { json: 'value' };
},
};
expect(inspect(object)).to.equal('{ json: "value" }');
});
it('handles toJSON function that uses this', () => {
const object = {
str: 'Hello World!',
toJSON() {
return this.str;
},
};
expect(inspect(object)).to.equal('Hello World!');
});
it('detect circular objects', () => {
const obj: { [name: string]: unknown } = {};
obj.self = obj;
obj.deepSelf = { self: obj };
expect(inspect(obj)).to.equal(
'{ self: [Circular], deepSelf: { self: [Circular] } }',
);
const array: any = [];
array[0] = array;
array[1] = [array];
expect(inspect(array)).to.equal('[[Circular], [[Circular]]]');
const mixed: any = { array: [] };
mixed.array[0] = mixed;
expect(inspect(mixed)).to.equal('{ array: [[Circular]] }');
const customA = {
toJSON: () => customB,
};
const customB = {
toJSON: () => customA,
};
expect(inspect(customA)).to.equal('[Circular]');
});
it('Use class names for the short form of an object', () => {
class Foo {
foo: string;
constructor() {
this.foo = 'bar';
}
}
expect(inspect([[new Foo()]])).to.equal('[[[Foo]]]');
class Foo2 {
foo: string;
[Symbol.toStringTag] = 'Bar';
constructor() {
this.foo = 'bar';
}
}
expect(inspect([[new Foo2()]])).to.equal('[[[Bar]]]');
const objectWithoutClassName = new (function (this: any) {
this.foo = 1;
} as any)();
expect(inspect([[objectWithoutClassName]])).to.equal('[[[Object]]]');
});
});