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