Skip to content

Commit

Permalink
fix(key): only count a key as an ancestor if there is a separator
Browse files Browse the repository at this point in the history
  • Loading branch information
Stebalien committed Feb 5, 2020
1 parent e9f6023 commit 954d9e2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 14 deletions.
19 changes: 13 additions & 6 deletions key.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,20 +212,27 @@ func (k Key) ChildString(s string) Key {
// NewKey("/Comedy").IsAncestorOf("/Comedy/MontyPython")
// true
func (k Key) IsAncestorOf(other Key) bool {
if other.string == k.string {
// equivalent to HasPrefix(other, k.string + "/")

if len(other.string) <= len(k.string) {
// We're not long enough to be a child.
return false
}
return strings.HasPrefix(other.string, k.string)

if k.string == "/" {
// We're the root and the other key is longer.
return true
}

// "other" starts with /k.string/
return other.string[len(k.string)] == '/' && other.string[:len(k.string)] == k.string
}

// IsDescendantOf returns whether this key contains another as a prefix.
// NewKey("/Comedy/MontyPython").IsDescendantOf("/Comedy")
// true
func (k Key) IsDescendantOf(other Key) bool {
if other.string == k.string {
return false
}
return strings.HasPrefix(k.string, other.string)
return other.IsAncestorOf(k)
}

// IsTopLevel returns whether this key has only one namespace.
Expand Down
20 changes: 12 additions & 8 deletions key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,23 @@ func CheckTrue(c *C, cond bool) {
func (ks *KeySuite) TestKeyAncestry(c *C) {
k1 := NewKey("/A/B/C")
k2 := NewKey("/A/B/C/D")
k3 := NewKey("/AB")
k4 := NewKey("/A")

c.Check(k1.String(), Equals, "/A/B/C")
c.Check(k2.String(), Equals, "/A/B/C/D")
CheckTrue(c, k1.IsAncestorOf(k2))
CheckTrue(c, k2.IsDescendantOf(k1))
CheckTrue(c, NewKey("/A").IsAncestorOf(k2))
CheckTrue(c, NewKey("/A").IsAncestorOf(k1))
CheckTrue(c, !NewKey("/A").IsDescendantOf(k2))
CheckTrue(c, !NewKey("/A").IsDescendantOf(k1))
CheckTrue(c, k2.IsDescendantOf(NewKey("/A")))
CheckTrue(c, k1.IsDescendantOf(NewKey("/A")))
CheckTrue(c, !k2.IsAncestorOf(NewKey("/A")))
CheckTrue(c, !k1.IsAncestorOf(NewKey("/A")))
CheckTrue(c, k4.IsAncestorOf(k2))
CheckTrue(c, k4.IsAncestorOf(k1))
CheckTrue(c, !k4.IsDescendantOf(k2))
CheckTrue(c, !k4.IsDescendantOf(k1))
CheckTrue(c, !k3.IsDescendantOf(k4))
CheckTrue(c, !k4.IsAncestorOf(k3))
CheckTrue(c, k2.IsDescendantOf(k4))
CheckTrue(c, k1.IsDescendantOf(k4))
CheckTrue(c, !k2.IsAncestorOf(k4))
CheckTrue(c, !k1.IsAncestorOf(k4))
CheckTrue(c, !k2.IsAncestorOf(k2))
CheckTrue(c, !k1.IsAncestorOf(k1))
c.Check(k1.Child(NewKey("D")).String(), Equals, k2.String())
Expand Down

0 comments on commit 954d9e2

Please sign in to comment.