import { CodeBox } from "../dist/main"; /** * A utility class used to concatenate the output of the CodeBox */ class OutputJoiner { constructor(joinChar = "|") { this.out = ""; this.JOIN_CHAR = joinChar; } push(newOutput) { if (this.out != "") { this.out += this.JOIN_CHAR; } this.out += newOutput; } } test("Initialize an empty CodeBox", () => { function emptyCodeBoxError() { new CodeBox(); } expect(emptyCodeBoxError).toThrow(/No room for the fish to survive/gm); }); test("Initialize a nonempty CodeBox", () => { const cb = new CodeBox("11+n;"); expect(cb.maxBoxHeight).toBe(1); expect(cb.maxBoxWidth).toBe(5); expect(cb.stacks[0].values()).toEqual([]); }); test("Test simple output", () => { const output = new OutputJoiner(); const cb = new CodeBox("11+n;", [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("2"); }); test("Test simple output with initial stack", () => { const output = new OutputJoiner(); const cb = new CodeBox("+n;", [1,3], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("4"); }); test("Test all arithmetic operators", () => { const output = new OutputJoiner(); const cb = new CodeBox("11+n94-n22*n93,nf3%9a)n9a(n99=n;", [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("2|5|4|3|0|1|1"); }); test("Test all redirects", () => { const output = new OutputJoiner(); const cb = new CodeBox(`v33*>n; >ff*^`, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("225"); }); test("Test out of bounds movement", () => { const output = new OutputJoiner(); const cb = new CodeBox("<;n+33", [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("6"); }); test("Test all mirror", () => { const output = new OutputJoiner(); const cb = new CodeBox(`v ; \\!aa|/+ ! n n 5 _`, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("20|5|5"); }); test("Test more complex mirror test", () => { const output = new OutputJoiner(""); const cb = new CodeBox(`>11+nv /o*84< \\72-n\\ /o*84< \\47*n\\ /o*84< \\94,n\\ /o*84< \\f4%n;`, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("2 5 28 2.25 3"); }); test("Test dive and rise", () => { const output = new OutputJoiner(""); const cb = new CodeBox(`"Hello, world!"r>Ool?u!|;`, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("Hello, world!"); }); test("Test stack splitting", () => { const cb = new CodeBox(`abcdef0983[D3[DII;`); cb.run(); expect(cb.stacks[0].values()).toEqual([10,11,12]); expect(cb.stacks[1].values()).toEqual([13,14,15]); expect(cb.stacks[2].values()).toEqual([0,9,8]); }); test("Test stack splitting and collapsing", () => { const cb = new CodeBox(`abcdef0983[D3[DIID]I];`); cb.run(); expect(cb.stacks[0].values()).toEqual([10,11,12,13,14,15,0,9,8]); }); test("Test printing with stack splitting and collapsing", () => { const output = new OutputJoiner(""); const cb = new CodeBox(`"Hello "r0["World"rDv ov!?l < I o>l?!;`, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("Hello World"); }); test("Test printing of string in initial stack", () => { const output = new OutputJoiner(""); const cb = new CodeBox(` r\\ o;!?l<`, '"Howdy doody"', { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("Howdy doody"); }); test("Test printing using vertical fisherman", () => { const output = new OutputJoiner(""); const cb = new CodeBox(`"hi"\` \`roo!/< " e y b " ;oooo\``, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("hi bye"); }); test("Test time variables: seconds", () => { const output = new OutputJoiner(""); const cb = new CodeBox(`sn;`, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe((new Date()).getUTCSeconds().toString()); }); test("Test time variables: minutes", () => { const output = new OutputJoiner(""); const cb = new CodeBox(`mn;`, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe((new Date()).getUTCMinutes().toString()); }); test("Test time variables: hours", () => { const output = new OutputJoiner(""); const cb = new CodeBox(`hn;`, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe((new Date()).getUTCHours().toString()); }); test("Test single-stack register", () => { const cb = new CodeBox(`a&;`); cb.run(); expect(cb.stacks[0].values()).toEqual([]); expect(cb.stacks[0].getRegisterValue()).toBe(10); cb.parseCodeBox("a&0&;"); cb.reset(); cb.run(); expect(cb.stacks[0].values()).toEqual([0,10]); }); test("Test multi-stack register", () => { const cb = new CodeBox(`a&0[f&D&;`); cb.run(); expect(cb.stacks[0].values()).toEqual([10]); expect(cb.stacks[0].getRegisterValue()).toBe(null); expect(cb.stacks[1].values()).toEqual([]); expect(cb.stacks[1].getRegisterValue()).toBe(15); }); test("Test push value from CodeBox", () => { const output = new OutputJoiner("|"); const cb = new CodeBox(`c22g\\ /g32/ \\nnn; 2`, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("50|110|12"); }); test("Test push out-of-bounds value from CodeBox", () => { const output = new OutputJoiner("|"); const cb = new CodeBox(`5fgn;`, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("0"); }); test("Test function call and return", () => { const output = new OutputJoiner(""); const cb = new CodeBox(`<;C10 v"It works!" { const output = new OutputJoiner(""); const cb = new CodeBox(` :?\\~11>*l1\\ -1:/ ;n\\?- /`, [10], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe("3628800"); }); test("Test - quine", () => { const output = new OutputJoiner(""); const cb = new CodeBox(`"r00gol?!;40.`, [], { outputCallback: output.push.bind(output), }); cb.run(); expect(output.out).toBe('"r00gol?!;40.'); });