summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/streams/transform-streams/lipfuzz.any.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/streams/transform-streams/lipfuzz.any.js')
-rw-r--r--testing/web-platform/tests/streams/transform-streams/lipfuzz.any.js163
1 files changed, 163 insertions, 0 deletions
diff --git a/testing/web-platform/tests/streams/transform-streams/lipfuzz.any.js b/testing/web-platform/tests/streams/transform-streams/lipfuzz.any.js
new file mode 100644
index 0000000000..f9f148aaf1
--- /dev/null
+++ b/testing/web-platform/tests/streams/transform-streams/lipfuzz.any.js
@@ -0,0 +1,163 @@
+// META: global=window,worker
+'use strict';
+
+class LipFuzzTransformer {
+ constructor(substitutions) {
+ this.substitutions = substitutions;
+ this.partialChunk = '';
+ this.lastIndex = undefined;
+ }
+
+ transform(chunk, controller) {
+ chunk = this.partialChunk + chunk;
+ this.partialChunk = '';
+ // lastIndex is the index of the first character after the last substitution.
+ this.lastIndex = 0;
+ chunk = chunk.replace(/\{\{([a-zA-Z0-9_-]+)\}\}/g, this.replaceTag.bind(this));
+ // Regular expression for an incomplete template at the end of a string.
+ const partialAtEndRegexp = /\{(\{([a-zA-Z0-9_-]+(\})?)?)?$/g;
+ // Avoid looking at any characters that have already been substituted.
+ partialAtEndRegexp.lastIndex = this.lastIndex;
+ this.lastIndex = undefined;
+ const match = partialAtEndRegexp.exec(chunk);
+ if (match) {
+ this.partialChunk = chunk.substring(match.index);
+ chunk = chunk.substring(0, match.index);
+ }
+ controller.enqueue(chunk);
+ }
+
+ flush(controller) {
+ if (this.partialChunk.length > 0) {
+ controller.enqueue(this.partialChunk);
+ }
+ }
+
+ replaceTag(match, p1, offset) {
+ let replacement = this.substitutions[p1];
+ if (replacement === undefined) {
+ replacement = '';
+ }
+ this.lastIndex = offset + replacement.length;
+ return replacement;
+ }
+}
+
+const substitutions = {
+ in1: 'out1',
+ in2: 'out2',
+ quine: '{{quine}}',
+ bogusPartial: '{{incompleteResult}'
+};
+
+const cases = [
+ {
+ input: [''],
+ output: ['']
+ },
+ {
+ input: [],
+ output: []
+ },
+ {
+ input: ['{{in1}}'],
+ output: ['out1']
+ },
+ {
+ input: ['z{{in1}}'],
+ output: ['zout1']
+ },
+ {
+ input: ['{{in1}}q'],
+ output: ['out1q']
+ },
+ {
+ input: ['{{in1}}{{in1}'],
+ output: ['out1', '{{in1}']
+ },
+ {
+ input: ['{{in1}}{{in1}', '}'],
+ output: ['out1', 'out1']
+ },
+ {
+ input: ['{{in1', '}}'],
+ output: ['', 'out1']
+ },
+ {
+ input: ['{{', 'in1}}'],
+ output: ['', 'out1']
+ },
+ {
+ input: ['{', '{in1}}'],
+ output: ['', 'out1']
+ },
+ {
+ input: ['{{', 'in1}'],
+ output: ['', '', '{{in1}']
+ },
+ {
+ input: ['{'],
+ output: ['', '{']
+ },
+ {
+ input: ['{', ''],
+ output: ['', '', '{']
+ },
+ {
+ input: ['{', '{', 'i', 'n', '1', '}', '}'],
+ output: ['', '', '', '', '', '', 'out1']
+ },
+ {
+ input: ['{{in1}}{{in2}}{{in1}}'],
+ output: ['out1out2out1']
+ },
+ {
+ input: ['{{wrong}}'],
+ output: ['']
+ },
+ {
+ input: ['{{wron', 'g}}'],
+ output: ['', '']
+ },
+ {
+ input: ['{{quine}}'],
+ output: ['{{quine}}']
+ },
+ {
+ input: ['{{bogusPartial}}'],
+ output: ['{{incompleteResult}']
+ },
+ {
+ input: ['{{bogusPartial}}}'],
+ output: ['{{incompleteResult}}']
+ }
+];
+
+for (const testCase of cases) {
+ const inputChunks = testCase.input;
+ const outputChunks = testCase.output;
+ promise_test(() => {
+ const lft = new TransformStream(new LipFuzzTransformer(substitutions));
+ const writer = lft.writable.getWriter();
+ const promises = [];
+ for (const inputChunk of inputChunks) {
+ promises.push(writer.write(inputChunk));
+ }
+ promises.push(writer.close());
+ const reader = lft.readable.getReader();
+ let readerChain = Promise.resolve();
+ for (const outputChunk of outputChunks) {
+ readerChain = readerChain.then(() => {
+ return reader.read().then(({ value, done }) => {
+ assert_false(done, `done should be false when reading ${outputChunk}`);
+ assert_equals(value, outputChunk, `value should match outputChunk`);
+ });
+ });
+ }
+ readerChain = readerChain.then(() => {
+ return reader.read().then(({ done }) => assert_true(done, `done should be true`));
+ });
+ promises.push(readerChain);
+ return Promise.all(promises);
+ }, `testing "${inputChunks}" (length ${inputChunks.length})`);
+}