Skip to content

Commit

Permalink
test: Write tests for Value class
Browse files Browse the repository at this point in the history
This change includes the following new tests:
  - TypeChecker(e.g. IsUndefined, IsObject) tests
  - TypeConverter from Native to JS(e.g. ToString) tests

PR-URL: nodejs/node-addon-api#197
Reviewed-By: Michael Dawson <[email protected]>
  • Loading branch information
wroy7860 committed Dec 6, 2017
1 parent 1d75f23 commit 4027196
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 0 deletions.
96 changes: 96 additions & 0 deletions test/basic_types/value.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include "napi.h"

using namespace Napi;

static Value IsEmpty(const CallbackInfo& info) {
Value value;
return Boolean::New(info.Env(), value.IsEmpty());
}

static Value IsUndefined(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsUndefined());
}

static Value IsNull(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsNull());
}

static Value IsBoolean(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsBoolean());
}

static Value IsNumber(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsNumber());
}

static Value IsString(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsString());
}

static Value IsSymbol(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsSymbol());
}

static Value IsArray(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsArray());
}

static Value IsArrayBuffer(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsArrayBuffer());
}

static Value IsTypedArray(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsTypedArray());
}

static Value IsObject(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsObject());
}

static Value IsFunction(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsFunction());
}

static Value IsPromise(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].IsPromise());
}

static Value ToBoolean(const CallbackInfo& info) {
return info[0].ToBoolean();
}

static Value ToNumber(const CallbackInfo& info) {
return info[0].ToNumber();
}

static Value ToString(const CallbackInfo& info) {
return info[0].ToString();
}

static Value ToObject(const CallbackInfo& info) {
return info[0].ToObject();
}

Object InitBasicTypesValue(Env env) {
Object exports = Object::New(env);

exports["isEmpty"] = Function::New(env, IsEmpty);
exports["isUndefined"] = Function::New(env, IsUndefined);
exports["isNull"] = Function::New(env, IsNull);
exports["isBoolean"] = Function::New(env, IsBoolean);
exports["isNumber"] = Function::New(env, IsNumber);
exports["isString"] = Function::New(env, IsString);
exports["isSymbol"] = Function::New(env, IsSymbol);
exports["isArray"] = Function::New(env, IsArray);
exports["isArrayBuffer"] = Function::New(env, IsArrayBuffer);
exports["isTypedArray"] = Function::New(env, IsTypedArray);
exports["isObject"] = Function::New(env, IsObject);
exports["isFunction"] = Function::New(env, IsFunction);
exports["isPromise"] = Function::New(env, IsPromise);
exports["toBoolean"] = Function::New(env, ToBoolean);
exports["toNumber"] = Function::New(env, ToNumber);
exports["toString"] = Function::New(env, ToString);
exports["toObject"] = Function::New(env, ToObject);

return exports;
}
116 changes: 116 additions & 0 deletions test/basic_types/value.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
'use strict';

const buildType = process.config.target_defaults.default_configuration;
const assert = require('assert');

test(require(`../build/${buildType}/binding.node`));
test(require(`../build/${buildType}/binding_noexcept.node`));

function test(binding) {
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.constructor)
return type;

if (value instanceof ArrayBuffer)
return 'arraybuffer';

if (ArrayBuffer.isView(value))
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) => {})
];

testValueList.forEach((testValue) => {
if (testValue !== null && expectedType === 'object') {
assert.strictEqual(typeChecker(testValue), typeof testValue === expectedType);
} 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));
}
});
}

const value = binding.basic_types_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');

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);
}
2 changes: 2 additions & 0 deletions test/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ using namespace Napi;
Object InitArrayBuffer(Env env);
Object InitAsyncWorker(Env env);
Object InitBasicTypesNumber(Env env);
Object InitBasicTypesValue(Env env);
Object InitBuffer(Env env);
Object InitError(Env env);
Object InitExternal(Env env);
Expand All @@ -19,6 +20,7 @@ Object Init(Env env, Object exports) {
exports.Set("arraybuffer", InitArrayBuffer(env));
exports.Set("asyncworker", InitAsyncWorker(env));
exports.Set("basic_types_number", InitBasicTypesNumber(env));
exports.Set("basic_types_value", InitBasicTypesValue(env));
exports.Set("buffer", InitBuffer(env));
exports.Set("error", InitError(env));
exports.Set("external", InitExternal(env));
Expand Down
1 change: 1 addition & 0 deletions test/binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
'arraybuffer.cc',
'asyncworker.cc',
'basic_types/number.cc',
'basic_types/value.cc',
'binding.cc',
'buffer.cc',
'error.cc',
Expand Down
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ let testModules = [
'arraybuffer',
'asyncworker',
'basic_types/number',
'basic_types/value',
'buffer',
'error',
'external',
Expand Down

0 comments on commit 4027196

Please sign in to comment.