storage/test/unit/test_locale_collation.js

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /**
     8  * Bug 499990 - Locale-aware collation
     9  *
    10  * Tests our custom, locale-aware collating sequences.
    11  */
    13 // The name of the file containing the strings we'll sort during this test.
    14 // The file's data is taken from intl/locale/tests/sort/us-ascii_base.txt and
    15 // and intl/locale/tests/sort/us-ascii_sort.txt.
    16 const DATA_BASENAME = "locale_collation.txt";
    18 // The test data from DATA_BASENAME is read into this array.
    19 var gStrings;
    21 // A collation created from the application's locale.  Used by localeCompare().
    22 var gLocaleCollation;
    24 // A connection to our in-memory UTF-16-encoded database.
    25 var gUtf16Conn;
    27 ///////////////////////////////////////////////////////////////////////////////
    28 //// Helper Functions
    30 /**
    31  * Since we create a UTF-16 database we have to clean it up, in addition to
    32  * the normal cleanup of Storage tests.
    33  */
    34 function cleanupLocaleTests()
    35 {
    36   print("-- Cleaning up test_locale_collation.js suite.");
    37   gUtf16Conn.close();
    38   cleanup();
    39 }
    41 /**
    42  * Creates a test database similar to the default one created in
    43  * head_storage.js, except that this one uses UTF-16 encoding.
    44  *
    45  * @return A connection to the database.
    46  */
    47 function createUtf16Database()
    48 {
    49   print("Creating the in-memory UTF-16-encoded database.");
    50   let conn = getService().openSpecialDatabase("memory");
    51   conn.executeSimpleSQL("PRAGMA encoding = 'UTF-16'");
    53   print("Make sure the encoding was set correctly and is now UTF-16.");
    54   let stmt = conn.createStatement("PRAGMA encoding");
    55   do_check_true(stmt.executeStep());
    56   let enc = stmt.getString(0);
    57   stmt.finalize();
    59   // The value returned will actually be UTF-16le or UTF-16be.
    60   do_check_true(enc === "UTF-16le" || enc === "UTF-16be");
    62   return conn;
    63 }
    65 /**
    66  * Compares aActual to aExpected, ensuring that the numbers and orderings of
    67  * the two arrays' elements are the same.
    68  *
    69  * @param aActual
    70  *        An array of strings retrieved from the database.
    71  * @param aExpected
    72  *        An array of strings to which aActual should be equivalent.
    73  */
    74 function ensureResultsAreCorrect(aActual, aExpected)
    75 {
    76   print("Actual results:   " + aActual);
    77   print("Expected results: " + aExpected);
    79   do_check_eq(aActual.length, aExpected.length);
    80   for (let i = 0; i < aActual.length; i++)
    81     do_check_eq(aActual[i], aExpected[i]);
    82 }
    84 /**
    85  * Synchronously SELECTs all rows from the test table of the given database
    86  * using the given collation.
    87  *
    88  * @param  aCollation
    89  *         The name of one of our custom locale collations.  The rows are
    90  *         ordered by this collation.
    91  * @param  aConn
    92  *         A connection to either the UTF-8 database or the UTF-16 database.
    93  * @return The resulting strings in an array.
    94  */
    95 function getResults(aCollation, aConn)
    96 {
    97   let results = [];
    98   let stmt = aConn.createStatement("SELECT t FROM test " +
    99                                    "ORDER BY t COLLATE " + aCollation + " ASC");
   100   while (stmt.executeStep())
   101     results.push(stmt.row.t);
   102   stmt.finalize();
   103   return results;
   104 }
   106 /**
   107  * Inserts strings into our test table of the given database in the order given.
   108  *
   109  * @param aStrings
   110  *        An array of strings.
   111  * @param aConn
   112  *        A connection to either the UTF-8 database or the UTF-16 database.
   113  */
   114 function initTableWithStrings(aStrings, aConn)
   115 {
   116   print("Initializing test table.");
   118   aConn.executeSimpleSQL("DROP TABLE IF EXISTS test");
   119   aConn.createTable("test", "t TEXT");
   120   let stmt = aConn.createStatement("INSERT INTO test (t) VALUES (:t)");
   121   aStrings.forEach(function (str) {
   122     stmt.params.t = str;
   123     stmt.execute();
   124     stmt.reset();
   125   });
   126   stmt.finalize();
   127 }
   129 /**
   130  * Returns a sorting function suitable for passing to Array.prototype.sort().
   131  * The returned function uses the application's locale to compare strings.
   132  *
   133  * @param  aCollation
   134  *         The name of one of our custom locale collations.  The sorting
   135  *         strength is computed from this value.
   136  * @return A function to use as a sorting callback.
   137  */
   138 function localeCompare(aCollation)
   139 {
   140   var strength;
   142   switch (aCollation) {
   143   case "locale":
   144     strength = Ci.nsICollation.kCollationCaseInSensitive;
   145     break;
   146   case "locale_case_sensitive":
   147     strength = Ci.nsICollation.kCollationAccentInsenstive;
   148     break;
   149   case "locale_accent_sensitive":
   150     strength = Ci.nsICollation.kCollationCaseInsensitiveAscii;
   151     break;
   152   case "locale_case_accent_sensitive":
   153     strength = Ci.nsICollation.kCollationCaseSensitive;
   154     break;
   155   default:
   156     do_throw("Error in test: unknown collation '" + aCollation + "'");
   157     break;
   158   }
   159   return function (aStr1, aStr2)
   160          gLocaleCollation.compareString(strength, aStr1, aStr2);
   161 }
   163 /**
   164  * Reads in the test data from the file DATA_BASENAME and returns it as an array
   165  * of strings.
   166  *
   167  * @return The test data as an array of strings.
   168  */
   169 function readTestData()
   170 {
   171   print("Reading in test data.");
   173   let file = do_get_file(DATA_BASENAME);
   175   let istream = Cc["@mozilla.org/network/file-input-stream;1"].
   176                 createInstance(Ci.nsIFileInputStream);
   177   istream.init(file, -1, -1, 0);
   178   istream.QueryInterface(Components.interfaces.nsILineInputStream);
   180   let line = {};
   181   let lines = [];
   182   while (istream.readLine(line))
   183     lines.push(line.value); 
   184   istream.close();
   186   return lines;
   187 }
   189 /**
   190  * Gets the results from the given database using the given collation and
   191  * ensures that they match gStrings sorted by the same collation.
   192  *
   193  * @param aCollation
   194  *        The name of one of our custom locale collations.  The rows from the
   195  *        database and the expected results are ordered by this collation.
   196  * @param aConn
   197  *        A connection to either the UTF-8 database or the UTF-16 database.
   198  */
   199 function runTest(aCollation, aConn)
   200 {
   201   ensureResultsAreCorrect(getResults(aCollation, aConn),
   202                           gStrings.slice(0).sort(localeCompare(aCollation)));
   203 }
   205 /**
   206  * Gets the results from the UTF-8 database using the given collation and
   207  * ensures that they match gStrings sorted by the same collation.
   208  *
   209  * @param aCollation
   210  *        The name of one of our custom locale collations.  The rows from the
   211  *        database and the expected results are ordered by this collation.
   212  */
   213 function runUtf8Test(aCollation)
   214 {
   215   runTest(aCollation, getOpenedDatabase());
   216 }
   218 /**
   219  * Gets the results from the UTF-16 database using the given collation and
   220  * ensures that they match gStrings sorted by the same collation.
   221  *
   222  * @param aCollation
   223  *        The name of one of our custom locale collations.  The rows from the
   224  *        database and the expected results are ordered by this collation.
   225  */
   226 function runUtf16Test(aCollation)
   227 {
   228   runTest(aCollation, gUtf16Conn);
   229 }
   231 /**
   232  * Sets up the test suite.
   233  */
   234 function setup()
   235 {
   236   print("-- Setting up the test_locale_collation.js suite.");
   238   gStrings = readTestData();
   240   initTableWithStrings(gStrings, getOpenedDatabase());
   242   gUtf16Conn = createUtf16Database();
   243   initTableWithStrings(gStrings, gUtf16Conn);
   245   let localeSvc = Cc["@mozilla.org/intl/nslocaleservice;1"].
   246                   getService(Ci.nsILocaleService);
   247   let collFact = Cc["@mozilla.org/intl/collation-factory;1"].
   248                  createInstance(Ci.nsICollationFactory);
   249   gLocaleCollation = collFact.CreateCollation(localeSvc.getApplicationLocale());
   250 }
   252 ///////////////////////////////////////////////////////////////////////////////
   253 //// Test Runs
   255 let gTests = [
   256   {
   257     desc: "Case and accent sensitive UTF-8",
   258     run:   function () runUtf8Test("locale_case_accent_sensitive")
   259   },
   261   {
   262     desc: "Case sensitive, accent insensitive UTF-8",
   263     run:   function () runUtf8Test("locale_case_sensitive")
   264   },
   266   {
   267     desc: "Case insensitive, accent sensitive UTF-8",
   268     run:   function () runUtf8Test("locale_accent_sensitive")
   269   },
   271   {
   272     desc: "Case and accent insensitive UTF-8",
   273     run:   function () runUtf8Test("locale")
   274   },
   276   {
   277     desc: "Case and accent sensitive UTF-16",
   278     run:   function () runUtf16Test("locale_case_accent_sensitive")
   279   },
   281   {
   282     desc: "Case sensitive, accent insensitive UTF-16",
   283     run:   function () runUtf16Test("locale_case_sensitive")
   284   },
   286   {
   287     desc: "Case insensitive, accent sensitive UTF-16",
   288     run:   function () runUtf16Test("locale_accent_sensitive")
   289   },
   291   {
   292     desc: "Case and accent insensitive UTF-16",
   293     run:   function () runUtf16Test("locale")
   294   },
   295 ];
   297 function run_test()
   298 {
   299   setup();
   300   gTests.forEach(function (test) {
   301     print("-- Running test: " + test.desc);
   302     test.run();
   303   });
   304 }

mercurial