From 954d9e2a0c8c889180f49fabf49a791df4171be1 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 3 Dec 2019 10:30:55 -0500 Subject: [PATCH] fix(key): only count a key as an ancestor if there is a separator --- key.go | 19 +++++++++++++------ key_test.go | 20 ++++++++++++-------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/key.go b/key.go index 1c740a2..42cea30 100644 --- a/key.go +++ b/key.go @@ -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. diff --git a/key_test.go b/key_test.go index 3219063..7272af0 100644 --- a/key_test.go +++ b/key_test.go @@ -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())