package unit; import support.Moad0002Algorithm; import support.Moad0002Algorithm.Context; import support.Moad0002Algorithm.DefectiveAudioSystem; import support.Moad0002Algorithm.DefectiveDisplaySystem; import support.Moad0002Algorithm.FixedAudioSystem; import support.Moad0002Algorithm.FixedDisplaySystem; /** * Unit tests for MOAD-0002: An Intertangled Defect. * * Proves from first principles: * 1. Defective: AudioSystem.setLocale() mutates state seen by DisplaySystem — * cross-subsystem interference through shared global state. * 2. Defective: two independent "contexts" sharing GLOBAL cannot coexist — * the second write tramples the first silently. * 3. Fixed: two Context objects carry independent values simultaneously. * 4. Fixed: AudioSystem and DisplaySystem read from separate Context objects * without interfering with each other. * * No build tool required. Compile and run: * * cd tests * java -m jdk.compiler/com.sun.tools.javac.Main -cp . \ * support/Moad0002Algorithm.java unit/Moad0002UnitTest.java * java -cp . unit.Moad0002UnitTest */ public class Moad0002UnitTest { private static int passed = 0; private static int failed = 0; public static void main(String[] args) { System.out.println("=== Moad0002UnitTest (An Intertangled Defect) ===\n"); System.out.println("-- Correctness: subsystems read values correctly --"); testDefectiveBasicRead(); testFixedBasicRead(); System.out.println("\n-- Defect: shared global state causes cross-subsystem interference --"); testDefectiveAudioLocaleLeaksToDisplay(); testDefectiveTwoContextsTrample(); System.out.println("\n-- Fix: isolated Context objects prevent interference --"); testFixedTwoContextsCoexist(); testFixedSubsystemsDoNotInterfere(); System.out.printf("\n%d passed, %d failed%n", passed, failed); if (failed > 0) System.exit(1); } // ── Correctness ─────────────────────────────────────────────────────────── static void testDefectiveBasicRead() { Moad0002Algorithm.resetGlobal(); DefectiveAudioSystem audio = new DefectiveAudioSystem(); audio.setVolume(80); assertEqual("defective audio: volume reads back correctly", 80, audio.getVolume()); } static void testFixedBasicRead() { Context ctx = new Context(70, 200, "fr"); FixedAudioSystem audio = new FixedAudioSystem(ctx); FixedDisplaySystem display = new FixedDisplaySystem(ctx); assertEqual("fixed audio: volume", 70, audio.getVolume()); assertEqual("fixed display: brightness", 200, display.getBrightness()); assertEqual("fixed audio: locale", "fr", audio.getLocale()); assertEqual("fixed display: locale", "fr", display.getLocale()); } // ── Defect ──────────────────────────────────────────────────────────────── static void testDefectiveAudioLocaleLeaksToDisplay() { Moad0002Algorithm.resetGlobal(); DefectiveAudioSystem audio = new DefectiveAudioSystem(); DefectiveDisplaySystem display = new DefectiveDisplaySystem(); // AudioSystem configures locale — conceptually an audio concern (TTS language) audio.setLocale("ja"); // DEFECT: DisplaySystem reads the same global — sees audio's mutation // This is the intertangle: two subsystems that should be independent // are coupled through a shared mutable state object. String displayLocale = display.getLocale(); assertEqual("defective: audio locale write leaks into display", "ja", displayLocale); } static void testDefectiveTwoContextsTrample() { Moad0002Algorithm.resetGlobal(); // Two independent "sessions" each configure their own audio subsystem. DefectiveAudioSystem session1 = new DefectiveAudioSystem(); DefectiveAudioSystem session2 = new DefectiveAudioSystem(); session1.setVolume(30); // session 1 sets volume to 30 session2.setVolume(90); // session 2 sets volume to 90 — TRAMPLES session 1 // DEFECT: session 1 now sees 90, not 30 — its configuration was silently destroyed. // Two contexts cannot coexist when they share a global state object. int session1Volume = session1.getVolume(); assertEqual("defective: session2 write tramples session1 volume", 90, session1Volume); } // ── Fix ─────────────────────────────────────────────────────────────────── static void testFixedTwoContextsCoexist() { Context ctx1 = new Context(30, 150, "en"); Context ctx2 = new Context(90, 200, "ja"); FixedAudioSystem s1 = new FixedAudioSystem(ctx1); FixedAudioSystem s2 = new FixedAudioSystem(ctx2); // FIX: both values coexist — ctx1 and ctx2 are independent objects assertEqual("fixed: session1 volume preserved after session2 created", 30, s1.getVolume()); assertEqual("fixed: session2 volume independent of session1", 90, s2.getVolume()); assertEqual("fixed: session1 locale preserved", "en", s1.getLocale()); assertEqual("fixed: session2 locale independent", "ja", s2.getLocale()); } static void testFixedSubsystemsDoNotInterfere() { Context audioCtx = new Context(75, 0, "de"); Context displayCtx = new Context(0, 180, "fr"); FixedAudioSystem audio = new FixedAudioSystem(audioCtx); FixedDisplaySystem display = new FixedDisplaySystem(displayCtx); // FIX: each subsystem reads only its own context — no cross-contamination assertEqual("fixed: audio locale unaffected by display context", "de", audio.getLocale()); assertEqual("fixed: display locale unaffected by audio context", "fr", display.getLocale()); assertEqual("fixed: display brightness from own context", 180, display.getBrightness()); assertEqual("fixed: audio volume from own context", 75, audio.getVolume()); } // ── Helpers ─────────────────────────────────────────────────────────────── static void assertEqual(String label, int expected, int actual) { if (expected == actual) { System.out.printf(" PASS: %s%n", label); passed++; } else { System.out.printf(" FAIL: %s — expected %d, got %d%n", label, expected, actual); failed++; } } static void assertEqual(String label, String expected, String actual) { if (expected == null ? actual == null : expected.equals(actual)) { System.out.printf(" PASS: %s%n", label); passed++; } else { System.out.printf(" FAIL: %s — expected '%s', got '%s'%n", label, expected, actual); failed++; } } }