tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

floating-point-total-queue-size.any.js (3115B)


      1 // META: global=window,worker,shadowrealm
      2 'use strict';
      3 
      4 // Due to the limitations of floating-point precision, the calculation of desiredSize sometimes gives different answers
      5 // than adding up the items in the queue would. It is important that implementations give the same result in these edge
      6 // cases so that developers do not come to depend on non-standard behaviour. See
      7 // https://github.com/whatwg/streams/issues/582 and linked issues for further discussion.
      8 
      9 promise_test(() => {
     10  const writer = setupTestStream();
     11 
     12  const writePromises = [
     13    writer.write(2),
     14    writer.write(Number.MAX_SAFE_INTEGER)
     15  ];
     16 
     17  assert_equals(writer.desiredSize, 0 - 2 - Number.MAX_SAFE_INTEGER,
     18    'desiredSize must be calculated using double-precision floating-point arithmetic (after writing two chunks)');
     19 
     20  return Promise.all(writePromises).then(() => {
     21    assert_equals(writer.desiredSize, 0, '[[queueTotalSize]] must clamp to 0 if it becomes negative');
     22  });
     23 }, 'Floating point arithmetic must manifest near NUMBER.MAX_SAFE_INTEGER (total ends up positive)');
     24 
     25 promise_test(() => {
     26  const writer = setupTestStream();
     27 
     28  const writePromises = [
     29    writer.write(1e-16),
     30    writer.write(1)
     31  ];
     32 
     33  assert_equals(writer.desiredSize, 0 - 1e-16 - 1,
     34    'desiredSize must be calculated using double-precision floating-point arithmetic (after writing two chunks)');
     35 
     36  return Promise.all(writePromises).then(() => {
     37    assert_equals(writer.desiredSize, 0, '[[queueTotalSize]] must clamp to 0 if it becomes negative');
     38  });
     39 }, 'Floating point arithmetic must manifest near 0 (total ends up positive, but clamped)');
     40 
     41 promise_test(() => {
     42  const writer = setupTestStream();
     43 
     44  const writePromises = [
     45    writer.write(1e-16),
     46    writer.write(1),
     47    writer.write(2e-16)
     48  ];
     49 
     50  assert_equals(writer.desiredSize, 0 - 1e-16 - 1 - 2e-16,
     51    'desiredSize must be calculated using double-precision floating-point arithmetic (after writing three chunks)');
     52 
     53  return Promise.all(writePromises).then(() => {
     54    assert_equals(writer.desiredSize, 0 - 1e-16 - 1 - 2e-16 + 1e-16 + 1 + 2e-16,
     55      'desiredSize must be calculated using floating-point arithmetic (after the three chunks have finished writing)');
     56  });
     57 }, 'Floating point arithmetic must manifest near 0 (total ends up positive, and not clamped)');
     58 
     59 promise_test(() => {
     60  const writer = setupTestStream();
     61 
     62  const writePromises = [
     63    writer.write(2e-16),
     64    writer.write(1)
     65  ];
     66 
     67  assert_equals(writer.desiredSize, 0 - 2e-16 - 1,
     68    'desiredSize must be calculated using double-precision floating-point arithmetic (after writing two chunks)');
     69 
     70  return Promise.all(writePromises).then(() => {
     71    assert_equals(writer.desiredSize, 0 - 2e-16 - 1 + 2e-16 + 1,
     72      'desiredSize must be calculated using floating-point arithmetic (after the two chunks have finished writing)');
     73  });
     74 }, 'Floating point arithmetic must manifest near 0 (total ends up zero)');
     75 
     76 function setupTestStream() {
     77  const strategy = {
     78    size(x) {
     79      return x;
     80    },
     81    highWaterMark: 0
     82  };
     83 
     84  const ws = new WritableStream({}, strategy);
     85 
     86  return ws.getWriter();
     87 }