1// META: global=window,worker
2'use strict';
3
4const highWaterMarkConversions = new Map([
5  [-Infinity, -Infinity],
6  [-5, -5],
7  [false, 0],
8  [true, 1],
9  [NaN, NaN],
10  ['foo', NaN],
11  ['0', 0],
12  [{}, NaN],
13  [() => {}, NaN]
14]);
15
16for (const QueuingStrategy of [CountQueuingStrategy, ByteLengthQueuingStrategy]) {
17  test(() => {
18    new QueuingStrategy({ highWaterMark: 4 });
19  }, `${QueuingStrategy.name}: Can construct a with a valid high water mark`);
20
21  test(() => {
22    const highWaterMark = 1;
23    const highWaterMarkObjectGetter = {
24      get highWaterMark() { return highWaterMark; }
25    };
26    const error = new Error('wow!');
27    const highWaterMarkObjectGetterThrowing = {
28      get highWaterMark() { throw error; }
29    };
30
31    assert_throws_js(TypeError, () => new QueuingStrategy(), 'construction fails with undefined');
32    assert_throws_js(TypeError, () => new QueuingStrategy(null), 'construction fails with null');
33    assert_throws_js(TypeError, () => new QueuingStrategy(true), 'construction fails with true');
34    assert_throws_js(TypeError, () => new QueuingStrategy(5), 'construction fails with 5');
35    assert_throws_js(TypeError, () => new QueuingStrategy({}), 'construction fails with {}');
36    assert_throws_exactly(error, () => new QueuingStrategy(highWaterMarkObjectGetterThrowing),
37      'construction fails with an object with a throwing highWaterMark getter');
38
39    assert_equals((new QueuingStrategy(highWaterMarkObjectGetter)).highWaterMark, highWaterMark);
40  }, `${QueuingStrategy.name}: Constructor behaves as expected with strange arguments`);
41
42  test(() => {
43    for (const [input, output] of highWaterMarkConversions.entries()) {
44      const strategy = new QueuingStrategy({ highWaterMark: input });
45      assert_equals(strategy.highWaterMark, output, `${input} gets set correctly`);
46    }
47  }, `${QueuingStrategy.name}: highWaterMark constructor values are converted per the unrestricted double rules`);
48
49  test(() => {
50    const size1 = (new QueuingStrategy({ highWaterMark: 5 })).size;
51    const size2 = (new QueuingStrategy({ highWaterMark: 10 })).size;
52
53    assert_equals(size1, size2);
54  }, `${QueuingStrategy.name}: size is the same function across all instances`);
55
56  test(() => {
57    const size = (new QueuingStrategy({ highWaterMark: 5 })).size;
58    assert_equals(size.name, 'size');
59  }, `${QueuingStrategy.name}: size should have the right name`);
60
61  test(() => {
62    class SubClass extends QueuingStrategy {
63      size() {
64        return 2;
65      }
66
67      subClassMethod() {
68        return true;
69      }
70    }
71
72    const sc = new SubClass({ highWaterMark: 77 });
73    assert_equals(sc.constructor.name, 'SubClass', 'constructor.name should be correct');
74    assert_equals(sc.highWaterMark, 77, 'highWaterMark should come from the parent class');
75    assert_equals(sc.size(), 2, 'size() on the subclass should override the parent');
76    assert_true(sc.subClassMethod(), 'subClassMethod() should work');
77  }, `${QueuingStrategy.name}: subclassing should work correctly`);
78
79  test(() => {
80    const size = new QueuingStrategy({ highWaterMark: 5 }).size;
81    assert_false('prototype' in size);
82  }, `${QueuingStrategy.name}: size should not have a prototype property`);
83}
84
85test(() => {
86  const size = new CountQueuingStrategy({ highWaterMark: 5 }).size;
87  assert_throws_js(TypeError, () => new size());
88}, `CountQueuingStrategy: size should not be a constructor`);
89
90test(() => {
91  const size = new ByteLengthQueuingStrategy({ highWaterMark: 5 }).size;
92  assert_throws_js(TypeError, () => new size({ byteLength: 1024 }));
93}, `ByteLengthQueuingStrategy: size should not be a constructor`);
94
95test(() => {
96  const size = (new CountQueuingStrategy({ highWaterMark: 5 })).size;
97  assert_equals(size.length, 0);
98}, 'CountQueuingStrategy: size should have the right length');
99
100test(() => {
101  const size = (new ByteLengthQueuingStrategy({ highWaterMark: 5 })).size;
102  assert_equals(size.length, 1);
103}, 'ByteLengthQueuingStrategy: size should have the right length');
104
105test(() => {
106  const size = 1024;
107  const chunk = { byteLength: size };
108  const chunkGetter = {
109    get byteLength() { return size; }
110  };
111  const error = new Error('wow!');
112  const chunkGetterThrowing = {
113    get byteLength() { throw error; }
114  };
115
116  const sizeFunction = (new CountQueuingStrategy({ highWaterMark: 5 })).size;
117
118  assert_equals(sizeFunction(), 1, 'size returns 1 with undefined');
119  assert_equals(sizeFunction(null), 1, 'size returns 1 with null');
120  assert_equals(sizeFunction('potato'), 1, 'size returns 1 with non-object type');
121  assert_equals(sizeFunction({}), 1, 'size returns 1 with empty object');
122  assert_equals(sizeFunction(chunk), 1, 'size returns 1 with a chunk');
123  assert_equals(sizeFunction(chunkGetter), 1, 'size returns 1 with chunk getter');
124  assert_equals(sizeFunction(chunkGetterThrowing), 1,
125    'size returns 1 with chunk getter that throws');
126}, 'CountQueuingStrategy: size behaves as expected with strange arguments');
127
128test(() => {
129  const size = 1024;
130  const chunk = { byteLength: size };
131  const chunkGetter = {
132    get byteLength() { return size; }
133  };
134  const error = new Error('wow!');
135  const chunkGetterThrowing = {
136    get byteLength() { throw error; }
137  };
138
139  const sizeFunction = (new ByteLengthQueuingStrategy({ highWaterMark: 5 })).size;
140
141  assert_throws_js(TypeError, () => sizeFunction(), 'size fails with undefined');
142  assert_throws_js(TypeError, () => sizeFunction(null), 'size fails with null');
143  assert_equals(sizeFunction('potato'), undefined, 'size succeeds with undefined with a random non-object type');
144  assert_equals(sizeFunction({}), undefined, 'size succeeds with undefined with an object without hwm property');
145  assert_equals(sizeFunction(chunk), size, 'size succeeds with the right amount with an object with a hwm');
146  assert_equals(sizeFunction(chunkGetter), size,
147    'size succeeds with the right amount with an object with a hwm getter');
148  assert_throws_exactly(error, () => sizeFunction(chunkGetterThrowing),
149    'size fails with the error thrown by the getter');
150}, 'ByteLengthQueuingStrategy: size behaves as expected with strange arguments');
151