chromium/third_party/blink/web_tests/fast/forms/file/input-file-entries.html

<!DOCTYPE html>
<html>
<body>
<input type="file" name="files" id="files">
<pre id="console"></pre>
<script src="../../../resources/js-test.js"></script>
<script>
description('Tests the webkitEntries attribute of &lt;input type="file"&gt;');

var testCases = [
  // Single file.
  ['dir1/UTF8.txt'],
  // Single directory.
  ['dir1'],
  // Multiple files.
  ['apple.gif', 'dir1/UTF8.txt', 'dir2/green.jpg'],
  // Multiple directories.
  ['dir1', 'dir2'],
  // Mixed case.
  ['dir1', 'dir1/UTF8.txt', 'test.txt', 'dir2']
];

// The expected directories/files info in the actual resources directory.
var expectedFileAttributes = {
  'dir1': { 'directory': true, 'files':[ '/dir1/UTF8.txt', '/dir1/UTF8-2.txt' ] },
  'dir2': { 'directory': true, 'files':[ '/dir2/green.jpg' ] },
  'apple.gif':       { 'directory': false, 'size': 3340 },
  'test.txt':        { 'directory': false, 'size': 5 },
  'dir1/UTF8.txt':   { 'directory': false, 'size': 5 },
  'dir1/UTF8-2.txt': { 'directory': false, 'size': 9 },
  'dir2/green.jpg':  { 'directory': false, 'size': 764 }
};

var droppedEntries, verifyingEntry, returnedMetadata, returnedEntries;

var jsTestIsAsync = true;
if (window.testRunner) {
    testRunner.waitUntilDone();
    doTest(0);
}

function doTest(index)
{
    if (index >= testCases.length) {
      finishJSTest();
      return;
    }

    debug('* Testing testCases[' + index + ']');
    var paths = testCases[index];
    var input = document.getElementById('files');
    input.onchange = function() { onInputFileChange(index); };
    if (paths.length > 1)
        input.setAttribute('multiple', 'multiple')
    else
        input.removeAttribute('multiple')
    var testPaths = paths.map(function(path) { return '../resources/' + path });
    eventSender.beginDragWithFiles(testPaths);
    var centerX = input.offsetLeft + input.offsetWidth / 2;
    var centerY = input.offsetTop + input.offsetHeight / 2;
    eventSender.mouseMoveTo(centerX, centerY);
    eventSender.mouseUp();
}

function onInputFileChange(index)
{
    droppedEntries = document.getElementById('files').webkitEntries;
    shouldBeTrue('Array.isArray(droppedEntries)');
    shouldBeTrue('Object.isFrozen(droppedEntries)');
    shouldEvaluateTo('droppedEntries.length', testCases[index].length);
    verifyEntry(index, 0);
}

function verifyEntry(testIndex, entryIndex)
{
    if (entryIndex == testCases[testIndex].length) {
        doTest(testIndex + 1);
        return;
    }

    var entry = verifyingEntry = droppedEntries[entryIndex];
    debug('Verifying entry (' + entryIndex + '/' + testCases[testIndex].length + '):' + entry.fullPath);

    var path = testCases[testIndex][entryIndex];
    var expected = expectedFileAttributes[path];
    var expectedPath = '/' + getBaseName(path);

    shouldBeEqualToString('verifyingEntry.fullPath', expectedPath);
    shouldEvaluateTo('verifyingEntry.isDirectory', expected.directory);

    var callback = function() { verifyEntry(testIndex, entryIndex + 1); };
    if (entry.isFile) {
        entry.getMetadata(verifyFile.bind(this, expected, callback), onError);
    } else {
        var reader = entry.createReader();
        reader.readEntries(verifyDirectory.bind(this, expected, callback), onError);
    }
}

function verifyFile(expected, callback, metadata)
{
    returnedMetadata = metadata;
    shouldEvaluateTo('returnedMetadata.size', expected.size);
    callback();
}

function verifyDirectory(expected, callback, entries)
{
    returnedEntries = [];
    for (var i = 0; i < entries.length; i++) {
        // Skip the entries that start with '.' (so that we do not get '.svn' etc)
        if (entries[i].name.indexOf('.') == 0)
            continue;
        returnedEntries.push(entries[i].fullPath);
    }
    returnedEntries.sort();
    shouldEvaluateTo('returnedEntries.length', expected.files.length);
    for (var i = 0; i < returnedEntries.length; i++)
        debug(returnedEntries[i]);
    callback();
}

function getBaseName(path)
{
    var components = path.split('/');
    return components[components.length - 1];
}

function onError(error)
{
    testFailed('Test finished with unexpected error: ' + error.code);
    finishJSTest();
}

</script>
</body>
</html>