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-06-02 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                 :         JS_FinalizeStub,
      26                 :         JSCLASS_NO_OPTIONAL_MEMBERS
      27                 :     };
      28                 :     
      29               1 :     obj1 = JS_NewObject(cx, &my_resolve_class, NULL, NULL);
      30               1 :     CHECK(obj1);
      31               1 :     obj2 = JS_NewObject(cx, &my_resolve_class, NULL, NULL);
      32               1 :     CHECK(obj2);
      33               1 :     JS_SetPrivate(obj1, this);
      34               1 :     JS_SetPrivate(obj2, this);
      35                 : 
      36               1 :     CHECK(JS_DefineProperty(cx, global, "obj1", OBJECT_TO_JSVAL(obj1), NULL, NULL, 0));
      37               1 :     CHECK(JS_DefineProperty(cx, global, "obj2", OBJECT_TO_JSVAL(obj2), NULL, NULL, 0));
      38                 : 
      39               1 :     resolveEntryCount = 0;
      40               1 :     resolveExitCount = 0;
      41                 : 
      42                 :     /* Start the essence of the test via invoking the first resolve hook. */
      43                 :     jsval v;
      44               1 :     EVAL("obj1.x", &v);
      45               1 :     CHECK_SAME(v, JSVAL_FALSE);
      46               1 :     CHECK_EQUAL(resolveEntryCount, 4);
      47               1 :     CHECK_EQUAL(resolveExitCount, 4);
      48               1 :     return true;
      49                 : }
      50                 : 
      51                 : JSObject *obj1;
      52                 : JSObject *obj2;
      53                 : unsigned resolveEntryCount;
      54                 : unsigned resolveExitCount;
      55                 : 
      56                 : struct AutoIncrCounters {
      57                 :     
      58               4 :     AutoIncrCounters(cls_testResolveRecursion *t) : t(t) {
      59               4 :         t->resolveEntryCount++;
      60               4 :     }
      61                 : 
      62               4 :     ~AutoIncrCounters() {
      63               4 :         t->resolveExitCount++;
      64               4 :     }
      65                 : 
      66                 :     cls_testResolveRecursion *t;
      67                 : };
      68                 : 
      69                 : bool
      70               4 : doResolve(JSObject *obj, jsid id, unsigned flags, JSObject **objp)
      71                 : {
      72               4 :     CHECK_EQUAL(resolveExitCount, 0);
      73               8 :     AutoIncrCounters incr(this);
      74               4 :     CHECK_EQUAL(obj, obj1 || obj == obj2);
      75                 :     
      76               4 :     CHECK(JSID_IS_STRING(id));
      77                 :     
      78               4 :     JSFlatString *str = JS_FlattenString(cx, JSID_TO_STRING(id));
      79               4 :     CHECK(str);
      80                 :     jsval v;
      81               4 :     if (JS_FlatStringEqualsAscii(str, "x")) {
      82               2 :         if (obj == obj1) {
      83                 :             /* First resolve hook invocation. */
      84               1 :             CHECK_EQUAL(resolveEntryCount, 1);
      85               1 :             EVAL("obj2.y = true", &v);
      86               1 :             CHECK_SAME(v, JSVAL_TRUE);
      87               1 :             CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_FALSE, NULL, NULL, 0));
      88               1 :             *objp = obj;
      89               1 :             return true;
      90                 :         }
      91               1 :         if (obj == obj2) {
      92               1 :             CHECK_EQUAL(resolveEntryCount, 4);
      93               1 :             *objp = NULL;
      94               1 :             return true;
      95                 :         }
      96               2 :     } else if (JS_FlatStringEqualsAscii(str, "y")) {
      97               2 :         if (obj == obj2) {
      98               1 :             CHECK_EQUAL(resolveEntryCount, 2);
      99               1 :             CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_NULL, NULL, NULL, 0));
     100               1 :             EVAL("obj1.x", &v);
     101               1 :             CHECK(JSVAL_IS_VOID(v));
     102               1 :             EVAL("obj1.y", &v);
     103               1 :             CHECK_SAME(v, JSVAL_ZERO);
     104               1 :             *objp = obj;
     105               1 :             return true;
     106                 :         }
     107               1 :         if (obj == obj1) {
     108               1 :             CHECK_EQUAL(resolveEntryCount, 3);
     109               1 :             EVAL("obj1.x", &v);
     110               1 :             CHECK(JSVAL_IS_VOID(v));
     111               1 :             EVAL("obj1.y", &v);
     112               1 :             CHECK(JSVAL_IS_VOID(v));
     113               1 :             EVAL("obj2.y", &v);
     114               1 :             CHECK(JSVAL_IS_NULL(v));
     115               1 :             EVAL("obj2.x", &v);
     116               1 :             CHECK(JSVAL_IS_VOID(v));
     117               1 :             EVAL("obj1.y = 0", &v);
     118               1 :             CHECK_SAME(v, JSVAL_ZERO);
     119               1 :             *objp = obj;
     120               1 :             return true;
     121                 :         }
     122                 :     }
     123               0 :     CHECK(false);
     124                 :     return false;
     125                 : }
     126                 : 
     127                 : static JSBool
     128               4 : my_resolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags, JSObject **objp)
     129                 : {
     130               4 :     return static_cast<cls_testResolveRecursion *>(JS_GetPrivate(obj))->
     131               4 :            doResolve(obj, id, flags, objp);
     132                 : }
     133                 : 
     134               2 : END_TEST(testResolveRecursion)

Generated by: LCOV version 1.7