aboutsummaryrefslogtreecommitdiffstats
path: root/utils/merkletrie/noder
diff options
context:
space:
mode:
Diffstat (limited to 'utils/merkletrie/noder')
-rw-r--r--utils/merkletrie/noder/noder_test.go8
-rw-r--r--utils/merkletrie/noder/path.go31
-rw-r--r--utils/merkletrie/noder/path_test.go151
3 files changed, 188 insertions, 2 deletions
diff --git a/utils/merkletrie/noder/noder_test.go b/utils/merkletrie/noder/noder_test.go
index 14bef4a..5e014fe 100644
--- a/utils/merkletrie/noder/noder_test.go
+++ b/utils/merkletrie/noder/noder_test.go
@@ -1,6 +1,12 @@
package noder
-import . "gopkg.in/check.v1"
+import (
+ "testing"
+
+ . "gopkg.in/check.v1"
+)
+
+func Test(t *testing.T) { TestingT(t) }
type NoderSuite struct{}
diff --git a/utils/merkletrie/noder/path.go b/utils/merkletrie/noder/path.go
index c992f7e..85742db 100644
--- a/utils/merkletrie/noder/path.go
+++ b/utils/merkletrie/noder/path.go
@@ -1,6 +1,9 @@
package noder
-import "bytes"
+import (
+ "bytes"
+ "strings"
+)
// Path values represent a noder and its ancestors. The root goes first
// and the actual final noder the path is refering to will be the last.
@@ -57,3 +60,29 @@ func (p Path) Children() ([]Noder, error) {
func (p Path) NumChildren() (int, error) {
return p.Last().NumChildren()
}
+
+// Compare returns -1, 0 or 1 if the path p is smaller, equal or bigger
+// than other, in "directory order"; for example:
+//
+// "a" < "b"
+// "a/b/c/d/z" < "b"
+// "a/b/a" > "a/b"
+func (p Path) Compare(other Path) int {
+ i := 0
+ for {
+ switch {
+ case len(other) == len(p) && i == len(p):
+ return 0
+ case i == len(other):
+ return 1
+ case i == len(p):
+ return -1
+ default:
+ cmp := strings.Compare(p[i].Name(), other[i].Name())
+ if cmp != 0 {
+ return cmp
+ }
+ }
+ i++
+ }
+}
diff --git a/utils/merkletrie/noder/path_test.go b/utils/merkletrie/noder/path_test.go
new file mode 100644
index 0000000..44e3c3c
--- /dev/null
+++ b/utils/merkletrie/noder/path_test.go
@@ -0,0 +1,151 @@
+package noder
+
+import . "gopkg.in/check.v1"
+
+type PathSuite struct{}
+
+var _ = Suite(&PathSuite{})
+
+func (s *PathSuite) TestShortFile(c *C) {
+ f := &noderMock{
+ name: "1",
+ isDir: false,
+ }
+ p := Path([]Noder{f})
+ c.Assert(p.String(), Equals, "1")
+}
+
+func (s *PathSuite) TestShortDir(c *C) {
+ d := &noderMock{
+ name: "1",
+ isDir: true,
+ children: NoChildren,
+ }
+ p := Path([]Noder{d})
+ c.Assert(p.String(), Equals, "1")
+}
+
+func (s *PathSuite) TestLongFile(c *C) {
+ n3 := &noderMock{
+ name: "3",
+ isDir: false,
+ }
+ n2 := &noderMock{
+ name: "2",
+ isDir: true,
+ children: []Noder{n3},
+ }
+ n1 := &noderMock{
+ name: "1",
+ isDir: true,
+ children: []Noder{n2},
+ }
+ p := Path([]Noder{n1, n2, n3})
+ c.Assert(p.String(), Equals, "1/2/3")
+}
+
+func (s *PathSuite) TestLongDir(c *C) {
+ n3 := &noderMock{
+ name: "3",
+ isDir: true,
+ children: NoChildren,
+ }
+ n2 := &noderMock{
+ name: "2",
+ isDir: true,
+ children: []Noder{n3},
+ }
+ n1 := &noderMock{
+ name: "1",
+ isDir: true,
+ children: []Noder{n2},
+ }
+ p := Path([]Noder{n1, n2, n3})
+ c.Assert(p.String(), Equals, "1/2/3")
+}
+
+func (s *PathSuite) TestCompareDepth1(c *C) {
+ p1 := Path([]Noder{&noderMock{name: "a"}})
+ p2 := Path([]Noder{&noderMock{name: "b"}})
+ c.Assert(p1.Compare(p2), Equals, -1)
+ c.Assert(p2.Compare(p1), Equals, 1)
+
+ p1 = Path([]Noder{&noderMock{name: "a"}})
+ p2 = Path([]Noder{&noderMock{name: "a"}})
+ c.Assert(p1.Compare(p2), Equals, 0)
+ c.Assert(p2.Compare(p1), Equals, 0)
+
+ p1 = Path([]Noder{&noderMock{name: "a.go"}})
+ p2 = Path([]Noder{&noderMock{name: "a"}})
+ c.Assert(p1.Compare(p2), Equals, 1)
+ c.Assert(p2.Compare(p1), Equals, -1)
+}
+
+func (s *PathSuite) TestCompareDepth2(c *C) {
+ p1 := Path([]Noder{
+ &noderMock{name: "a"},
+ &noderMock{name: "b"},
+ })
+ p2 := Path([]Noder{
+ &noderMock{name: "b"},
+ &noderMock{name: "a"},
+ })
+ c.Assert(p1.Compare(p2), Equals, -1)
+ c.Assert(p2.Compare(p1), Equals, 1)
+
+ p1 = Path([]Noder{
+ &noderMock{name: "a"},
+ &noderMock{name: "b"},
+ })
+ p2 = Path([]Noder{
+ &noderMock{name: "a"},
+ &noderMock{name: "b"},
+ })
+ c.Assert(p1.Compare(p2), Equals, 0)
+ c.Assert(p2.Compare(p1), Equals, 0)
+
+ p1 = Path([]Noder{
+ &noderMock{name: "a"},
+ &noderMock{name: "b"},
+ })
+ p2 = Path([]Noder{
+ &noderMock{name: "a"},
+ &noderMock{name: "a"},
+ })
+ c.Assert(p1.Compare(p2), Equals, 1)
+ c.Assert(p2.Compare(p1), Equals, -1)
+}
+
+func (s *PathSuite) TestCompareMixedDepths(c *C) {
+ p1 := Path([]Noder{
+ &noderMock{name: "a"},
+ &noderMock{name: "b"},
+ })
+ p2 := Path([]Noder{&noderMock{name: "b"}})
+ c.Assert(p1.Compare(p2), Equals, -1)
+ c.Assert(p2.Compare(p1), Equals, 1)
+
+ p1 = Path([]Noder{
+ &noderMock{name: "b"},
+ &noderMock{name: "b"},
+ })
+ p2 = Path([]Noder{&noderMock{name: "b"}})
+ c.Assert(p1.Compare(p2), Equals, 1)
+ c.Assert(p2.Compare(p1), Equals, -1)
+
+ p1 = Path([]Noder{&noderMock{name: "a.go"}})
+ p2 = Path([]Noder{
+ &noderMock{name: "a"},
+ &noderMock{name: "a.go"},
+ })
+ c.Assert(p1.Compare(p2), Equals, 1)
+ c.Assert(p2.Compare(p1), Equals, -1)
+
+ p1 = Path([]Noder{&noderMock{name: "b.go"}})
+ p2 = Path([]Noder{
+ &noderMock{name: "a"},
+ &noderMock{name: "a.go"},
+ })
+ c.Assert(p1.Compare(p2), Equals, 1)
+ c.Assert(p2.Compare(p1), Equals, -1)
+}