aboutsummaryrefslogblamecommitdiffstats
path: root/difftree/internal/merkletrie/iter_test.go
blob: 65116e1c31a392697d3aa5d5a9d875b9459feab8 (plain) (tree)















































































































































































                                                                             
package merkletrie

import . "gopkg.in/check.v1"

type IterSuite struct{}

var _ = Suite(&IterSuite{})

// we don't care about hashes for iterating the tree, so
// use this hash for every object
var hash = []byte{}

// leafs have no children, use this empty list.
var empty = []*node{}

// test a defined as an operation to run on an iterator and the key of
// the node expected to be returned by the operation.  Use "" as the
// expected key for when there are no more objects in the tree.
type test struct {
	operation int    // next or step
	expected  string // key of the expected node, "" for nil node
}

// test.operation
const (
	next = iota
	step
)

// goes over a list of tests, calling each operation on the iter and
// checking that the obtained result is equal to the expected result
func runTests(c *C, description string, iter *Iter, list []test) {
	var obtained Noder
	var ok bool
	var comment CommentInterface

	for i, t := range list {
		comment = Commentf("description %q, operation #%d",
			description, i+1)

		switch t.operation {
		case next:
			obtained, ok = iter.Next()
		case step:
			obtained, ok = iter.Step()
		default:
			c.Fatalf("invalid operation %d", t.operation)
		}

		if t.expected == "" {
			c.Assert(ok, Equals, false, comment)
			c.Assert(obtained, IsNil, comment)
		} else {
			c.Assert(ok, Equals, true, comment)
			c.Assert(obtained.Key(), Equals, t.expected, comment)
		}
	}
}

// a simple tree consisting on just a leaf
func (s *IterSuite) TestLeaf(c *C) {
	for description, tests := range runs0 {
		runTests(c, description, iterLeaf(), tests)
	}
}

//     root
//       |
//       a
func (s *IterSuite) TestOneChild(c *C) {
	for description, tests := range runs1 {
		runTests(c, description, iter1(), tests)
	}
}

//     root
//      / \
//     a   b
func (s *IterSuite) Test2HorizontalSorted(c *C) {
	for description, tests := range runs2Horizontal {
		runTests(c, description, iter2HorizontalSorted(), tests)
	}
}

//     root
//      / \
//     b   a
func (s *IterSuite) Test2HorizontalReverse(c *C) {
	for description, tests := range runs2Horizontal {
		runTests(c, description, iter2HorizontalReverse(), tests)
	}
}

//     root
//      |
//      a
//      |
//      b
func (s *IterSuite) Test2VerticalSorted(c *C) {
	for description, tests := range runs2VerticalSorted {
		runTests(c, description, iter2VerticalSorted(), tests)
	}
}

//     root
//      |
//      b
//      |
//      a
func (s *IterSuite) Test2VerticalReverse(c *C) {
	for description, tests := range runs2VerticalReverse {
		runTests(c, description, iter2VerticalReverse(), tests)
	}
}

//     root
//      /|\
//     c a b
func (s *IterSuite) Test3Horizontal(c *C) {
	for description, tests := range runs3Horizontal {
		runTests(c, description, iter3Horizontal(), tests)
	}
}

//     root
//      |
//      b
//      |
//      c
//      |
//      a
func (s *IterSuite) Test3Vertical(c *C) {
	for description, tests := range runs3Vertical {
		runTests(c, description, iter3Vertical(), tests)
	}
}

//     root
//      / \
//     c   a
//     |
//     b
func (s *IterSuite) Test3Mix1(c *C) {
	for description, tests := range runs3Mix1 {
		runTests(c, description, iter3Mix1(), tests)
	}
}

//     root
//      / \
//     b   a
//         |
//         c
func (s *IterSuite) Test3Mix2(c *C) {
	for description, tests := range runs3Mix2 {
		runTests(c, description, iter3Mix2(), tests)
	}
}

//      root
//      / | \
//     /  |  ----
//    f   d      h --------
//   /\         /  \      |
//  e   a      j   b      g
//  |  / \     |
//  l  n  k    icm
//     |
//     o
//     |
//     p
func (s *IterSuite) TestCrazy(c *C) {
	for description, tests := range runsCrazy {
		runTests(c, description, iterCrazy(), tests)
	}
}