github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/merkledag/traverse/traverse_test.go (about)

     1  package traverse
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"testing"
     7  
     8  	mdag "github.com/ipfs/go-ipfs/merkledag"
     9  )
    10  
    11  func TestDFSPreNoSkip(t *testing.T) {
    12  	opts := Options{Order: DFSPre}
    13  
    14  	testWalkOutputs(t, newFan(t), opts, []byte(`
    15  0 /a
    16  1 /a/aa
    17  1 /a/ab
    18  1 /a/ac
    19  1 /a/ad
    20  `))
    21  
    22  	testWalkOutputs(t, newLinkedList(t), opts, []byte(`
    23  0 /a
    24  1 /a/aa
    25  2 /a/aa/aaa
    26  3 /a/aa/aaa/aaaa
    27  4 /a/aa/aaa/aaaa/aaaaa
    28  `))
    29  
    30  	testWalkOutputs(t, newBinaryTree(t), opts, []byte(`
    31  0 /a
    32  1 /a/aa
    33  2 /a/aa/aaa
    34  2 /a/aa/aab
    35  1 /a/ab
    36  2 /a/ab/aba
    37  2 /a/ab/abb
    38  `))
    39  
    40  	testWalkOutputs(t, newBinaryDAG(t), opts, []byte(`
    41  0 /a
    42  1 /a/aa
    43  2 /a/aa/aaa
    44  3 /a/aa/aaa/aaaa
    45  4 /a/aa/aaa/aaaa/aaaaa
    46  4 /a/aa/aaa/aaaa/aaaaa
    47  3 /a/aa/aaa/aaaa
    48  4 /a/aa/aaa/aaaa/aaaaa
    49  4 /a/aa/aaa/aaaa/aaaaa
    50  2 /a/aa/aaa
    51  3 /a/aa/aaa/aaaa
    52  4 /a/aa/aaa/aaaa/aaaaa
    53  4 /a/aa/aaa/aaaa/aaaaa
    54  3 /a/aa/aaa/aaaa
    55  4 /a/aa/aaa/aaaa/aaaaa
    56  4 /a/aa/aaa/aaaa/aaaaa
    57  1 /a/aa
    58  2 /a/aa/aaa
    59  3 /a/aa/aaa/aaaa
    60  4 /a/aa/aaa/aaaa/aaaaa
    61  4 /a/aa/aaa/aaaa/aaaaa
    62  3 /a/aa/aaa/aaaa
    63  4 /a/aa/aaa/aaaa/aaaaa
    64  4 /a/aa/aaa/aaaa/aaaaa
    65  2 /a/aa/aaa
    66  3 /a/aa/aaa/aaaa
    67  4 /a/aa/aaa/aaaa/aaaaa
    68  4 /a/aa/aaa/aaaa/aaaaa
    69  3 /a/aa/aaa/aaaa
    70  4 /a/aa/aaa/aaaa/aaaaa
    71  4 /a/aa/aaa/aaaa/aaaaa
    72  `))
    73  }
    74  
    75  func TestDFSPreSkip(t *testing.T) {
    76  	opts := Options{Order: DFSPre, SkipDuplicates: true}
    77  
    78  	testWalkOutputs(t, newFan(t), opts, []byte(`
    79  0 /a
    80  1 /a/aa
    81  1 /a/ab
    82  1 /a/ac
    83  1 /a/ad
    84  `))
    85  
    86  	testWalkOutputs(t, newLinkedList(t), opts, []byte(`
    87  0 /a
    88  1 /a/aa
    89  2 /a/aa/aaa
    90  3 /a/aa/aaa/aaaa
    91  4 /a/aa/aaa/aaaa/aaaaa
    92  `))
    93  
    94  	testWalkOutputs(t, newBinaryTree(t), opts, []byte(`
    95  0 /a
    96  1 /a/aa
    97  2 /a/aa/aaa
    98  2 /a/aa/aab
    99  1 /a/ab
   100  2 /a/ab/aba
   101  2 /a/ab/abb
   102  `))
   103  
   104  	testWalkOutputs(t, newBinaryDAG(t), opts, []byte(`
   105  0 /a
   106  1 /a/aa
   107  2 /a/aa/aaa
   108  3 /a/aa/aaa/aaaa
   109  4 /a/aa/aaa/aaaa/aaaaa
   110  `))
   111  }
   112  
   113  func TestDFSPostNoSkip(t *testing.T) {
   114  	opts := Options{Order: DFSPost}
   115  
   116  	testWalkOutputs(t, newFan(t), opts, []byte(`
   117  1 /a/aa
   118  1 /a/ab
   119  1 /a/ac
   120  1 /a/ad
   121  0 /a
   122  `))
   123  
   124  	testWalkOutputs(t, newLinkedList(t), opts, []byte(`
   125  4 /a/aa/aaa/aaaa/aaaaa
   126  3 /a/aa/aaa/aaaa
   127  2 /a/aa/aaa
   128  1 /a/aa
   129  0 /a
   130  `))
   131  
   132  	testWalkOutputs(t, newBinaryTree(t), opts, []byte(`
   133  2 /a/aa/aaa
   134  2 /a/aa/aab
   135  1 /a/aa
   136  2 /a/ab/aba
   137  2 /a/ab/abb
   138  1 /a/ab
   139  0 /a
   140  `))
   141  
   142  	testWalkOutputs(t, newBinaryDAG(t), opts, []byte(`
   143  4 /a/aa/aaa/aaaa/aaaaa
   144  4 /a/aa/aaa/aaaa/aaaaa
   145  3 /a/aa/aaa/aaaa
   146  4 /a/aa/aaa/aaaa/aaaaa
   147  4 /a/aa/aaa/aaaa/aaaaa
   148  3 /a/aa/aaa/aaaa
   149  2 /a/aa/aaa
   150  4 /a/aa/aaa/aaaa/aaaaa
   151  4 /a/aa/aaa/aaaa/aaaaa
   152  3 /a/aa/aaa/aaaa
   153  4 /a/aa/aaa/aaaa/aaaaa
   154  4 /a/aa/aaa/aaaa/aaaaa
   155  3 /a/aa/aaa/aaaa
   156  2 /a/aa/aaa
   157  1 /a/aa
   158  4 /a/aa/aaa/aaaa/aaaaa
   159  4 /a/aa/aaa/aaaa/aaaaa
   160  3 /a/aa/aaa/aaaa
   161  4 /a/aa/aaa/aaaa/aaaaa
   162  4 /a/aa/aaa/aaaa/aaaaa
   163  3 /a/aa/aaa/aaaa
   164  2 /a/aa/aaa
   165  4 /a/aa/aaa/aaaa/aaaaa
   166  4 /a/aa/aaa/aaaa/aaaaa
   167  3 /a/aa/aaa/aaaa
   168  4 /a/aa/aaa/aaaa/aaaaa
   169  4 /a/aa/aaa/aaaa/aaaaa
   170  3 /a/aa/aaa/aaaa
   171  2 /a/aa/aaa
   172  1 /a/aa
   173  0 /a
   174  `))
   175  }
   176  
   177  func TestDFSPostSkip(t *testing.T) {
   178  	opts := Options{Order: DFSPost, SkipDuplicates: true}
   179  
   180  	testWalkOutputs(t, newFan(t), opts, []byte(`
   181  1 /a/aa
   182  1 /a/ab
   183  1 /a/ac
   184  1 /a/ad
   185  0 /a
   186  `))
   187  
   188  	testWalkOutputs(t, newLinkedList(t), opts, []byte(`
   189  4 /a/aa/aaa/aaaa/aaaaa
   190  3 /a/aa/aaa/aaaa
   191  2 /a/aa/aaa
   192  1 /a/aa
   193  0 /a
   194  `))
   195  
   196  	testWalkOutputs(t, newBinaryTree(t), opts, []byte(`
   197  2 /a/aa/aaa
   198  2 /a/aa/aab
   199  1 /a/aa
   200  2 /a/ab/aba
   201  2 /a/ab/abb
   202  1 /a/ab
   203  0 /a
   204  `))
   205  
   206  	testWalkOutputs(t, newBinaryDAG(t), opts, []byte(`
   207  4 /a/aa/aaa/aaaa/aaaaa
   208  3 /a/aa/aaa/aaaa
   209  2 /a/aa/aaa
   210  1 /a/aa
   211  0 /a
   212  `))
   213  }
   214  
   215  func TestBFSNoSkip(t *testing.T) {
   216  	opts := Options{Order: BFS}
   217  
   218  	testWalkOutputs(t, newFan(t), opts, []byte(`
   219  0 /a
   220  1 /a/aa
   221  1 /a/ab
   222  1 /a/ac
   223  1 /a/ad
   224  `))
   225  
   226  	testWalkOutputs(t, newLinkedList(t), opts, []byte(`
   227  0 /a
   228  1 /a/aa
   229  2 /a/aa/aaa
   230  3 /a/aa/aaa/aaaa
   231  4 /a/aa/aaa/aaaa/aaaaa
   232  `))
   233  
   234  	testWalkOutputs(t, newBinaryTree(t), opts, []byte(`
   235  0 /a
   236  1 /a/aa
   237  1 /a/ab
   238  2 /a/aa/aaa
   239  2 /a/aa/aab
   240  2 /a/ab/aba
   241  2 /a/ab/abb
   242  `))
   243  
   244  	testWalkOutputs(t, newBinaryDAG(t), opts, []byte(`
   245  0 /a
   246  1 /a/aa
   247  1 /a/aa
   248  2 /a/aa/aaa
   249  2 /a/aa/aaa
   250  2 /a/aa/aaa
   251  2 /a/aa/aaa
   252  3 /a/aa/aaa/aaaa
   253  3 /a/aa/aaa/aaaa
   254  3 /a/aa/aaa/aaaa
   255  3 /a/aa/aaa/aaaa
   256  3 /a/aa/aaa/aaaa
   257  3 /a/aa/aaa/aaaa
   258  3 /a/aa/aaa/aaaa
   259  3 /a/aa/aaa/aaaa
   260  4 /a/aa/aaa/aaaa/aaaaa
   261  4 /a/aa/aaa/aaaa/aaaaa
   262  4 /a/aa/aaa/aaaa/aaaaa
   263  4 /a/aa/aaa/aaaa/aaaaa
   264  4 /a/aa/aaa/aaaa/aaaaa
   265  4 /a/aa/aaa/aaaa/aaaaa
   266  4 /a/aa/aaa/aaaa/aaaaa
   267  4 /a/aa/aaa/aaaa/aaaaa
   268  4 /a/aa/aaa/aaaa/aaaaa
   269  4 /a/aa/aaa/aaaa/aaaaa
   270  4 /a/aa/aaa/aaaa/aaaaa
   271  4 /a/aa/aaa/aaaa/aaaaa
   272  4 /a/aa/aaa/aaaa/aaaaa
   273  4 /a/aa/aaa/aaaa/aaaaa
   274  4 /a/aa/aaa/aaaa/aaaaa
   275  4 /a/aa/aaa/aaaa/aaaaa
   276  `))
   277  }
   278  
   279  func TestBFSSkip(t *testing.T) {
   280  	opts := Options{Order: BFS, SkipDuplicates: true}
   281  
   282  	testWalkOutputs(t, newFan(t), opts, []byte(`
   283  0 /a
   284  1 /a/aa
   285  1 /a/ab
   286  1 /a/ac
   287  1 /a/ad
   288  `))
   289  
   290  	testWalkOutputs(t, newLinkedList(t), opts, []byte(`
   291  0 /a
   292  1 /a/aa
   293  2 /a/aa/aaa
   294  3 /a/aa/aaa/aaaa
   295  4 /a/aa/aaa/aaaa/aaaaa
   296  `))
   297  
   298  	testWalkOutputs(t, newBinaryTree(t), opts, []byte(`
   299  0 /a
   300  1 /a/aa
   301  1 /a/ab
   302  2 /a/aa/aaa
   303  2 /a/aa/aab
   304  2 /a/ab/aba
   305  2 /a/ab/abb
   306  `))
   307  
   308  	testWalkOutputs(t, newBinaryDAG(t), opts, []byte(`
   309  0 /a
   310  1 /a/aa
   311  2 /a/aa/aaa
   312  3 /a/aa/aaa/aaaa
   313  4 /a/aa/aaa/aaaa/aaaaa
   314  `))
   315  }
   316  
   317  func testWalkOutputs(t *testing.T, root *mdag.Node, opts Options, expect []byte) {
   318  	expect = bytes.TrimLeft(expect, "\n")
   319  
   320  	buf := new(bytes.Buffer)
   321  	walk := func(current State) error {
   322  		s := fmt.Sprintf("%d %s\n", current.Depth, current.Node.Data)
   323  		t.Logf("walk: %s", s)
   324  		buf.Write([]byte(s))
   325  		return nil
   326  	}
   327  
   328  	opts.Func = walk
   329  	if err := Traverse(root, opts); err != nil {
   330  		t.Error(err)
   331  		return
   332  	}
   333  
   334  	actual := buf.Bytes()
   335  	if !bytes.Equal(actual, expect) {
   336  		t.Error("error: outputs differ")
   337  		t.Logf("expect:\n%s", expect)
   338  		t.Logf("actual:\n%s", actual)
   339  	} else {
   340  		t.Logf("expect matches actual:\n%s", expect)
   341  	}
   342  }
   343  
   344  func newFan(t *testing.T) *mdag.Node {
   345  	a := &mdag.Node{Data: []byte("/a")}
   346  	addChild(t, a, "aa")
   347  	addChild(t, a, "ab")
   348  	addChild(t, a, "ac")
   349  	addChild(t, a, "ad")
   350  	return a
   351  }
   352  
   353  func newLinkedList(t *testing.T) *mdag.Node {
   354  	a := &mdag.Node{Data: []byte("/a")}
   355  	aa := addChild(t, a, "aa")
   356  	aaa := addChild(t, aa, "aaa")
   357  	aaaa := addChild(t, aaa, "aaaa")
   358  	addChild(t, aaaa, "aaaaa")
   359  	return a
   360  }
   361  
   362  func newBinaryTree(t *testing.T) *mdag.Node {
   363  	a := &mdag.Node{Data: []byte("/a")}
   364  	aa := addChild(t, a, "aa")
   365  	ab := addChild(t, a, "ab")
   366  	addChild(t, aa, "aaa")
   367  	addChild(t, aa, "aab")
   368  	addChild(t, ab, "aba")
   369  	addChild(t, ab, "abb")
   370  	return a
   371  }
   372  
   373  func newBinaryDAG(t *testing.T) *mdag.Node {
   374  	a := &mdag.Node{Data: []byte("/a")}
   375  	aa := addChild(t, a, "aa")
   376  	aaa := addChild(t, aa, "aaa")
   377  	aaaa := addChild(t, aaa, "aaaa")
   378  	aaaaa := addChild(t, aaaa, "aaaaa")
   379  	addLink(t, a, aa)
   380  	addLink(t, aa, aaa)
   381  	addLink(t, aaa, aaaa)
   382  	addLink(t, aaaa, aaaaa)
   383  	return a
   384  }
   385  
   386  func addLink(t *testing.T, a, b *mdag.Node) {
   387  	to := string(a.Data) + "2" + string(b.Data)
   388  	if err := a.AddNodeLink(to, b); err != nil {
   389  		t.Error(err)
   390  	}
   391  }
   392  
   393  func addChild(t *testing.T, a *mdag.Node, name string) *mdag.Node {
   394  	c := &mdag.Node{Data: []byte(string(a.Data) + "/" + name)}
   395  	addLink(t, a, c)
   396  	return c
   397  }