<html>
<head>
<script src="../../http/tests/inspector/inspector-test.js"></script>
<script src="../../http/tests/inspector/debugger-test.js"></script>
<script src="../../http/tests/inspector/workspace-test.js"></script>
<script>
document.write("<scrip" + "t>function foo() { }</sc" + "ript>");

function createScriptTag()
{
    var scriptElement = document.createElement("script");
    scriptElement.textContent = "function bar() { }";
    document.head.appendChild(scriptElement);
}

var test = function()
{
    InspectorTest.startDebuggerTest(step1);

    var scripts;
    function step1()
    {
        InspectorTest.evaluateInPage("createScriptTag()", step2);
    }
    
    function step2()
    {
        WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, step3);
        step3();
    }
    
    function step3()
    {
        scripts = Object.values(WebInspector.debuggerModel.scripts);
        function filterOutStandaloneAndInlineScripts(script)
        {
            return !script.isInlineScript() && script.sourceURL.indexOf("dynamic-script-tag.html") !== -1;
        }
        scripts = scripts.filter(filterOutStandaloneAndInlineScripts);
        if (scripts.length >= 2) {
            WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, step3);
            step4();
        }
    }
    
    function step4()
    {
        var uiSourceCodes = [];
        InspectorTest.addResult("Dumping scripts:");
        for (var i = 0; i < scripts.length; ++i) {
            var script = scripts[i];
            var url = script.sourceURL.replace(/.*LayoutTests/, "LayoutTests");
            InspectorTest.addResult("script" + (i+1) + ": " + url);
            InspectorTest.addResult("Is anonymous:" + script.isAnonymousScript());
            InspectorTest.addResult("Is inline script:" + script.isInlineScript());
            uiSourceCodes.push(script.rawLocationToUILocation(0, 0).uiSourceCode);
        }

        var seenUISourceCodes = new Map();
        InspectorTest.addResult("Dumping uiSourceCodes:");
        
        var index = 0;
        dumpNextUISourceCode();
        function dumpNextUISourceCode()
        {
            if (index >= uiSourceCodes.length) {
                uiSourceCodesDumped();
                return;
            }
            var uiSourceCode = uiSourceCodes[index];
            InspectorTest.dumpUISourceCode(uiSourceCode, uiSourceCodeDumped);

            function uiSourceCodeDumped()
            {
                InspectorTest.assertTrue(!seenUISourceCodes.get(uiSourceCode), "UISourceCode matches two scripts: " + uiSourceCode.originURL());
                seenUISourceCodes.put(uiSourceCode, uiSourceCode);
                ++index;
                dumpNextUISourceCode();
            }
        }
        
        function uiSourceCodesDumped()
        {
            InspectorTest.completeDebuggerTest();
        }
    }
}
</script>
</head>
<body onload="runTest()">
<p>Tests that inline scripts and document.write scripts get different uiSourceCodes with different URLs.
<a href="https://bugs.webkit.org/show_bug.cgi?id=87119">Bug 87119</a>
</body>
</html>
