koffi
Version:
Fast and simple C FFI (foreign function interface) for Node.js
263 lines (239 loc) • 10.4 kB
JavaScript
/*
* First tests are for setting and getting the ObjectReference on the
* casted Array as Object. Then the tests are for the ObjectReference
* to an empty Object. They test setting the ObjectReference with a C
* string, a JavaScript string, and a JavaScript Number as the keys.
* Then getting the value of those keys through the Reference function
* Value() and through the ObjectReference getters. Finally, they test
* Unref() and Ref() to determine if the reference count is as
* expected and errors are thrown when expected.
*/
'use strict';
const assert = require('assert');
const testUtil = require('./testUtil');
module.exports = require('./common').runTest(test);
const enumType = {
JS: 0, // Napi::Value
C_STR: 1, // const char *
CPP_STR: 2, // std::string
BOOL: 3, // bool
INT: 4, // uint32_t
DOUBLE: 5, // double
JS_CAST: 6 // napi_value
};
const configObjects = [
{ keyType: enumType.C_STR, valType: enumType.JS, key: 'hello', val: 'worlds' },
{ keyType: enumType.C_STR, valType: enumType.C_STR, key: 'hello', val: 'worldd' },
{ keyType: enumType.C_STR, valType: enumType.BOOL, key: 'hello', val: false },
{ keyType: enumType.C_STR, valType: enumType.DOUBLE, key: 'hello', val: 3.56 },
{ keyType: enumType.C_STR, valType: enumType.JS_CAST, key: 'hello_cast', val: 'world' },
{ keyType: enumType.CPP_STR, valType: enumType.JS, key: 'hello_cpp', val: 'world_js' },
{ keyType: enumType.CPP_STR, valType: enumType.JS_CAST, key: 'hello_cpp', val: 'world_js_cast' },
{ keyType: enumType.CPP_STR, valType: enumType.CPP_STR, key: 'hello_cpp', val: 'world_cpp_str' },
{ keyType: enumType.CPP_STR, valType: enumType.BOOL, key: 'hello_cpp', val: true },
{ keyType: enumType.CPP_STR, valType: enumType.DOUBLE, key: 'hello_cpp', val: 3.58 },
{ keyType: enumType.INT, valType: enumType.JS, key: 1, val: 'hello world' },
{ keyType: enumType.INT, valType: enumType.JS_CAST, key: 2, val: 'hello world' },
{ keyType: enumType.INT, valType: enumType.C_STR, key: 3, val: 'hello world' },
{ keyType: enumType.INT, valType: enumType.CPP_STR, key: 8, val: 'hello world' },
{ keyType: enumType.INT, valType: enumType.BOOL, key: 3, val: false },
{ keyType: enumType.INT, valType: enumType.DOUBLE, key: 4, val: 3.14159 }
];
function test (binding) {
binding.objectreference.moveOpTest();
function testCastedEqual (testToCompare) {
const compareTest = ['hello', 'world', '!'];
if (testToCompare instanceof Array) {
assert.deepEqual(compareTest, testToCompare);
} else if (testToCompare instanceof String) {
assert.deepEqual('No Referenced Value', testToCompare);
} else {
assert.fail();
}
}
return testUtil.runGCTests([
'Weak Casted Array',
() => {
binding.objectreference.setCastedObjects();
const test = binding.objectreference.getCastedFromValue('weak');
const test2 = [];
test2[0] = binding.objectreference.getCastedFromGetter('weak', 0);
test2[1] = binding.objectreference.getCastedFromGetter('weak', 1);
test2[2] = binding.objectreference.getCastedFromGetter('weak', 2);
testCastedEqual(test);
testCastedEqual(test2);
},
'Persistent Casted Array',
() => {
binding.objectreference.setCastedObjects();
const test = binding.objectreference.getCastedFromValue('persistent');
const test2 = [];
test2[0] = binding.objectreference.getCastedFromGetter('persistent', 0);
test2[1] = binding.objectreference.getCastedFromGetter('persistent', 1);
test2[2] = binding.objectreference.getCastedFromGetter('persistent', 2);
assert.ok(test instanceof Array);
assert.ok(test2 instanceof Array);
testCastedEqual(test);
testCastedEqual(test2);
},
'References Casted Array',
() => {
binding.objectreference.setCastedObjects();
const test = binding.objectreference.getCastedFromValue();
const test2 = [];
test2[0] = binding.objectreference.getCastedFromGetter('reference', 0);
test2[1] = binding.objectreference.getCastedFromGetter('reference', 1);
test2[2] = binding.objectreference.getCastedFromGetter('reference', 2);
assert.ok(test instanceof Array);
assert.ok(test2 instanceof Array);
testCastedEqual(test);
testCastedEqual(test2);
},
'Weak',
() => {
for (const configObject of configObjects) {
binding.objectreference.setObject(configObject);
const test = binding.objectreference.getFromValue('weak');
const test2 = binding.objectreference.getFromGetters('weak', configObject);
const assertObject = {
[configObject.key]: configObject.val
};
assert.deepEqual(assertObject, test);
assert.equal(configObject.val, test2);
}
}, () => {
const configObjA = { keyType: enumType.INT, valType: enumType.JS, key: 0, val: 'hello' };
const configObjB = { keyType: enumType.INT, valType: enumType.JS, key: 1, val: 'world' };
binding.objectreference.setObject(configObjA);
binding.objectreference.setObject(configObjB);
const test = binding.objectreference.getFromValue('weak');
const test2 = binding.objectreference.getFromGetters('weak', configObjA);
const test3 = binding.objectreference.getFromGetters('weak', configObjB);
assert.deepEqual({ 1: 'world' }, test);
assert.equal(undefined, test2);
assert.equal('world', test3);
},
() => {
binding.objectreference.setObject({ keyType: enumType.JS, valType: enumType.JS, key: 'hello', val: 'world' });
assert.doesNotThrow(
() => {
let rcount = binding.objectreference.refObjects('weak');
assert.equal(rcount, 1);
rcount = binding.objectreference.unrefObjects('weak');
assert.equal(rcount, 0);
},
Error
);
assert.throws(
() => {
binding.objectreference.unrefObjects('weak');
},
Error
);
},
'Persistent',
() => {
for (const configObject of configObjects) {
binding.objectreference.setObject(configObject);
const test = binding.objectreference.getFromValue('persistent');
const test2 = binding.objectreference.getFromGetters('persistent', configObject);
const assertObject = {
[configObject.key]: configObject.val
};
assert.deepEqual(assertObject, test);
assert.equal(configObject.val, test2);
}
},
() => {
binding.objectreference.setObject({ keyType: enumType.CPP_STR, valType: enumType.JS, key: 'hello', val: 'world' });
const test = binding.objectreference.getFromValue('persistent');
const test2 = binding.objectreference.getFromValue('persistent', 'hello');
assert.deepEqual({ hello: 'world' }, test);
assert.deepEqual({ hello: 'world' }, test2);
assert.deepEqual(test, test2);
},
() => {
const configObjA = { keyType: enumType.INT, valType: enumType.JS, key: 0, val: 'hello' };
const configObjB = { keyType: enumType.INT, valType: enumType.JS, key: 1, val: 'world' };
binding.objectreference.setObject(configObjA);
binding.objectreference.setObject(configObjB);
const test = binding.objectreference.getFromValue('persistent');
const test2 = binding.objectreference.getFromGetters('persistent', configObjA);
const test3 = binding.objectreference.getFromGetters('persistent', configObjB);
assert.deepEqual({ 1: 'world' }, test);
assert.equal(undefined, test2);
assert.equal('world', test3);
},
() => {
binding.objectreference.setObject({ keyType: enumType.CPP_STR, valType: enumType.JS, key: 'hello', val: 'world' });
assert.doesNotThrow(
() => {
let rcount = binding.objectreference.unrefObjects('persistent');
assert.equal(rcount, 0);
rcount = binding.objectreference.refObjects('persistent');
assert.equal(rcount, 1);
rcount = binding.objectreference.unrefObjects('persistent');
assert.equal(rcount, 0);
rcount = binding.objectreference.refObjects('persistent');
assert.equal(rcount, 1);
rcount = binding.objectreference.unrefObjects('persistent');
assert.equal(rcount, 0);
},
Error
);
assert.throws(
() => {
binding.objectreference.unrefObjects('persistent');
},
Error
);
},
'References',
() => {
for (const configObject of configObjects) {
binding.objectreference.setObject(configObject);
const test = binding.objectreference.getFromValue();
const test2 = binding.objectreference.getFromGetters('reference', configObject);
const assertObject = {
[configObject.key]: configObject.val
};
assert.deepEqual(assertObject, test);
assert.equal(configObject.val, test2);
}
},
() => {
const configObjA = { keyType: enumType.INT, valType: enumType.JS, key: 0, val: 'hello' };
const configObjB = { keyType: enumType.INT, valType: enumType.JS, key: 1, val: 'world' };
binding.objectreference.setObject(configObjA);
binding.objectreference.setObject(configObjB);
const test = binding.objectreference.getFromValue();
const test2 = binding.objectreference.getFromGetters('reference', configObjA);
const test3 = binding.objectreference.getFromGetters('reference', configObjB);
assert.deepEqual({ 1: 'world' }, test);
assert.equal(undefined, test2);
assert.equal('world', test3);
},
() => {
binding.objectreference.setObject({ keyType: enumType.CPP_STR, valType: enumType.JS, key: 'hello', val: 'world' });
assert.doesNotThrow(
() => {
let rcount = binding.objectreference.unrefObjects('references');
assert.equal(rcount, 1);
rcount = binding.objectreference.refObjects('references');
assert.equal(rcount, 2);
rcount = binding.objectreference.unrefObjects('references');
assert.equal(rcount, 1);
rcount = binding.objectreference.unrefObjects('references');
assert.equal(rcount, 0);
},
Error
);
assert.throws(
() => {
binding.objectreference.unrefObjects('references');
},
Error
);
}
]);
}