Skip to content

Commit 7215caf

Browse files
bavulapatikraenhansenclaudelegendecas
authored
feat: port test_conversions to CTS (#38)
* feat: port test_conversions to CTS Ports [test_conversions](https://github.com/nodejs/node/tree/main/test/js-native-api/test_conversions) from the Node.js test suite to the CTS. Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com> * docs: update PORTING.md with the test status Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com> * feat: port test_constructor to CTS (#29) Exercises napi_define_class with method, data value, accessor, and static property descriptors. Includes null-argument tests for napi_define_class via test_null.c/test_null.js. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Chengzhong Wu <legendecas@gmail.com> * docs: update PORTING.md with the test status Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com> * resolve conflitcts Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com> * resolve conflicts Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com> --------- Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com> Co-authored-by: Kræn Hansen <kraen@elevenlabs.io> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Chengzhong Wu <cwu631@bloomberg.net>
1 parent 203bd5e commit 7215caf

File tree

6 files changed

+485
-1
lines changed

6 files changed

+485
-1
lines changed

PORTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Tests covering the engine-specific part of Node-API, defined in `js_native_api.h
5151
| `test_bigint` | Ported ✅ | Easy |
5252
| `test_cannot_run_js` | Not ported | Medium |
5353
| `test_constructor` | Ported ✅ | Medium |
54-
| `test_conversions` | Not ported | Medium |
54+
| `test_conversions` | Ported ✅ | Medium |
5555
| `test_dataview` | Not ported | Medium |
5656
| `test_date` | Ported ✅ | Easy |
5757
| `test_error` | Ported ✅ | Medium |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_node_api_cts_addon(test_conversions test_conversions.c test_null.c)
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
"use strict";
2+
const test = loadAddon("test_conversions");
3+
4+
const boolExpected = /boolean was expected/;
5+
const numberExpected = /number was expected/;
6+
const stringExpected = /string was expected/;
7+
8+
const testSym = Symbol("test");
9+
10+
assert.strictEqual(test.asBool(false), false);
11+
assert.strictEqual(test.asBool(true), true);
12+
assert.throws(() => test.asBool(undefined), boolExpected);
13+
assert.throws(() => test.asBool(null), boolExpected);
14+
assert.throws(() => test.asBool(Number.NaN), boolExpected);
15+
assert.throws(() => test.asBool(0), boolExpected);
16+
assert.throws(() => test.asBool(""), boolExpected);
17+
assert.throws(() => test.asBool("0"), boolExpected);
18+
assert.throws(() => test.asBool(1), boolExpected);
19+
assert.throws(() => test.asBool("1"), boolExpected);
20+
assert.throws(() => test.asBool("true"), boolExpected);
21+
assert.throws(() => test.asBool({}), boolExpected);
22+
assert.throws(() => test.asBool([]), boolExpected);
23+
assert.throws(() => test.asBool(testSym), boolExpected);
24+
25+
[test.asInt32, test.asUInt32, test.asInt64].forEach((asInt) => {
26+
assert.strictEqual(asInt(0), 0);
27+
assert.strictEqual(asInt(1), 1);
28+
assert.strictEqual(asInt(1.0), 1);
29+
assert.strictEqual(asInt(1.1), 1);
30+
assert.strictEqual(asInt(1.9), 1);
31+
assert.strictEqual(asInt(0.9), 0);
32+
assert.strictEqual(asInt(999.9), 999);
33+
assert.strictEqual(asInt(Number.NaN), 0);
34+
assert.throws(() => asInt(undefined), numberExpected);
35+
assert.throws(() => asInt(null), numberExpected);
36+
assert.throws(() => asInt(false), numberExpected);
37+
assert.throws(() => asInt(""), numberExpected);
38+
assert.throws(() => asInt("1"), numberExpected);
39+
assert.throws(() => asInt({}), numberExpected);
40+
assert.throws(() => asInt([]), numberExpected);
41+
assert.throws(() => asInt(testSym), numberExpected);
42+
});
43+
44+
assert.strictEqual(test.asInt32(-1), -1);
45+
assert.strictEqual(test.asInt64(-1), -1);
46+
assert.strictEqual(test.asUInt32(-1), Math.pow(2, 32) - 1);
47+
48+
assert.strictEqual(test.asDouble(0), 0);
49+
assert.strictEqual(test.asDouble(1), 1);
50+
assert.strictEqual(test.asDouble(1.0), 1.0);
51+
assert.strictEqual(test.asDouble(1.1), 1.1);
52+
assert.strictEqual(test.asDouble(1.9), 1.9);
53+
assert.strictEqual(test.asDouble(0.9), 0.9);
54+
assert.strictEqual(test.asDouble(999.9), 999.9);
55+
assert.strictEqual(test.asDouble(-1), -1);
56+
assert.ok(Number.isNaN(test.asDouble(Number.NaN)));
57+
assert.throws(() => test.asDouble(undefined), numberExpected);
58+
assert.throws(() => test.asDouble(null), numberExpected);
59+
assert.throws(() => test.asDouble(false), numberExpected);
60+
assert.throws(() => test.asDouble(""), numberExpected);
61+
assert.throws(() => test.asDouble("1"), numberExpected);
62+
assert.throws(() => test.asDouble({}), numberExpected);
63+
assert.throws(() => test.asDouble([]), numberExpected);
64+
assert.throws(() => test.asDouble(testSym), numberExpected);
65+
66+
assert.strictEqual(test.asString(""), "");
67+
assert.strictEqual(test.asString("test"), "test");
68+
assert.throws(() => test.asString(undefined), stringExpected);
69+
assert.throws(() => test.asString(null), stringExpected);
70+
assert.throws(() => test.asString(false), stringExpected);
71+
assert.throws(() => test.asString(1), stringExpected);
72+
assert.throws(() => test.asString(1.1), stringExpected);
73+
assert.throws(() => test.asString(Number.NaN), stringExpected);
74+
assert.throws(() => test.asString({}), stringExpected);
75+
assert.throws(() => test.asString([]), stringExpected);
76+
assert.throws(() => test.asString(testSym), stringExpected);
77+
78+
assert.strictEqual(test.toBool(true), true);
79+
assert.strictEqual(test.toBool(1), true);
80+
assert.strictEqual(test.toBool(-1), true);
81+
assert.strictEqual(test.toBool("true"), true);
82+
assert.strictEqual(test.toBool("false"), true);
83+
assert.strictEqual(test.toBool({}), true);
84+
assert.strictEqual(test.toBool([]), true);
85+
assert.strictEqual(test.toBool(testSym), true);
86+
assert.strictEqual(test.toBool(false), false);
87+
assert.strictEqual(test.toBool(undefined), false);
88+
assert.strictEqual(test.toBool(null), false);
89+
assert.strictEqual(test.toBool(0), false);
90+
assert.strictEqual(test.toBool(Number.NaN), false);
91+
assert.strictEqual(test.toBool(""), false);
92+
93+
assert.strictEqual(test.toNumber(0), 0);
94+
assert.strictEqual(test.toNumber(1), 1);
95+
assert.strictEqual(test.toNumber(1.1), 1.1);
96+
assert.strictEqual(test.toNumber(-1), -1);
97+
assert.strictEqual(test.toNumber("0"), 0);
98+
assert.strictEqual(test.toNumber("1"), 1);
99+
assert.strictEqual(test.toNumber("1.1"), 1.1);
100+
assert.strictEqual(test.toNumber([]), 0);
101+
assert.strictEqual(test.toNumber(false), 0);
102+
assert.strictEqual(test.toNumber(null), 0);
103+
assert.strictEqual(test.toNumber(""), 0);
104+
assert.ok(Number.isNaN(test.toNumber(Number.NaN)));
105+
assert.ok(Number.isNaN(test.toNumber({})));
106+
assert.ok(Number.isNaN(test.toNumber(undefined)));
107+
assert.throws(() => test.toNumber(testSym), TypeError);
108+
109+
assert.deepStrictEqual({}, test.toObject({}));
110+
assert.deepStrictEqual({ test: 1 }, test.toObject({ test: 1 }));
111+
assert.deepStrictEqual([], test.toObject([]));
112+
assert.deepStrictEqual([1, 2, 3], test.toObject([1, 2, 3]));
113+
assert.deepStrictEqual(new Boolean(false), test.toObject(false));
114+
assert.deepStrictEqual(new Boolean(true), test.toObject(true));
115+
assert.deepStrictEqual(new String(""), test.toObject(""));
116+
assert.deepStrictEqual(new Number(0), test.toObject(0));
117+
assert.deepStrictEqual(new Number(Number.NaN), test.toObject(Number.NaN));
118+
assert.deepStrictEqual(new Object(testSym), test.toObject(testSym));
119+
assert.notStrictEqual(test.toObject(false), false);
120+
assert.notStrictEqual(test.toObject(true), true);
121+
assert.notStrictEqual(test.toObject(""), "");
122+
assert.notStrictEqual(test.toObject(0), 0);
123+
assert.ok(!Number.isNaN(test.toObject(Number.NaN)));
124+
125+
assert.strictEqual(test.toString(""), "");
126+
assert.strictEqual(test.toString("test"), "test");
127+
assert.strictEqual(test.toString(undefined), "undefined");
128+
assert.strictEqual(test.toString(null), "null");
129+
assert.strictEqual(test.toString(false), "false");
130+
assert.strictEqual(test.toString(true), "true");
131+
assert.strictEqual(test.toString(0), "0");
132+
assert.strictEqual(test.toString(1.1), "1.1");
133+
assert.strictEqual(test.toString(Number.NaN), "NaN");
134+
assert.strictEqual(test.toString({}), "[object Object]");
135+
assert.strictEqual(test.toString({ toString: () => "test" }), "test");
136+
assert.strictEqual(test.toString([]), "");
137+
assert.strictEqual(test.toString([1, 2, 3]), "1,2,3");
138+
assert.throws(() => test.toString(testSym), TypeError);
139+
140+
assert.deepStrictEqual(test.testNull.getValueBool(), {
141+
envIsNull: "Invalid argument",
142+
valueIsNull: "Invalid argument",
143+
resultIsNull: "Invalid argument",
144+
inputTypeCheck: "A boolean was expected",
145+
});
146+
147+
assert.deepStrictEqual(test.testNull.getValueInt32(), {
148+
envIsNull: "Invalid argument",
149+
valueIsNull: "Invalid argument",
150+
resultIsNull: "Invalid argument",
151+
inputTypeCheck: "A number was expected",
152+
});
153+
154+
assert.deepStrictEqual(test.testNull.getValueUint32(), {
155+
envIsNull: "Invalid argument",
156+
valueIsNull: "Invalid argument",
157+
resultIsNull: "Invalid argument",
158+
inputTypeCheck: "A number was expected",
159+
});
160+
161+
assert.deepStrictEqual(test.testNull.getValueInt64(), {
162+
envIsNull: "Invalid argument",
163+
valueIsNull: "Invalid argument",
164+
resultIsNull: "Invalid argument",
165+
inputTypeCheck: "A number was expected",
166+
});
167+
168+
assert.deepStrictEqual(test.testNull.getValueDouble(), {
169+
envIsNull: "Invalid argument",
170+
valueIsNull: "Invalid argument",
171+
resultIsNull: "Invalid argument",
172+
inputTypeCheck: "A number was expected",
173+
});
174+
175+
assert.deepStrictEqual(test.testNull.coerceToBool(), {
176+
envIsNull: "Invalid argument",
177+
valueIsNull: "Invalid argument",
178+
resultIsNull: "Invalid argument",
179+
inputTypeCheck: "napi_ok",
180+
});
181+
182+
assert.deepStrictEqual(test.testNull.coerceToObject(), {
183+
envIsNull: "Invalid argument",
184+
valueIsNull: "Invalid argument",
185+
resultIsNull: "Invalid argument",
186+
inputTypeCheck: "napi_ok",
187+
});
188+
189+
assert.deepStrictEqual(test.testNull.coerceToString(), {
190+
envIsNull: "Invalid argument",
191+
valueIsNull: "Invalid argument",
192+
resultIsNull: "Invalid argument",
193+
inputTypeCheck: "napi_ok",
194+
});
195+
196+
assert.deepStrictEqual(test.testNull.getValueStringUtf8(), {
197+
envIsNull: "Invalid argument",
198+
valueIsNull: "Invalid argument",
199+
wrongTypeIn: "A string was expected",
200+
bufAndOutLengthIsNull: "Invalid argument",
201+
});
202+
203+
assert.deepStrictEqual(test.testNull.getValueStringLatin1(), {
204+
envIsNull: "Invalid argument",
205+
valueIsNull: "Invalid argument",
206+
wrongTypeIn: "A string was expected",
207+
bufAndOutLengthIsNull: "Invalid argument",
208+
});
209+
210+
assert.deepStrictEqual(test.testNull.getValueStringUtf16(), {
211+
envIsNull: "Invalid argument",
212+
valueIsNull: "Invalid argument",
213+
wrongTypeIn: "A string was expected",
214+
bufAndOutLengthIsNull: "Invalid argument",
215+
});
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#include <js_native_api.h>
2+
#include "../common.h"
3+
#include "../entry_point.h"
4+
#include "test_null.h"
5+
6+
static napi_value AsBool(napi_env env, napi_callback_info info) {
7+
size_t argc = 1;
8+
napi_value args[1];
9+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
10+
11+
bool value;
12+
NODE_API_CALL(env, napi_get_value_bool(env, args[0], &value));
13+
14+
napi_value output;
15+
NODE_API_CALL(env, napi_get_boolean(env, value, &output));
16+
17+
return output;
18+
}
19+
20+
static napi_value AsInt32(napi_env env, napi_callback_info info) {
21+
size_t argc = 1;
22+
napi_value args[1];
23+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
24+
25+
int32_t value;
26+
NODE_API_CALL(env, napi_get_value_int32(env, args[0], &value));
27+
28+
napi_value output;
29+
NODE_API_CALL(env, napi_create_int32(env, value, &output));
30+
31+
return output;
32+
}
33+
34+
static napi_value AsUInt32(napi_env env, napi_callback_info info) {
35+
size_t argc = 1;
36+
napi_value args[1];
37+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
38+
39+
uint32_t value;
40+
NODE_API_CALL(env, napi_get_value_uint32(env, args[0], &value));
41+
42+
napi_value output;
43+
NODE_API_CALL(env, napi_create_uint32(env, value, &output));
44+
45+
return output;
46+
}
47+
48+
static napi_value AsInt64(napi_env env, napi_callback_info info) {
49+
size_t argc = 1;
50+
napi_value args[1];
51+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
52+
53+
int64_t value;
54+
NODE_API_CALL(env, napi_get_value_int64(env, args[0], &value));
55+
56+
napi_value output;
57+
NODE_API_CALL(env, napi_create_int64(env, (double)value, &output));
58+
59+
return output;
60+
}
61+
62+
static napi_value AsDouble(napi_env env, napi_callback_info info) {
63+
size_t argc = 1;
64+
napi_value args[1];
65+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
66+
67+
double value;
68+
NODE_API_CALL(env, napi_get_value_double(env, args[0], &value));
69+
70+
napi_value output;
71+
NODE_API_CALL(env, napi_create_double(env, value, &output));
72+
73+
return output;
74+
}
75+
76+
static napi_value AsString(napi_env env, napi_callback_info info) {
77+
size_t argc = 1;
78+
napi_value args[1];
79+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
80+
81+
char value[100];
82+
NODE_API_CALL(env,
83+
napi_get_value_string_utf8(env, args[0], value, sizeof(value), NULL));
84+
85+
napi_value output;
86+
NODE_API_CALL(env, napi_create_string_utf8(
87+
env, value, NAPI_AUTO_LENGTH, &output));
88+
89+
return output;
90+
}
91+
92+
static napi_value ToBool(napi_env env, napi_callback_info info) {
93+
size_t argc = 1;
94+
napi_value args[1];
95+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
96+
97+
napi_value output;
98+
NODE_API_CALL(env, napi_coerce_to_bool(env, args[0], &output));
99+
100+
return output;
101+
}
102+
103+
static napi_value ToNumber(napi_env env, napi_callback_info info) {
104+
size_t argc = 1;
105+
napi_value args[1];
106+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
107+
108+
napi_value output;
109+
NODE_API_CALL(env, napi_coerce_to_number(env, args[0], &output));
110+
111+
return output;
112+
}
113+
114+
static napi_value ToObject(napi_env env, napi_callback_info info) {
115+
size_t argc = 1;
116+
napi_value args[1];
117+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
118+
119+
napi_value output;
120+
NODE_API_CALL(env, napi_coerce_to_object(env, args[0], &output));
121+
122+
return output;
123+
}
124+
125+
static napi_value ToString(napi_env env, napi_callback_info info) {
126+
size_t argc = 1;
127+
napi_value args[1];
128+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
129+
130+
napi_value output;
131+
NODE_API_CALL(env, napi_coerce_to_string(env, args[0], &output));
132+
133+
return output;
134+
}
135+
136+
EXTERN_C_START
137+
napi_value Init(napi_env env, napi_value exports) {
138+
napi_property_descriptor descriptors[] = {
139+
DECLARE_NODE_API_PROPERTY("asBool", AsBool),
140+
DECLARE_NODE_API_PROPERTY("asInt32", AsInt32),
141+
DECLARE_NODE_API_PROPERTY("asUInt32", AsUInt32),
142+
DECLARE_NODE_API_PROPERTY("asInt64", AsInt64),
143+
DECLARE_NODE_API_PROPERTY("asDouble", AsDouble),
144+
DECLARE_NODE_API_PROPERTY("asString", AsString),
145+
DECLARE_NODE_API_PROPERTY("toBool", ToBool),
146+
DECLARE_NODE_API_PROPERTY("toNumber", ToNumber),
147+
DECLARE_NODE_API_PROPERTY("toObject", ToObject),
148+
DECLARE_NODE_API_PROPERTY("toString", ToString),
149+
};
150+
151+
NODE_API_CALL(env, napi_define_properties(
152+
env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
153+
154+
init_test_null(env, exports);
155+
156+
return exports;
157+
}
158+
EXTERN_C_END

0 commit comments

Comments
 (0)