<!DOCTYPE html>
<html>
<head>
    <script src="../../resources/testharness.js"></script>
    <script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
    // To test a named property deleter with [OverrideBuiltins] specified, we use DOMStringMap via element.dataset.
    test(() => {
        let element = document.createElement("div");
        element.dataset["a"] = "value1";
        element.dataset["b"] = "value2";
        
        assert_true(delete element.dataset["a"], "Deleting a property known to be in the dataset should return true.");
        assert_true(element.dataset["a"] == undefined, "Deleting a property known to be in the dataset should return true.");
        assert_true(delete element.dataset["c"], "Deleting a property known NOT to be in the dataset should return true.");
        assert_true(delete element.dataset["-invalid"], "Deleting a property known NOT to be in the dataset and invalid should return true.");
    }, "Test that the return value of deleting properties is correct ([OverrideBuiltins] specified).");

    test(() => {
        let element = document.createElement("div");
        element.dataset[1] = "value1";
        element.dataset[2] = "value2";

        assert_true(delete element.dataset[1], "Deleting a numeric property known to be in the dataset should return true.");
        assert_equals(element.dataset[1], undefined, "Deleting a numeric property known to be in the dataset should remove the property.");
        assert_true(delete element.dataset[3], "Deleting a numeric property known NOT to be in the dataset should return true.");
    }, "Test that the return value of deleting numeric properties is correct ([OverrideBuiltins] specified).");

    test((t) => {
        t.add_cleanup(() => {
          delete DOMStringMap.prototype["customProperty"];
        });

        let element = document.createElement("div");

        DOMStringMap.prototype["customProperty"] = 'prototype-value';
        assert_true(delete element.dataset["customProperty"], "");
        assert_equals(DOMStringMap.prototype["customProperty"], 'prototype-value');
    }, "Test that deleting a property that does not exist in the map, but does on the prototype, will return true and not remove the property from the prototype ([OverrideBuiltins] specified).");

    // To test a named property deleter without [OverrideBuiltins] specified, we use Storage via window.sessionStorage.
    test((t) => {
        t.add_cleanup(() => {
          window.sessionStorage.clear();
        });
        
        window.sessionStorage.clear();
        assert_equals(window.sessionStorage.length, 0);

        window.sessionStorage["a"] = "value1";
        window.sessionStorage["b"] = "value2";

        assert_true(delete window.sessionStorage["a"], "Deleting a property known to be in the dataset should return true.");
        assert_true(window.sessionStorage["a"] == undefined, "Deleting a property known to be in the dataset should return true.");
        assert_true(delete window.sessionStorage["c"], "Deleting a property known NOT to be in the dataset should return true.");
    }, "Test that the return value of deleting properties is correct ([OverrideBuiltins] not specified).");

    test((t) => {
        t.add_cleanup(() => {
          window.sessionStorage.clear();
        });
        
        window.sessionStorage.clear();
        assert_equals(window.sessionStorage.length, 0);

        window.sessionStorage[1] = "value1";
        window.sessionStorage[2] = "value2";

        assert_true(delete window.sessionStorage[1], "Deleting a numeric property known to be in the dataset should return true.");
        assert_equals(window.sessionStorage[1], undefined, "Deleting a numeric property known to be in the dataset should remove the property.");
        assert_true(delete window.sessionStorage[3], "Deleting a numeric property known NOT to be in the dataset should return true.");
    }, "Test that the return value of deleting numeric properties is correct ([OverrideBuiltins] not specified).");

    test((t) => {
        t.add_cleanup(() => {
          window.sessionStorage.clear();
        });
        
        window.sessionStorage.clear();
        assert_equals(window.sessionStorage.length, 0);

        window.sessionStorage['a'] = "value1";
        window.sessionStorage['b'] = "value2";

        // First note that trying to set the builtin, length in this case, does not work.
        let currentLength = window.sessionStorage['length'];
        window.sessionStorage['length'] = 'value3';
        assert_equals(window.sessionStorage['length'], currentLength);

        // Attempting to delete it also does not work.
        assert_true(delete window.sessionStorage['length'], "Deleting a builtin property returns true.");
        assert_equals(window.sessionStorage['length'], currentLength);
    }, "Test that you can't delete a builtin property ([OverrideBuiltins] not specified).");

    test((t) => {
        t.add_cleanup(() => {
          window.sessionStorage.clear();
          delete Storage.prototype["customProperty"];
        });

        Storage.prototype["customProperty"] = 'prototype-value';
        assert_true(delete window.sessionStorage["customProperty"], "Deleting the a property known to exist on the prototype but not in the map should return true.");
        assert_equals(Storage.prototype["customProperty"], 'prototype-value');

    }, "Test that deleting a property that does not exist in the map, but does on the prototype, will return true and not remove the property from the prototype ([OverrideBuiltins] not specified).");
</script>
</body>
</html>
