What's wrong
The span-based IsChildOf in Semantics.Paths/Implementations/AbsoluteDirectoryPath.cs (~lines 218-228) checks for a prefix match. It then requires a directory separator at thisPath[parent.Length]. IsParentOf delegates to the same logic, and AbsoluteFilePath.IsChildOf has an equivalent check.
A filesystem root already ends in a separator (/, C:\). For a path directly under a root, the character at parent.Length is therefore the first letter of the child's name, not a separator, so the check fails.
Reproduction
(Linux; the same happens on Windows with C:\foo and C:\.)
var root = AbsoluteDirectoryPath.Create<AbsoluteDirectoryPath>("/");
var home = AbsoluteDirectoryPath.Create<AbsoluteDirectoryPath>("/home");
home.IsChildOf(root); // False, expected True
root.IsParentOf(home); // False, expected True
AbsoluteFilePath.Create<AbsoluteFilePath>("/etc.txt").IsChildOf(root); // False, expected True
The type contradicts itself: home.Parent returns /, and GetAncestors() yields /. Deeper paths such as /home/user under /home work correctly.
Why it matters
Containment checks are a typical guard, for example "is this file inside the chosen directory?". They give the wrong answer whenever the user picks a drive or filesystem root, which is a common choice.
Suggested fix / acceptance criteria
- After the prefix match, return
true when the parent ends in a separator (Path.EndsInDirectorySeparator(parentPathSpan)) and the child is longer. Otherwise keep the existing next-character check.
- Apply the change to both
AbsoluteDirectoryPath and AbsoluteFilePath.
- Add tests for
/home vs /, /etc.txt vs /, and (Windows-conditional) C:\foo vs C:\. Add a negative test that /home2 is not a child of /home.
Confirmed by running against main (8c06aba) on Linux.
What's wrong
The span-based
IsChildOfinSemantics.Paths/Implementations/AbsoluteDirectoryPath.cs(~lines 218-228) checks for a prefix match. It then requires a directory separator atthisPath[parent.Length].IsParentOfdelegates to the same logic, andAbsoluteFilePath.IsChildOfhas an equivalent check.A filesystem root already ends in a separator (
/,C:\). For a path directly under a root, the character atparent.Lengthis therefore the first letter of the child's name, not a separator, so the check fails.Reproduction
(Linux; the same happens on Windows with
C:\fooandC:\.)The type contradicts itself:
home.Parentreturns/, andGetAncestors()yields/. Deeper paths such as/home/userunder/homework correctly.Why it matters
Containment checks are a typical guard, for example "is this file inside the chosen directory?". They give the wrong answer whenever the user picks a drive or filesystem root, which is a common choice.
Suggested fix / acceptance criteria
truewhen the parent ends in a separator (Path.EndsInDirectorySeparator(parentPathSpan)) and the child is longer. Otherwise keep the existing next-character check.AbsoluteDirectoryPathandAbsoluteFilePath./homevs/,/etc.txtvs/, and (Windows-conditional)C:\foovsC:\. Add a negative test that/home2is not a child of/home.Confirmed by running against
main(8c06aba) on Linux.