<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>window.performance User Timing measure() method is working properly</title>
        <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
        <link rel="help" href="http://www.w3.org/TR/user-timing/#dom-performance-measure"/>
        <script src="/resources/testharness.js"></script>
        <script src="/resources/testharnessreport.js"></script>
        <script src="resources/webperftestharness.js"></script>

    <script type="text/javascript">
        // test data
        var startMarkName = "mark_start";
        var startMarkValue;
        var endMarkName = "mark_end";
        var endMarkValue;
        var measures;
        var testThreshold = 20;

        // test measures
        var measureTestDelay = 200;
        var TEST_MEASURES =
        [
            {
                name:                   "measure_no_start_no_end",
                startMark:              undefined,
                endMark:                undefined,
                startTime:              undefined,
                duration:               undefined,
                entryType:              "measure",
                entryMatch:             undefined,
                order:                  undefined,
                found:                  false
            },
            {
                name:                   "measure_start_no_end",
                startMark:              "mark_start",
                endMark:                undefined,
                startTime:              undefined,
                duration:               undefined,
                entryType:              "measure",
                entryMatch:             undefined,
                order:                  undefined,
                found:                  false
            },
            {
                name:                   "measure_start_end",
                startMark:              "mark_start",
                endMark:                "mark_end",
                startTime:              undefined,
                duration:               undefined,
                entryType:              "measure",
                entryMatch:             undefined,
                order:                  undefined,
                found:                  false
            },
            {
                name:                   "measure_no_start_no_end",
                startMark:              undefined,
                endMark:                undefined,
                startTime:              undefined,
                duration:               undefined,
                entryType:              "measure",
                entryMatch:             undefined,
                order:                  undefined,
                found:                  false
            }
        ];

        setup({explicit_done: true});

        test_namespace();

        function onload_test()
        {
            // test for existance of User Timing and Performance Timeline interface
            if (window.performance.mark == undefined ||
                window.performance.clearMarks == undefined ||
                window.performance.measure == undefined ||
                window.performance.clearMeasures == undefined ||
                window.performance.getEntriesByName == undefined ||
                window.performance.getEntriesByType == undefined ||
                window.performance.getEntries == undefined)
            {
                test_true(false,
                          "The User Timing and Performance Timeline interfaces, which are required for this test, " +
                          "are defined.");

                done();
            }
            else
            {
                // create the start mark for the test measures
                window.performance.mark(startMarkName);

                // get the start mark's value
                startMarkValue = window.performance.getEntriesByName(startMarkName)[0].startTime;

                // create the test end mark using the test delay; this will allow for a significant difference between
                // the mark values that should be represented in the duration of measures using these marks
                setTimeout(measure_test_cb, measureTestDelay);
            }
        }

        function measure_test_cb()
        {
            // create the end mark for the test measures
            window.performance.mark(endMarkName);

            // get the end mark's value
            endMarkValue = window.performance.getEntriesByName(endMarkName)[0].startTime;

            // loop through all measure scenarios and create the corresponding measures
            for (var i in TEST_MEASURES)
            {
                var scenario = TEST_MEASURES[i];

                if (scenario.startMark == undefined && scenario.endMark == undefined)
                {
                    // both startMark and endMark are undefined, don't provide either parameters
                    window.performance.measure(scenario.name);

                    // when startMark isn't provided to the measure() call, a DOMHighResTimeStamp corresponding
                    // to the navigationStart attribute with a timebase of the same attribute is used; this is
                    // equivalent to 0
                    scenario.startTime = 0;

                    // when endMark isn't provided to the measure() call, a DOMHighResTimeStamp corresponding to
                    // the current time with a timebase of the navigationStart attribute is used
                    scenario.duration = (new Date()) - window.performance.timing.navigationStart;
                }
                else if (scenario.startMark != undefined && scenario.endMark == undefined)
                {
                    // only startMark is defined, provide startMark and don't provide endMark
                    window.performance.measure(scenario.name, scenario.startMark);

                    // when startMark is provided to the measure() call, the value of the mark whose name is
                    // provided is used for the startMark
                    scenario.startTime = startMarkValue;

                    // when endMark isn't provided to the measure() call, a DOMHighResTimeStamp corresponding to
                    // the current time with a timebase of the navigationStart attribute is used
                    scenario.duration = ((new Date()) - window.performance.timing.navigationStart) -
                                                startMarkValue;
                }
                else if (scenario.startMark != undefined && scenario.endMark != undefined)
                {
                    // both startMark and endMark are defined, provide both parameters
                    window.performance.measure(scenario.name, scenario.startMark, scenario.endMark);

                    // when startMark is provided to the measure() call, the value of the mark whose name is
                    // provided is used for the startMark
                    scenario.startTime = startMarkValue;

                    // when endMark is provided to the measure() call, the value of the mark whose name is
                    // provided is used for the startMark
                    scenario.duration = endMarkValue - startMarkValue;
                }
            }

            // test that expected measures are returned by getEntriesByName
            for (var i in TEST_MEASURES)
            {
                entries = window.performance.getEntriesByName(TEST_MEASURES[i].name);
                // for all test measures, the test will be validate the test measure against the first entry returned
                // by getEntriesByName(), except for the last measure, where since it is a duplicate measure, the test
                // will validate it against the second entry returned by getEntriesByName()
                test_measure(entries[(i == 3 ? 1 : 0)],
                            "window.performance.getEntriesByName(\"" + TEST_MEASURES[i].name + "\")[" +
                            (i == 3 ? 1 : 0) + "]",
                            TEST_MEASURES[i].name,
                            TEST_MEASURES[i].startTime,
                            TEST_MEASURES[i].duration);
                TEST_MEASURES[i].entryMatch = entries[(i == 3 ? 1 : 0)];
            }

            // test that expected measures are returned by getEntriesByName with the entryType parameter provided
            for (var i in TEST_MEASURES)
            {
                entries = window.performance.getEntriesByName(TEST_MEASURES[i].name, "measure");

                test_true(match_entries(entries[(i == 3 ? 1 : 0)], TEST_MEASURES[i].entryMatch),
                          "window.performance.getEntriesByName(\"" + TEST_MEASURES[i].name + "\", \"measure\")[" +
                          (i == 3 ? 1 : 0) + "] returns an object containing the \"" + TEST_MEASURES[i].name +
                          "\" measure in the correct order, and its value matches the \"" + TEST_MEASURES[i].name +
                          "\" measure returned by window.performance.getEntriesByName(\"" + TEST_MEASURES[i].name +
                          "\")");
            }

            // test that expected measures are returned by getEntries
            entries = get_test_entries(window.performance.getEntries(), "measure");

            test_measure_list(entries, "window.performance.getEntries()", TEST_MEASURES);

            // test that expected measures are returned by getEntriesByType
            entries = window.performance.getEntriesByType("measure");

            test_measure_list(entries, "window.performance.getEntriesByType(\"measure\")", TEST_MEASURES);

            done();
        }

        function match_entries(entry1, entry2, threshold)
        {
            if (threshold == undefined)
            {
                threshold = 0;
            }

            var pass = true;

            // match name
            pass = pass && (entry1.name == entry2.name);

            // match startTime
            pass = pass && (Math.abs(entry1.startTime - entry2.startTime) <= testThreshold);

            // match entryType
            pass = pass && (entry1.entryType == entry2.entryType);

            // match duration
            pass = pass && (Math.abs(entry1.duration - entry2.duration) <= testThreshold);

            return pass;
        }

        function test_measure(measureEntry, measureEntryCommand, expectedName, expectedStartTime, expectedDuration)
        {
            // test name
            test_true(measureEntry.name == expectedName, measureEntryCommand + ".name == \"" + expectedName + "\"");

            // test startTime; since for a mark, the startTime is always equal to a mark's value or the value of a
            // navigation timing attribute, the actual startTime should match the expected value exactly
            test_true(Math.abs(measureEntry.startTime - expectedStartTime) == 0,
                      measureEntryCommand + ".startTime == " + expectedStartTime);

            // test entryType
            test_true(measureEntry.entryType == "measure", measureEntryCommand + ".entryType == \"measure\"");

            // test duration, allow for an acceptable threshold in the difference between the actual duration and the
            // expected value for the duration
            test_true(Math.abs(measureEntry.duration - expectedDuration) <= testThreshold, measureEntryCommand +
                      ".duration ~== " + expectedDuration + " (up to " + testThreshold + "ms difference allowed)");
        }

        function test_measure_list(measureEntryList, measureEntryListCommand, measureScenarios)
        {
            // give all entries a "found" property that can be set to ensure it isn't tested twice
            for (var i in measureEntryList)
            {
                measureEntryList[i].found = false;
            }

            for (var i in measureScenarios)
            {
                measureScenarios[i].found = false;

                for (var j in measureEntryList)
                {
                    if (match_entries(measureEntryList[j], measureScenarios[i]) && !measureEntryList[j].found)
                    {
                        test_true(match_entries(measureEntryList[j], measureScenarios[i].entryMatch),
                                  measureEntryListCommand + " returns an object containing the \"" +
                                  measureScenarios[i].name + "\" measure, and it's value matches the measure " +
                                  "returned by window.performance.getEntriesByName(\"" + measureScenarios[i].name +
                                  "\")[" + (i == 3 ? 1 : 0) + "].");

                        measureEntryList[j].found = true;
                        measureScenarios[i].found = true;
                        break;
                    }
                }

                if (!measureScenarios[i].found)
                {
                    test_true(false,
                              measureEntryListCommand + " returns an object containing the \"" +
                              measureScenarios[i].name + "\" measure.");
                }
            }

            // verify order of output of getEntriesByType
            var startTimeCurr = 0;
            var pass = true;
            for (var i in measureEntryList)
            {
                if (measureEntryList[i].startTime < startTimeCurr)
                {
                    pass = false;
                }
                startTimeCurr = measureEntryList[i].startTime;
            }
            test_true(pass,
                      measureEntryListCommand + " returns an object containing all test " +
                      "measures in order.");
        }

        function get_test_entries(entryList, entryType)
        {
            var testEntries = new Array();

            // filter entryList
            for (var i in entryList)
            {
                if (entryList[i].entryType == entryType)
                {
                    testEntries.push(entryList[i]);
                }
            }

            return testEntries;
        }
    </script>
    </head>
    <body onload="onload_test();">
        <h1>Description</h1>
        <p>This test validates that the performance.measure() method is working properly. This test creates the
           following measures to test this method:
            <ul>
                <li>"measure_no_start_no_end": created using a measure() call without a startMark or endMark
                    provided</li>
                <li>"measure_start_no_end": created using a measure() call with only the startMark provided</li>
                <li>"measure_start_end": created using a measure() call with both a startMark or endMark provided</li>
                <li>"measure_no_start_no_end": duplicate of the first measure, used to confirm names can be re-used</li>
            </ul>
           After creating each measure, the existence of these measures is validated by calling
           performance.getEntriesByName() (both with and without the entryType parameter provided),
           performance.getEntriesByType(), and performance.getEntries()
        </p>

        <div id="log"></div>
    </body>
</html>
