Browse Source

Extend get/set prototype API testcase

Now covers undefined/object for set call, naked objects etc.
Does not cover invalid arguments to duk_set_prototype().
v1.0-maintenance
Sami Vaarala 10 years ago
parent
commit
3855d77c35
  1. 119
      api-testcases/test-get-set-prototype.c

119
api-testcases/test-get-set-prototype.c

@ -9,12 +9,33 @@
* Even so, user code is expected to never create a prototype loop on purpose.
*/
/* XXX: missing tests for API call type validation */
/*===
*** test_1 (duk_safe_call)
==> rc=0, result='undefined'
*** test_2 (duk_safe_call)
*** test_basic (duk_safe_call)
top before set: 2
top after set: 1
top before get: 1
top after get: 2
prototype: undefined
top before get: 2
top after get: 3
obj1 proto === Object.prototype: 1
obj1.isPrototypeOf is undefined: 0
top before set: 3
top after set: 2
top before get: 2
top after get: 3
prototype: TypeError: [[DefaultValue]] coerce failed
top before get: 2
top after get: 3
obj1 proto === Object.prototype: 0
obj1 proto === obj0: 1
obj1.isPrototypeOf is undefined: 1
obj1.foo=123
final top: 2
==> rc=0, result='undefined'
*** test_3 (duk_safe_call)
*** test_loop (duk_safe_call)
set obj0 prototype to obj1
set obj1 prototype to obj0
obj0.foo=123
@ -22,17 +43,84 @@ obj0.bar=123
==> rc=1, result='Error: prototype chain limit'
===*/
static duk_ret_t test_1(duk_context *ctx) {
(void) ctx;
return 0;
}
/* Multiple basic tests in one: test duk_set_prototype() and duk_get_prototype()
* stack top changes, and object/undefined for duk_set_prototype(). Also checks
* how a naked object works.
*/
static duk_ret_t test_basic(duk_context *ctx) {
/* Prototype object: { foo: 123 }, internal prototype is null. */
duk_push_object(ctx);
duk_push_undefined(ctx);
printf("top before set: %ld\n", (long) duk_get_top(ctx));
duk_set_prototype(ctx, -2);
printf("top after set: %ld\n", (long) duk_get_top(ctx));
duk_push_int(ctx, 123);
duk_put_prop_string(ctx, -2, "foo");
/* The prototype object is "naked", read back its prototype. */
printf("top before get: %ld\n", (long) duk_get_top(ctx));
duk_get_prototype(ctx, 0);
printf("top after get: %ld\n", (long) duk_get_top(ctx));
printf("prototype: %s\n", duk_safe_to_string(ctx, -1));
duk_pop(ctx);
static duk_ret_t test_2(duk_context *ctx) {
(void) ctx;
/* Target object, initially inherits from Object.prototype. */
duk_push_object(ctx);
/* Check original prototype. */
printf("top before get: %ld\n", (long) duk_get_top(ctx));
duk_get_prototype(ctx, 1);
printf("top after get: %ld\n", (long) duk_get_top(ctx));
duk_eval_string(ctx, "Object.prototype");
printf("obj1 proto === Object.prototype: %d\n", (int) duk_strict_equals(ctx, -2, -1));
duk_pop_2(ctx);
/* Check Object.prototype inheritance in practice. */
duk_get_prop_string(ctx, 1, "isPrototypeOf");
printf("obj1.isPrototypeOf is undefined: %d\n", (int) duk_is_undefined(ctx, -1));
duk_pop(ctx);
/* Change prototype. */
duk_dup(ctx, 0);
printf("top before set: %ld\n", (long) duk_get_top(ctx));
duk_set_prototype(ctx, -2);
printf("top after set: %ld\n", (long) duk_get_top(ctx));
/* Read back the prototype. The object is "naked" and doesn't have
* valueOf() or toString(), so that the string coercion will fail
* here on purpose. Unfortunately this check depends on the specific
* error message and is brittle.
*/
printf("top before get: %ld\n", (long) duk_get_top(ctx));
duk_get_prototype(ctx, 1);
printf("top after get: %ld\n", (long) duk_get_top(ctx));
printf("prototype: %s\n", duk_safe_to_string(ctx, -1));
duk_pop(ctx);
/* Check that prototype is no longer Object.prototype. */
printf("top before get: %ld\n", (long) duk_get_top(ctx));
duk_get_prototype(ctx, 1);
printf("top after get: %ld\n", (long) duk_get_top(ctx));
duk_eval_string(ctx, "Object.prototype");
printf("obj1 proto === Object.prototype: %d\n", (int) duk_strict_equals(ctx, -2, -1));
printf("obj1 proto === obj0: %d\n", (int) duk_strict_equals(ctx, -2, 0));
duk_pop_2(ctx);
/* Check that isPrototypeOf can no longer be accessed. */
duk_get_prop_string(ctx, 1, "isPrototypeOf");
printf("obj1.isPrototypeOf is undefined: %d\n", (int) duk_is_undefined(ctx, -1));
duk_pop(ctx);
/* Check that 'foo' can be accessed. */
duk_get_prop_string(ctx, 1, "foo");
printf("obj1.foo=%s\n", duk_safe_to_string(ctx, -1));
duk_pop(ctx);
printf("final top: %ld\n", (long) duk_get_top(ctx));
return 0;
}
static duk_ret_t test_3(duk_context *ctx) {
static duk_ret_t test_loop(duk_context *ctx) {
duk_push_object(ctx);
duk_push_int(ctx, 123);
duk_put_prop_string(ctx, -2, "foo");
@ -74,11 +162,14 @@ static duk_ret_t test_3(duk_context *ctx) {
printf("obj0.foo=%s\n", duk_safe_to_string(ctx, -1));
duk_pop(ctx);
/* NOTE: there are much more extensive prototype loop tests in
* test-dev-prototype-loop.c
*/
return 0;
}
void test(duk_context *ctx) {
TEST_SAFE_CALL(test_1);
TEST_SAFE_CALL(test_2);
TEST_SAFE_CALL(test_3);
TEST_SAFE_CALL(test_basic);
TEST_SAFE_CALL(test_loop);
}

Loading…
Cancel
Save