def test_input(self): """Tests the input operator.""" alphabet = "abcdefghijklmnopqrstuvwxyz" chars = [*alphabet] ords = [ord(char) for char in chars] + [0] * 5 for k in range(len(alphabet) + 5): sys.stdin = io.StringIO(alphabet) symb = "," * k _, code = symb2btry(symb) p, m, o = E(code) with self.subTest(k=k, symb=symb, input=alphabet): self.assertEqual(p, 0) if k and k <= len(alphabet): self.assertEqual(m, [ords[k - 1]]) elif k > len(alphabet): self.assertEqual(m, [0]) self.assertEqual(o, "") sys.stdin = io.StringIO(alphabet) symb = ",>" * k _, code = symb2btry(symb) p, m, o = E(code) with self.subTest(k=k, symb=symb, input=alphabet): self.assertEqual(p, k) self.assertEqual(m, ords[:k] + [0]) self.assertEqual(o, "")
def test_output(self): """Test the output operator.""" _, code = symb2btry("...") p, m, o = E(code) self.assertEqual(p, 0) self.assertEqual(m, [0]) self.assertEqual(o, "\u0000" * 3) strings = ["head", "shoulders", "knees and toes, knees and toes!"] for string in strings: for k in range(1, len(string) + 5): sys.stdin = io.StringIO(string) symb = ",." * k _, code = symb2btry(symb) p, m, o = E(code) with self.subTest(k=k, symb=symb, input=string): self.assertEqual(p, 0) if k > len(string): self.assertEqual(m, [0]) self.assertEqual(o, string + "\u0000" * (k - len(string))) else: self.assertEqual(m, [ord(string[k - 1])]) self.assertEqual(o, string[:k])
def test_several_ops(self): """Test translations with larger programs.""" for k in range(5, 10): for i in range(len(self.ops) - k + 1): code = "".join(self.ops[i:i + k] * 3) idx, btry = symb2btry(code) with self.subTest(code=code): self.assertEqual(btry2symb(btry), code) self.assertEqual(self.translate(idx), code)
def test_single_op(self): """Test translations with code containing a single operator.""" for op in self.ops: for i in range(1, 5): code = op * i idx, btry = symb2btry(code) golfed = golf(btry) with self.subTest(code=code): self.assertEqual(btry2symb(btry), code) self.assertEqual(self.translate(idx), code) self.assertEqual(btry2symb(golfed), code) if btry.count("\n") < len(btry): self.assertLess(len(golfed), len(btry))
def test_monte_carlo(self): """Create random symbolic programs and translate them.""" N = 100 for _ in range(N): code = "" for _ in range(random.randint(25, 35)): code += random.choice(self.ops) idx, btry = symb2btry(code) golfed = golf(btry) with self.subTest(code=code): self.assertEqual(btry2symb(btry), code) self.assertEqual(self.translate(idx), code) self.assertEqual(btry2symb(golfed), code) if btry.count("\n") < len(btry): self.assertLess(len(golfed), len(btry))
def test_plus_minus(self): """Tests the usage of plus and minus.""" for r in range(20): cases = [ ("+" * r, [r]), ("+-" * r, [0]), ("+" * r + "-" * r, [0]), ("-+" * r, [0]), ("-" * r + "+" * r, [0]), ] for symb, mem in cases: _, code = symb2btry(symb) p, m, o = E(code) with self.subTest(symb=symb): self.assertEqual(p, 0) self.assertEqual(m, mem) self.assertEqual(o, "")
def test_right_left(self): """Tests the usage of the left/right operators.""" for r in range(1, 20): cases = [ (">" * r, [0] * (r + 1), r), ("<" * r, [0] * (r + 1), 0), ("><" * r, [0, 0], 0), ("<>" * r, [0, 0], 1), (">" * r + "<" * r, [0] * (r + 1), 0), ("<" * r + ">" * r, [0] * (r + 1), r), ] for symb, mem, ptr in cases: _, code = symb2btry(symb) p, m, o = E(code) with self.subTest(symb=symb): self.assertEqual(p, ptr) self.assertEqual(m, mem) self.assertEqual(o, "")
def test_examples(self): """Test translations on the example programs available.""" mainpath = pathlib.Path(__file__).absolute().parent.parent / "btry" paths = [ p for p in mainpath.iterdir() if not p.is_dir() and p.name.endswith(".btry") ] for path in paths: with open(path, "r") as f: btry = f.read() if not btry: continue golfed = golf(btry) symb = btry2symb(btry) idx, _ = symb2btry(symb) with self.subTest(example=path.name): self.assertEqual(symb, btry2symb(golfed)) self.assertLess(len(golfed), len(btry)) self.assertEqual(self.translate(idx), symb)