//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

if (typeof(WScript) != "undefined") {
  WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
}

var tests = {
  // Note: each test has name (string) and body (function) properties.
  //       Success is when the body does not throw, failure -- when it throws.

  test01: {
    name: "formal arg: simple: verify connection: named vs indexed arg",
    body: function () {
      var passedValue = 1;
      function f(a) {
        var val1 = 2;
        a = val1;
        assert.areEqual(val1, a, "wrong value of named parameter (val1)");
        assert.areEqual(val1, arguments[0], "wrong value of indexed parameter (val1)");

        var val2 = 3;
        arguments[0] = val2;
        assert.areEqual(val2, arguments[0], "wrong value of indexed parameter (val2)");
        assert.areEqual(val2, a, "wrong value of named parameter (val2)");
      }
      f(passedValue);
    }
  },

  test02: {
    name: "formal arg: defineProperty, check property descriptor",
    body: function () {
      var passedValue = 1;
      function f(a) {
        var val = 2;
        Object.defineProperty(arguments, 0, { configurable: false, enumerable: false, value: val });
        // Note that we expect writable: true because this was omitted in defineProperty above
        // which is actually re-define property with all attributes == true.
        var expected = { configurable: false, enumerable: false, writable: true, value: val };
        assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0), "wrong value of getOwnPropertyDescriptor");
        assert.areEqual(val, a, "wrong value of named parameter");
      }
      f(passedValue);
    }
  },

  test03: {
    name: "formal arg: defineProperty, set writable to false, verify writability and lost connection. WOOB 1128023",
    body: function () {
      var passedValue = 1;
      function f(a) {
        Object.defineProperty(arguments, 0, { writable: false });
        var expected = { configurable: true, enumerable: true, writable: false, value: passedValue };
        assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0), "wrong value of getOwnPropertyDescriptor");

        // Attempt to change arguments[0] which is not writable now.
        var val1 = 2;
        arguments[0] = val1;
        assert.areEqual(passedValue, arguments[0], "non-writable changed");
        assert.areEqual(passedValue, a, "non-writable changed: named arg also changed");

        // Change named arg value, verify we are in connection named vs indexed arg.
        var val2 = 3;
        a = val2;
        assert.areEqual(val2, a, "Attemp to change named arg: didn't work");
        assert.areEqual(passedValue, arguments[0], "At this time we should not be connected, but we are");
      }
      f(passedValue);
    }
  },

  test04: {
    name: "formal arg: defineProperty, set writable to false AND set value, verify that value changed in both named and indexed arg and that the item was disconnected",
    body: function () {
      var passedValue = 1;
      function f(a) {
        var val1 = 2;
        var val2 = 3;
        Object.defineProperty(arguments, 0, { writable: false, value: val1 });
        var expected = { configurable: true, enumerable: true, writable: false, value: val1 };
        assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0), "wrong value of getOwnPropertyDescriptor");

        assert.areEqual(val1, arguments[0], "value: arguments[0]");
        assert.areEqual(val1, a, "value: a");

        // Verify we are disconnected now.

        a = val2;
        assert.areEqual(val2, a, "new value: a");
        assert.areEqual(val1, arguments[0], "value: arguments[0] -- did not get disconnected!");
      }
      f(passedValue);
    }
  },

  test05: {
    name: "formal arg: defineProperty w/o cause of disconnect, verify still connected to named arg",
    body: function () {
      var passedValue = 1;
      var val1 = 2;
      var val2 = 3;
      function f(a) {
        Object.defineProperty(arguments, 0, { value: val1 });
        a = val1;
        assert.areEqual(val1, arguments[0], "arguments[0] got disconnected");
        arguments[0] = val2;
        assert.areEqual(val2, a, "a got disconnected");
      }
      f(passedValue);
    }
  },

  test06: {
    name: "formal arg: defineProperty, disconnect arg[0], verify that arg[1] is still connected",
    body: function () {
      function f(a, b) {
        Object.defineProperty(arguments, 0, { writable: false });
        var val1 = 3;
        var val2 = 4;
        arguments[1] = val1;
        assert.areEqual(val1, b, "arg[1] got disconnected");
        b = val2;
        assert.areEqual(val2, arguments[1], "arg[1] got disconnected");
      }
      f(1, 2);
    }
  },

  test07: {
    name: "formal arg: defineProperty: convert to accessor property",
    body: function () {
      function f(a) {
        var isGetterFired = false;
        var isSetterFired = false;

        Object.defineProperty(arguments, 0, {
          get: function() { isGetterFired = true; return this.value; },
          set: function(arg) { isSetterFired = true; this.value = arg; }
        });

        assert.areEqual(undefined, arguments[0], "unexpected arg[0] value right after conversion to accessor property");
        assert.areEqual(true, isGetterFired, "isGetterFired (1)");
        isGetterFired = false;

        var val1 = 2;
        arguments[0] = val1;
        assert.areEqual(true, isSetterFired, "isSetterFired");
        assert.areEqual(val1, arguments[0], "get value after set");
        assert.areEqual(true, isGetterFired, "isGetterFired (2)");
      }
      f(1);
    }
  },

  test08: {
    name: "formal arg: defineProperty: convert to accessor, then to data property, verify value and that connection is lost",
    body: function () {
      var passedValue = 1;
      var val1 = 2;
      var val2 = 3;
      function f(a) {
        Object.defineProperty(arguments, 0, {
          get: function() { return this.value; },
          set: function(arg) { this.value = arg; }
        });
        Object.defineProperty(arguments, 0, { value: val1 });
        a = val2;

        assert.areEqual(arguments[0], val1, "arguments[0]");
        assert.areNotEqual(arguments[0], a, "arguments[0] != a");
      }
      f(passedValue);
    }
  },

  test09: {
    name: "formal arg: defineProperty: force convert to ES5 version but keep connected, check enumeration",
    body: function () {
      var passedValue = 1;
      function f(a) {
        Object.defineProperty(arguments, 0, { enumerable: true });
        var accumulator = "";
        for (var i in arguments) {
          accumulator += i.toString() + ": " + arguments[i] + ";";
        }
        assert.areEqual("0: " + passedValue + ";" , accumulator, "accumulator");
      }
      f(passedValue);
    }
  },

  test10: {
    name: "formal arg: defineProperty: set non-enumerable/non-writable/delete, check enumeration",
    body: function () {
      var passedValue1 = 2;
      var passedValue2 = 4;
      function f(a, b, c, d) {
        Object.defineProperty(arguments, 0, { enumerable: false }); // arguments[0].enumerable = false.
        Object.defineProperty(arguments, 1, { writable: false });   // arguments[1].writable = false -> disconnected.
        delete arguments[2];                                            // arguments[2] is deleted.
        var i, accumulator = "";
        for (i in arguments) {
          accumulator += i.toString() + ": " + arguments[i] + ";";
        }
        // Note that we expect [1].enumerable = true because this was omitted in defineProperty above
        // which is actually re-define property that previously already had enumerable = true.
        assert.areEqual("1: " + passedValue1 + ";" + "3: " + passedValue2 + ";", accumulator, "accumulator");
      }
      f(1, passedValue1, 3, passedValue2);
    }
  },

  test11: {
    name: "passed/undeclared arg: verify there is no correlation with Object.prototype indexed data properties. WOOB 1143896",
    body: function () {
      var passedValue = "passed";
      Object.defineProperty(Object.prototype, 0, { value: "from proto", configurable: true, writable: false });
      try {
        function f() { return arguments; }
        var argObj = f(passedValue);
        assert.areEqual(passedValue, argObj[0]);
      } finally {
        delete Object.prototype[0];
      }
    }
  },

  test12: {
    name: "formal arg: verify there is no correlation with Object.prototype indexed properties",
    body: function () {
      var passedValue = "passed";
      Object.defineProperty(Object.prototype, 0, { value: "from proto", configurable: true, writable: false });
      try {
        function f(a) { return arguments }
        var argObj = f(passedValue);
        assert.areEqual(passedValue, argObj[0]);
      } finally {
        delete Object.prototype[0];
      }
    }
  },

  test13: {
    name: "passed/undeclared arg: verify there is no correlation with Object.prototype indexed accessor properties. WOOB 1144602",
    body: function () {
      var initial = "initial";
      var passedValue = "passed";
      var data = initial;
      Object.defineProperty(Object.prototype, 0, {
        configurable: true,
        get: function() { return data; },
        set: function(arg) { data = arg; }
      });
      try {
        function f() { return arguments; }
        var argObj = f(passedValue);
        assert.areEqual(initial, data, "data: should not be changed as setter on prototype should not be fired");
        assert.areEqual(passedValue, argObj[0], "argObj[0]");
      } finally {
        delete Object.prototype[0];
      }
    }
  },

  test14: {
    name: "formal arg: verify there is no correlation with Object.prototype indexed accessor properties",
    body: function () {
      var initial = "initial";
      var passedValue = "passed";
      var data = initial;
      Object.defineProperty(Object.prototype, 0, {
        configurable: true,
        get: function() { return data; },
        set: function(arg) { data = arg; }
      });
      try {
        function f(a) { return arguments; }
        var argObj = f(passedValue);
        assert.areEqual(initial, data, "data: should not be changed as setter on prototype should not be fired");
        assert.areEqual(passedValue, argObj[0], "argObj[0]");
      } finally {
        delete Object.prototype[0];
      }
    }
  },

  test15: {
    name: "formal arg: delete, make sure it's deleted",
    body: function () {
      var passedValue = 1;
      function f(a) {
        Object.defineProperty(arguments, 0, { enumerable: false }); // Force convert to ES5 version.
        delete arguments[0];
        assert.areEqual(undefined, arguments[0], "was not deleted.");
        assert.areEqual(passedValue, a, "a is changed.");
      }
      f(passedValue);
    }
  },

  test16: {
    name: "formal arg: delete, add, check named arg is not changed",
    body: function () {
      var passedValue = 1;
      function f(a, b) {
        Object.defineProperty(arguments, 0, { enumerable: false }); // Force convert to ES5 version.
        delete arguments[0];
        arguments[0] = passedValue + 1;
        assert.areEqual(passedValue, a, "a is changed.");
      }
      f(passedValue, 2);
    }
  },

  test17: {
    name: "formal arg: delete, then defineProperty with attributes for data property, check the value",
    body: function () {
      var passedValue = 1;
      function f(a) {
        delete arguments[0];
        var val = 2;
        Object.defineProperty(arguments, 0, { enumerable: true, configurable: true, writable: true, value: val });
        assert.areEqual(val, arguments[0], "wrong value");
      }
      f(passedValue);
    }
  },

  test18: {
    name: "formal arg: delete, then defineProperty with attributes for accessor property, check the enumeration",
    body: function () {
      var passedValue = 1;
      var getter = function() {return this.value; };
      var setter = function(arg) { this.value = arg; };
      function f(a) {
        delete arguments[0];
        Object.defineProperty(arguments, 0, { enumerable: true, configurable: true, get: getter, set: setter });
        var expected = { configurable: true, enumerable: true, get: getter, set: setter };
        assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0), "wrong descriptor");
        var accumulator = "";
        for (var i in arguments) {
          accumulator += i.toString() + ": " + arguments[i] + ";";
        }
        assert.areEqual("0: " + undefined + ";", accumulator, "accumulator 2");
      }
      f(passedValue);
    }
  },

  test19: {
    name: "formal arg, es5 heap arguments: delete, add, check enumerable/order",
    body: function () {
      var passedValue1 = 1;
      var passedValue2 = 2;
      var newValue1 = 100;
      var newValue2 = 200;
      var i, accumulator;
      function f(a, b) {
        // Scenario 1: delete prior to converting to ES5 version.
        delete arguments[0];                                       // Delete [0] prior to conversion to ES5.
        Object.defineProperty(arguments, 0, { configurable: true, enumerable: true, value: newValue1 }); // Bring back [0] by defineProperty. Now args is ES5.
        accumulator = "";
        for (i in arguments) {
          accumulator += i.toString() + ": " + arguments[i] + ";";
        }
        assert.areEqual("0: " + newValue1 + ";" + "1: " + passedValue2 + ";", accumulator, "accumulator 1");

        // Scenario 2: delete after converting to ES5 version.
        Object.defineProperty(arguments, 0, { configurable: true, enumerable: true, writable: true, value: newValue1 }); // Bring back [0] by defineProperty. Now args is ES5.
        delete arguments[0];                                      // Delete [0] prior after conversion to ES5.
        arguments[0] = newValue2;                                 // Bring back [0] by setting value.
        accumulator = "";
        for (i in arguments) {
          accumulator += i.toString() + ": " + arguments[i] + ";";
        }
        assert.areEqual("0: " + newValue2 + ";" + "1: " + passedValue2 + ";", accumulator, "accumulator 2");
      }
      f(passedValue1, passedValue2);
    }
  },

  test20: {
    name: "formal arg, es5 heap arguments: delete, add, keep another arg in objectArray and use one non-formal, check enumerable/order",
    body: function () {
      var passedValue1 = 1;
      var passedValue2 = 2;
      var passedValue3 = 3;
      var passedValue4 = 4;
      var newValue = 100;

      function f(a, b, c) {
        Object.defineProperty(arguments, 0, { enumerable: true }); // Add objectArray item
        Object.defineProperty(arguments, 2, { enumerable: true }); // Add objectArray item
        var accumulator = "";
        delete arguments[0];
        arguments[0] = newValue;
        for (var i in arguments) {
          accumulator += i.toString() + ": " + arguments[i] + ";";
        }
        assert.areEqual(
          "0: " + newValue + ";" + "1: " + passedValue2 + ";" + "2: " + passedValue3 + ";" + "3: " + passedValue4 + ";",
          accumulator,
          "accumulator");
      }
      f(passedValue1, passedValue2, passedValue3, passedValue4);
    }
  },

  test21: {
    name: "formal arg: defineProperty, set enumerable to false, check getOwnPropertyNames",
    body: function (a, b) {
      function f(a) {
        Object.defineProperty(arguments, 0, { enumerable: false });
        // Note: Object.getOwnPropertyNames returns all properties, even non-enumerable.
        var actual = Object.getOwnPropertyNames(arguments);
        var expected = { 0: "0", 1: "1", 2: "length", 3: "callee" };
        assert.areEqual(expected, actual, "wrong property names");
      }
      f(101, 102);
    }
  },

  test22Helper: function test22Helper(isConvertNeeded, messagePrefix) {
    function mkerr(message) {
      return messagePrefix + ": " + message;
    }

    var passedValue = 1;
    var newPropertyName = "x";
    function f(a, b) {
      if (isConvertNeeded) {
        Object.defineProperty(arguments, 1, { enumerable: true }); // Force convert to ES5 version.
      }

      Object.preventExtensions(arguments); // No new properties can be added.
      assert.areEqual(false, Object.isExtensible(arguments), mkerr("isExtensible"));
      try {
        Object.defineProperty(arguments, newPropertyName, { enumerable: true, value: 100 }); // add new property
        assert.fail(mkerr("did not throw exception"));
      } catch (ex) {
      }

      arguments[newPropertyName] = 100;
      assert.areEqual(undefined, arguments[newPropertyName], mkerr("New property was added after preventExtensions was called"));
    }
    f(passedValue, passedValue + 1);
  },

  test22_1: {
    name: "arguments (non-ES5 version): call Object.preventExtensions, try add new property by defineProperty and direct set",
    body: function () {
      tests.test22Helper(false, "non-ES5 version");
    }
  },

  test22_2: {
    name: "arguments (ES5 version): call Object.preventExtensions, try add new property by defineProperty and direct set",
    body: function () {
      tests.test22Helper(true, "ES5 version");
    }
  },

  test23Helper: function test23Helper(isConvertNeeded, messagePrefix) {
    function mkerr(message) {
      return messagePrefix + ": " + message;
    }

    var passedValue = 1;
    function f(a, b) {
      if (isConvertNeeded) {
        Object.defineProperty(arguments, 1, { enumerable: true }); // Force convert to ES5 version.
      }

      Object.preventExtensions(arguments); // This causes configurable, writable = false for all properties + Object.preventExtensions.
      // Note: formals existed prior to calling Object.preventExtensions, thus they are still modifiable.
      assert.areEqual(false, Object.isExtensible(arguments), "isExtensible");

      var actual = Object.getOwnPropertyDescriptor(arguments, 0);
      var expected = { configurable: true, enumerable: true, writable: true, value: passedValue };
      assert.areEqual(expected, actual, mkerr("wrong descriptor - initial"));

      // Try to modify/re-configure
      // Note: do not change value here as it causes different code path than exercised by identified issue.
      Object.defineProperty(arguments, 0, { enumerable: false });
      Object.defineProperty(arguments, 0, { writable: false });
      Object.defineProperty(arguments, 0, { configurable: false });
      var expected = { configurable: false, enumerable: false, writable: false, value: passedValue };
      assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0), mkerr("wrong descriptor - after redefine"));
    }
    f(passedValue, passedValue + 1);
  },

  // After Object.preventExtensions(arguments) we can't modify the attributes on formals.
  test23_1: {
    name: "arguments (non-ES5 version): call Object.preventExtensions, make sure we can still modify atttibutes on formals without changing the value",
    body: function () {
      tests.test23Helper(false, "non-ES5 version");
    }
  },

  // After Object.preventExtensions(arguments) we can't modify the attributes on formals.
  test23_2: {
    name: "arguments (ES5 version): call Object.preventExtensions, make sure we can still modify atttibutes on formals without changing the value",
    body: function () {
      tests.test23Helper(true, "ES5 version");
    }
  },

  test24Helper: function test24Helper(isConvertNeeded, messagePrefix) {
    function mkerr(message) {
      return messagePrefix + ": " + message;
    }

    var passedValue = 1;
    function f(a, b) {
      if (isConvertNeeded) {
        Object.defineProperty(arguments, 1, { enumerable: true }); // Force convert to ES5 version.
      }

      Object.seal(arguments); // This causes configurable = false for all properties + Object.preventExtensions.

      assert.areEqual(true, Object.isSealed(arguments), mkerr("isSealed"));
      assert.areEqual(false, Object.isExtensible(arguments), mkerr("isExtensible"));

      var actual = Object.getOwnPropertyDescriptor(arguments, 0);
      var expected = { configurable: false, enumerable: true, writable: true, value: passedValue };
      assert.areEqual(expected, actual, mkerr("wrong descriptor"));
    }
    f(passedValue, passedValue + 1);
  },

  // Object.freeze(arguments -- not ES5 version) does not set configurable to false on formals.
  test24_1: {
    name: "arguments (non-ES5 version): call Object.seal, verify descriptor on formal",
    body: function () {
      tests.test24Helper(false, "non-ES5 version");
    }
  },

  test24_2: {
    name: "arguments (ES5 version): call Object.seal, verify descriptor on formal",
    body: function () {
      tests.test24Helper(true, "ES5 version");
    }
  },

  test25Helper: function test25Helper(isConvertNeeded, messagePrefix) {
    function mkerr(message) {
      return messagePrefix + ": " + message;
    }

    var passedValue = 1;
    function f(a, b) {
      if (isConvertNeeded) {
        Object.defineProperty(arguments, 1, { enumerable: true }); // Force convert to ES5 version.
      }

      Object.freeze(arguments); // This causes configurable AND writable = false for all properties + Object.preventExtensions.

      assert.areEqual(true, Object.isFrozen(arguments), mkerr("isFrozen"));
      assert.areEqual(true, Object.isSealed(arguments), mkerr("isSealed"));
      assert.areEqual(false, Object.isExtensible(arguments), mkerr("isExtensible"));

      var actual = Object.getOwnPropertyDescriptor(arguments, 0);
      var expected = { configurable: false, enumerable: true, writable: false, value: passedValue };
      assert.areEqual(expected, actual, mkerr("wrong descriptor"));
    }
    f(passedValue, passedValue + 1);
  },

  // Object.freeze(arguments -- not ES5 version) does not set configurable and writable to false on formals.
  test25_1: {
    name: "arguments (non-ES5 version): call Object.freeze, verify descriptor on formal",
    body: function () {
      tests.test25Helper(false, "non-ES5 version");
    }
  },

  test25_2: {
    name: "arguments (ES5 version): call Object.freeze, verify descriptor on formal",
    body: function () {
      tests.test25Helper(true, "ES5 version");
    }
  },

  test26: {
    name: "formal arg: delete, preventExtensions, enumerate, make sure the item is deleted",
    body: function () {
      var passedValue1 = 1;
      var passedValue2 = 2;
      function f(a, b) {
        delete arguments[1];
        Object.preventExtensions(arguments);
        var accumulator = "";
        for (var i in arguments) {
          accumulator += i.toString() + ": " + arguments[i] + ";";
        }
        assert.areEqual("0: " + passedValue1 + ";", accumulator, "accumulator");
        assert.areEqual(undefined, arguments[1], "arguments[1]");
      }
      f(passedValue1, passedValue2);
    }
  },

  test27: {
    name: "formal arg: convert to ES5 version, change value and set writable to false",
    body: function () {
      var passedValue1 = 1;
      var val = 2;
      function f(a) {
        Object.defineProperty(arguments, 0, { enumerable: true });
        a = val;
        Object.defineProperty(arguments, 0, { writable: false });
        var expected = { configurable: true, enumerable: true, writable: false, value: val };
        assert.areEqual(expected, Object.getOwnPropertyDescriptor(arguments, 0));
      }
      f(passedValue1);
    }
  },

  test28: {
    name: "formal arg: convert to ES5 version, enumerate when number of actual params is less than number of formals",
    body: function () {
      var accumulator = "";
      function f(a, b) {
        Object.preventExtensions(arguments);
        for (var i in arguments) {
          if (accumulator.length != 0) accumulator += ",";
          accumulator += arguments[i];
        }
      }
      var value = 5;
      f(value);
      var expected = helpers.isVersion10OrLater ?
        value.toString() :
        value.toString() + ",undefined"; // IE9 compat mode -- Win8 558490.
      assert.areEqual(expected, accumulator, "Wrong accumulated value");
    }
  },

} // tests.

testRunner.runTests(tests);
