let lib = import ; codingRulesLib = (import ../../lib {inherit lib;}).coding-rules; # Test 1: instructions are generated correctly with custom rulesDir testInstructions = let rules = codingRulesLib.mkCodingRules { agents = "/tmp/fake-agents"; languages = ["python"]; concerns = ["naming"]; rulesDir = ".coding-rules"; }; in assert rules.instructions == [ ".coding-rules/concerns/naming.md" ".coding-rules/languages/python.md" ]; {result = "pass";}; # Test 2: default rulesDir is .opencode-rules testDefaultRulesDir = let rules = codingRulesLib.mkCodingRules { agents = "/tmp/fake-agents"; }; hasCorrectPrefix = builtins.all (s: builtins.substring 0 15 s == ".opencode-rules") rules.instructions; in assert hasCorrectPrefix == true; {result = "pass";}; # Test 3: shellHook contains both the symlink command and the config generation testShellHook = let rules = codingRulesLib.mkCodingRules { agents = "/tmp/fake-agents"; }; hook = rules.shellHook; hasSymlink = builtins.match ".*ln -sfn.*" hook != null; hasConfigGen = builtins.match ".*coding-rules.json.*" hook != null; in assert hasSymlink; assert hasConfigGen; {result = "pass";}; # Test 4: forPi=false does not include AGENTS.md logic in shellHook testForPiDisabled = let rules = codingRulesLib.mkCodingRules { agents = "/tmp/fake-agents"; forPi = false; }; hook = rules.shellHook; hasPiBlock = builtins.match ".*CODING-RULES:START.*" hook != null; in assert hasPiBlock == false; {result = "pass";}; # Test 5: forPi=true adds CODING-RULES markers to shellHook (when agents path has rules) # Note: This test uses the real AGENTS repo at /home/sascha.koenig/p/AI/AGENTS # It is only run when the path exists. testForPiEnabled = let agentsPath = /home/sascha.koenig/p/AI/AGENTS; rules = codingRulesLib.mkCodingRules { agents = agentsPath; forPi = true; concerns = ["coding-style"]; languages = []; frameworks = []; }; hook = rules.shellHook; hasPiBlock = builtins.match ".*CODING-RULES:START.*" hook != null; hasCodingStyle = builtins.match ".*Coding Style.*" hook != null; in assert hasPiBlock == true; assert hasCodingStyle == true; {result = "pass";}; # Test 6: concatRulesMd produces concatenated markdown (with real agents path) testConcatRulesMd = let agentsPath = /home/sascha.koenig/p/AI/AGENTS; md = codingRulesLib.concatRulesMd { agents = agentsPath; concerns = ["coding-style"]; languages = []; frameworks = []; }; hasHeader = builtins.match ".*Coding Style.*" md != null; hasCritical = builtins.match ".*Critical Rules.*" md != null; in assert hasHeader == true; assert hasCritical == true; {result = "pass";}; # Test 7: mkRulesMdSection wraps content with markers testRulesMdSection = let agentsPath = /home/sascha.koenig/p/AI/AGENTS; section = codingRulesLib.mkRulesMdSection { agents = agentsPath; concerns = ["coding-style"]; languages = []; frameworks = []; }; hasStartMarker = builtins.match ".*CODING-RULES:START.*" section != null; hasEndMarker = builtins.match ".*CODING-RULES:END.*" section != null; hasHeader = builtins.match ".*# Coding Rules.*" section != null; in assert hasStartMarker == true; assert hasEndMarker == true; assert hasHeader == true; {result = "pass";}; in { instructions-correct = testInstructions; default-rules-dir = testDefaultRulesDir; shell-hook = testShellHook; forpi-disabled = testForPiDisabled; forpi-enabled = testForPiEnabled; concat-rules-md = testConcatRulesMd; rules-md-section = testRulesMdSection; }