Skip to content

Commit

Permalink
enable unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Deepak Rajamohan committed Oct 15, 2021
1 parent 2fc9d73 commit bfe9f5e
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 94 deletions.
22 changes: 11 additions & 11 deletions unit-test/binding-file-template.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
module.exports.generateFileContent = function(configs) {
module.exports.generateFileContent = function (bindingConfigurations) {
const content = [];
const inits = [];
const exports = [];

for (let config of configs) {
for (const config of bindingConfigurations) {
inits.push(`Object Init${config.objectName}(Env env);`);
exports.push(`exports.Set(\"${config.propertyName}\", Init${config.objectName}(env));`);
}

content.push("#include \"napi.h\"");
content.push("using namespace Napi;");
content.push('#include "napi.h"');
content.push('using namespace Napi;');

//content.push("Object InitName(Env env);");
// content.push("Object InitName(Env env);");
inits.forEach(init => content.push(init));

content.push("Object Init(Env env, Object exports) {");
content.push('Object Init(Env env, Object exports) {');

//content.push("exports.Set(\"name\", InitName(env));");
// content.push("exports.Set(\"name\", InitName(env));");
exports.forEach(exp => content.push(exp));

content.push("return exports;");
content.push("}");
content.push("NODE_API_MODULE(addon, Init);");
content.push('return exports;');
content.push('}');
content.push('NODE_API_MODULE(addon, Init);');

return Promise.resolve(content.join('\r\n'));
}
};
24 changes: 12 additions & 12 deletions unit-test/exceptions.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
module.exports = {
'nouns': {
'constructor': 'constructor',
'threadsafe': 'threadSafe',
'objectwrap': 'objectWrap',
nouns: {
constructor: 'constructor',
threadsafe: 'threadSafe',
objectwrap: 'objectWrap'
},
'exportNames': {
'AsyncWorkerPersistent': 'PersistentAsyncWorker',
exportNames: {
AsyncWorkerPersistent: 'PersistentAsyncWorker'
},
'propertyNames': {
'async_worker_persistent': 'persistentasyncworker',
'objectwrap_constructor_exception':'objectwrapConstructorException',
propertyNames: {
async_worker_persistent: 'persistentasyncworker',
objectwrap_constructor_exception: 'objectwrapConstructorException'
},
'skipBinding': [
skipBinding: [
'global_object_delete_property',
'global_object_get_property',
'global_object_has_own_property',
'global_object_set_property',
'global_object_set_property'
]
};
};
45 changes: 36 additions & 9 deletions unit-test/generate-binding-cc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ const generateFileContent = require('./binding-file-template').generateFileConte
const buildDirs = listOfTestModules.dirs;
const buildFiles = listOfTestModules.files;

function generateBindingConfigurations() {
const configs = [];

function generateBindingConfigurations () {
const testFilesToBind = process.argv.slice(2);
console.log('test modules to bind: ', testFilesToBind);

const configs = [];

testFilesToBind.forEach((file) => {
const configName = file.split('.cc')[0];

if (buildDirs[configName]) {
for (let file of buildDirs[configName]) {
for (const file of buildDirs[configName]) {
if (exceptions.skipBinding.includes(file)) continue;
configs.push(buildFiles[file]);
}
Expand All @@ -31,11 +31,38 @@ function generateBindingConfigurations() {
return Promise.resolve(configs);
}

function writeToBindingFile(content) {
const generatedFilePath = path.join(__dirname, 'generated', 'binding.cc' );
fs.writeFileSync(generatedFilePath , "" );
fs.writeFileSync(generatedFilePath, content, { flag: "a" } );
console.log('generated binding file ', generatedFilePath, new Date());
function writeToBindingFile (content) {
const generatedFilePath = path.join(__dirname, 'generated', 'binding.cc');
fs.writeFileSync(generatedFilePath, '');
fs.writeFileSync(generatedFilePath, content, { flag: 'a' });
console.log('generated binding file ', generatedFilePath, new Date());
}

generateBindingConfigurations().then(generateFileContent).then(writeToBindingFile);

/**
*
* Test cases
* @fires only when run directly from terminal
*
*
*
*/
if (require.main === module) {
const assert = require('assert');

const setArgsAndCall = (fn, filterCondition) => { process.argv = [null, null, ...filterCondition.split(' ')]; return fn(); };
const assertPromise = (promise, expectedVal) => promise.then((val) => assert.deepEqual(val, expectedVal)).catch(console.log);

const expectedVal = [{
dir: '',
objectName: 'AsyncProgressWorker',
propertyName: 'async_progress_worker'
},
{
dir: '',
objectName: 'PersistentAsyncWorker',
propertyName: 'persistentasyncworker'
}];
assertPromise(setArgsAndCall(generateBindingConfigurations, 'async_progress_worker async_worker_persistent'), expectedVal);
}
45 changes: 35 additions & 10 deletions unit-test/injectTestParams.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,33 @@ const listOfTestModules = require('./listOfTestModules');
const buildDirs = listOfTestModules.dirs;
const buildFiles = listOfTestModules.files;

/**
*
* @returns : list of files to compile by node-gyp
* @param : none
* @requires : picks `filter` parameter from process.env
* This function is used as an utility method to inject a list of files to compile into binding.gyp
*
*
*/
module.exports.filesToCompile = function () {
!fs.existsSync('./generated/') && fs.mkdirSync('./generated/', { recursive: true });

const filterCondition = require('./matchModules').matchWildCards(process.env.filter || '');
let files_to_compile = './generated/binding.cc test_helper.h';
let conditions = filterCondition.split(' ').length ? filterCondition.split(' ') : [filterCondition];
let files = [];
const files_to_compile = './generated/binding.cc test_helper.h';
const conditions = filterCondition.split(' ').length ? filterCondition.split(' ') : [filterCondition];
const files = [];

for (let matchCondition of conditions) {
for (const matchCondition of conditions) {
if (buildDirs[matchCondition.toLowerCase()]) {
for (let file of buildDirs[matchCondition.toLowerCase()] ) {
for (const file of buildDirs[matchCondition.toLowerCase()]) {
const config = buildFiles[file];
const separator = config.dir.length ? '/' : ''
const separator = config.dir.length ? '/' : '';
files.push(config.dir + separator + file);
}
} else if (buildFiles[matchCondition.toLowerCase()]) {
const config = buildFiles[matchCondition.toLowerCase()];
const separator = config.dir.length ? '/' : ''
const separator = config.dir.length ? '/' : '';
files.push(config.dir + separator + matchCondition.toLowerCase());
}
}
Expand All @@ -32,13 +43,27 @@ module.exports.filesToCompile = function () {
return `${files_to_compile} ${addedFiles}`;
};

/**
* @returns list of test files to bind exported init functions
* @param : none
* @requires : picks `filter` parameter from process.env
* This function is used as an utility method by the generateBindingCC step in binding.gyp
*
*/
module.exports.filesForBinding = function () {
const filterCondition = require('./matchModules').matchWildCards(process.env.filter || '');
fs.writeFileSync(__dirname + '/generated/bindingList', filterCondition);
return filterCondition;
};


/**
*
* Test cases
* @fires only when run directly from terminal
*
*
*
*/
if (require.main === module) {
const assert = require('assert');

Expand All @@ -60,10 +85,10 @@ if (require.main === module) {
'../test/typed_threadsafe_function/typed_threadsafe_function_ptr.cc',
'../test/typed_threadsafe_function/typed_threadsafe_function_sum.cc',
'../test/typed_threadsafe_function/typed_threadsafe_function_unref.cc'
]
];
assert.strictEqual(setEnvAndCall(exports.filesToCompile, 'threadsafe_function typed_threadsafe_function'), expectedFilesToMatch.join(' '));

assert.strictEqual(setEnvAndCall(exports.filesToCompile, 'objectwrap'), './generated/binding.cc test_helper.h ../test/objectwrap.cc');

console.log('ALL tests passed')
console.log('ALL tests passed');
}
39 changes: 23 additions & 16 deletions unit-test/listOfTestModules.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const exceptions = require('./exceptions');
const buildFiles = {};
const buidDirs = {};

function getExportObjectName(fileName) {
function getExportObjectName (fileName) {
fileName = fileName.split('_').map(token => exceptions.nouns[token] ? exceptions.nouns[token] : token).join('_');
const str = fileName.replace(/(\_\w)/g, (k) => k[1].toUpperCase());
const exportObjectName = str.charAt(0).toUpperCase() + str.substring(1);
Expand All @@ -15,14 +15,14 @@ function getExportObjectName(fileName) {
return exportObjectName;
}

function getExportPropertyName(fileName) {
function getExportPropertyName (fileName) {
if (exceptions.propertyNames[fileName.toLowerCase()]) {
return exceptions.propertyNames[fileName.toLowerCase()];
}
return fileName;
}

function listOfTestModules(currentDirectory = __dirname + '/../test', pre = '') {
function listOfTestModules (currentDirectory = __dirname + '/../test', pre = '') {
fs.readdirSync(currentDirectory).forEach((file) => {
if (file === 'binding.cc' ||
file === 'binding.gyp' ||
Expand All @@ -31,17 +31,17 @@ function listOfTestModules(currentDirectory = __dirname + '/../test', pre = '')
file === 'thunking_manual.cc' ||
file === 'addon_build' ||
file[0] === '.') {
return;
return;
}
const absoluteFilepath = path.join(currentDirectory, file);
const fileName = file.toLowerCase().replace('.cc', '');
if (fs.statSync(absoluteFilepath).isDirectory()) {
buidDirs[fileName] = []
buidDirs[fileName] = [];
listOfTestModules(absoluteFilepath, pre + file + '/');
} else {
if (!file.toLowerCase().endsWith('.cc')) return;
if (currentDirectory.trim().split('/test/').length > 1) {
buidDirs[currentDirectory.split('/test/')[1].toLowerCase()].push(fileName)
buidDirs[currentDirectory.split('/test/')[1].toLowerCase()].push(fileName);
}
const relativePath = (currentDirectory.split(`${fileName}.cc`)[0]).split('/test/')[1] || '';
buildFiles[fileName] = { dir: relativePath, propertyName: getExportPropertyName(fileName), objectName: getExportObjectName(fileName) };
Expand All @@ -55,16 +55,23 @@ module.exports = {
files: buildFiles
};


/**
*
* Test cases
* @fires only when run directly from terminal
*
*
*
*/
if (require.main === module) {
const assert = require('assert')
assert.strictEqual(getExportObjectName('objectwrap_constructor_exception'), 'ObjectWrapConstructorException')
assert.strictEqual(getExportObjectName('typed_threadsafe_function'), 'TypedThreadSafeFunction')
assert.strictEqual(getExportObjectName('objectwrap_removewrap'), 'ObjectWrapRemovewrap')
assert.strictEqual(getExportObjectName('function_reference'), 'FunctionReference')
assert.strictEqual(getExportObjectName('async_worker'), 'AsyncWorker')
assert.strictEqual(getExportObjectName('async_progress_worker'), 'AsyncProgressWorker')
assert.strictEqual(getExportObjectName('async_worker_persistent'), 'PersistentAsyncWorker')
const assert = require('assert');
assert.strictEqual(getExportObjectName('objectwrap_constructor_exception'), 'ObjectWrapConstructorException');
assert.strictEqual(getExportObjectName('typed_threadsafe_function'), 'TypedThreadSafeFunction');
assert.strictEqual(getExportObjectName('objectwrap_removewrap'), 'ObjectWrapRemovewrap');
assert.strictEqual(getExportObjectName('function_reference'), 'FunctionReference');
assert.strictEqual(getExportObjectName('async_worker'), 'AsyncWorker');
assert.strictEqual(getExportObjectName('async_progress_worker'), 'AsyncProgressWorker');
assert.strictEqual(getExportObjectName('async_worker_persistent'), 'PersistentAsyncWorker');

console.log('ALL tests passed')
console.log('ALL tests passed');
}
63 changes: 35 additions & 28 deletions unit-test/matchModules.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,27 @@ const listOfTestModules = require('./listOfTestModules');
const buildDirs = listOfTestModules.dirs;
const buildFiles = listOfTestModules.files;

function isWildcard(filter) {
function isWildcard (filter) {
if (filter.includes('*')) return true;
return false;
}

function filterBy(wildcard, item) {
return new RegExp('^' + wildcard.replace(/\*/g, '.*') + '$').test(item)
function filterBy (wildcard, item) {
return new RegExp('^' + wildcard.replace(/\*/g, '.*') + '$').test(item);
}

function matchWildCards(filterCondition) {
let conditions = filterCondition.split(' ').length ? filterCondition.split(' ') : [filterCondition];
let matches = [];
function matchWildCards (filterCondition) {
const conditions = filterCondition.split(' ').length ? filterCondition.split(' ') : [filterCondition];
const matches = [];

for (let filter of conditions) {
for (const filter of conditions) {
if (isWildcard(filter)) {
const matchedDirs = Object.keys(buildDirs).filter(e => filterBy(filter, e));
if (matchedDirs.length) {
matches.push(matchedDirs.join(' '));
} else {
const matchedModules = Object.keys(buildFiles).filter(e => filterBy(filter, e));
if (matchedModules.length)
matches.push(matchedModules.join(' '));
if (matchedModules.length) { matches.push(matchedModules.join(' ')); }
}
} else {
matches.push(filter);
Expand All @@ -35,24 +34,32 @@ function matchWildCards(filterCondition) {

module.exports.matchWildCards = matchWildCards;

/**
*
* Test cases
* @fires only when run directly from terminal
*
*
*
*/
if (require.main === module) {
const assert = require('assert')

assert.strictEqual(matchWildCards('typed*ex'), 'typed*ex')
assert.strictEqual(matchWildCards('typed*ex*'), 'typed_threadsafe_function_existing_tsfn')
assert.strictEqual(matchWildCards('async*'), 'async_context async_progress_queue_worker async_progress_worker async_worker async_worker_persistent')
assert.strictEqual(matchWildCards('typed*func'), 'typed*func')
assert.strictEqual(matchWildCards('typed*func*'), 'typed_threadsafe_function')
assert.strictEqual(matchWildCards('typed*function'), 'typed_threadsafe_function')
assert.strictEqual(matchWildCards('object*inh'), 'object*inh')
assert.strictEqual(matchWildCards('object*inh*'), 'objectwrap_multiple_inheritance')
assert.strictEqual(matchWildCards('*remove*'), 'objectwrap_removewrap')
assert.strictEqual(matchWildCards('*function'), 'threadsafe_function typed_threadsafe_function')
assert.strictEqual(matchWildCards('**function'), 'threadsafe_function typed_threadsafe_function')
assert.strictEqual(matchWildCards('a*w*p*'), 'async_worker_persistent')
assert.strictEqual(matchWildCards('fun*ref'), 'fun*ref')
assert.strictEqual(matchWildCards('fun*ref*'), 'function_reference')
assert.strictEqual(matchWildCards('*reference'), 'function_reference object_reference reference')

console.log('ALL tests passed')
const assert = require('assert');

assert.strictEqual(matchWildCards('typed*ex'), 'typed*ex');
assert.strictEqual(matchWildCards('typed*ex*'), 'typed_threadsafe_function_existing_tsfn');
assert.strictEqual(matchWildCards('async*'), 'async_context async_progress_queue_worker async_progress_worker async_worker async_worker_persistent');
assert.strictEqual(matchWildCards('typed*func'), 'typed*func');
assert.strictEqual(matchWildCards('typed*func*'), 'typed_threadsafe_function');
assert.strictEqual(matchWildCards('typed*function'), 'typed_threadsafe_function');
assert.strictEqual(matchWildCards('object*inh'), 'object*inh');
assert.strictEqual(matchWildCards('object*inh*'), 'objectwrap_multiple_inheritance');
assert.strictEqual(matchWildCards('*remove*'), 'objectwrap_removewrap');
assert.strictEqual(matchWildCards('*function'), 'threadsafe_function typed_threadsafe_function');
assert.strictEqual(matchWildCards('**function'), 'threadsafe_function typed_threadsafe_function');
assert.strictEqual(matchWildCards('a*w*p*'), 'async_worker_persistent');
assert.strictEqual(matchWildCards('fun*ref'), 'fun*ref');
assert.strictEqual(matchWildCards('fun*ref*'), 'function_reference');
assert.strictEqual(matchWildCards('*reference'), 'function_reference object_reference reference');

console.log('ALL tests passed');
}
Loading

0 comments on commit bfe9f5e

Please sign in to comment.