
scope {
  var o = {}; 
  assert 'object' === typename o;
  o.x = o;
  o.x['x'].'z' = 1;
  assert 1 === o.x.'x'['x'].z;
  assert 1 === o.x['x'].('z');
  assert 1 === o.x['x'].('x').('z');
  assert 1 === o.x['x'].('x')['x'].('z');
  o.x = 1;
  o.x = o.x + 2;
  assert 3 === o.x;
  assert 6 === o.x * 2;
  assert 4 === 1 + o.('x');
  assert 2 === o['x'] * 3 % 7;
  var z = 'x';
  assert 3 === o[z];
  assert 9 === o.(z) * o[z];
}

scope {
  var o = {a:1};
  assert 2 === (o.a+=1);
  assert -2 === (o.a*=3*3-10);
  o.a = 2; 
  assert 10===(o.a*=3+2);
  assert 10 === o.a;
  assert 5 === (o['a'] /= 2);
  assert 20 === (o['a'] <<= 2);
  assert 20 === o.a;
}

scope {
  var o = {a:1}, o2 = {prototype:o};
  assert o2 inherits o;
  assert 1 === o2.a;
  o2.a = -1;
  assert 1 === o.a;
  assert -1 === o2.a;
  unset o2.a;
  assert 1 === o2.a;
  unset o2.a;
  assert 1 === o2.a /* o.a not cleared by unset */;
  o2.unset('a');
  assert 1 === o2.a /* o.a not cleared by o2.unset() */;
  o.clearProperties();
  assert undefined === o2.a;

  o.x = 1, o2.x = 1;
  assert 1 === o.x && 1 === o2.x;
  unset o.x, o2.x;
  assert undefined === o.x /* ensure unset handles commas properly */;
  assert undefined === o2.x /* ensure unset handles commas properly */;
}

scope {
    // Test 20190706 fix for bool lookup/property key bug...
    var o = {};
    assert undefined === o[true] /* must not resolve to a truthy-keyed
                                    property (e.g. a member method) */;
    o[true] = 3; // bool-typed property key
    assert undefined === o['x'] /*must not match a boolean true property key */;
    assert 3 === o[true] /* must match existing bool-type key */;
    assert undefined === o.true /* note that o.true is a STRING key, not bool */;
    assert undefined === o[false] /* just checking */;
    o[false] = 1;
    assert 1 === o[false] /* must match literal bool prop key */;
    assert undefined === o.false /* note that o.false is a STRING key, not bool */;
    assert undefined === o[0] /* must not match property key [false] */;
    o[0] = 2;
    unset o[false];
    assert undefined === o[false] /* must not match falsy property key [0] */;
}
