#include <stdio.h>
#include <string.h>
#include "napi_test_helpers.h"
int main(void) {
napi_env env = napi_wasm_init_env();
CHECK_OR_FAIL(env != NULL, "napi_wasm_init_env returned NULL");
{
napi_value obj;
NAPI_CALL(env, napi_create_object(env, &obj));
napi_value key;
NAPI_CALL(env,
napi_create_string_utf8(env, "foo", NAPI_AUTO_LENGTH, &key));
napi_value val;
NAPI_CALL(env, napi_create_int32(env, 10, &val));
NAPI_CALL(env, napi_set_property(env, obj, key, val));
bool has;
NAPI_CALL(env, napi_has_property(env, obj, key, &has));
CHECK_OR_FAIL(has, "has_property: expected true for 'foo'");
napi_value missing_key;
NAPI_CALL(env,
napi_create_string_utf8(env, "bar", NAPI_AUTO_LENGTH,
&missing_key));
NAPI_CALL(env, napi_has_property(env, obj, missing_key, &has));
CHECK_OR_FAIL(!has, "has_property: expected false for 'bar'");
}
{
napi_value obj;
NAPI_CALL(env, napi_create_object(env, &obj));
napi_value key;
NAPI_CALL(env,
napi_create_string_utf8(env, "own", NAPI_AUTO_LENGTH, &key));
napi_value val;
NAPI_CALL(env, napi_create_int32(env, 1, &val));
NAPI_CALL(env, napi_set_property(env, obj, key, val));
bool has;
NAPI_CALL(env, napi_has_own_property(env, obj, key, &has));
CHECK_OR_FAIL(has, "has_own_property: expected true for 'own'");
napi_value inherited_key;
NAPI_CALL(env,
napi_create_string_utf8(env, "toString", NAPI_AUTO_LENGTH,
&inherited_key));
NAPI_CALL(env, napi_has_own_property(env, obj, inherited_key, &has));
CHECK_OR_FAIL(!has,
"has_own_property: expected false for inherited 'toString'");
}
{
napi_value obj;
NAPI_CALL(env, napi_create_object(env, &obj));
napi_value key;
NAPI_CALL(env,
napi_create_string_utf8(env, "deleteme", NAPI_AUTO_LENGTH,
&key));
napi_value val;
NAPI_CALL(env, napi_create_int32(env, 42, &val));
NAPI_CALL(env, napi_set_property(env, obj, key, val));
bool has;
NAPI_CALL(env, napi_has_property(env, obj, key, &has));
CHECK_OR_FAIL(has, "delete_property: property should exist before delete");
bool deleted;
NAPI_CALL(env, napi_delete_property(env, obj, key, &deleted));
CHECK_OR_FAIL(deleted, "delete_property: expected true (deleted)");
NAPI_CALL(env, napi_has_property(env, obj, key, &has));
CHECK_OR_FAIL(!has, "delete_property: property should not exist after delete");
}
{
napi_value obj;
NAPI_CALL(env, napi_create_object(env, &obj));
napi_value val;
NAPI_CALL(env, napi_create_int32(env, 5, &val));
NAPI_CALL(env, napi_set_named_property(env, obj, "named", val));
bool has;
NAPI_CALL(env, napi_has_named_property(env, obj, "named", &has));
CHECK_OR_FAIL(has, "has_named_property: expected true for 'named'");
NAPI_CALL(env, napi_has_named_property(env, obj, "missing", &has));
CHECK_OR_FAIL(!has, "has_named_property: expected false for 'missing'");
}
{
napi_value arr;
NAPI_CALL(env, napi_create_array(env, &arr));
napi_value v0, v1;
NAPI_CALL(env, napi_create_int32(env, 100, &v0));
NAPI_CALL(env, napi_create_int32(env, 200, &v1));
NAPI_CALL(env, napi_set_element(env, arr, 0, v0));
NAPI_CALL(env, napi_set_element(env, arr, 1, v1));
bool has;
NAPI_CALL(env, napi_has_element(env, arr, 0, &has));
CHECK_OR_FAIL(has, "has_element: expected true for index 0");
NAPI_CALL(env, napi_has_element(env, arr, 1, &has));
CHECK_OR_FAIL(has, "has_element: expected true for index 1");
NAPI_CALL(env, napi_has_element(env, arr, 5, &has));
CHECK_OR_FAIL(!has, "has_element: expected false for index 5");
bool deleted;
NAPI_CALL(env, napi_delete_element(env, arr, 0, &deleted));
CHECK_OR_FAIL(deleted, "delete_element: expected true");
NAPI_CALL(env, napi_has_element(env, arr, 0, &has));
CHECK_OR_FAIL(!has,
"delete_element: expected false for index 0 after delete");
}
{
napi_value obj;
NAPI_CALL(env, napi_create_object(env, &obj));
napi_value va, vb, vc;
NAPI_CALL(env, napi_create_int32(env, 1, &va));
NAPI_CALL(env, napi_create_int32(env, 2, &vb));
NAPI_CALL(env, napi_create_int32(env, 3, &vc));
NAPI_CALL(env, napi_set_named_property(env, obj, "a", va));
NAPI_CALL(env, napi_set_named_property(env, obj, "b", vb));
NAPI_CALL(env, napi_set_named_property(env, obj, "c", vc));
napi_value names;
NAPI_CALL(env, napi_get_property_names(env, obj, &names));
bool is_arr;
NAPI_CALL(env, napi_is_array(env, names, &is_arr));
CHECK_OR_FAIL(is_arr, "get_property_names: expected array");
uint32_t length;
NAPI_CALL(env, napi_get_array_length(env, names, &length));
CHECK_OR_FAIL(length == 3,
"get_property_names: expected 3 property names");
int found_a = 0, found_b = 0, found_c = 0;
for (uint32_t i = 0; i < length; i++) {
napi_value name;
NAPI_CALL(env, napi_get_element(env, names, i, &name));
char buf[256];
size_t len;
NAPI_CALL(env,
napi_get_value_string_utf8(env, name, buf, sizeof(buf), &len));
if (strcmp(buf, "a") == 0) found_a = 1;
else if (strcmp(buf, "b") == 0) found_b = 1;
else if (strcmp(buf, "c") == 0) found_c = 1;
}
CHECK_OR_FAIL(found_a && found_b && found_c,
"get_property_names: missing expected property names");
}
{
napi_value obj;
NAPI_CALL(env, napi_create_object(env, &obj));
napi_value val;
NAPI_CALL(env, napi_create_int32(env, 10, &val));
NAPI_CALL(env, napi_set_named_property(env, obj, "frozen_prop", val));
NAPI_CALL(env, napi_object_freeze(env, obj));
napi_value got;
NAPI_CALL(env, napi_get_named_property(env, obj, "frozen_prop", &got));
int32_t result;
NAPI_CALL(env, napi_get_value_int32(env, got, &result));
CHECK_OR_FAIL(result == 10,
"object_freeze: existing property should be readable");
napi_value new_val;
NAPI_CALL(env, napi_create_int32(env, 99, &new_val));
napi_set_named_property(env, obj, "frozen_prop", new_val);
bool is_pending;
NAPI_CALL(env, napi_is_exception_pending(env, &is_pending));
if (is_pending) {
napi_value exc;
NAPI_CALL(env, napi_get_and_clear_last_exception(env, &exc));
}
NAPI_CALL(env, napi_get_named_property(env, obj, "frozen_prop", &got));
NAPI_CALL(env, napi_get_value_int32(env, got, &result));
CHECK_OR_FAIL(result == 10,
"object_freeze: property should remain unchanged after freeze");
}
{
napi_value obj;
NAPI_CALL(env, napi_create_object(env, &obj));
napi_value val;
NAPI_CALL(env, napi_create_int32(env, 20, &val));
NAPI_CALL(env, napi_set_named_property(env, obj, "sealed_prop", val));
NAPI_CALL(env, napi_object_seal(env, obj));
napi_value got;
NAPI_CALL(env, napi_get_named_property(env, obj, "sealed_prop", &got));
int32_t result;
NAPI_CALL(env, napi_get_value_int32(env, got, &result));
CHECK_OR_FAIL(result == 20,
"object_seal: existing property should be readable");
napi_value new_val;
NAPI_CALL(env, napi_create_int32(env, 30, &new_val));
NAPI_CALL(env, napi_set_named_property(env, obj, "sealed_prop", new_val));
NAPI_CALL(env, napi_get_named_property(env, obj, "sealed_prop", &got));
NAPI_CALL(env, napi_get_value_int32(env, got, &result));
CHECK_OR_FAIL(result == 30,
"object_seal: existing property should be modifiable");
napi_value extra;
NAPI_CALL(env, napi_create_int32(env, 50, &extra));
napi_set_named_property(env, obj, "new_prop", extra);
bool is_pending;
NAPI_CALL(env, napi_is_exception_pending(env, &is_pending));
if (is_pending) {
napi_value exc;
NAPI_CALL(env, napi_get_and_clear_last_exception(env, &exc));
}
bool has;
NAPI_CALL(env, napi_has_named_property(env, obj, "new_prop", &has));
CHECK_OR_FAIL(!has,
"object_seal: should not be able to add new properties");
}
{
napi_value obj;
NAPI_CALL(env, napi_create_object(env, &obj));
napi_value proto;
NAPI_CALL(env, napi_get_prototype(env, obj, &proto));
napi_valuetype vtype;
NAPI_CALL(env, napi_typeof(env, proto, &vtype));
CHECK_OR_FAIL(vtype == napi_object,
"get_prototype: expected prototype to be an object");
napi_value ts_key;
NAPI_CALL(env,
napi_create_string_utf8(env, "toString", NAPI_AUTO_LENGTH,
&ts_key));
bool has;
NAPI_CALL(env, napi_has_own_property(env, proto, ts_key, &has));
CHECK_OR_FAIL(has,
"get_prototype: Object.prototype should have 'toString'");
}
{
napi_value obj;
NAPI_CALL(env, napi_create_object(env, &obj));
napi_value val;
NAPI_CALL(env, napi_create_int32(env, 1, &val));
NAPI_CALL(env, napi_set_named_property(env, obj, "keep", val));
NAPI_CALL(env, napi_object_freeze(env, obj));
napi_value key;
NAPI_CALL(env,
napi_create_string_utf8(env, "keep", NAPI_AUTO_LENGTH, &key));
bool deleted;
napi_status status = napi_delete_property(env, obj, key, &deleted);
bool is_pending;
NAPI_CALL(env, napi_is_exception_pending(env, &is_pending));
if (is_pending) {
napi_value exc;
NAPI_CALL(env, napi_get_and_clear_last_exception(env, &exc));
}
if (status == napi_ok) {
CHECK_OR_FAIL(!deleted,
"delete_property: non-configurable property should not be deleted");
}
}
return PrintSuccess("TEST_OBJECT_PROPERTIES");
}