{"atom":"regression/module-name-case","family":"regression","slug":"module-name-case","header":{"atom":"regression/module-name-case","kind":"whole-program — a minimal repro, not yet reduced to an atom","source":"curated"},"axes":null,"cols":null,"engines":["rakudo-2026.07","rakupp-3.14.0"],"kinds":["ref","pp"],"defFrom":"rakupp:t/regression/module-name-case.raku","counts":{"a":1,"f":0,"d":0,"c":0,"r":0,"n":0},"files":["atoms/regression/module-name-case.grid"],"records":[["0001","","# Regression: on a case-insensitive filesystem (APFS, NTFS) the module\n# resolver's plain ifstream open let `use Config` load a stray `config.raku`\n# from the search path — a demo grammar named config.raku silently SHADOWED\n# the installed ecosystem Config dist (\"No such method 'read' for invocant\n# of type 'Config'\" from showcase/modinfo was the symptom). Module names are\n# case-sensitive: both resolver loops now compare the actual directory entry\n# byte-exact (realpath does NOT case-correct on APFS; readdir does not lie).\n#\n# The contract is portable: on a case-SENSITIVE filesystem the mismatched\n# file is simply never found, so \"must not resolve\" holds everywhere — and\n# Rakudo refuses it too (its resolution is name-exact via metadata).\n#\n# Contract: exit 0 + last line PASS.\nmy @fail;\n\nsub check(Bool() $cond, $desc) {\n    @fail.push($desc) unless $cond;\n}\n\nmy $tmp = $*TMPDIR.add(\"case-test-$*PID\");\nmy $lib = $tmp.add('lib');\n$lib.mkdir;\nLEAVE { run 'rm', '-rf', $tmp.Str }\n\n$lib.add('casemod.rakumod').spurt('unit module CaseMod; sub cm() is export { \"lower\" }');\n$lib.add('CaseGood.rakumod').spurt('unit module CaseGood; sub cg() is export { \"good\" }');\n\nmy $exe = $*EXECUTABLE.absolute;\n\nmy $wrong = run $exe, '-I', $lib.Str, '-e', 'use CaseMod; say cm()', :out, :err;\n$wrong.out.slurp(:close);\n$wrong.err.slurp(:close);\ncheck $wrong.exitcode != 0,\n      'a case-mismatched module file does not satisfy a use';\n\nmy $right = run $exe, '-I', $lib.Str, '-e', 'use CaseGood; say cg()', :out, :err;\nmy $out = $right.out.slurp(:close);\n$right.err.slurp(:close);\ncheck $right.exitcode == 0 && $out eq \"good\\n\",\n      'the exactly-named module still loads';\n\nif @fail {\n    .say for @fail;\n    say \"FAIL\";\n    exit 1;\n}\nsay \"PASS\";","output PASS","a",["PASS","PASS"],0,[["budget","20s"]]]]}