Skip to content

Commit 4d92a60

Browse files
Anisha Rohramhdawson
authored andcommitted
src: Add ObjectReference test case
PR-URL: #212 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
1 parent 2885c18 commit 4d92a60

File tree

5 files changed

+483
-1
lines changed

5 files changed

+483
-1
lines changed

test/binding.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Object InitObject(Env env);
1919
Object InitPromise(Env env);
2020
Object InitTypedArray(Env env);
2121
Object InitObjectWrap(Env env);
22+
Object InitObjectReference(Env env);
2223

2324
Object Init(Env env, Object exports) {
2425
exports.Set("arraybuffer", InitArrayBuffer(env));
@@ -39,6 +40,7 @@ Object Init(Env env, Object exports) {
3940
exports.Set("promise", InitPromise(env));
4041
exports.Set("typedarray", InitTypedArray(env));
4142
exports.Set("objectwrap", InitObjectWrap(env));
43+
exports.Set("objectreference", InitObjectReference(env));
4244
return exports;
4345
}
4446

test/binding.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
'promise.cc',
2525
'typedarray.cc',
2626
'objectwrap.cc',
27+
'objectreference.cc',
2728
],
2829
'include_dirs': ["<!@(node -p \"require('../').include\")"],
2930
'dependencies': ["<!(node -p \"require('../').gyp\")"],

test/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ let testModules = [
2929
'object/set_property',
3030
'promise',
3131
'typedarray',
32-
'objectwrap'
32+
'objectwrap',
33+
'objectreference',
3334
];
3435

3536
if (typeof global.gc === 'function') {

test/objectreference.cc

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
/* ObjectReference can be used to create references to Values that
2+
are not Objects by creating a blank Object and setting Values to
3+
it. Subclasses of Objects can only be set using an ObjectReference
4+
by first casting it as an Object. */
5+
6+
#include "napi.h"
7+
8+
using namespace Napi;
9+
10+
ObjectReference weak;
11+
ObjectReference persistent;
12+
ObjectReference reference;
13+
14+
ObjectReference casted_weak;
15+
ObjectReference casted_persistent;
16+
ObjectReference casted_reference;
17+
18+
// info[0] is the key, which can be either a string or a number.
19+
// info[1] is the value.
20+
// info[2] is a flag that differentiates whether the key is a
21+
// C string or a JavaScript string.
22+
void SetObjects(const CallbackInfo& info) {
23+
Env env = info.Env();
24+
HandleScope scope(env);
25+
26+
weak = Weak(Object::New(env));
27+
weak.SuppressDestruct();
28+
29+
persistent = Persistent(Object::New(env));
30+
persistent.SuppressDestruct();
31+
32+
reference = Reference<Object>::New(Object::New(env), 2);
33+
reference.SuppressDestruct();
34+
35+
if (info[0].IsString()) {
36+
if (info[2].As<String>() == String::New(env, "javascript")) {
37+
weak.Set(info[0].As<String>(), info[1]);
38+
persistent.Set(info[0].As<String>(), info[1]);
39+
reference.Set(info[0].As<String>(), info[1]);
40+
} else {
41+
weak.Set(info[0].As<String>().Utf8Value(), info[1]);
42+
persistent.Set(info[0].As<String>().Utf8Value(), info[1]);
43+
reference.Set(info[0].As<String>().Utf8Value(), info[1]);
44+
}
45+
} else if (info[0].IsNumber()) {
46+
weak.Set(info[0].As<Number>(), info[1]);
47+
persistent.Set(info[0].As<Number>(), info[1]);
48+
reference.Set(info[0].As<Number>(), info[1]);
49+
}
50+
}
51+
52+
void SetCastedObjects(const CallbackInfo& info) {
53+
Env env = info.Env();
54+
HandleScope scope(env);
55+
56+
Array ex = Array::New(env);
57+
ex.Set((uint32_t)0, String::New(env, "hello"));
58+
ex.Set(1, String::New(env, "world"));
59+
ex.Set(2, String::New(env, "!"));
60+
61+
casted_weak = Weak(ex.As<Object>());
62+
casted_weak.SuppressDestruct();
63+
64+
casted_persistent = Persistent(ex.As<Object>());
65+
casted_persistent.SuppressDestruct();
66+
67+
casted_reference = Reference<Object>::New(ex.As<Object>(), 2);
68+
casted_reference.SuppressDestruct();
69+
}
70+
71+
// info[0] is a flag to determine if the weak, persistent, or
72+
// multiple reference ObjectReference is being requested.
73+
Value GetFromValue(const CallbackInfo& info) {
74+
Env env = info.Env();
75+
76+
if (info[0].As<String>() == String::New(env, "weak")) {
77+
if (weak.IsEmpty()) {
78+
return String::New(env, "No Referenced Value");
79+
} else {
80+
return weak.Value();
81+
}
82+
} else if (info[0].As<String>() == String::New(env, "persistent")) {
83+
return persistent.Value();
84+
} else {
85+
return reference.Value();
86+
}
87+
}
88+
89+
// info[0] is a flag to determine if the weak, persistent, or
90+
// multiple reference ObjectReference is being requested.
91+
// info[1] is the key, and it be either a String or a Number.
92+
Value GetFromGetter(const CallbackInfo& info) {
93+
Env env = info.Env();
94+
95+
if (info[0].As<String>() == String::New(env, "weak")) {
96+
if (weak.IsEmpty()) {
97+
return String::New(env, "No Referenced Value");
98+
} else {
99+
if (info[1].IsString()) {
100+
return weak.Get(info[1].As<String>().Utf8Value());
101+
} else if (info[1].IsNumber()) {
102+
return weak.Get(info[1].As<Number>().Uint32Value());
103+
}
104+
}
105+
} else if (info[0].As<String>() == String::New(env, "persistent")) {
106+
if (info[1].IsString()) {
107+
return persistent.Get(info[1].As<String>().Utf8Value());
108+
} else if (info[1].IsNumber()) {
109+
return persistent.Get(info[1].As<Number>().Uint32Value());
110+
}
111+
} else {
112+
if (info[0].IsString()) {
113+
return reference.Get(info[0].As<String>().Utf8Value());
114+
} else if (info[0].IsNumber()) {
115+
return reference.Get(info[0].As<Number>().Uint32Value());
116+
}
117+
}
118+
119+
return String::New(env, "Error: Reached end of getter");
120+
}
121+
122+
// info[0] is a flag to determine if the weak, persistent, or
123+
// multiple reference ObjectReference is being requested.
124+
Value GetCastedFromValue(const CallbackInfo& info) {
125+
Env env = info.Env();
126+
127+
if (info[0].As<String>() == String::New(env, "weak")) {
128+
if (casted_weak.IsEmpty()) {
129+
return String::New(env, "No Referenced Value");
130+
} else {
131+
return casted_weak.Value();
132+
}
133+
} else if (info[0].As<String>() == String::New(env, "persistent")) {
134+
return casted_persistent.Value();
135+
} else {
136+
return casted_reference.Value();
137+
}
138+
}
139+
140+
// info[0] is a flag to determine if the weak, persistent, or
141+
// multiple reference ObjectReference is being requested.
142+
// info[1] is the key and it must be a Number.
143+
Value GetCastedFromGetter(const CallbackInfo& info) {
144+
Env env = info.Env();
145+
146+
if (info[0].As<String>() == String::New(env, "weak")) {
147+
if (casted_weak.IsEmpty()) {
148+
return String::New(env, "No Referenced Value");
149+
} else {
150+
return casted_weak.Get(info[1].As<Number>());
151+
}
152+
} else if (info[0].As<String>() == String::New(env, "persistent")) {
153+
return casted_persistent.Get(info[1].As<Number>());
154+
} else {
155+
return casted_reference.Get(info[1].As<Number>());
156+
}
157+
}
158+
159+
// info[0] is a flag to determine if the weak, persistent, or
160+
// multiple reference ObjectReference is being requested.
161+
Number UnrefObjects(const CallbackInfo& info) {
162+
Env env = info.Env();
163+
uint32_t num;
164+
165+
if (info[0].As<String>() == String::New(env, "weak")) {
166+
num = weak.Unref();
167+
} else if (info[0].As<String>() == String::New(env, "persistent")) {
168+
num = persistent.Unref();
169+
} else if (info[0].As<String>() == String::New(env, "references")) {
170+
num = reference.Unref();
171+
} else if (info[0].As<String>() == String::New(env, "casted weak")) {
172+
num = casted_weak.Unref();
173+
} else if (info[0].As<String>() == String::New(env, "casted persistent")) {
174+
num = casted_persistent.Unref();
175+
} else {
176+
num = casted_reference.Unref();
177+
}
178+
179+
return Number::New(env, num);
180+
}
181+
182+
// info[0] is a flag to determine if the weak, persistent, or
183+
// multiple reference ObjectReference is being requested.
184+
Number RefObjects(const CallbackInfo& info) {
185+
Env env = info.Env();
186+
uint32_t num;
187+
188+
if (info[0].As<String>() == String::New(env, "weak")) {
189+
num = weak.Ref();
190+
} else if (info[0].As<String>() == String::New(env, "persistent")) {
191+
num = persistent.Ref();
192+
} else if (info[0].As<String>() == String::New(env, "references")) {
193+
num = reference.Ref();
194+
} else if (info[0].As<String>() == String::New(env, "casted weak")) {
195+
num = casted_weak.Ref();
196+
} else if (info[0].As<String>() == String::New(env, "casted persistent")) {
197+
num = casted_persistent.Ref();
198+
} else {
199+
num = casted_reference.Ref();
200+
}
201+
202+
return Number::New(env, num);
203+
}
204+
205+
Object InitObjectReference(Env env) {
206+
Object exports = Object::New(env);
207+
208+
exports["setCastedObjects"] = Function::New(env, SetCastedObjects);
209+
exports["setObjects"] = Function::New(env, SetObjects);
210+
exports["getCastedFromValue"] = Function::New(env, GetCastedFromValue);
211+
exports["getFromGetter"] = Function::New(env, GetFromGetter);
212+
exports["getCastedFromGetter"] = Function::New(env, GetCastedFromGetter);
213+
exports["getFromValue"] = Function::New(env, GetFromValue);
214+
exports["unrefObjects"] = Function::New(env, UnrefObjects);
215+
exports["refObjects"] = Function::New(env, RefObjects);
216+
217+
return exports;
218+
}

0 commit comments

Comments
 (0)