import { Cube, FACES, COLORS } from "../src/utils/Cube.js"; import assert from "assert"; console.log("Running Cube Integrity Tests..."); const cube = new Cube(); // Helper: Count colors on all faces const countColors = () => { const counts = { [COLORS.WHITE]: 0, [COLORS.YELLOW]: 0, [COLORS.ORANGE]: 0, [COLORS.RED]: 0, [COLORS.GREEN]: 0, [COLORS.BLUE]: 0, [COLORS.BLACK]: 0, // Should be ignored or internal }; cube.cubies.forEach((cubie) => { Object.values(cubie.faces).forEach((color) => { if (counts[color] !== undefined) { counts[color]++; } }); }); return counts; }; // Helper: Verify solved state counts const verifyCounts = (counts) => { // Each face has 9 stickers. 6 faces. // 9 * 6 = 54 colored stickers. // 27 cubies * 6 faces = 162 total faces. // 162 - 54 = 108 black faces (internal). assert.strictEqual(counts[COLORS.WHITE], 9, "White count should be 9"); assert.strictEqual(counts[COLORS.YELLOW], 9, "Yellow count should be 9"); assert.strictEqual(counts[COLORS.ORANGE], 9, "Orange count should be 9"); assert.strictEqual(counts[COLORS.RED], 9, "Red count should be 9"); assert.strictEqual(counts[COLORS.GREEN], 9, "Green count should be 9"); assert.strictEqual(counts[COLORS.BLUE], 9, "Blue count should be 9"); }; // Helper: Verify piece integrity // Corners: 8 corners, each has 3 colors. // Edges: 12 edges, each has 2 colors. // Centers: 6 centers, each has 1 color. // Core: 1 core, 0 colors. const verifyPieceTypes = () => { let corners = 0; let edges = 0; let centers = 0; let cores = 0; cube.cubies.forEach((cubie) => { const coloredFaces = Object.values(cubie.faces).filter( (c) => c !== COLORS.BLACK, ).length; if (coloredFaces === 3) corners++; else if (coloredFaces === 2) edges++; else if (coloredFaces === 1) centers++; else if (coloredFaces === 0) cores++; else assert.fail( `Invalid cubie with ${coloredFaces} colors at (${cubie.x},${cubie.y},${cubie.z})`, ); }); assert.strictEqual(corners, 8, "Should have 8 corners"); assert.strictEqual(edges, 12, "Should have 12 edges"); assert.strictEqual(centers, 6, "Should have 6 centers"); assert.strictEqual(cores, 1, "Should have 1 core"); }; // Helper: Verify specific relative positions of centers (they never change relative to each other) // Up (White) opposite Down (Yellow) // Front (Green) opposite Back (Blue) // Left (Orange) opposite Right (Red) const verifyCenters = () => { const centers = cube.cubies.filter( (c) => Object.values(c.faces).filter((f) => f !== COLORS.BLACK).length === 1, ); // Find center by color const findCenter = (color) => centers.find((c) => Object.values(c.faces).includes(color)); const white = findCenter(COLORS.WHITE); const yellow = findCenter(COLORS.YELLOW); const green = findCenter(COLORS.GREEN); const blue = findCenter(COLORS.BLUE); const orange = findCenter(COLORS.ORANGE); const red = findCenter(COLORS.RED); // Check opposites // Distance between opposites should be 2 (e.g. y=1 and y=-1) // And they should be on same axis // Note: After rotations, x/y/z coordinates change. // But relative vectors should hold? // Actually, centers DO rotate around the core. // But White is always opposite Yellow. // So vector(White) + vector(Yellow) == (0,0,0). const checkOpposite = (c1, c2, name) => { assert.strictEqual(c1.x + c2.x, 0, `${name} X mismatch`); assert.strictEqual(c1.y + c2.y, 0, `${name} Y mismatch`); assert.strictEqual(c1.z + c2.z, 0, `${name} Z mismatch`); }; checkOpposite(white, yellow, "White-Yellow"); checkOpposite(green, blue, "Green-Blue"); checkOpposite(orange, red, "Orange-Red"); }; // --- Test Execution --- // 1. Initial State console.log("Test 1: Initial State Integrity"); verifyCounts(countColors()); verifyPieceTypes(); verifyCenters(); console.log("PASS Initial State"); // 2. Single Rotation (R) console.log("Test 2: Single Rotation (R)"); cube.rotateLayer("x", 1, -1); // R verifyCounts(countColors()); verifyPieceTypes(); verifyCenters(); console.log("PASS Single Rotation"); // 3. Multiple Rotations (R U R' U') console.log("Test 3: Sexy Move (R U R' U')"); cube.reset(); cube.move("R"); cube.move("U"); cube.move("R'"); cube.move("U'"); verifyCounts(countColors()); verifyPieceTypes(); verifyCenters(); console.log("PASS Sexy Move"); // 4. Random Rotations (Fuzzing) console.log("Test 4: 100 Random Moves"); cube.reset(); const axes = ["x", "y", "z"]; const indices = [-1, 0, 1]; const dirs = [1, -1]; for (let i = 0; i < 100; i++) { const axis = axes[Math.floor(Math.random() * axes.length)]; const index = indices[Math.floor(Math.random() * indices.length)]; const dir = dirs[Math.floor(Math.random() * dirs.length)]; cube.rotateLayer(axis, index, dir); } verifyCounts(countColors()); verifyPieceTypes(); verifyCenters(); console.log("PASS 100 Random Moves"); console.log("ALL INTEGRITY TESTS PASSED");