<html>
<head>
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
<script src="resources/property-descriptor-utilities.js"></script>
<script>
if (window.internals)
    window.internals.settings.setUnhandledPromiseRejectionToConsoleEnabled(false);

function test()
{
    let suite = ProtocolTest.createAsyncSuite("Runtime.getProperties");

    function addTestCase({name, expression, ownProperties, fetchStart, fetchCount}) {
        suite.addTestCase({
            name,
            async test() {
                ProtocolTest.log(`Evaluating expression...`);
                let evaluateResponse = await InspectorProtocol.awaitCommand({
                    method: "Runtime.evaluate",
                    params: {expression},
                });
                ProtocolTest.assert(!evaluateResponse.wasThrown);

                let getPropertiesPreLog = "Getting";
                if (ownProperties)
                    getPropertiesPreLog += " own";
                getPropertiesPreLog += " properties";
                if (fetchStart)
                    getPropertiesPreLog += ` with fetchStart ${fetchStart}`;
                if (fetchCount)
                    getPropertiesPreLog += ` with fetchCount ${fetchCount}`;
                ProtocolTest.log(getPropertiesPreLog + "...");

                let getPropertiesResponse = await InspectorProtocol.awaitCommand({
                    method: "Runtime.getProperties",
                    params: {
                        objectId: evaluateResponse.result.objectId,
                        ownProperties,
                        fetchStart,
                        fetchCount,
                    },
                });

                let properties = getPropertiesResponse.properties;
                if (properties) {
                    ProtocolTest.assert(!fetchCount || properties.length <= fetchCount + (fetchStart ? 0 : 1), `Should only get ${fetchCount} properties.`);

                    ProtocolTest.log("Properties:");
                    properties.forEach(ProtocolTest.PropertyDescriptorUtilities.logForEach);
                }

                let internalProperties = getPropertiesResponse.internalProperties;
                if (internalProperties) {
                    ProtocolTest.log("Internal Properties:");
                    internalProperties.forEach(ProtocolTest.PropertyDescriptorUtilities.logForEach);
                }
            },
        });
    }

    addTestCase({
        name: "Runtime.getProperties.Object",
        expression: `(function() { let r = Object(5); r.foo = "cat"; return r; })()`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.Array",
        expression: `['red', 'green', 'blue']`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.Constructor",
        expression: `(class Test { })`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.BoundConstructor",
        expression: `(class Test { }).bind(null)`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.BoundConstructorArguments",
        expression: `(class Test { }).bind(null, 1, 2, 3)`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.Function",
        expression: `(function(a, b, c){})`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.FunctionNoParameters",
        expression: `(function(){})`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.BoundFunction",
        expression: `(function(a, b, c){}).bind(null)`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.BoundFunctionWithArguments",
        expression: `(function(a, b, c){}).bind(null, 1, 2, 3)`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.BoundFunctionNoParameters",
        expression: `(function(){}).bind(null)`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.BoundFunctionNoParametersWithArguments",
        expression: `(function(){}).bind(null, 1, 2, 3)`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.Promise.Resolved",
        expression: `Promise.resolve(123)`,
        ownProperties: true,
    });

    addTestCase({
        name: "Runtime.getProperties.Promise.Rejected",
        expression: `Promise.reject(123)`,
        ownProperties: true,
    });

    for (let type of ["Object", "Array"]) {
        addTestCase({
            name: `Runtime.getProperties.fetchStart.${type}`,
            expression: `make${type}(10)`,
            ownProperties: true,
            fetchStart: 5,
        });

        addTestCase({
            name: `Runtime.getProperties.fetchCount.${type}`,
            expression: `make${type}(10)`,
            ownProperties: true,
            fetchCount: 5,
        });

        addTestCase({
            name: `Runtime.getProperties.fetchStartCount.${type}`,
            expression: `make${type}(10)`,
            ownProperties: true,
            fetchStart: 3,
            fetchCount: 4,
        });
    }

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onLoad="runTest()">
<p>Tests for the Runtime.getProperties command.</p>
</body>
</html>
