diff options
Diffstat (limited to 'utils/merkletrie/noder')
-rw-r--r-- | utils/merkletrie/noder/noder_test.go | 8 | ||||
-rw-r--r-- | utils/merkletrie/noder/path.go | 31 | ||||
-rw-r--r-- | utils/merkletrie/noder/path_test.go | 151 |
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) +} |