• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// META: global=window,worker
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
9promise_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
25promise_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
41promise_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
59promise_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
76function 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}
88