Skip to content

Commit

Permalink
test: Write tests for Number class
Browse files Browse the repository at this point in the history
The new tests cover a part of the basic type conversion from JavaScript
type to native type.

PR-URL: nodejs/node-addon-api#195
Reviewed-By: Michael Dawson <[email protected]>
  • Loading branch information
John French committed Dec 6, 2017
1 parent 505afb1 commit 272bf25
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 0 deletions.
57 changes: 57 additions & 0 deletions test/basic_types/number.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include <cfloat>

#include "napi.h"

using namespace Napi;

Value ToInt32(const CallbackInfo& info) {
return Number::New(info.Env(), info[0].As<Number>().Int32Value());
}

Value ToUint32(const CallbackInfo& info) {
return Number::New(info.Env(), info[0].As<Number>().Uint32Value());
}

Value ToInt64(const CallbackInfo& info) {
return Number::New(info.Env(), info[0].As<Number>().Int64Value());
}

Value ToFloat(const CallbackInfo& info) {
return Number::New(info.Env(), info[0].As<Number>().FloatValue());
}

Value ToDouble(const CallbackInfo& info) {
return Number::New(info.Env(), info[0].As<Number>().DoubleValue());
}

Value MinFloat(const CallbackInfo& info) {
return Number::New(info.Env(), FLT_MIN);
}

Value MaxFloat(const CallbackInfo& info) {
return Number::New(info.Env(), FLT_MAX);
}

Value MinDouble(const CallbackInfo& info) {
return Number::New(info.Env(), DBL_MIN);
}

Value MaxDouble(const CallbackInfo& info) {
return Number::New(info.Env(), DBL_MAX);
}

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

exports["toInt32"] = Function::New(env, ToInt32);
exports["toUint32"] = Function::New(env, ToUint32);
exports["toInt64"] = Function::New(env, ToInt64);
exports["toFloat"] = Function::New(env, ToFloat);
exports["toDouble"] = Function::New(env, ToDouble);
exports["minFloat"] = Function::New(env, MinFloat);
exports["maxFloat"] = Function::New(env, MaxFloat);
exports["minDouble"] = Function::New(env, MinDouble);
exports["maxDouble"] = Function::New(env, MaxDouble);

return exports;
}
83 changes: 83 additions & 0 deletions test/basic_types/number.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
'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) {
const MIN_INT32 = -2147483648;
const MAX_INT32 = 2147483647;
const MIN_UINT32 = 0;
const MAX_UINT32 = 4294967295;
const MIN_INT64 = Number.MIN_SAFE_INTEGER;
const MAX_INT64 = Number.MAX_SAFE_INTEGER;
const MIN_FLOAT = binding.basic_types_number.minFloat();
const MAX_FLOAT = binding.basic_types_number.maxFloat();
const MIN_DOUBLE = binding.basic_types_number.minDouble();
const MAX_DOUBLE = binding.basic_types_number.maxDouble();

function randomRangeTestForInteger(min, max, converter) {
for (let i = min; i < max; i+= Math.floor(Math.random() * max / 100)) {
assert.strictEqual(i, converter(i));
}
}

// Test for 32bit signed integer [-2147483648, 2147483647]
{
// Range tests
randomRangeTestForInteger(MIN_INT32, MAX_INT32, binding.basic_types_number.toInt32);
assert.strictEqual(MIN_INT32, binding.basic_types_number.toInt32(MIN_INT32));
assert.strictEqual(MAX_INT32, binding.basic_types_number.toInt32(MAX_INT32));

// Overflow tests
assert.notStrictEqual(MAX_INT32 + 1, binding.basic_types_number.toInt32(MAX_INT32 + 1));
assert.notStrictEqual(MIN_INT32 - 1, binding.basic_types_number.toInt32(MIN_INT32 - 1));
}

// Test for 32bit unsigned integer [0, 4294967295]
{
// Range tests
randomRangeTestForInteger(MIN_UINT32, MAX_UINT32, binding.basic_types_number.toUint32);
assert.strictEqual(MIN_UINT32, binding.basic_types_number.toUint32(MIN_UINT32));
assert.strictEqual(MAX_UINT32, binding.basic_types_number.toUint32(MAX_UINT32));

// Overflow tests
assert.notStrictEqual(MAX_UINT32 + 1, binding.basic_types_number.toUint32(MAX_UINT32 + 1));
assert.notStrictEqual(MIN_UINT32 - 1, binding.basic_types_number.toUint32(MIN_UINT32 - 1));
}

// Test for 64bit signed integer
{
// Range tests
randomRangeTestForInteger(MIN_INT64, MAX_INT64, binding.basic_types_number.toInt64);
assert.strictEqual(MIN_INT64, binding.basic_types_number.toInt64(MIN_INT64));
assert.strictEqual(MAX_INT64, binding.basic_types_number.toInt64(MAX_INT64));

// The int64 type can't be represented with full precision in JavaScript.
// So, we are not able to do overflow test here.
// Please see https://tc39.github.io/ecma262/#sec-ecmascript-language-types-number-type.
}

// Test for float type (might be single-precision 32bit IEEE 754 floating point number)
{
// Range test
assert.strictEqual(MIN_FLOAT, binding.basic_types_number.toFloat(MIN_FLOAT));
assert.strictEqual(MAX_FLOAT, binding.basic_types_number.toFloat(MAX_FLOAT));

// Overflow test
assert.strictEqual(0, binding.basic_types_number.toFloat(MIN_FLOAT * MIN_FLOAT));
assert.strictEqual(Infinity, binding.basic_types_number.toFloat(MAX_FLOAT * MAX_FLOAT));
}

// Test for double type (is double-precision 64 bit IEEE 754 floating point number)
{
assert.strictEqual(MIN_DOUBLE, binding.basic_types_number.toDouble(MIN_DOUBLE));
assert.strictEqual(MAX_DOUBLE, binding.basic_types_number.toDouble(MAX_DOUBLE));

// Overflow test
assert.strictEqual(0, binding.basic_types_number.toDouble(MIN_DOUBLE * MIN_DOUBLE));
assert.strictEqual(Infinity, binding.basic_types_number.toDouble(MAX_DOUBLE * MAX_DOUBLE));
}
}
2 changes: 2 additions & 0 deletions test/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ using namespace Napi;

Object InitArrayBuffer(Env env);
Object InitAsyncWorker(Env env);
Object InitBasicTypesNumber(Env env);
Object InitBuffer(Env env);
Object InitError(Env env);
Object InitExternal(Env env);
Expand All @@ -17,6 +18,7 @@ Object InitObjectWrap(Env env);
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("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 @@ -3,6 +3,7 @@
'sources': [
'arraybuffer.cc',
'asyncworker.cc',
'basic_types/number.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 @@ -10,6 +10,7 @@ process.config.target_defaults.default_configuration =
let testModules = [
'arraybuffer',
'asyncworker',
'basic_types/number',
'buffer',
'error',
'external',
Expand Down

0 comments on commit 272bf25

Please sign in to comment.