<html>
<head>
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
<script src="resources/property-descriptor-utilities.js"></script>
<script>
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, `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>
