summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/downloads/tests/unit/test_DownloadPaths.js
blob: 77249169d7f48f63ffb04fa7062f86df98b40b87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
/* ***** BEGIN LICENSE BLOCK *****
 *
 * Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/
 *
 * ***** END LICENSE BLOCK ***** */

/**
 * Tests for the "DownloadPaths.jsm" JavaScript module.
 */

var Cc = Components.classes;
var Ci = Components.interfaces;
var Cu = Components.utils;
var Cr = Components.results;

Cu.import("resource://gre/modules/DownloadPaths.jsm");

/**
 * Provides a temporary save directory.
 *
 * @returns nsIFile pointing to the new or existing directory.
 */
function createTemporarySaveDirectory()
{
  var saveDir = Cc["@mozilla.org/file/directory_service;1"].
                getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
  saveDir.append("testsavedir");
  if (!saveDir.exists()) {
    saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
  }
  return saveDir;
}

function testSplitBaseNameAndExtension(aLeafName, [aBase, aExt])
{
  var [base, ext] = DownloadPaths.splitBaseNameAndExtension(aLeafName);
  do_check_eq(base, aBase);
  do_check_eq(ext, aExt);

  // If we modify the base name and concatenate it with the extension again,
  // another roundtrip through the function should give a consistent result.
  // The only exception is when we introduce an extension in a file name that
  // didn't have one or that ended with one of the special cases like ".gz". If
  // we avoid using a dot and we introduce at least another special character,
  // the results are always consistent.
  [base, ext] = DownloadPaths.splitBaseNameAndExtension("(" + base + ")" + ext);
  do_check_eq(base, "(" + aBase + ")");
  do_check_eq(ext, aExt);
}

function testCreateNiceUniqueFile(aTempFile, aExpectedLeafName)
{
  var createdFile = DownloadPaths.createNiceUniqueFile(aTempFile);
  do_check_eq(createdFile.leafName, aExpectedLeafName);
}

function run_test()
{
  // Usual file names.
  testSplitBaseNameAndExtension("base",             ["base", ""]);
  testSplitBaseNameAndExtension("base.ext",         ["base", ".ext"]);
  testSplitBaseNameAndExtension("base.application", ["base", ".application"]);
  testSplitBaseNameAndExtension("base.x.Z",         ["base", ".x.Z"]);
  testSplitBaseNameAndExtension("base.ext.Z",       ["base", ".ext.Z"]);
  testSplitBaseNameAndExtension("base.ext.gz",      ["base", ".ext.gz"]);
  testSplitBaseNameAndExtension("base.ext.Bz2",     ["base", ".ext.Bz2"]);
  testSplitBaseNameAndExtension("base..ext",        ["base.", ".ext"]);
  testSplitBaseNameAndExtension("base..Z",          ["base.", ".Z"]);
  testSplitBaseNameAndExtension("base. .Z",         ["base. ", ".Z"]);
  testSplitBaseNameAndExtension("base.base.Bz2",    ["base.base", ".Bz2"]);
  testSplitBaseNameAndExtension("base  .ext",       ["base  ", ".ext"]);

  // Corner cases. A name ending with a dot technically has no extension, but
  // we consider the ending dot separately from the base name so that modifying
  // the latter never results in an extension being introduced accidentally.
  // Names beginning with a dot are hidden files on Unix-like platforms and if
  // their name doesn't contain another dot they should have no extension, but
  // on Windows the whole name is considered as an extension.
  testSplitBaseNameAndExtension("base.",            ["base", "."]);
  testSplitBaseNameAndExtension(".ext",             ["", ".ext"]);

  // Unusual file names (not recommended as input to the function).
  testSplitBaseNameAndExtension("base. ",           ["base", ". "]);
  testSplitBaseNameAndExtension("base ",            ["base ", ""]);
  testSplitBaseNameAndExtension("",                 ["", ""]);
  testSplitBaseNameAndExtension(" ",                [" ", ""]);
  testSplitBaseNameAndExtension(" . ",              [" ", ". "]);
  testSplitBaseNameAndExtension(" .. ",             [" .", ". "]);
  testSplitBaseNameAndExtension(" .ext",            [" ", ".ext"]);
  testSplitBaseNameAndExtension(" .ext. ",          [" .ext", ". "]);
  testSplitBaseNameAndExtension(" .ext.gz ",        [" .ext", ".gz "]);

  var destDir = createTemporarySaveDirectory();
  try {
    // Single extension.
    var tempFile = destDir.clone();
    tempFile.append("test.txt");
    testCreateNiceUniqueFile(tempFile, "test.txt");
    testCreateNiceUniqueFile(tempFile, "test(1).txt");
    testCreateNiceUniqueFile(tempFile, "test(2).txt");

    // Double extension.
    tempFile.leafName = "test.tar.gz";
    testCreateNiceUniqueFile(tempFile, "test.tar.gz");
    testCreateNiceUniqueFile(tempFile, "test(1).tar.gz");
    testCreateNiceUniqueFile(tempFile, "test(2).tar.gz");

    // Test automatic shortening of long file names. We don't know exactly how
    // many characters are removed, because it depends on the name of the folder
    // where the file is located.
    tempFile.leafName = new Array(256).join("T") + ".txt";
    var newFile = DownloadPaths.createNiceUniqueFile(tempFile);
    do_check_true(newFile.leafName.length < tempFile.leafName.length);
    do_check_eq(newFile.leafName.slice(-4), ".txt");

    // Creating a valid file name from an invalid one is not always possible.
    tempFile.append("file-under-long-directory.txt");
    try {
      DownloadPaths.createNiceUniqueFile(tempFile);
      do_throw("Exception expected with a long parent directory name.")
    } catch (e) {
      // An exception is expected, but we don't know which one exactly.
    }
  } finally {
    // Clean up the temporary directory.
    destDir.remove(true);
  }
}