<!doctype html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function test()
{
    let options = {
        workInterval: 100,
    };

    function createTaskItems(size = 5) {
        return Array(size).fill("test");
    }

    let suite = InspectorTest.createAsyncSuite("YieldableTask");

    suite.addTestCase({
        name: "ItemsAreProcessedInIterationOrder",
        description: "Check that yieldableTaskWillProcessItem delegate is called on input items in order.",
        test(resolve, reject) {
            let expectedItems = createTaskItems();
            let delegate = {
                yieldableTaskWillProcessItem: (task, item) => {
                    let expectedItem = expectedItems.shift();
                    InspectorTest.expectThat(item === expectedItem, "Item to process should be next expected item.");
                },
                yieldableTaskDidFinish: (task) => {
                    InspectorTest.log("The yieldable task finished.");
                    InspectorTest.expectThat(!task.cancelled, "Task should not be cancelled.");
                    InspectorTest.expectThat(!task.processing, "Task should not be processing.");
                    resolve();
                }
            };

            new WI.YieldableTask(delegate, expectedItems.slice(), options).start();
        }
    });

    suite.addTestCase({
        name: "ProcessedItemsArgumentContainsExpectedItems",
        description: "The list of processed items after a yield should contain the items that were processed by yieldableTaskWillProcessItem.",
        test(resolve, reject) {
            const itemsToProcessBeforeForcingTaskToYield = 10;
            let actualProcessedItems = [];

            let delegate = {
                yieldableTaskWillProcessItem: (task, item) => {
                    actualProcessedItems.push(item);
                    if (actualProcessedItems.length < itemsToProcessBeforeForcingTaskToYield)
                        return;

                    // Busy wait until workInterval is exceeded.
                    let startTime = Date.now();
                    while (Date.now() - startTime <= task.workInterval) {}
                },
                yieldableTaskDidYield: (task, processedItems, elapsedTime) => {
                    InspectorTest.expectThat(itemsToProcessBeforeForcingTaskToYield === processedItems.length, `processedItems argument should contain ${itemsToProcessBeforeForcingTaskToYield} items.`);
                    InspectorTest.expectThat(elapsedTime > 0, "Time to process items before yielding should be greater than zero.");
                    InspectorTest.expectThat(Object.shallowEqual(processedItems, actualProcessedItems), "processedItems argument should contain all items processed since the previous yield.");
                    actualProcessedItems = [];
                },
                yieldableTaskDidFinish: (task) => {
                    InspectorTest.log("Finished processing items.");
                    resolve();
                }
            };

            new WI.YieldableTask(delegate, createTaskItems(40), options).start();
        }
    });

    suite.addTestCase({
        name: "TaskFinishesWhenInterruptedByCancellation",
        description: "Check that a task can be cancelled.",
        test(resolve, reject) {
            let items = createTaskItems(40);
            let delegate = {
                yieldableTaskWillProcessItem: (task, item) => {
                    InspectorTest.log("Process item: " + JSON.stringify(item));
                    task.cancel();
                },
                yieldableTaskDidFinish: (task) => {
                    InspectorTest.log("Finished processing items.");
                    InspectorTest.expectThat(!task.processing, "Task should not be processing.");
                    InspectorTest.expectThat(task.cancelled, "Task should be cancelled.");
                    resolve();
                }
            };

            new WI.YieldableTask(delegate, items, options).start();
        }
    });

    suite.addTestCase({
        name: "ShortTaskCompletesWithoutYielding",
        description: "A task with very few items should run to completion without yielding.",
        test(resolve, reject) {
            let processedItemsCount = 0;

            let delegate = {
                yieldableTaskWillProcessItem: (task, item) => {},
                yieldableTaskDidYield: (task, processedItems, elapsedTime) => { processedItemsCount++; },
                yieldableTaskDidFinish: (task) => {
                    // Note: we expect a fake yield notification when the final item is processed, whether
                    // or not the task actually yielded the run loop.
                    InspectorTest.expectThat(processedItemsCount === 1, "Should process all items without yielding.");
                    InspectorTest.log("Finished processing items.");
                    InspectorTest.expectThat(!task.cancelled, "Task should not be cancelled.");
                    InspectorTest.expectThat(!task.processing, "Task should not be processing.");
                    resolve();
                }
            };

            new WI.YieldableTask(delegate, createTaskItems(50)).start();
        }
    });

    function addTestCaseForIterable(iterable, name) {
        suite.addTestCase({
            name: `ProcessItemsFrom${name}`,
            description: "Check that any iterable object is supported.",
            test(resolve, reject) {
                let delegate = {
                    yieldableTaskWillProcessItem: (task, item) => {
                        InspectorTest.log("Process item: " + JSON.stringify(item));
                    },
                    yieldableTaskDidFinish: (task) => {
                        InspectorTest.log("Finished processing items.");
                        InspectorTest.expectThat(!task.cancelled, "Task should not be cancelled.");
                        InspectorTest.expectThat(!task.processing, "Task should not be processing.");
                        resolve();
                    }
                };

                new WI.YieldableTask(delegate, iterable).start();
            }
        });
    }

    function* gen() {
        let i = 0;
        while (i < 8)
            yield 1 << i++;
    }
    addTestCaseForIterable(gen(), "Generator");

    let map = new Map;
    map.set(1, "one");
    map.set(2, "two");
    map.set(3, "three");
    addTestCaseForIterable(map, "Map");

    let set = new Set;
    set.add(1);
    set.add(2);
    set.add(3);
    addTestCaseForIterable(set, "Set");

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
    <p>Testing WI.YieldableTask.</p>
</body>
</html>
