gecko-dev/testing/web-platform/tests/streams/transform-streams/lipfuzz.any.js
Jason Orendorff 47519c94b2 Bug 1513570 - Part 1: Adapt stream tests to run in the shell. r=Ms2ger
We don't support byte streams, transform streams, writable streams, or piping
yet, but we will, and in the meantime our own meta files disable those tests
for us.

Differential Revision: https://phabricator.services.mozilla.com/D14314

--HG--
extra : moz-landing-system : lando
2018-12-14 18:14:56 +00:00

163 lines
3.8 KiB
JavaScript

// META: global=worker,jsshell
'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})`);
}