2026-04-15 18:43:00 +00:00
|
|
|
let
|
|
|
|
|
lib = import <nixpkgs/lib>;
|
|
|
|
|
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
|
2026-04-18 10:05:59 +00:00
|
|
|
assert rules.instructions
|
|
|
|
|
== [
|
2026-04-15 18:43:00 +00:00
|
|
|
".coding-rules/concerns/naming.md"
|
|
|
|
|
".coding-rules/languages/python.md"
|
2026-04-18 10:05:59 +00:00
|
|
|
]; {result = "pass";};
|
2026-04-15 18:43:00 +00:00
|
|
|
|
|
|
|
|
# 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
|
2026-04-18 10:05:59 +00:00
|
|
|
assert hasCorrectPrefix == true; {result = "pass";};
|
2026-04-15 18:43:00 +00:00
|
|
|
|
2026-04-20 19:16:22 +02:00
|
|
|
# Test 3: shellHook contains both the symlink command and the config generation
|
2026-04-15 18:43:00 +00:00
|
|
|
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;
|
2026-04-18 10:05:59 +00:00
|
|
|
assert hasConfigGen; {result = "pass";};
|
2026-04-21 20:24:38 +02:00
|
|
|
|
|
|
|
|
# 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";};
|
2026-04-15 18:43:00 +00:00
|
|
|
in {
|
|
|
|
|
instructions-correct = testInstructions;
|
|
|
|
|
default-rules-dir = testDefaultRulesDir;
|
|
|
|
|
shell-hook = testShellHook;
|
2026-04-21 20:24:38 +02:00
|
|
|
forpi-disabled = testForPiDisabled;
|
|
|
|
|
forpi-enabled = testForPiEnabled;
|
|
|
|
|
concat-rules-md = testConcatRulesMd;
|
|
|
|
|
rules-md-section = testRulesMdSection;
|
2026-04-15 18:43:00 +00:00
|
|
|
}
|