<html>
<head>
<script src="../http/tests/inspector/inspector-test.js"></script>
<script>
function test()
{
    var paths = {
        FOO: "/home/username/projects/foo",
        BAR: "/home/username/projects/bar",
        SITE1: "/www/site1"
    };

    function addFileSystem(fileSystemMapping, path)
    {
        InspectorTest.addResult("Adding file system " + path);
        fileSystemMapping.addFileSystemMapping(path);
    }

    function removeFileSystem(fileSystemMapping, path)
    {
        InspectorTest.addResult("Removing file system " + path);
        fileSystemMapping.removeFileSystemMapping(path);
    }

    function checkAndDumpFileSystemMapping(fileSystemMapping)
    {
        var fileSystemPaths = fileSystemMapping.fileSystemPaths();
        InspectorTest.addResult("Testing file system mapping.");
        InspectorTest.addResult("    file system paths:");
        for (var i = 0; i < fileSystemPaths.length; ++i) {
            var id = fileSystemMapping.fileSystemId(fileSystemPaths[i]);
            InspectorTest.addResult("     - " + fileSystemPaths[i] + "(id = " + id + ")");
        }
        InspectorTest.addResult("    fileSystemPathForPrefix:");
        // Call fileSystemPathForPrefix twice for each path prefix to check caching.
        for (var i = 0; i < 2; ++i) {
            for (pathId in paths) {
                var pathPrefix = paths[pathId];
                var fileSystemPath = fileSystemMapping.fileSystemPathForPrefix(pathPrefix + "/");
                if (!fileSystemPath)
                    continue;
                InspectorTest.addResult("        " + pathPrefix + " => " + fileSystemPath);
            }
        }
        InspectorTest.addResult("");
    }

    // At first create file system mapping and clear it.
    var fileSystemMapping = new WebInspector.FileSystemMappingImpl();
    var fileSystemPaths = fileSystemMapping.fileSystemPaths();
    for (var i = 0; i < fileSystemPaths.length; ++i)
        fileSystemMapping.removeFileSystemMapping(fileSystemPaths[i]);
    
    // Now fill it with file systems and test.
    checkAndDumpFileSystemMapping(fileSystemMapping);
    addFileSystem(fileSystemMapping, paths.FOO)
    checkAndDumpFileSystemMapping(fileSystemMapping);
    addFileSystem(fileSystemMapping, paths.BAR)
    checkAndDumpFileSystemMapping(fileSystemMapping);
    addFileSystem(fileSystemMapping, paths.SITE1)
    checkAndDumpFileSystemMapping(fileSystemMapping);

    // Then create another file mapping to make sure it is correctly restored from the settings.
    InspectorTest.addResult("Creating another file system mapping.");
    var fileSystemMapping = new WebInspector.FileSystemMappingImpl();
    checkAndDumpFileSystemMapping(fileSystemMapping);

    // Now remove file systems and test.
    removeFileSystem(fileSystemMapping, paths.SITE1)
    checkAndDumpFileSystemMapping(fileSystemMapping);
    removeFileSystem(fileSystemMapping, paths.FOO)
    checkAndDumpFileSystemMapping(fileSystemMapping);
    removeFileSystem(fileSystemMapping, paths.BAR)
    checkAndDumpFileSystemMapping(fileSystemMapping);

    InspectorTest.completeTest();
}
</script>
</head>
<body onload="runTest()">
<p>Tests FileSystemMapping</p>
</body>
</html>
