def test_orientation_transform(orientation, turn): cube1 = Cube((3, 3, 3)) cube2 = Cube((3, 3, 3)) turn.perform(cube1, orientation) origin = Orientation() turn.from_orientation(orientation, origin).perform(cube2, origin) for side in Side: o = Orientation.regular(side) assert str(cube1.get_side(o).colors) == str(cube2.get_side(o).colors)
def test_wrong_columns(self): cube = Cube((2, 2, 2)) colors = [[Color.WHITE, Color.RED, Color.BLUE], [Color.ORANGE, Color.GREEN, Color.BLUE]] with raises(argparse.ArgumentTypeError) as e: apply_side(cube, self.orientation, colors) assert str(e.value) == "Incorrect number of columns"
def test_runtime_globals(): runtime = CubeRuntime(Cube((3, 3, 3)), Orientation(), lambda action: None, lambda: None) existing = set(runtime.functions.global_values.keys()) assert existing.issuperset(set(CubeRuntime.COLOR_NAMES.keys())) assert existing.issuperset(set(CubeRuntime.SIDE_NAMES.keys())) assert "push_orientation" in existing
def test_flip_flops(): code = """ let count: int while top[1, 1] != top[2, 2] or count == 0 do RUR'U' count = count + 1 end out(count) """ out_fn = MagicMock() stack = Stack() finish_function = MagicMock() cube_runtime = CubeRuntime(Cube((3, 3, 3)), Orientation(), lambda action: None, finish_function) cube_runtime.functions.initialize_stack(stack) stdlib.initialize_stack(stack) stack.add_global("out", Function(([Integer], Void))) globals = {"out": out_fn, **stdlib.exec_globals, **cube_runtime.functions.exec_globals} executor = ExecutionContext(globals) executor.compile(parser.parse(code, stack)) executor.execute(MockTracebackWriter()) cube_runtime.finished() out_fn.assert_called_once_with(6) finish_function.assert_called_once()
def test_apply_side(self): cube = Cube((2, 2, 2)) colors = [[Color.WHITE, Color.RED], [Color.ORANGE, Color.GREEN]] apply_side(cube, self.orientation, colors) actual_colors = [[ cube.get_side(self.orientation).colors[i, j] for j in [0, 1] ] for i in [0, 1]] assert colors == actual_colors
def test_orient_not_matching_side(): cube = Cube((3, 3, 3)) for action in parse_actions("RUR'U'"): action.perform(cube, Orientation()) match = cube.orient(Orientation(), front=Pattern([[Color.WHITE, Color.GREEN, None], [None, None, None], [None, None, None]])) assert match is None
def test_get_side(): orientation: Orientation = Orientation(Side.LEFT, Side.TOP) orientation.get_side_rotation = MagicMock() orientation.get_side_rotation.return_value = 0 cube = Cube((3, 3, 3)) side = cube.get_side(orientation) assert isinstance(side, CubeSide) assert side == cube.sides[Side.LEFT]
def test_action_callback(): callback: Callable[[Action], None] = MagicMock() runtime = CubeRuntime(Cube((3, 3, 3)), Orientation(), callback, lambda: None) runtime.perform_turn(Side.LEFT, 2, [1]) callback: MagicMock action = callback.call_args_list[0][0][0] assert isinstance(action, Turn) assert action.type == TurningType.VERTICAL
def test_orient_not_matching_groups(): cube = Cube((3, 3, 3)) for action in parse_actions("RUR'U'"): action.perform(cube, Orientation()) match = cube.orient(Orientation(), front=Pattern([["a", "a", "b"], [None, None, None], [None, None, None]]), right=Pattern([["a", None, None], [None, None, None], ["a", None, "b"]])) assert match is None
def test_orient_keep(): cube = Cube((3, 3, 3)) for action in parse_actions("RUR'U'"): action.perform(cube, Orientation()) match = cube.orient(Orientation(), keeping=Side.LEFT, bottom=Pattern([[Color.WHITE, None, None], [None, None, None], [None, None, None]])) assert Orientation(Side.FRONT, Side.TOP) == match
def test_suspend_rotations(): actions = [] runtime = CubeRuntime(Cube((2, 2, 2)), Orientation(), actions.append, lambda: None) runtime.perform_turn(Side.FRONT, 1, [1]) runtime.perform_rotate(Side.TOP, False) runtime.suspend_rotations() for _ in range(3): runtime.perform_turn(Side.FRONT, 1, [1]) runtime.perform_rotate(Side.TOP, False) runtime.resume_rotations() assert "FYFRBY'" == "".join(map(str, actions))
def test_iterate() -> None: def orient_to_str(side: Side, i: int, j: int) -> str: return f"{side.name[0].upper()}{i}:{j}" cube = Cube((3, 4, 4)) result = set(map(lambda x: orient_to_str(*x), cube.iterate_components())) assert result == { "F0:0", "F0:1", "F0:2", "F1:0", "F1:1", "F1:2", "F2:0", "F2:1", "F2:2", "F3:0", "F3:1", "F3:2", "R0:1", "R0:2", "R1:1", "R1:2", "R2:1", "R2:2", "R3:1", "R3:2", "B0:0", "B0:1", "B0:2", "B1:0", "B1:1", "B1:2", "B2:0", "B2:1", "B2:2", "B3:0", "B3:1", "B3:2", "L0:1", "L0:2", "L1:1", "L1:2", "L2:1", "L2:2", "L3:1", "L3:2", "T1:1", "T2:1", "B1:1", "B2:1" }
def test_get_color(side, orientation): class Colors: def __getitem__(self, item): pass class Side: def __init__(self): self.colors = Colors() with patch.object(Cube, 'get_side', return_value=Side()) as mock_method: runtime = CubeRuntime(Cube((3, 3, 3)), Orientation(), lambda action: None, lambda: None) runtime.get_color(side, 0, 0) mock_method.assert_called_once_with(orientation)
def test_state_stack(): actions = [] runtime = CubeRuntime(Cube((2, 2, 2)), Orientation(), actions.append, lambda: None) runtime.perform_turn(Side.FRONT, 1, [1]) runtime.perform_rotate(Side.TOP, False) runtime.push_orientation() for _ in range(3): runtime.perform_turn(Side.FRONT, 1, [1]) runtime.perform_rotate(Side.TOP, False) runtime.pop_orientation() assert "FYFYFYFYY" == "".join(map(str, actions))
def test_cube_flip_flop(): cube = Cube((3, 3, 3)) assert_cube(cube, "RRR/RRR/RRR", "GGG/GGG/GGG", "OOO/OOO/OOO", "BBB/BBB/BBB", "YYY/YYY/YYY", "WWW/WWW/WWW") for action in parse_actions("RUR'U'"): action.perform(cube, Orientation()) assert_cube(cube, "RRW/RRY/RRR", "GGY/OGG/YGG", "OGG/OOO/OOO", "OBB/BBB/BBB", "YYB/YYR/YYR", "WWG/WWW/WWW") for _ in range(5): for action in parse_actions("RUR'U'"): action.perform(cube, Orientation()) assert_cube(cube, "RRR/RRR/RRR", "GGG/GGG/GGG", "OOO/OOO/OOO", "BBB/BBB/BBB", "YYY/YYY/YYY", "WWW/WWW/WWW")
def run_test(seed, filename, dimension): scramble = subprocess.check_output( ["python", "-m", "cubelang.scrambler", "-d", str(dimension), "-s", str(seed)]) scramble = scramble.decode(stdout.encoding).strip() cube = Cube((dimension, dimension, dimension)) orientation = Orientation() for action in parse_actions(scramble): orientation = action.perform(cube, orientation) arguments = ["python", "-m", "cubelang", "-d", str(dimension), "-s", scramble, str(Path(__file__).parents[1] / "examples" / filename)] solution = subprocess.check_output(arguments).decode("utf-8") for action in parse_actions(solution): orientation = action.perform(cube, orientation) assert_solved(cube)
def sample_cube() -> Cube: cube = Cube((3, 3, 3)) orientation = Orientation() assert orientation.get_side_rotation() == 0 red = cube.get_side(orientation) _set_side_colors(red, [[Color.ORANGE, Color.RED, Color.GREEN], [Color.YELLOW, Color.RED, Color.GREEN], [Color.BLUE, Color.WHITE, Color.GREEN]]) green = cube.get_side(orientation.to_right) _set_side_colors(green, [[Color.RED, Color.ORANGE, Color.ORANGE], [Color.RED, Color.GREEN, Color.WHITE], [Color.RED, Color.GREEN, Color.WHITE]]) orange = cube.get_side(orientation.to_left.to_left) _set_side_colors(orange, [[Color.YELLOW, Color.YELLOW, Color.RED], [Color.ORANGE, Color.ORANGE, Color.WHITE], [Color.ORANGE, Color.ORANGE, Color.GREEN]]) blue = cube.get_side(orientation.to_left) _set_side_colors(blue, [[Color.YELLOW, Color.YELLOW, Color.YELLOW], [Color.BLUE, Color.BLUE, Color.RED], [Color.ORANGE, Color.WHITE, Color.WHITE]]) yellow = cube.get_side(orientation.to_top) _set_side_colors(yellow, [[Color.BLUE, Color.GREEN, Color.GREEN], [Color.BLUE, Color.YELLOW, Color.YELLOW], [Color.BLUE, Color.BLUE, Color.WHITE]]) white = cube.get_side(orientation.to_bottom) _set_side_colors(white, [[Color.RED, Color.GREEN, Color.YELLOW], [Color.RED, Color.WHITE, Color.ORANGE], [Color.WHITE, Color.BLUE, Color.BLUE]]) assert_cube(cube, "ORG/YRG/BWG", "ROO/RGW/RGW", "YYR/OOW/OOG", "YYY/BBR/OWW", "BGG/BYY/BBW", "RGY/RWO/WBB") return cube
def test_orient_full(): cube = Cube((3, 3, 3)) for action in parse_actions("RUR'U'"): action.perform(cube, Orientation()) match = cube.orient(Orientation(), top=Pattern([[Color.WHITE, None, None], [None, "a", None], ["a", None, None]]), front=Pattern([[None, None, None], [None, None, Color.ORANGE], [None, None, None]]), right=Pattern([[None, None, None], [Color.YELLOW, None, None], ["a", None, None]]), back=Pattern([[None, None, None], [None, None, None], [Color.BLUE, None, None]]), left=Pattern([[None, Color.ORANGE, None], [None, None, None], [None, Color.GREEN, None]]), bottom=Pattern([[Color.BLUE, None, Color.RED], [None, None, None], [None, None, None]])) assert Orientation(Side.RIGHT, Side.BOTTOM) == match
def test_orient(): code = """ orient top: {G--/---/---}, bottom: {--Y/---/---} then out(red) else-orient top: {-W-/---/---}, right: {---/---/-O-} then out(top[1, 1]) end """ out_fn = MagicMock() stack = Stack() cube_runtime = CubeRuntime(Cube((3, 3, 3)), Orientation(), lambda action: None, lambda: None) cube_runtime.functions.initialize_stack(stack) stdlib.initialize_stack(stack) stack.add_global("out", Function(([Color], Void))) globals = {"out": out_fn, **stdlib.exec_globals, **cube_runtime.functions.exec_globals} executor = ExecutionContext(globals) executor.compile(parser.parse(code, stack)) executor.execute(MockTracebackWriter()) cube_runtime.finished() out_fn.assert_called_once_with(orientation.Color.WHITE)
def main(): arg_parser = ArgumentParser() arg_parser.add_argument("-d", dest="dimension", help="dimensions of a cube", default=3, metavar="N", type=integer_type(2)) arg_parser.add_argument("-n", dest="turns_num", help="number of turns", type=integer_type(1), default=20) arg_parser.add_argument( "-a", dest="output_args", action="store_true", help= "display the state of the cube after the turns instead of the formula") arg_parser.add_argument( "-s", dest="seed", help="the seed for the pseudorandom number generator") args = arg_parser.parse_args() dim = args.dimension if args.seed is not None: random.seed(args.seed) actions: List[Turn] = [] prev_side = None for i in range(args.turns_num): if prev_side is None: sides = SIDES else: sides = [x for x in SIDES if x != prev_side] prev_side = random.choice(sides) first_index = random.randint(1, dim // 2) last_index = random.randint(1, first_index) if first_index == last_index: indices = [first_index] else: indices = [last_index, ..., first_index] turn = Turn(prev_side, indices, random.randint(1, 3)) actions.append(turn) if not args.output_args: for action in actions: print(str(action), end="") print() else: cube = Cube((dim, ) * 3) orientation = Orientation() for action in actions: action.perform(cube, orientation) print("--front", repr(cube.get_side(orientation).colors)) print("--right", repr(cube.get_side(orientation.to_right).colors)) print("--left", repr(cube.get_side(orientation.to_left).colors)) print("--back", repr(cube.get_side(orientation.to_right.to_right).colors)) print("--top", repr(cube.get_side(orientation.to_top).colors)) print("--bottom", repr(cube.get_side(orientation.to_bottom).colors))
def test_get_absolute_2(side, i, j, a, b, c) -> None: cube = Cube((2, 2, 2)) x, y, z = cube.get_absolute_coordinates(side, i, j) assert x == a assert y == b assert z == c
def test_wrong_lines(self): cube = Cube((2, 2, 2)) colors = [[Color.WHITE, Color.RED]] with raises(argparse.ArgumentTypeError) as e: apply_side(cube, self.orientation, colors) assert str(e.value) == "Incorrect number of lines"