serenity
serenity copied to clipboard
LibWeb/Tests: Support running text tests containing async
I have been trying to implement tests for the Web::Blob::stream implementation.
Due to the async nature of streams, it seems to currently be not possible to add text tests for this (or I am messing something up here!) - as the async code will finish running after the document has loaded where the documents' text is dumped.
Below is a simple example test that I was trying to write:
<script src="../include.js"></script>
<script>
async function readFromBlobStream() {
let blob = new Blob(["Hello friends!"], {
type: "text/plain"
});
const readableStream = blob.stream();
const stream = readableStream.getReader();
let result = "";
while (true) {
let { done, value } = await stream.read();
if (done)
break;
result += value;
}
return result;
}
test(async () => {
const result = await readFromBlobStream();
println(result);
});
</script>
It would be nice if we could figure out a way of adding tests for this type of thing. Hopefully the fix is as simple as changing the implementation of my above attempt of a test.
If you restructure your code a bit, this seems to work for me.
First, you have a bug in that you will end up with a list of code points, and not a string, in result. But that's not the issue.
If you queue up your promise inside your script block, without attaching it to the DOMContentLoaded
event by using test()
,
the browser will try to finish your script before firing the event. And since it's a quick and simple async function, it will succeed.
This works for me:
<script src="./include.js"></script>
<script>
let blob = new Blob(["Hello friends!"], {
type: "text/plain"
});
async function readFromBlobStream() {
const stream = blob.stream().getReader();
let result = "";
while (true) {
let { done, value } = await stream.read();
if (done)
break;
result += String.fromCodePoint(...value);
}
return result;
}
// Enqueue the promise inside the script block, and attach only
// the printing to the DOMContentLoaded event
readFromBlobStream().then(result => test(() => println(result)));
</script>
First, you have a bug in that you will end up with a list of code points, and not a string, in result. But that's not the issue.
Yeah, that was me being lazy and not tidying up :laughing: I knew I was getting a list of code points, just didn't tidy it up at the time. Thanks though!