UNPKG

qrloop

Version:

Envelop big blob of data into frames that can be displayed in series of QR Codes

136 lines (128 loc) 4.03 kB
import { dataToFrames, makeFountainFrame, makeDataFrame, wrapData, parseFramesReducer, areFramesComplete, currentNumberOfFrames, framesToData, } from ".."; import { cutAndPad } from "../Buffer"; test("there is at least one fountain frame and it's recovering one frame", () => { [1000, 5000, 99999].forEach((size) => { const data = Buffer.from( Array(size) .fill(null) .map((_, i) => i % 256) ); const framesExport = dataToFrames(data, 200, 4); let acc = null; for (let i = 0; i < framesExport.length; i++) { acc = parseFramesReducer(acc, framesExport[i]); } if (!acc) throw new Error("falsy acc"); expect(acc.fountainsQueue.length).toBe(0); expect(acc.exploredFountains.length).toBeGreaterThan(0); }); }); test("wrapData", () => { const data = Buffer.from( Array(2000) .fill(null) .map((_, i) => i % 256) ); const wrappedData = wrapData(data); const buffers = cutAndPad(wrappedData, 200); const frames = buffers.map((data, frameIndex) => makeDataFrame({ data, nonce: 0, frameIndex, totalFrames: buffers.length, }) ); const r = frames.reduce(parseFramesReducer, null); expect(areFramesComplete(r)).toBe(true); expect(framesToData(r).toString("hex")).toBe(data.toString("hex")); }); test("a fountain can recover one missing frame", () => { const data = Buffer.from( Array(2000) .fill(null) .map((_, i) => i % 256) ); const wrappedData = wrapData(data); const buffers = cutAndPad(wrappedData, 200); const frames = buffers.map((data, frameIndex) => ({ frame: makeDataFrame({ data, nonce: 0, frameIndex, totalFrames: buffers.length, }), frameIndex, })); for (let i = 0; i < buffers.length - 1; i++) { const framesMissingOne = frames.slice(0, i).concat(frames.slice(i + 1)); const fountainFrame = makeFountainFrame( buffers, frames.map((o) => o.frameIndex) ); const missingOne = framesMissingOne .map((o) => o.frame) .reduce(parseFramesReducer, null); expect(areFramesComplete(missingOne)).toBe(false); expect(currentNumberOfFrames(missingOne)).toBe(buffers.length - 1); const withFountains = parseFramesReducer(missingOne, fountainFrame); expect(areFramesComplete(withFountains)).toBe(true); expect(currentNumberOfFrames(withFountains)).toBe(buffers.length); expect(framesToData(withFountains).toString("hex")).toBe( data.toString("hex") ); } }); test("2 fountains cascading", () => { const data = Buffer.from( Array(2000) .fill(null) .map((_, i) => i % 256) ); const wrappedData = wrapData(data); const buffers = cutAndPad(wrappedData, 200); const frames = buffers.map((data, frameIndex) => ({ frame: makeDataFrame({ data, nonce: 0, frameIndex, totalFrames: buffers.length, }), frameIndex, })); const framesMissingThree = frames.slice(2, frames.length - 1); const fountain1Frame = makeFountainFrame( buffers, frames.map((o) => o.frameIndex).slice(0, frames.length / 2) ); const fountainAllFrame = makeFountainFrame( buffers, frames.map((o) => o.frameIndex) ); const missingThree = framesMissingThree .map((o) => o.frame) .reduce(parseFramesReducer, null); expect(areFramesComplete(missingThree)).toBe(false); expect(currentNumberOfFrames(missingThree)).toBe(buffers.length - 3); const withFountains = [fountain1Frame, fountainAllFrame].reduce( parseFramesReducer, missingThree ); expect(areFramesComplete(withFountains)).toBe(false); expect(currentNumberOfFrames(withFountains)).toBe(buffers.length - 3); const withOneMoreFrame = parseFramesReducer(withFountains, frames[0].frame); expect(areFramesComplete(withOneMoreFrame)).toBe(true); expect(currentNumberOfFrames(withOneMoreFrame)).toBe(buffers.length); expect(framesToData(withOneMoreFrame).toString("hex")).toBe( data.toString("hex") ); });