LCOV - app.info - js/src/jsapi-tests/testResolveRecursion.cpp

LCOV - code coverage report
| Current view: | directory - js/src/jsapi-tests - testResolveRecursion.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 70 | 69 | 98.6 %
| Date: | 2012-04-07 | Functions: | 12 | 10 | 83.3 %

           1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  * vim: set ts=8 sw=4 et tw=99:
           3                 :  */
           4                 :
           5                 : #include "tests.h"
           6                 :
           7                 : /*
           8                 :  * Test that resolve hook recursion for the same object and property is
           9                 :  * prevented.
          10                 :  */
          11                 :
          12               4 : BEGIN_TEST(testResolveRecursion)
          13                 : {
          14                 :     static JSClass my_resolve_class = {
          15                 :         "MyResolve",
          16                 :         JSCLASS_NEW_RESOLVE | JSCLASS_HAS_PRIVATE,
          17                 :
          18                 :         JS_PropertyStub,       // add
          19                 :         JS_PropertyStub,       // delete
          20                 :         JS_PropertyStub,         // get
          21                 :         JS_StrictPropertyStub, // set
          22                 :         JS_EnumerateStub,
          23                 :         (JSResolveOp) my_resolve,
          24                 :         JS_ConvertStub
          25                 :     };
          26                 :
          27               1 :     obj1 = JS_NewObject(cx, &my_resolve_class, NULL, NULL);
          28               1 :     CHECK(obj1);
          29               1 :     obj2 = JS_NewObject(cx, &my_resolve_class, NULL, NULL);
          30               1 :     CHECK(obj2);
          31               1 :     JS_SetPrivate(obj1, this);
          32               1 :     JS_SetPrivate(obj2, this);
          33                 :
          34               1 :     CHECK(JS_DefineProperty(cx, global, "obj1", OBJECT_TO_JSVAL(obj1), NULL, NULL, 0));
          35               1 :     CHECK(JS_DefineProperty(cx, global, "obj2", OBJECT_TO_JSVAL(obj2), NULL, NULL, 0));
          36                 :
          37               1 :     resolveEntryCount = 0;
          38               1 :     resolveExitCount = 0;
          39                 :
          40                 :     /* Start the essence of the test via invoking the first resolve hook. */
          41                 :     jsval v;
          42               1 :     EVAL("obj1.x", &v);
          43               1 :     CHECK_SAME(v, JSVAL_FALSE);
          44               1 :     CHECK_EQUAL(resolveEntryCount, 4);
          45               1 :     CHECK_EQUAL(resolveExitCount, 4);
          46               1 :     return true;
          47                 : }
          48                 :
          49                 : JSObject *obj1;
          50                 : JSObject *obj2;
          51                 : unsigned resolveEntryCount;
          52                 : unsigned resolveExitCount;
          53                 :
          54                 : struct AutoIncrCounters {
          55                 :
          56               4 :     AutoIncrCounters(cls_testResolveRecursion *t) : t(t) {
          57               4 :         t->resolveEntryCount++;
          58               4 :     }
          59                 :
          60               4 :     ~AutoIncrCounters() {
          61               4 :         t->resolveExitCount++;
          62               4 :     }
          63                 :
          64                 :     cls_testResolveRecursion *t;
          65                 : };
          66                 :
          67                 : bool
          68               4 : doResolve(JSObject *obj, jsid id, unsigned flags, JSObject **objp)
          69                 : {
          70               4 :     CHECK_EQUAL(resolveExitCount, 0);
          71               8 :     AutoIncrCounters incr(this);
          72               4 :     CHECK_EQUAL(obj, obj1 || obj == obj2);
          73                 :
          74               4 :     CHECK(JSID_IS_STRING(id));
          75                 :
          76               4 :     JSFlatString *str = JS_FlattenString(cx, JSID_TO_STRING(id));
          77               4 :     CHECK(str);
          78                 :     jsval v;
          79               4 :     if (JS_FlatStringEqualsAscii(str, "x")) {
          80               2 :         if (obj == obj1) {
          81                 :             /* First resolve hook invocation. */
          82               1 :             CHECK_EQUAL(resolveEntryCount, 1);
          83               1 :             EVAL("obj2.y = true", &v);
          84               1 :             CHECK_SAME(v, JSVAL_TRUE);
          85               1 :             CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_FALSE, NULL, NULL, 0));
          86               1 :             *objp = obj;
          87               1 :             return true;
          88                 :         }
          89               1 :         if (obj == obj2) {
          90               1 :             CHECK_EQUAL(resolveEntryCount, 4);
          91               1 :             *objp = NULL;
          92               1 :             return true;
          93                 :         }
          94               2 :     } else if (JS_FlatStringEqualsAscii(str, "y")) {
          95               2 :         if (obj == obj2) {
          96               1 :             CHECK_EQUAL(resolveEntryCount, 2);
          97               1 :             CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_NULL, NULL, NULL, 0));
          98               1 :             EVAL("obj1.x", &v);
          99               1 :             CHECK(JSVAL_IS_VOID(v));
         100               1 :             EVAL("obj1.y", &v);
         101               1 :             CHECK_SAME(v, JSVAL_ZERO);
         102               1 :             *objp = obj;
         103               1 :             return true;
         104                 :         }
         105               1 :         if (obj == obj1) {
         106               1 :             CHECK_EQUAL(resolveEntryCount, 3);
         107               1 :             EVAL("obj1.x", &v);
         108               1 :             CHECK(JSVAL_IS_VOID(v));
         109               1 :             EVAL("obj1.y", &v);
         110               1 :             CHECK(JSVAL_IS_VOID(v));
         111               1 :             EVAL("obj2.y", &v);
         112               1 :             CHECK(JSVAL_IS_NULL(v));
         113               1 :             EVAL("obj2.x", &v);
         114               1 :             CHECK(JSVAL_IS_VOID(v));
         115               1 :             EVAL("obj1.y = 0", &v);
         116               1 :             CHECK_SAME(v, JSVAL_ZERO);
         117               1 :             *objp = obj;
         118               1 :             return true;
         119                 :         }
         120                 :     }
         121               0 :     CHECK(false);
         122                 :     return false;
         123                 : }
         124                 :
         125                 : static JSBool
         126               4 : my_resolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags, JSObject **objp)
         127                 : {
         128               4 :     return static_cast<cls_testResolveRecursion *>(JS_GetPrivate(obj))->
         129               4 :            doResolve(obj, id, flags, objp);
         130                 : }
         131                 :
         132               2 : END_TEST(testResolveRecursion)

Generated by: LCOV version 1.7