-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP: test(mesh-io): browser readPointSet test
- Loading branch information
Showing
9 changed files
with
2,064 additions
and
937 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
packages/mesh-io/typescript/cypress/e2e/read-point-set.cy.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import { demoServer, verifyPointSet } from "./common.ts"; | ||
|
||
describe("read-point-set", () => { | ||
beforeEach(function () { | ||
cy.visit(demoServer); | ||
|
||
const testPathPrefix = "../test/data/input/"; | ||
|
||
const testImageFiles = ["box-points.obj"]; | ||
testImageFiles.forEach((fileName) => { | ||
cy.readFile(`${testPathPrefix}${fileName}`, null).as(fileName); | ||
}); | ||
}); | ||
|
||
it("Reads an point set File in the demo", function () { | ||
cy.get('sl-tab[panel="readPointSet-panel"]').click(); | ||
|
||
const testFile = { | ||
contents: new Uint8Array(this["box-points.obj"]), | ||
fileName: "box-points.obj", | ||
}; | ||
cy.get( | ||
'#readPointSetInputs input[name="serialized-point-set-file"]', | ||
).selectFile([testFile], { force: true }); | ||
cy.get("#readPointSet-serialized-point-set-details").should( | ||
"contain", | ||
"35,32", | ||
); | ||
|
||
cy.get('#readPointSetInputs sl-button[name="run"]').click(); | ||
|
||
cy.get("#readPointSet-point-set-details").should("contain", "pointSetType"); | ||
}); | ||
|
||
it("Reads an pointSet BinaryFile", function () { | ||
cy.window().then(async (win) => { | ||
const arrayBuffer = new Uint8Array(this["box-points.obj"]).buffer; | ||
const { pointSet, webWorker } = await win.meshIo.readPointSet({ | ||
data: new Uint8Array(arrayBuffer), | ||
path: "box-points.obj", | ||
}); | ||
webWorker.terminate(); | ||
verifyPointSet(pointSet); | ||
}); | ||
}); | ||
|
||
it("Reads an pointSet File", function () { | ||
cy.window().then(async (win) => { | ||
const arrayBuffer = new Uint8Array(this["box-points.obj"]).buffer; | ||
const cowFile = new win.File([arrayBuffer], "box-points.obj"); | ||
const { pointSet, webWorker } = await win.meshIo.readPointSet(cowFile); | ||
webWorker.terminate(); | ||
verifyPointSet(pointSet); | ||
}); | ||
}); | ||
|
||
it("Reads re-uses a WebWorker", function () { | ||
cy.window().then(async (win) => { | ||
const arrayBuffer = new Uint8Array(this["box-points.obj"]).buffer; | ||
const cowFile = new win.File([arrayBuffer], "box-points.obj"); | ||
const { webWorker } = await win.meshIo.readPointSet(cowFile); | ||
const { pointSet } = await win.meshIo.readPointSet(cowFile, { | ||
webWorker, | ||
}); | ||
webWorker.terminate(); | ||
verifyPointSet(pointSet); | ||
}); | ||
}); | ||
|
||
it( | ||
"Throws a catchable error for an invalid file", | ||
{ defaultCommandTimeout: 120000 }, | ||
function () { | ||
cy.window().then(async (win) => { | ||
const invalidArray = new Uint8Array([21, 4, 4, 4, 4, 9, 5, 0, 82, 42]); | ||
const invalidBlob = new win.Blob([invalidArray]); | ||
const invalidFile = new win.File([invalidBlob], "invalid.file"); | ||
try { | ||
const { webWorker, pointSet } = | ||
await win.meshIo.readPointSet(invalidFile); | ||
webWorker.terminate(); | ||
} catch (error) { | ||
cy.expect(error.message).to.equal( | ||
"Could not find IO for: invalid.file", | ||
); | ||
} | ||
}); | ||
}, | ||
); | ||
}); |
2,403 changes: 1,467 additions & 936 deletions
2,403
packages/mesh-io/typescript/test/browser/demo-app/index.html
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
packages/mesh-io/typescript/test/browser/demo-app/read-mesh-load-sample-inputs.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
206 changes: 206 additions & 0 deletions
206
packages/mesh-io/typescript/test/browser/demo-app/read-point-set-controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
import * as meshIo from "../../../dist/index.js"; | ||
import readPointSetLoadSampleInputs, { | ||
usePreRun, | ||
} from "./read-point-set-load-sample-inputs.js"; | ||
|
||
class ReadPointSetModel { | ||
inputs: Map<string, any>; | ||
options: Map<string, any>; | ||
outputs: Map<string, any>; | ||
|
||
constructor() { | ||
this.inputs = new Map(); | ||
this.options = new Map(); | ||
this.outputs = new Map(); | ||
} | ||
} | ||
|
||
class ReadPointSetController { | ||
constructor(loadSampleInputs) { | ||
this.loadSampleInputs = loadSampleInputs; | ||
|
||
this.model = new ReadPointSetModel(); | ||
const model = this.model; | ||
|
||
this.webWorker = null; | ||
|
||
if (loadSampleInputs) { | ||
const loadSampleInputsButton = document.querySelector( | ||
"#readPointSetInputs [name=loadSampleInputs]", | ||
); | ||
loadSampleInputsButton.setAttribute("style", "display: block-inline;"); | ||
loadSampleInputsButton.addEventListener("click", async (event) => { | ||
loadSampleInputsButton.loading = true; | ||
await loadSampleInputs(model); | ||
loadSampleInputsButton.loading = false; | ||
}); | ||
} | ||
|
||
// ---------------------------------------------- | ||
// Inputs | ||
const serializedPointSetElement = document.querySelector( | ||
"#readPointSetInputs input[name=serialized-point-set-file]", | ||
); | ||
serializedPointSetElement.addEventListener("change", async (event) => { | ||
const dataTransfer = event.dataTransfer; | ||
const files = event.target.files || dataTransfer.files; | ||
|
||
const arrayBuffer = await files[0].arrayBuffer(); | ||
model.inputs.set("serializedPointSet", { | ||
data: new Uint8Array(arrayBuffer), | ||
path: files[0].name, | ||
}); | ||
const details = document.getElementById( | ||
"readPointSet-serialized-pointSet-details", | ||
); | ||
details.innerHTML = `<pre>${globalThis.escapeHtml(model.inputs.get("serializedPointSet").data.subarray(0, 50).toString() + " ...")}</pre>`; | ||
details.disabled = false; | ||
}); | ||
|
||
// ---------------------------------------------- | ||
// Options | ||
const informationOnlyElement = document.querySelector( | ||
"#readPointSetInputs sl-checkbox[name=information-only]", | ||
); | ||
informationOnlyElement.addEventListener("sl-change", (event) => { | ||
model.options.set("informationOnly", informationOnlyElement.checked); | ||
}); | ||
|
||
// ---------------------------------------------- | ||
// Outputs | ||
const pointSetOutputDownload = document.querySelector( | ||
"#readPointSetOutputs sl-button[name=point-set-download]", | ||
); | ||
pointSetOutputDownload.addEventListener("click", async (event) => { | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
if (model.outputs.has("pointSet")) { | ||
const pointSetDownloadFormat = document.getElementById( | ||
"point-set-output-format", | ||
); | ||
const downloadFormat = pointSetDownloadFormat.value || "nrrd"; | ||
const fileName = `pointSet.${downloadFormat}`; | ||
const { webWorker, serializedPointSet } = await meshIo.writePointSet( | ||
model.outputs.get("pointSet"), | ||
fileName, | ||
); | ||
|
||
webWorker.terminate(); | ||
globalThis.downloadFile(serializedPointSet, fileName); | ||
} | ||
}); | ||
|
||
const preRun = async () => { | ||
if (!this.webWorker && loadSampleInputs && usePreRun) { | ||
await loadSampleInputs(model, true); | ||
await this.run(); | ||
} | ||
}; | ||
|
||
const onSelectTab = async (event) => { | ||
if (event.detail.name === "readPointSet-panel") { | ||
const params = new URLSearchParams(window.location.search); | ||
if ( | ||
!params.has("functionName") || | ||
params.get("functionName") !== "readPointSet" | ||
) { | ||
params.set("functionName", "readPointSet"); | ||
const url = new URL(document.location); | ||
url.search = params; | ||
window.history.replaceState( | ||
{ functionName: "readPointSet" }, | ||
"", | ||
url, | ||
); | ||
await preRun(); | ||
} | ||
} | ||
}; | ||
|
||
const tabGroup = document.querySelector("sl-tab-group"); | ||
tabGroup.addEventListener("sl-tab-show", onSelectTab); | ||
function onInit() { | ||
const params = new URLSearchParams(window.location.search); | ||
if ( | ||
params.has("functionName") && | ||
params.get("functionName") === "readPointSet" | ||
) { | ||
tabGroup.show("readPointSet-panel"); | ||
preRun(); | ||
} | ||
} | ||
onInit(); | ||
|
||
const runButton = document.querySelector( | ||
'#readPointSetInputs sl-button[name="run"]', | ||
); | ||
runButton.addEventListener("click", async (event) => { | ||
event.preventDefault(); | ||
|
||
if (!model.inputs.has("serializedPointSet")) { | ||
globalThis.notify( | ||
"Required input not provided", | ||
"serializedPointSet", | ||
"danger", | ||
"exclamation-octagon", | ||
); | ||
return; | ||
} | ||
|
||
try { | ||
runButton.loading = true; | ||
|
||
const t0 = performance.now(); | ||
const { couldRead, pointSet } = await this.run(); | ||
const t1 = performance.now(); | ||
globalThis.notify( | ||
"readPointSet successfully completed", | ||
`in ${t1 - t0} milliseconds.`, | ||
"success", | ||
"rocket-fill", | ||
); | ||
|
||
model.outputs.set("pointSet", pointSet); | ||
pointSetOutputDownload.variant = "success"; | ||
pointSetOutputDownload.disabled = false; | ||
const pointSetDetails = document.getElementById( | ||
"readPointSet-point-set-details", | ||
); | ||
pointSetDetails.innerHTML = `<pre>${globalThis.escapeHtml(JSON.stringify(pointSet, globalThis.interfaceTypeJsonReplacer, 2))}</pre>`; | ||
pointSetDetails.disabled = false; | ||
const pointSetOutput = document.getElementById( | ||
"readPointSet-point-set-details", | ||
); | ||
} catch (error) { | ||
globalThis.notify( | ||
"Error while running pipeline", | ||
error.toString(), | ||
"danger", | ||
"exclamation-octagon", | ||
); | ||
throw error; | ||
} finally { | ||
runButton.loading = false; | ||
} | ||
}); | ||
} | ||
|
||
async run() { | ||
const options = Object.fromEntries(this.model.options.entries()); | ||
options.webWorker = this.webWorker; | ||
const { webWorker, pointSet } = await meshIo.readPointSet( | ||
{ | ||
data: this.model.inputs.get("serializedPointSet").data.slice(), | ||
path: this.model.inputs.get("serializedPointSet").path, | ||
}, | ||
options, | ||
); | ||
this.webWorker = webWorker; | ||
|
||
return { pointSet }; | ||
} | ||
} | ||
|
||
const readPointSetController = new ReadPointSetController( | ||
readPointSetLoadSampleInputs, | ||
); |
20 changes: 20 additions & 0 deletions
20
packages/mesh-io/typescript/test/browser/demo-app/read-point-set-load-sample-inputs.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
export default async function readPointSetLoadSampleInputs (model, preRun=false) { | ||
const inputButton = document.querySelector('#readPointSetInputs sl-button[name=serialized-point-set-file-button]') | ||
if (!preRun) { | ||
inputButton.loading = true | ||
} | ||
const fileName = 'box-points.obj' | ||
const inputResponse = await fetch(`https://bafybeigniwg5zquxmw5izw22absoqvxwrrezr6wv3hc3gbrvgs6ywv4mdq.ipfs.w3s.link/ipfs/bafybeigniwg5zquxmw5izw22absoqvxwrrezr6wv3hc3gbrvgs6ywv4mdq/input/${fileName}`) | ||
const inputData = new Uint8Array(await inputResponse.arrayBuffer()) | ||
model.inputs.set('serializedPointSet', { data: inputData, path: fileName }) | ||
if (!preRun) { | ||
const inputElement = document.getElementById('readPointSet-serialized-point-set-details') | ||
inputElement.innerHTML = `<pre>${globalThis.escapeHtml(inputData.subarray(0, 50).toString())}</pre>` | ||
inputElement.disabled = false | ||
inputButton.loading = false | ||
} | ||
|
||
return model | ||
} | ||
|
||
export const usePreRun = true |
Oops, something went wrong.