js/src/tests/ecma_5/Object/defineProperty-setup.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/tests/ecma_5/Object/defineProperty-setup.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1106 @@
     1.4 +// |reftest| skip -- not a test.
     1.5 +// Any copyright is dedicated to the Public Domain.
     1.6 +// http://creativecommons.org/licenses/publicdomain/
     1.7 +
     1.8 +assertEq("defineProperty" in Object, true);
     1.9 +assertEq(Object.defineProperty.length, 3);
    1.10 +
    1.11 +/*
    1.12 + * Disable an assertion that is pathologically slow given the exhaustiveness of
    1.13 + * these tests.
    1.14 + */
    1.15 +if (typeof enableStackWalkingAssertion === "function")
    1.16 +  enableStackWalkingAssertion(false);
    1.17 +
    1.18 +if (!Object.prototype.toSource)
    1.19 +{
    1.20 +  Object.defineProperty(Object.prototype, "toSource",
    1.21 +  {
    1.22 +    value: function toSource()
    1.23 +    {
    1.24 +      if (this instanceof RegExp)
    1.25 +      {
    1.26 +        var v = "new RegExp(" + uneval(this.source);
    1.27 +        var f = (this.multiline ? "m" : "") +
    1.28 +                (this.global ? "g" : "") +
    1.29 +                (this.ignoreCase ? "i" : "");
    1.30 +        return v + (f ? ", '" + f + "'" : "") + ")";
    1.31 +      }
    1.32 +      return JSON.stringify(this);
    1.33 +    },
    1.34 +    enumerable: false,
    1.35 +    configurable: true,
    1.36 +    writable: true
    1.37 +  });
    1.38 +}
    1.39 +if (!("uneval" in this))
    1.40 +{
    1.41 +  Object.defineProperty(this, "uneval",
    1.42 +  {
    1.43 +    value: function uneval(v)
    1.44 +    {
    1.45 +      if (v === null)
    1.46 +        return "null";
    1.47 +      if (typeof v === "object")
    1.48 +        return v.toSource();
    1.49 +      if (typeof v === "string")
    1.50 +      {
    1.51 +        v = JSON.stringify({v:v});
    1.52 +        return v.substring(5, v.length - 1);
    1.53 +      }
    1.54 +      return "" + v;
    1.55 +    },
    1.56 +    enumerable: false,
    1.57 +    configurable: true,
    1.58 +    writable: true
    1.59 +  });
    1.60 +}
    1.61 +
    1.62 +// reimplemented for the benefit of engines which don't have this helper
    1.63 +function assertEq(v1, v2, m)
    1.64 +{
    1.65 +  if (!SameValue(v1, v2))
    1.66 +  {
    1.67 +    throw "assertion failed: " +
    1.68 +          "got " + uneval(v1) + ", expected " + uneval(v2) +
    1.69 +          (m ? ": " + m : "");
    1.70 +  }
    1.71 +}
    1.72 +
    1.73 +function SameValue(v1, v2)
    1.74 +{
    1.75 +  if (v1 === 0 && v2 === 0)
    1.76 +    return 1 / v1 === 1 / v2;
    1.77 +  if (v1 !== v1 && v2 !== v2)
    1.78 +    return true;
    1.79 +  return v1 === v2;
    1.80 +}
    1.81 +
    1.82 +function PropertyDescriptor(pd)
    1.83 +{
    1.84 +  if (pd)
    1.85 +    this.update(pd);
    1.86 +}
    1.87 +PropertyDescriptor.prototype.update = function update(pd)
    1.88 +{
    1.89 +  if ("get" in pd)
    1.90 +    this.get = pd.get;
    1.91 +  if ("set" in pd)
    1.92 +    this.set = pd.set;
    1.93 +  if ("configurable" in pd)
    1.94 +    this.configurable = pd.configurable;
    1.95 +  if ("writable" in pd)
    1.96 +    this.writable = pd.writable;
    1.97 +  if ("enumerable" in pd)
    1.98 +    this.enumerable = pd.enumerable;
    1.99 +  if ("value" in pd)
   1.100 +    this.value = pd.value;
   1.101 +};
   1.102 +PropertyDescriptor.prototype.convertToDataDescriptor = function convertToDataDescriptor()
   1.103 +{
   1.104 +  delete this.get;
   1.105 +  delete this.set;
   1.106 +  this.writable = false;
   1.107 +  this.value = undefined;
   1.108 +};
   1.109 +PropertyDescriptor.prototype.convertToAccessorDescriptor = function convertToAccessorDescriptor()
   1.110 +{
   1.111 +  delete this.writable;
   1.112 +  delete this.value;
   1.113 +  this.get = undefined;
   1.114 +  this.set = undefined;
   1.115 +};
   1.116 +
   1.117 +function compareDescriptors(d1, d2)
   1.118 +{
   1.119 +  if (d1 === undefined)
   1.120 +  {
   1.121 +    assertEq(d2, undefined, "non-descriptors");
   1.122 +    return;
   1.123 +  }
   1.124 +  if (d2 === undefined)
   1.125 +  {
   1.126 +    assertEq(true, false, "descriptor-equality mismatch: " + uneval(d1) + ", " + uneval(d2));
   1.127 +    return;
   1.128 +  }
   1.129 +
   1.130 +  var props = ["value", "get", "set", "enumerable", "configurable", "writable"];
   1.131 +  for (var i = 0, sz = props.length; i < sz; i++)
   1.132 +  {
   1.133 +    var p = props[i];
   1.134 +    assertEq(p in d1, p in d2, p + " different in d1/d2");
   1.135 +    if (p in d1)
   1.136 +      assertEq(d1[p], d2[p], p);
   1.137 +  }
   1.138 +}
   1.139 +
   1.140 +function examine(desc, field, allowDefault)
   1.141 +{
   1.142 +  if (field in desc)
   1.143 +    return desc[field];
   1.144 +  assertEq(allowDefault, true, "reimplementation error");
   1.145 +  switch (field)
   1.146 +  {
   1.147 +    case "value":
   1.148 +    case "get":
   1.149 +    case "set":
   1.150 +      return undefined;
   1.151 +    case "writable":
   1.152 +    case "enumerable":
   1.153 +    case "configurable":
   1.154 +      return false;
   1.155 +    default:
   1.156 +      assertEq(true, false, "bad field name: " + field);
   1.157 +  }
   1.158 +}
   1.159 +
   1.160 +function IsAccessorDescriptor(desc)
   1.161 +{
   1.162 +  if (!desc)
   1.163 +    return false;
   1.164 +  if (!("get" in desc) && !("set" in desc))
   1.165 +    return false;
   1.166 +  return true;
   1.167 +}
   1.168 +
   1.169 +function IsDataDescriptor(desc)
   1.170 +{
   1.171 +  if (!desc)
   1.172 +    return false;
   1.173 +  if (!("value" in desc) && !("writable" in desc))
   1.174 +    return false;
   1.175 +  return true;
   1.176 +}
   1.177 +
   1.178 +function IsGenericDescriptor(desc)
   1.179 +{
   1.180 +  if (!desc)
   1.181 +    return false;
   1.182 +  if (!IsAccessorDescriptor(desc) && !IsDataDescriptor(desc))
   1.183 +    return true;
   1.184 +  return false;
   1.185 +}
   1.186 +
   1.187 +
   1.188 +
   1.189 +function CustomObject()
   1.190 +{
   1.191 +  this.properties = {};
   1.192 +  this.extensible = true;
   1.193 +}
   1.194 +CustomObject.prototype =
   1.195 +{
   1.196 +  _reject: function _reject(throwing, msg)
   1.197 +  {
   1.198 +    if (throwing)
   1.199 +      throw new TypeError(msg + "; rejected!");
   1.200 +    return false;
   1.201 +  },
   1.202 +  defineOwnProperty: function defineOwnProperty(propname, desc, throwing)
   1.203 +  {
   1.204 +    assertEq(typeof propname, "string", "non-string propname");
   1.205 +
   1.206 +    // Step 1.
   1.207 +    var current = this.properties[propname];
   1.208 +
   1.209 +    // Step 2.
   1.210 +    var extensible = this.extensible;
   1.211 +
   1.212 +    // Step 3.
   1.213 +    if (current === undefined && !extensible)
   1.214 +      return this._reject(throwing, "object not extensible");
   1.215 +
   1.216 +    // Step 4.
   1.217 +    if (current === undefined && extensible)
   1.218 +    {
   1.219 +      var p;
   1.220 +      // Step 4(a).
   1.221 +      if (IsGenericDescriptor(desc) || IsDataDescriptor(desc))
   1.222 +      {
   1.223 +        p = new PropertyDescriptor();
   1.224 +        p.value = examine(desc, "value", true);
   1.225 +        p.writable = examine(desc, "writable", true);
   1.226 +        p.enumerable = examine(desc, "enumerable", true);
   1.227 +        p.configurable = examine(desc, "configurable", true);
   1.228 +      }
   1.229 +      // Step 4(b).
   1.230 +      else
   1.231 +      {
   1.232 +        p = new PropertyDescriptor();
   1.233 +        p.get = examine(desc, "get", true);
   1.234 +        p.set = examine(desc, "set", true);
   1.235 +        p.enumerable = examine(desc, "enumerable", true);
   1.236 +        p.configurable = examine(desc, "configurable", true);
   1.237 +      }
   1.238 +
   1.239 +      this.properties[propname] = p;
   1.240 +
   1.241 +      // Step 4(c).
   1.242 +      return true;
   1.243 +    }
   1.244 +
   1.245 +    // Step 5.
   1.246 +    if (!("value" in desc) && !("get" in desc) && !("set" in desc) &&
   1.247 +        !("writable" in desc) && !("enumerable" in desc) &&
   1.248 +        !("configurable" in desc))
   1.249 +    {
   1.250 +      return;
   1.251 +    }
   1.252 +
   1.253 +    // Step 6.
   1.254 +    do
   1.255 +    {
   1.256 +      if ("value" in desc)
   1.257 +      {
   1.258 +        if (!("value" in current) || !SameValue(desc.value, current.value))
   1.259 +          break;
   1.260 +      }
   1.261 +      if ("get" in desc)
   1.262 +      {
   1.263 +        if (!("get" in current) || !SameValue(desc.get, current.get))
   1.264 +          break;
   1.265 +      }
   1.266 +      if ("set" in desc)
   1.267 +      {
   1.268 +        if (!("set" in current) || !SameValue(desc.set, current.set))
   1.269 +          break;
   1.270 +      }
   1.271 +      if ("writable" in desc)
   1.272 +      {
   1.273 +        if (!("writable" in current) ||
   1.274 +            !SameValue(desc.writable, current.writable))
   1.275 +        {
   1.276 +          break;
   1.277 +        }
   1.278 +      }
   1.279 +      if ("enumerable" in desc)
   1.280 +      {
   1.281 +        if (!("enumerable" in current) ||
   1.282 +            !SameValue(desc.enumerable, current.enumerable))
   1.283 +        {
   1.284 +          break;
   1.285 +        }
   1.286 +      }
   1.287 +      if ("configurable" in desc)
   1.288 +      {
   1.289 +        if (!("configurable" in current) ||
   1.290 +            !SameValue(desc.configurable, current.configurable))
   1.291 +        {
   1.292 +          break;
   1.293 +        }
   1.294 +      }
   1.295 +
   1.296 +      // all fields in desc also in current, with the same values
   1.297 +      return true;
   1.298 +    }
   1.299 +    while (false);
   1.300 +
   1.301 +    // Step 7.
   1.302 +    if (!examine(current, "configurable"))
   1.303 +    {
   1.304 +      if ("configurable" in desc && examine(desc, "configurable"))
   1.305 +        return this._reject(throwing, "can't make configurable again");
   1.306 +      if ("enumerable" in desc &&
   1.307 +          examine(current, "enumerable") !== examine(desc, "enumerable"))
   1.308 +      {
   1.309 +        return this._reject(throwing, "can't change enumerability");
   1.310 +      }
   1.311 +    }
   1.312 +
   1.313 +    // Step 8.
   1.314 +    if (IsGenericDescriptor(desc))
   1.315 +    {
   1.316 +      // do nothing
   1.317 +    }
   1.318 +    // Step 9.
   1.319 +    else if (IsDataDescriptor(current) !== IsDataDescriptor(desc))
   1.320 +    {
   1.321 +      // Step 9(a).
   1.322 +      if (!examine(current, "configurable"))
   1.323 +        return this._reject(throwing, "can't change unconfigurable descriptor's type");
   1.324 +      // Step 9(b).
   1.325 +      if (IsDataDescriptor(current))
   1.326 +        current.convertToAccessorDescriptor();
   1.327 +      // Step 9(c).
   1.328 +      else
   1.329 +        current.convertToDataDescriptor();
   1.330 +    }
   1.331 +    // Step 10.
   1.332 +    else if (IsDataDescriptor(current) && IsDataDescriptor(desc))
   1.333 +    {
   1.334 +      // Step 10(a)
   1.335 +      if (!examine(current, "configurable"))
   1.336 +      {
   1.337 +        // Step 10(a).i.
   1.338 +        if (!examine(current, "writable") &&
   1.339 +            "writable" in desc && examine(desc, "writable"))
   1.340 +        {
   1.341 +          return this._reject(throwing, "can't make data property writable again");
   1.342 +        }
   1.343 +        // Step 10(a).ii.
   1.344 +        if (!examine(current, "writable"))
   1.345 +        {
   1.346 +          if ("value" in desc &&
   1.347 +              !SameValue(examine(desc, "value"), examine(current, "value")))
   1.348 +          {
   1.349 +            return this._reject(throwing, "can't change value if not writable");
   1.350 +          }
   1.351 +        }
   1.352 +      }
   1.353 +      // Step 10(b).
   1.354 +      else
   1.355 +      {
   1.356 +        assertEq(examine(current, "configurable"), true,
   1.357 +                 "spec bug step 10(b)");
   1.358 +      }
   1.359 +    }
   1.360 +    // Step 11.
   1.361 +    else
   1.362 +    {
   1.363 +      assertEq(IsAccessorDescriptor(current) && IsAccessorDescriptor(desc),
   1.364 +               true,
   1.365 +               "spec bug");
   1.366 +
   1.367 +      // Step 11(a).
   1.368 +      if (!examine(current, "configurable"))
   1.369 +      {
   1.370 +        // Step 11(a).i.
   1.371 +        if ("set" in desc &&
   1.372 +            !SameValue(examine(desc, "set"), examine(current, "set")))
   1.373 +        {
   1.374 +          return this._reject(throwing, "can't change setter if not configurable");
   1.375 +        }
   1.376 +        // Step 11(a).ii.
   1.377 +        if ("get" in desc &&
   1.378 +            !SameValue(examine(desc, "get"), examine(current, "get")))
   1.379 +        {
   1.380 +          return this._reject(throwing, "can't change getter if not configurable");
   1.381 +        }
   1.382 +      }
   1.383 +    }
   1.384 +
   1.385 +    // Step 12.
   1.386 +    current.update(desc);
   1.387 +
   1.388 +    // Step 13.
   1.389 +    return true;
   1.390 +  }
   1.391 +};
   1.392 +
   1.393 +function IsCallable(v)
   1.394 +{
   1.395 +  return typeof v === "undefined" || typeof v === "function";
   1.396 +}
   1.397 +
   1.398 +var NativeTest =
   1.399 +  {
   1.400 +    newObject: function newObject()
   1.401 +    {
   1.402 +      return {};
   1.403 +    },
   1.404 +    defineProperty: function defineProperty(obj, propname, propdesc)
   1.405 +    {
   1.406 +      Object.defineProperty(obj, propname, propdesc);
   1.407 +    },
   1.408 +    getDescriptor: function getDescriptor(obj, propname)
   1.409 +    {
   1.410 +      return Object.getOwnPropertyDescriptor(obj, propname);
   1.411 +    }
   1.412 +  };
   1.413 +
   1.414 +var ReimplTest =
   1.415 +  {
   1.416 +    newObject: function newObject()
   1.417 +    {
   1.418 +      return new CustomObject();
   1.419 +    },
   1.420 +    defineProperty: function defineProperty(obj, propname, propdesc)
   1.421 +    {
   1.422 +      assertEq(obj instanceof CustomObject, true, "obj not instanceof CustomObject");
   1.423 +      if ("get" in propdesc || "set" in propdesc)
   1.424 +      {
   1.425 +        if ("value" in propdesc || "writable" in propdesc)
   1.426 +          throw new TypeError("get/set and value/writable");
   1.427 +        if (!IsCallable(propdesc.get))
   1.428 +          throw new TypeError("get defined, uncallable");
   1.429 +        if (!IsCallable(propdesc.set))
   1.430 +          throw new TypeError("set defined, uncallable");
   1.431 +      }
   1.432 +      return obj.defineOwnProperty(propname, propdesc, true);
   1.433 +    },
   1.434 +    getDescriptor: function getDescriptor(obj, propname)
   1.435 +    {
   1.436 +      if (!(propname in obj.properties))
   1.437 +        return undefined;
   1.438 +
   1.439 +      return new PropertyDescriptor(obj.properties[propname]);
   1.440 +    }
   1.441 +  };
   1.442 +
   1.443 +var JSVAL_INT_MAX = Math.pow(2, 30) - 1;
   1.444 +var JSVAL_INT_MIN = -Math.pow(2, 30);
   1.445 +
   1.446 +
   1.447 +function isValidDescriptor(propdesc)
   1.448 +{
   1.449 +  if ("get" in propdesc || "set" in propdesc)
   1.450 +  {
   1.451 +    if ("value" in propdesc || "writable" in propdesc)
   1.452 +      return false;
   1.453 +
   1.454 +    // We permit null here simply because this test's author believes the
   1.455 +    // implementation may sometime be susceptible to making mistakes in this
   1.456 +    // regard and would prefer to be cautious.
   1.457 +    if (propdesc.get !== null && propdesc.get !== undefined && !IsCallable(propdesc.get))
   1.458 +      return false;
   1.459 +    if (propdesc.set !== null && propdesc.set !== undefined && !IsCallable(propdesc.set))
   1.460 +      return false;
   1.461 +  }
   1.462 +
   1.463 +  return true;
   1.464 +}
   1.465 +
   1.466 +
   1.467 +var OMIT = {};
   1.468 +var VALUES =
   1.469 +  [-Infinity, JSVAL_INT_MIN, -0, +0, 1.5, JSVAL_INT_MAX, Infinity,
   1.470 +   NaN, "foo", "bar", null, undefined, true, false, {}, /a/, OMIT];
   1.471 +var GETS =
   1.472 +  [undefined, function get1() { return 1; }, function get2() { return 2; },
   1.473 +   null, 5, OMIT];
   1.474 +var SETS =
   1.475 +  [undefined, function set1() { return 1; }, function set2() { return 2; },
   1.476 +   null, 5, OMIT];
   1.477 +var ENUMERABLES = [true, false, OMIT];
   1.478 +var CONFIGURABLES = [true, false, OMIT];
   1.479 +var WRITABLES = [true, false, OMIT];
   1.480 +
   1.481 +function mapTestDescriptors(filter)
   1.482 +{
   1.483 +  var descs = [];
   1.484 +  var desc = {};
   1.485 +
   1.486 +  function put(field, value)
   1.487 +  {
   1.488 +    if (value !== OMIT)
   1.489 +      desc[field] = value;
   1.490 +  }
   1.491 +
   1.492 +  VALUES.forEach(function(value)
   1.493 +  {
   1.494 +    GETS.forEach(function(get)
   1.495 +    {
   1.496 +      SETS.forEach(function(set)
   1.497 +      {
   1.498 +        ENUMERABLES.forEach(function(enumerable)
   1.499 +        {
   1.500 +          CONFIGURABLES.forEach(function(configurable)
   1.501 +          {
   1.502 +            WRITABLES.forEach(function(writable)
   1.503 +            {
   1.504 +              desc = {};
   1.505 +              put("value", value);
   1.506 +              put("get", get);
   1.507 +              put("set", set);
   1.508 +              put("enumerable", enumerable);
   1.509 +              put("configurable", configurable);
   1.510 +              put("writable", writable);
   1.511 +              if (filter(desc))
   1.512 +                descs.push(desc);
   1.513 +            });
   1.514 +          });
   1.515 +        });
   1.516 +      });
   1.517 +    });
   1.518 +  });
   1.519 +
   1.520 +  return descs;
   1.521 +}
   1.522 +
   1.523 +var ALL_DESCRIPTORS = mapTestDescriptors(function(d) { return true; });
   1.524 +var VALID_DESCRIPTORS = mapTestDescriptors(isValidDescriptor);
   1.525 +
   1.526 +var SKIP_FULL_FUNCTION_LENGTH_TESTS = true;
   1.527 +
   1.528 +function TestRunner()
   1.529 +{
   1.530 +  this._logLines = [];
   1.531 +}
   1.532 +TestRunner.prototype =
   1.533 +  {
   1.534 +    // MAIN METHODS
   1.535 +
   1.536 +    runFunctionLengthTests: function runFunctionLengthTests()
   1.537 +    {
   1.538 +      var self = this;
   1.539 +      function functionLengthTests()
   1.540 +      {
   1.541 +        if (SKIP_FULL_FUNCTION_LENGTH_TESTS)
   1.542 +        {
   1.543 +          print("Skipping full tests for redefining Function.length for now " +
   1.544 +                "because we don't support redefinition of properties with " +
   1.545 +                "native getter or setter...");
   1.546 +          self._simpleFunctionLengthTests();
   1.547 +        }
   1.548 +        else
   1.549 +        {
   1.550 +          self._simpleFunctionLengthTests();
   1.551 +          self._fullFunctionLengthTests(function() { }, 0);
   1.552 +          self._fullFunctionLengthTests(function(one) { }, 1);
   1.553 +          self._fullFunctionLengthTests(function(one, two) { }, 2);
   1.554 +        }
   1.555 +      }
   1.556 +
   1.557 +      this._runTestSet(functionLengthTests, "Function length tests completed!");
   1.558 +    },
   1.559 +
   1.560 +    runNotPresentTests: function runNotPresentTests()
   1.561 +    {
   1.562 +      var self = this;
   1.563 +      function notPresentTests()
   1.564 +      {
   1.565 +        print("Running not-present tests now...");
   1.566 +
   1.567 +        for (var i = 0, sz = ALL_DESCRIPTORS.length; i < sz; i++)
   1.568 +          self._runSingleNotPresentTest(ALL_DESCRIPTORS[i]);
   1.569 +      };
   1.570 +
   1.571 +      this._runTestSet(notPresentTests, "Not-present length tests completed!");
   1.572 +    },
   1.573 +
   1.574 +    runPropertyPresentTestsFraction:
   1.575 +    function runPropertyPresentTestsFraction(part, parts)
   1.576 +    {
   1.577 +      var self = this;
   1.578 +      function propertyPresentTests()
   1.579 +      {
   1.580 +        print("Running already-present tests now...");
   1.581 +
   1.582 +        var total = VALID_DESCRIPTORS.length;
   1.583 +        var start = Math.floor((part - 1) / parts * total);
   1.584 +        var end = Math.floor(part / parts * total);
   1.585 +
   1.586 +        for (var i = start; i < end; i++)
   1.587 +        {
   1.588 +          var old = VALID_DESCRIPTORS[i];
   1.589 +          print("Starting test with old descriptor " + old.toSource() + "...");
   1.590 +
   1.591 +          for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
   1.592 +            self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], []);
   1.593 +        }
   1.594 +      }
   1.595 +
   1.596 +      this._runTestSet(propertyPresentTests,
   1.597 +                       "Property-present fraction " + part + " of " + parts +
   1.598 +                       " completed!");
   1.599 +    },
   1.600 +
   1.601 +    runNonTerminalPropertyPresentTestsFraction:
   1.602 +    function runNonTerminalPropertyPresentTestsFraction(part, parts)
   1.603 +    {
   1.604 +      var self = this;
   1.605 +
   1.606 +      /*
   1.607 +       * A plain old property to define on the object before redefining the
   1.608 +       * originally-added property, to test redefinition of a property that's
   1.609 +       * not also lastProperty.  NB: we could loop over every possible
   1.610 +       * descriptor here if we wanted, even try adding more than one, but we'd
   1.611 +       * hit cubic complexity and worse, and SpiderMonkey only distinguishes by
   1.612 +       * the mere presence of the middle property, not its precise details.
   1.613 +       */
   1.614 +      var middleDefines =
   1.615 +        [{
   1.616 +           property: "middle",
   1.617 +           descriptor:
   1.618 +             { value: 17, writable: true, configurable: true, enumerable: true }
   1.619 +         }];
   1.620 +
   1.621 +      function nonTerminalPropertyPresentTests()
   1.622 +      {
   1.623 +        print("Running non-terminal already-present tests now...");
   1.624 +
   1.625 +        var total = VALID_DESCRIPTORS.length;
   1.626 +        var start = Math.floor((part - 1) / parts * total);
   1.627 +        var end = Math.floor(part / parts * total);
   1.628 +
   1.629 +        for (var i = start; i < end; i++)
   1.630 +        {
   1.631 +          var old = VALID_DESCRIPTORS[i];
   1.632 +          print("Starting test with old descriptor " + old.toSource() + "...");
   1.633 +
   1.634 +          for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
   1.635 +          {
   1.636 +            self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j],
   1.637 +                                               middleDefines);
   1.638 +          }
   1.639 +        }
   1.640 +      }
   1.641 +
   1.642 +      this._runTestSet(nonTerminalPropertyPresentTests,
   1.643 +                       "Non-terminal property-present fraction " +
   1.644 +                       part + " of " + parts + " completed!");
   1.645 +    },
   1.646 +
   1.647 +    runDictionaryPropertyPresentTestsFraction:
   1.648 +    function runDictionaryPropertyPresentTestsFraction(part, parts)
   1.649 +    {
   1.650 +      var self = this;
   1.651 +
   1.652 +      /*
   1.653 +       * Add and readd properties such that the scope for the object is in
   1.654 +       * dictionary mode.
   1.655 +       */
   1.656 +      var middleDefines =
   1.657 +        [
   1.658 +         {
   1.659 +           property: "mid1",
   1.660 +           descriptor:
   1.661 +             { value: 17, writable: true, configurable: true, enumerable: true }
   1.662 +         },
   1.663 +         {
   1.664 +           property: "mid2",
   1.665 +           descriptor:
   1.666 +             { value: 17, writable: true, configurable: true, enumerable: true }
   1.667 +         },
   1.668 +         {
   1.669 +           property: "mid1",
   1.670 +           descriptor:
   1.671 +             { get: function g() { }, set: function s(v){}, configurable: false,
   1.672 +               enumerable: true }
   1.673 +         },
   1.674 +         ];
   1.675 +
   1.676 +      function dictionaryPropertyPresentTests()
   1.677 +      {
   1.678 +        print("Running dictionary already-present tests now...");
   1.679 +
   1.680 +        var total = VALID_DESCRIPTORS.length;
   1.681 +        var start = Math.floor((part - 1) / parts * total);
   1.682 +        var end = Math.floor(part / parts * total);
   1.683 +
   1.684 +        for (var i = start; i < end; i++)
   1.685 +        {
   1.686 +          var old = VALID_DESCRIPTORS[i];
   1.687 +          print("Starting test with old descriptor " + old.toSource() + "...");
   1.688 +
   1.689 +          for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
   1.690 +          {
   1.691 +            self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j],
   1.692 +                                               middleDefines);
   1.693 +          }
   1.694 +        }
   1.695 +      }
   1.696 +
   1.697 +      this._runTestSet(dictionaryPropertyPresentTests,
   1.698 +                       "Dictionary property-present fraction " +
   1.699 +                       part + " of " + parts + " completed!");
   1.700 +    },
   1.701 +
   1.702 +
   1.703 +    // HELPERS
   1.704 +
   1.705 +    runPropertyPresentTests: function runPropertyPresentTests()
   1.706 +    {
   1.707 +      print("Running already-present tests now...");
   1.708 +
   1.709 +      for (var i = 0, sz = VALID_DESCRIPTORS.length; i < sz; i++)
   1.710 +      {
   1.711 +        var old = VALID_DESCRIPTORS[i];
   1.712 +        print("Starting test with old descriptor " + old.toSource() + "...");
   1.713 +
   1.714 +        for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
   1.715 +          this._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], []);
   1.716 +      }
   1.717 +    },
   1.718 +    _runTestSet: function _runTestSet(fun, completeMessage)
   1.719 +    {
   1.720 +      try
   1.721 +      {
   1.722 +        fun();
   1.723 +
   1.724 +        print(completeMessage);
   1.725 +      }
   1.726 +      catch (e)
   1.727 +      {
   1.728 +        print("ERROR, EXITING (line " + (e.lineNumber || -1) + "): " + e);
   1.729 +        throw e;
   1.730 +      }
   1.731 +      finally
   1.732 +      {
   1.733 +        this._reportAllErrors();
   1.734 +      }
   1.735 +    },
   1.736 +    _reportAllErrors: function _reportAllErrors()
   1.737 +    {
   1.738 +      var errorCount = this._logLines.length;
   1.739 +      print("Full accumulated number of errors: " + errorCount);
   1.740 +      if (errorCount > 0)
   1.741 +        throw errorCount + " errors detected, FAIL";
   1.742 +    },
   1.743 +    _simpleFunctionLengthTests: function _simpleFunctionLengthTests(fun)
   1.744 +    {
   1.745 +      print("Running simple Function.length tests now..");
   1.746 +
   1.747 +      function expectThrowTypeError(o, p, desc)
   1.748 +      {
   1.749 +        var err = "<none>", passed = false;
   1.750 +        try
   1.751 +        {
   1.752 +          Object.defineProperty(o, p, desc);
   1.753 +        }
   1.754 +        catch (e)
   1.755 +        {
   1.756 +          err = e;
   1.757 +          passed = e instanceof TypeError;
   1.758 +        }
   1.759 +        assertEq(passed, true, fun + " didn't throw TypeError when called: " + err);
   1.760 +      }
   1.761 +
   1.762 +      expectThrowTypeError(function a() { }, "length", { value: 1 });
   1.763 +      expectThrowTypeError(function a() { }, "length", { enumerable: true });
   1.764 +      expectThrowTypeError(function a() { }, "length", { configurable: true });
   1.765 +      expectThrowTypeError(function a() { }, "length", { writable: true });
   1.766 +    },
   1.767 +    _fullFunctionLengthTests: function _fullFunctionLengthTests(fun)
   1.768 +    {
   1.769 +      var len = fun.length;
   1.770 +      print("Running Function.length (" + len + ") tests now...");
   1.771 +
   1.772 +      var desc;
   1.773 +      var gen = new DescriptorState();
   1.774 +      while ((desc = gen.nextDescriptor()))
   1.775 +        this._runSingleFunctionLengthTest(fun, len, desc);
   1.776 +    },
   1.777 +    _log: function _log(v)
   1.778 +    {
   1.779 +      var m = "" + v;
   1.780 +      print(m);
   1.781 +      this._logLines.push(m);
   1.782 +    },
   1.783 +    _runSingleNotPresentTest: function _runSingleNotPresentTest(desc)
   1.784 +    {
   1.785 +      var nativeObj = NativeTest.newObject();
   1.786 +      var reimplObj = ReimplTest.newObject();
   1.787 +
   1.788 +      try
   1.789 +      {
   1.790 +        NativeTest.defineProperty(nativeObj, "foo", desc);
   1.791 +      }
   1.792 +      catch (e)
   1.793 +      {
   1.794 +        try
   1.795 +        {
   1.796 +          ReimplTest.defineProperty(reimplObj, "foo", desc);
   1.797 +        }
   1.798 +        catch (e2)
   1.799 +        {
   1.800 +          if (e.constructor !== e2.constructor)
   1.801 +          {
   1.802 +            this._log("Difference when comparing native/reimplementation " +
   1.803 +                      "behavior for new descriptor " + desc.toSource() +
   1.804 +                      ", native threw " + e + ", reimpl threw " + e2);
   1.805 +          }
   1.806 +          return;
   1.807 +        }
   1.808 +        this._log("Difference when comparing native/reimplementation " +
   1.809 +                  "behavior for new descriptor " + desc.toSource() +
   1.810 +                  ", error " + e);
   1.811 +        return;
   1.812 +      }
   1.813 +
   1.814 +      try
   1.815 +      {
   1.816 +        ReimplTest.defineProperty(reimplObj, "foo", desc);
   1.817 +      }
   1.818 +      catch (e)
   1.819 +      {
   1.820 +        this._log("Reimpl threw defining new descriptor " + desc.toSource() +
   1.821 +                  ", error: " + e);
   1.822 +        return;
   1.823 +      }
   1.824 +
   1.825 +      var nativeDesc = NativeTest.getDescriptor(nativeObj, "foo");
   1.826 +      var reimplDesc = ReimplTest.getDescriptor(reimplObj, "foo");
   1.827 +      try
   1.828 +      {
   1.829 +        compareDescriptors(nativeDesc, reimplDesc);
   1.830 +      }
   1.831 +      catch (e)
   1.832 +      {
   1.833 +        this._log("Difference comparing returned descriptors for new " +
   1.834 +                  "property defined with descriptor " + desc.toSource() +
   1.835 +                  "; error: " + e);
   1.836 +        return;
   1.837 +      }
   1.838 +    },
   1.839 +    _runSinglePropertyPresentTest:
   1.840 +    function _runSinglePropertyPresentTest(old, add, middleDefines)
   1.841 +    {
   1.842 +      var nativeObj = NativeTest.newObject();
   1.843 +      var reimplObj = ReimplTest.newObject();
   1.844 +
   1.845 +      try
   1.846 +      {
   1.847 +        NativeTest.defineProperty(nativeObj, "foo", old);
   1.848 +      }
   1.849 +      catch (e)
   1.850 +      {
   1.851 +        if (!SameValue(NativeTest.getDescriptor(nativeObj, "foo"), undefined))
   1.852 +        {
   1.853 +          this._log("defining bad property descriptor: " + old.toSource());
   1.854 +          return;
   1.855 +        }
   1.856 +
   1.857 +        try
   1.858 +        {
   1.859 +          ReimplTest.defineProperty(reimplObj, "foo", old);
   1.860 +        }
   1.861 +        catch (e2)
   1.862 +        {
   1.863 +          if (!SameValue(ReimplTest.getDescriptor(reimplObj, "foo"),
   1.864 +                         undefined))
   1.865 +          {
   1.866 +            this._log("defining bad property descriptor: " + old.toSource() +
   1.867 +                      "; reimplObj: " + uneval(reimplObj));
   1.868 +          }
   1.869 +
   1.870 +          if (e.constructor !== e2.constructor)
   1.871 +          {
   1.872 +            this._log("Different errors defining bad property descriptor: " +
   1.873 +                      old.toSource() + "; native threw " + e + ", reimpl " +
   1.874 +                      "threw " + e2);
   1.875 +          }
   1.876 +
   1.877 +          return;
   1.878 +        }
   1.879 +
   1.880 +        this._log("Difference defining a property with descriptor " +
   1.881 +                  old.toSource() + ", error " + e);
   1.882 +        return;
   1.883 +      }
   1.884 +
   1.885 +      try
   1.886 +      {
   1.887 +        ReimplTest.defineProperty(reimplObj, "foo", old);
   1.888 +      }
   1.889 +      catch (e)
   1.890 +      {
   1.891 +        this._log("Difference when comparing native/reimplementation " +
   1.892 +                  "behavior when adding descriptor " + add.toSource() +
   1.893 +                  ", error: " + e);
   1.894 +        return;
   1.895 +      }
   1.896 +
   1.897 +      // Now add (or even readd) however many properties were specified between
   1.898 +      // the original property to add and the new one, to test redefining
   1.899 +      // non-last-properties and properties in scopes in dictionary mode.
   1.900 +      for (var i = 0, sz = middleDefines.length; i < sz; i++)
   1.901 +      {
   1.902 +        var middle = middleDefines[i];
   1.903 +        var prop = middle.property;
   1.904 +        var desc = middle.descriptor;
   1.905 +
   1.906 +        try
   1.907 +        {
   1.908 +          NativeTest.defineProperty(nativeObj, prop, desc);
   1.909 +          ReimplTest.defineProperty(reimplObj, prop, desc);
   1.910 +        }
   1.911 +        catch (e)
   1.912 +        {
   1.913 +          this._log("failure defining middle descriptor: " + desc.toSource() +
   1.914 +                    ", error " + e);
   1.915 +          return;
   1.916 +        }
   1.917 +
   1.918 +        // Sanity check
   1.919 +        var nativeDesc = NativeTest.getDescriptor(nativeObj, prop);
   1.920 +        var reimplDesc = ReimplTest.getDescriptor(reimplObj, prop);
   1.921 +
   1.922 +        compareDescriptors(nativeDesc, reimplDesc);
   1.923 +        compareDescriptors(nativeDesc, desc);
   1.924 +      }
   1.925 +
   1.926 +      try
   1.927 +      {
   1.928 +        NativeTest.defineProperty(nativeObj, "foo", add);
   1.929 +      }
   1.930 +      catch (e)
   1.931 +      {
   1.932 +        try
   1.933 +        {
   1.934 +          ReimplTest.defineProperty(reimplObj, "foo", add);
   1.935 +        }
   1.936 +        catch (e2)
   1.937 +        {
   1.938 +          if (e.constructor !== e2.constructor)
   1.939 +          {
   1.940 +            this._log("Difference when comparing native/reimplementation " +
   1.941 +                      "behavior for descriptor " + add.toSource() +
   1.942 +                      " overwriting descriptor " + old.toSource() + "; " +
   1.943 +                      "native threw " + e + ", reimpl threw " + e2);
   1.944 +          }
   1.945 +          return;
   1.946 +        }
   1.947 +        this._log("Difference when comparing native/reimplementation " +
   1.948 +                  "behavior for added descriptor " + add.toSource() + ", " +
   1.949 +                  "initial was " + old.toSource() + "; error: " + e);
   1.950 +        return;
   1.951 +      }
   1.952 +
   1.953 +      try
   1.954 +      {
   1.955 +        ReimplTest.defineProperty(reimplObj, "foo", add);
   1.956 +      }
   1.957 +      catch (e)
   1.958 +      {
   1.959 +        this._log("Difference when comparing native/reimplementation " +
   1.960 +                  "behavior for readded descriptor " + add.toSource() + ", " +
   1.961 +                  "initial was " + old.toSource() + "; native readd didn't " +
   1.962 +                  "throw, reimpl add did, error: " + e);
   1.963 +        return;
   1.964 +      }
   1.965 +
   1.966 +      var nativeDesc = NativeTest.getDescriptor(nativeObj, "foo");
   1.967 +      var reimplDesc = ReimplTest.getDescriptor(reimplObj, "foo");
   1.968 +      try
   1.969 +      {
   1.970 +        compareDescriptors(nativeDesc, reimplDesc);
   1.971 +      }
   1.972 +      catch (e)
   1.973 +      {
   1.974 +        this._log("Difference comparing returned descriptors for readded " +
   1.975 +                  "property defined with descriptor " + add.toSource() + "; " +
   1.976 +                  "initial was " + old.toSource() + "; error: " + e);
   1.977 +        return;
   1.978 +      }
   1.979 +    },
   1.980 +    _runSingleFunctionLengthTest: function _runSingleFunctionLengthTest(fun, len, desc)
   1.981 +    {
   1.982 +      var nativeObj = fun;
   1.983 +      var reimplObj = ReimplTest.newObject();
   1.984 +      ReimplTest.defineProperty(reimplObj, "length",
   1.985 +      {
   1.986 +        value: len,
   1.987 +        enumerable: false,
   1.988 +        configurable: false,
   1.989 +        writable: false
   1.990 +      });
   1.991 +
   1.992 +      try
   1.993 +      {
   1.994 +        NativeTest.defineProperty(nativeObj, "length", desc);
   1.995 +      }
   1.996 +      catch (e)
   1.997 +      {
   1.998 +        try
   1.999 +        {
  1.1000 +          ReimplTest.defineProperty(reimplObj, "length", desc);
  1.1001 +        }
  1.1002 +        catch (e2)
  1.1003 +        {
  1.1004 +          if (e.constructor !== e2.constructor)
  1.1005 +          {
  1.1006 +            this._log("Difference when comparing native/reimplementation " +
  1.1007 +                      "behavior defining fun.length with " + desc.toSource() +
  1.1008 +                      "; native threw " + e + ", reimpl threw " + e2);
  1.1009 +          }
  1.1010 +          return;
  1.1011 +        }
  1.1012 +        this._log("Difference when comparing Function.length native/reimpl " +
  1.1013 +                  "behavior for descriptor " + desc.toSource() +
  1.1014 +                  ", native impl threw error " + e);
  1.1015 +        return;
  1.1016 +      }
  1.1017 +
  1.1018 +      try
  1.1019 +      {
  1.1020 +        ReimplTest.defineProperty(reimplObj, "length", desc);
  1.1021 +      }
  1.1022 +      catch (e)
  1.1023 +      {
  1.1024 +        this._log("Difference defining new Function.length descriptor: impl " +
  1.1025 +                  "succeeded, reimpl threw for descriptor " +
  1.1026 +                  desc.toSource() + ", error: " + e);
  1.1027 +        return;
  1.1028 +      }
  1.1029 +
  1.1030 +      var nativeDesc = NativeTest.getDescriptor(nativeObj, "length");
  1.1031 +      var reimplDesc = ReimplTest.getDescriptor(reimplObj, "length");
  1.1032 +      try
  1.1033 +      {
  1.1034 +        compareDescriptors(nativeDesc, reimplDesc);
  1.1035 +      }
  1.1036 +      catch (e)
  1.1037 +      {
  1.1038 +        this._log("Difference comparing returned descriptors for " +
  1.1039 +                  "Function.length with descriptor " + desc.toSource() +
  1.1040 +                  "; error: " + e);
  1.1041 +        return;
  1.1042 +      }
  1.1043 +    }
  1.1044 +  };
  1.1045 +
  1.1046 +function runDictionaryPropertyPresentTestsFraction(PART, PARTS)
  1.1047 +{
  1.1048 +  var testfile =
  1.1049 +    '15.2.3.6-dictionary-redefinition-' + PART + '-of-' + PARTS + '.js';
  1.1050 +  var BUGNUMBER = 560566;
  1.1051 +  var summary =
  1.1052 +    'ES5 Object.defineProperty(O, P, Attributes): dictionary redefinition ' +
  1.1053 +    PART + ' of ' + PARTS;
  1.1054 +
  1.1055 +  print(BUGNUMBER + ": " + summary);
  1.1056 +
  1.1057 +  try
  1.1058 +  {
  1.1059 +    new TestRunner().runDictionaryPropertyPresentTestsFraction(PART, PARTS);
  1.1060 +  }
  1.1061 +  catch (e)
  1.1062 +  {
  1.1063 +    throw "Error thrown during testing: " + e +
  1.1064 +            " at line " + e.lineNumber + "\n" +
  1.1065 +          (e.stack
  1.1066 +            ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
  1.1067 +            : "");
  1.1068 +  }
  1.1069 +
  1.1070 +  if (typeof reportCompare === "function")
  1.1071 +    reportCompare(true, true);
  1.1072 +
  1.1073 +  print("Tests complete!");
  1.1074 +}
  1.1075 +
  1.1076 +function runNonTerminalPropertyPresentTestsFraction(PART, PARTS)
  1.1077 +{
  1.1078 +  var BUGNUMBER = 560566;
  1.1079 +  var summary =
  1.1080 +    'ES5 Object.defineProperty(O, P, Attributes): middle redefinition ' +
  1.1081 +    PART + ' of ' + PARTS;
  1.1082 +
  1.1083 +  print(BUGNUMBER + ": " + summary);
  1.1084 +
  1.1085 +
  1.1086 +  /**************
  1.1087 +   * BEGIN TEST *
  1.1088 +   **************/
  1.1089 +
  1.1090 +  try
  1.1091 +  {
  1.1092 +    new TestRunner().runNonTerminalPropertyPresentTestsFraction(PART, PARTS);
  1.1093 +  }
  1.1094 +  catch (e)
  1.1095 +  {
  1.1096 +    throw "Error thrown during testing: " + e +
  1.1097 +            " at line " + e.lineNumber + "\n" +
  1.1098 +          (e.stack
  1.1099 +            ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
  1.1100 +            : "");
  1.1101 +  }
  1.1102 +
  1.1103 +  /******************************************************************************/
  1.1104 +
  1.1105 +  if (typeof reportCompare === "function")
  1.1106 +    reportCompare(true, true);
  1.1107 +
  1.1108 +  print("Tests complete!");
  1.1109 +}

mercurial