'use strict';
const assert = require('assert');
module.exports = require('../common').runTest(test);
function test (binding) {
const externalValue = binding.basic_types_value.createExternal();
function isObject (value) {
return (typeof value === 'object' && value !== externalValue) ||
(typeof value === 'function');
}
function detailedTypeOf (value) {
const type = typeof value;
if (type !== 'object') { return type; }
if (value === null) { return 'null'; }
if (Array.isArray(value)) { return 'array'; }
if (value === externalValue) { return 'external'; }
if (!value.constructor) { return type; }
if (value instanceof ArrayBuffer) { return 'arraybuffer'; }
if (ArrayBuffer.isView(value)) {
if (value instanceof DataView) {
return 'dataview';
} else {
return 'typedarray';
}
}
if (value instanceof Promise) { return 'promise'; }
return 'object';
}
function typeCheckerTest (typeChecker, expectedType) {
const testValueList = [
undefined,
null,
true,
10,
'string',
Symbol('symbol'),
[],
new ArrayBuffer(10),
new Int32Array(new ArrayBuffer(12)),
{},
function () {},
new Promise((resolve, reject) => {}),
new DataView(new ArrayBuffer(12)),
externalValue
];
testValueList.forEach((testValue) => {
if (testValue !== null && expectedType === 'object') {
assert.strictEqual(typeChecker(testValue), isObject(testValue));
} else {
assert.strictEqual(typeChecker(testValue), detailedTypeOf(testValue) === expectedType);
}
});
}
function typeConverterTest (typeConverter, expectedType) {
const testValueList = [
true,
false,
0,
10,
'string',
[],
new ArrayBuffer(10),
new Int32Array(new ArrayBuffer(12)),
{},
function () {},
new Promise((resolve, reject) => {})
];
testValueList.forEach((testValue) => {
const expected = expectedType(testValue);
const actual = typeConverter(testValue);
if (isNaN(expected)) {
assert(isNaN(actual));
} else {
assert.deepStrictEqual(typeConverter(testValue), expectedType(testValue));
}
});
}
function assertValueStrictlyEqual (value) {
const newValue = value.createNonEmptyValue();
assert(value.strictlyEquals(newValue, newValue));
assert(value.strictlyEqualsOverload(newValue, newValue));
}
function assertValueStrictlyNonEqual (value) {
const valueA = value.createNonEmptyValue();
const valueB = value.createExternal();
assert(value.strictlyNotEqualsOverload(valueA, valueB));
}
function assertValueReturnsCorrectEnv (value) {
assert(value.assertValueReturnsCorrectEnv());
}
function assertEmptyValueNullPtrOnCast (value) {
assert(value.assertEmptyValReturnNullPtrOnCast());
}
function assertNonEmptyReturnValOnCast (value) {
assert(value.assertNonEmptyReturnValOnCast());
}
function accessPropTest (value) {
const testObject = { key: '123' };
const testSymbol = Symbol('123');
const testNumber = 123;
const destObj = {
testObject,
testSymbol,
[testNumber]: testNumber
};
assert.strictEqual(value.accessProp(destObj, 'testObject'), testObject);
assert.strictEqual(value.accessProp(destObj, 'testSymbol'), testSymbol);
assert.strictEqual(value.accessProp(destObj, testNumber), testNumber);
assert.strictEqual(value.accessProp(destObj, 'invalidKey'), undefined);
}
const value = binding.basic_types_value;
assertValueStrictlyEqual(value);
assertValueStrictlyNonEqual(value);
assertValueReturnsCorrectEnv(value);
assertEmptyValueNullPtrOnCast(value);
assertNonEmptyReturnValOnCast(value);
typeCheckerTest(value.isUndefined, 'undefined');
typeCheckerTest(value.isNull, 'null');
typeCheckerTest(value.isBoolean, 'boolean');
typeCheckerTest(value.isNumber, 'number');
typeCheckerTest(value.isString, 'string');
typeCheckerTest(value.isSymbol, 'symbol');
typeCheckerTest(value.isArray, 'array');
typeCheckerTest(value.isArrayBuffer, 'arraybuffer');
typeCheckerTest(value.isTypedArray, 'typedarray');
typeCheckerTest(value.isObject, 'object');
typeCheckerTest(value.isFunction, 'function');
typeCheckerTest(value.isPromise, 'promise');
typeCheckerTest(value.isDataView, 'dataview');
typeCheckerTest(value.isExternal, 'external');
typeConverterTest(value.toBoolean, Boolean);
assert.strictEqual(value.toBoolean(undefined), false);
assert.strictEqual(value.toBoolean(null), false);
typeConverterTest(value.toNumber, Number);
assert(isNaN(value.toNumber(undefined)));
assert.strictEqual(value.toNumber(null), 0);
typeConverterTest(value.toString, String);
assert.strictEqual(value.toString(undefined), 'undefined');
assert.strictEqual(value.toString(null), 'null');
typeConverterTest(value.toObject, Object);
accessPropTest(value);
}