js/src/tests/ecma/Date/shell.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/tests/ecma/Date/shell.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,149 @@
     1.4 +
     1.5 +var BUGNUMBER;
     1.6 +var summary;
     1.7 +
     1.8 +function runDSTOffsetCachingTestsFraction(part, parts)
     1.9 +{
    1.10 +  BUGNUMBER = 563938;
    1.11 +  summary = 'Cache DST offsets to improve SunSpider score';
    1.12 +
    1.13 +  print(BUGNUMBER + ": " + summary);
    1.14 +
    1.15 +  var MAX_UNIX_TIMET = 2145859200;
    1.16 +  var RANGE_EXPANSION_AMOUNT = 30 * 24 * 60 * 60;
    1.17 +
    1.18 +  /**
    1.19 +   * Computes the time zone offset in minutes at the given timestamp.
    1.20 +   */
    1.21 +  function tzOffsetFromUnixTimestamp(timestamp)
    1.22 +  {
    1.23 +    var d = new Date(NaN);
    1.24 +    d.setTime(timestamp); // local slot = NaN, UTC slot = timestamp
    1.25 +    return d.getTimezoneOffset(); // get UTC, calculate local => diff in minutes
    1.26 +  }
    1.27 +
    1.28 +  /**
    1.29 +   * Clear the DST offset cache, leaving it initialized to include a timestamp
    1.30 +   * completely unlike the provided one (i.e. one very, very far away in time
    1.31 +   * from it).  Thus an immediately following lookup for the provided timestamp
    1.32 +   * will cache-miss and compute a clean value.
    1.33 +   */
    1.34 +  function clearDSTOffsetCache(undesiredTimestamp)
    1.35 +  {
    1.36 +    var opposite = (undesiredTimestamp + MAX_UNIX_TIMET / 2) % MAX_UNIX_TIMET;
    1.37 +
    1.38 +    // Generic purge to known, but not necessarily desired, state
    1.39 +    tzOffsetFromUnixTimestamp(0);
    1.40 +    tzOffsetFromUnixTimestamp(MAX_UNIX_TIMET);
    1.41 +
    1.42 +    // Purge to desired state.  Cycle 2x in case opposite or undesiredTimestamp
    1.43 +    // is close to 0 or MAX_UNIX_TIMET.
    1.44 +    tzOffsetFromUnixTimestamp(opposite);
    1.45 +    tzOffsetFromUnixTimestamp(undesiredTimestamp);
    1.46 +    tzOffsetFromUnixTimestamp(opposite);
    1.47 +    tzOffsetFromUnixTimestamp(undesiredTimestamp);
    1.48 +  }
    1.49 +
    1.50 +  function computeCanonicalTZOffset(timestamp)
    1.51 +  {
    1.52 +    clearDSTOffsetCache(timestamp);
    1.53 +    return tzOffsetFromUnixTimestamp(timestamp);
    1.54 +  }
    1.55 +
    1.56 +  var TEST_TIMESTAMPS_SECONDS =
    1.57 +    [
    1.58 +     // Special-ish timestamps
    1.59 +     0,
    1.60 +     RANGE_EXPANSION_AMOUNT,
    1.61 +     MAX_UNIX_TIMET,
    1.62 +    ];
    1.63 +
    1.64 +  var ONE_DAY = 24 * 60 * 60;
    1.65 +  var EIGHTY_THREE_HOURS = 83 * 60 * 60;
    1.66 +  var NINETY_EIGHT_HOURS = 98 * 60 * 60;
    1.67 +  function nextIncrement(i)
    1.68 +  {
    1.69 +    return i === EIGHTY_THREE_HOURS ? NINETY_EIGHT_HOURS : EIGHTY_THREE_HOURS;
    1.70 +  }
    1.71 +
    1.72 +  // Now add a long sequence of non-special timestamps, from a fixed range, that
    1.73 +  // overlaps a DST change by "a bit" on each side.  67 days should be enough
    1.74 +  // displacement that we can occasionally exercise the implementation's
    1.75 +  // thirty-day expansion and the DST-offset-change logic.  Use two different
    1.76 +  // increments just to be safe and catch something a single increment might not.
    1.77 +  var DST_CHANGE_DATE = 1268553600; // March 14, 2010
    1.78 +  for (var t = DST_CHANGE_DATE - 67 * ONE_DAY,
    1.79 +           i = nextIncrement(NINETY_EIGHT_HOURS),
    1.80 +           end = DST_CHANGE_DATE + 67 * ONE_DAY;
    1.81 +       t < end;
    1.82 +       i = nextIncrement(i), t += i)
    1.83 +  {
    1.84 +    TEST_TIMESTAMPS_SECONDS.push(t);
    1.85 +  }
    1.86 +
    1.87 +  var TEST_TIMESTAMPS =
    1.88 +    TEST_TIMESTAMPS_SECONDS.map(function(v) { return v * 1000; });
    1.89 +
    1.90 +  /**************
    1.91 +   * BEGIN TEST *
    1.92 +   **************/
    1.93 +
    1.94 +  // Compute the correct time zone offsets for all timestamps to be tested.
    1.95 +  var CORRECT_TZOFFSETS = TEST_TIMESTAMPS.map(computeCanonicalTZOffset);
    1.96 +
    1.97 +  // Intentionally and knowingly invoking every single logic path in the cache
    1.98 +  // isn't easy for a human to get right (and know he's gotten it right), so
    1.99 +  // let's do it the easy way: exhaustively try all possible four-date sequences
   1.100 +  // selecting from our array of possible timestamps.
   1.101 +
   1.102 +  var sz = TEST_TIMESTAMPS.length;
   1.103 +  var start = Math.floor((part - 1) / parts * sz);
   1.104 +  var end = Math.floor(part / parts * sz);
   1.105 +
   1.106 +  print("Exhaustively testing timestamps " +
   1.107 +        "[" + start + ", " + end + ") of " + sz + "...");
   1.108 +
   1.109 +  try
   1.110 +  {
   1.111 +    for (var i = start; i < end; i++)
   1.112 +    {
   1.113 +      print("Testing timestamp " + i + "...");
   1.114 +
   1.115 +      var t1 = TEST_TIMESTAMPS[i];
   1.116 +      for (var j = 0; j < sz; j++)
   1.117 +      {
   1.118 +        var t2 = TEST_TIMESTAMPS[j];
   1.119 +        for (var k = 0; k < sz; k++)
   1.120 +        {
   1.121 +          var t3 = TEST_TIMESTAMPS[k];
   1.122 +          for (var w = 0; w < sz; w++)
   1.123 +          {
   1.124 +            var t4 = TEST_TIMESTAMPS[w];
   1.125 +
   1.126 +            clearDSTOffsetCache(t1);
   1.127 +
   1.128 +            var tzo1 = tzOffsetFromUnixTimestamp(t1);
   1.129 +            var tzo2 = tzOffsetFromUnixTimestamp(t2);
   1.130 +            var tzo3 = tzOffsetFromUnixTimestamp(t3);
   1.131 +            var tzo4 = tzOffsetFromUnixTimestamp(t4);
   1.132 +
   1.133 +            assertEq(tzo1, CORRECT_TZOFFSETS[i]);
   1.134 +            assertEq(tzo2, CORRECT_TZOFFSETS[j]);
   1.135 +            assertEq(tzo3, CORRECT_TZOFFSETS[k]);
   1.136 +            assertEq(tzo4, CORRECT_TZOFFSETS[w]);
   1.137 +          }
   1.138 +        }
   1.139 +      }
   1.140 +    }
   1.141 +  }
   1.142 +  catch (e)
   1.143 +  {
   1.144 +    assertEq(true, false,
   1.145 +             "Error when testing with timestamps " +
   1.146 +             i + ", " + j + ", " + k + ", " + w +
   1.147 +             " (" + t1 + ", " + t2 + ", " + t3 + ", " + t4 + ")!");
   1.148 +  }
   1.149 +
   1.150 +  reportCompare(true, true);
   1.151 +  print("All tests passed!");
   1.152 +}

mercurial