|
1 | 1 | #include "node_test_fixture.h" |
2 | | -#include "node_internals.h" // RunBootstrapping() |
| 2 | +#include "node_api.h" |
3 | 3 |
|
4 | 4 | void InitializeBinding(v8::Local<v8::Object> exports, |
5 | 5 | v8::Local<v8::Value> module, |
@@ -83,3 +83,110 @@ TEST_F(LinkedBindingTest, LocallyDefinedLinkedBindingTest) { |
83 | 83 | CHECK_EQ(strcmp(*utf8val, "value"), 0); |
84 | 84 | CHECK_EQ(calls, 1); |
85 | 85 | } |
| 86 | + |
| 87 | +napi_value InitializeLocalNapiBinding(napi_env env, napi_value exports) { |
| 88 | + napi_value key, value; |
| 89 | + CHECK_EQ( |
| 90 | + napi_create_string_utf8(env, "hello", NAPI_AUTO_LENGTH, &key), napi_ok); |
| 91 | + CHECK_EQ( |
| 92 | + napi_create_string_utf8(env, "world", NAPI_AUTO_LENGTH, &value), napi_ok); |
| 93 | + CHECK_EQ(napi_set_property(env, exports, key, value), napi_ok); |
| 94 | + return nullptr; |
| 95 | +} |
| 96 | + |
| 97 | +static napi_module local_linked_napi = { |
| 98 | + NAPI_MODULE_VERSION, |
| 99 | + node::ModuleFlags::kLinked, |
| 100 | + nullptr, |
| 101 | + InitializeLocalNapiBinding, |
| 102 | + "local_linked_napi", |
| 103 | + nullptr, |
| 104 | + {0}, |
| 105 | +}; |
| 106 | + |
| 107 | +TEST_F(LinkedBindingTest, LocallyDefinedLinkedBindingNapiTest) { |
| 108 | + const v8::HandleScope handle_scope(isolate_); |
| 109 | + const Argv argv; |
| 110 | + Env test_env {handle_scope, argv}; |
| 111 | + |
| 112 | + AddLinkedBinding(*test_env, local_linked_napi); |
| 113 | + |
| 114 | + v8::Local<v8::Context> context = isolate_->GetCurrentContext(); |
| 115 | + |
| 116 | + const char* run_script = |
| 117 | + "process._linkedBinding('local_linked_napi').hello"; |
| 118 | + v8::Local<v8::Script> script = v8::Script::Compile( |
| 119 | + context, |
| 120 | + v8::String::NewFromOneByte(isolate_, |
| 121 | + reinterpret_cast<const uint8_t*>(run_script)) |
| 122 | + .ToLocalChecked()) |
| 123 | + .ToLocalChecked(); |
| 124 | + v8::Local<v8::Value> completion_value = script->Run(context).ToLocalChecked(); |
| 125 | + v8::String::Utf8Value utf8val(isolate_, completion_value); |
| 126 | + CHECK_NOT_NULL(*utf8val); |
| 127 | + CHECK_EQ(strcmp(*utf8val, "world"), 0); |
| 128 | +} |
| 129 | + |
| 130 | +napi_value NapiLinkedWithInstanceData(napi_env env, napi_value exports) { |
| 131 | + int* instance_data = new int(0); |
| 132 | + CHECK_EQ( |
| 133 | + napi_set_instance_data( |
| 134 | + env, |
| 135 | + instance_data, |
| 136 | + [](napi_env env, void* data, void* hint) { |
| 137 | + ++*static_cast<int*>(data); |
| 138 | + }, nullptr), |
| 139 | + napi_ok); |
| 140 | + |
| 141 | + napi_value key, value; |
| 142 | + CHECK_EQ( |
| 143 | + napi_create_string_utf8(env, "hello", NAPI_AUTO_LENGTH, &key), napi_ok); |
| 144 | + CHECK_EQ( |
| 145 | + napi_create_external(env, instance_data, nullptr, nullptr, &value), |
| 146 | + napi_ok); |
| 147 | + CHECK_EQ(napi_set_property(env, exports, key, value), napi_ok); |
| 148 | + return nullptr; |
| 149 | +} |
| 150 | + |
| 151 | +static napi_module local_linked_napi_id = { |
| 152 | + NAPI_MODULE_VERSION, |
| 153 | + node::ModuleFlags::kLinked, |
| 154 | + nullptr, |
| 155 | + NapiLinkedWithInstanceData, |
| 156 | + "local_linked_napi_id", |
| 157 | + nullptr, |
| 158 | + {0}, |
| 159 | +}; |
| 160 | + |
| 161 | +TEST_F(LinkedBindingTest, LocallyDefinedLinkedBindingNapiInstanceDataTest) { |
| 162 | + const v8::HandleScope handle_scope(isolate_); |
| 163 | + int* instance_data = nullptr; |
| 164 | + |
| 165 | + { |
| 166 | + const Argv argv; |
| 167 | + Env test_env {handle_scope, argv}; |
| 168 | + |
| 169 | + AddLinkedBinding(*test_env, local_linked_napi_id); |
| 170 | + |
| 171 | + v8::Local<v8::Context> context = isolate_->GetCurrentContext(); |
| 172 | + |
| 173 | + const char* run_script = |
| 174 | + "process._linkedBinding('local_linked_napi_id').hello"; |
| 175 | + v8::Local<v8::Script> script = v8::Script::Compile( |
| 176 | + context, |
| 177 | + v8::String::NewFromOneByte(isolate_, |
| 178 | + reinterpret_cast<const uint8_t*>(run_script)) |
| 179 | + .ToLocalChecked()) |
| 180 | + .ToLocalChecked(); |
| 181 | + v8::Local<v8::Value> completion_value = |
| 182 | + script->Run(context).ToLocalChecked(); |
| 183 | + CHECK(completion_value->IsExternal()); |
| 184 | + instance_data = static_cast<int*>( |
| 185 | + completion_value.As<v8::External>()->Value()); |
| 186 | + CHECK_NE(instance_data, nullptr); |
| 187 | + CHECK_EQ(*instance_data, 0); |
| 188 | + } |
| 189 | + |
| 190 | + CHECK_EQ(*instance_data, 1); |
| 191 | + delete instance_data; |
| 192 | +} |
0 commit comments