fix display modified parents; fix tests
This commit is contained in:
parent
a47105cc7d
commit
598d95f5f7
@ -1,13 +1,16 @@
|
||||
package filetree
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAssignDiffType(t *testing.T) {
|
||||
tree := NewFileTree()
|
||||
tree.AddPath("/usr", BlankFileChangeInfo("/usr", Changed))
|
||||
node, err := tree.AddPath("/usr", BlankFileChangeInfo("/usr"))
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error from fetching path. got: %v", err)
|
||||
}
|
||||
node.Data.DiffType = Changed
|
||||
if tree.Root.Children["usr"].Data.DiffType != Changed {
|
||||
t.Fail()
|
||||
}
|
||||
@ -28,19 +31,7 @@ func TestMergeDiffTypes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func AssertDiffType(node *FileNode, expectedDiffType DiffType, t *testing.T) error {
|
||||
if node.Data.FileInfo == nil {
|
||||
t.Errorf("Expected *FileInfo but got nil at Path %s", node.Path())
|
||||
return fmt.Errorf("expected *FileInfo but got nil at Path %s", node.Path())
|
||||
}
|
||||
if node.Data.DiffType != expectedDiffType {
|
||||
t.Errorf("Expecting node at %s to have DiffType %v, but had %v", node.Path(), expectedDiffType, node.Data.DiffType)
|
||||
return fmt.Errorf("Assertion failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func BlankFileChangeInfo(path string, diffType DiffType) (f *FileInfo) {
|
||||
func BlankFileChangeInfo(path string) (f *FileInfo) {
|
||||
result := FileInfo{
|
||||
Path: path,
|
||||
Typeflag: 1,
|
||||
|
@ -64,8 +64,6 @@ func (node *FileNode) String() string {
|
||||
var style *color.Color
|
||||
if node == nil {
|
||||
return ""
|
||||
} else if node.Data.FileInfo == nil {
|
||||
return node.Name
|
||||
}
|
||||
switch node.Data.DiffType {
|
||||
case Added:
|
||||
@ -82,15 +80,20 @@ func (node *FileNode) String() string {
|
||||
return style.Sprint(node.Name)
|
||||
}
|
||||
|
||||
func (node *FileNode) VisitDepthChildFirst(visiter Visiter) error {
|
||||
func (node *FileNode) VisitDepthChildFirst(visiter Visiter, evaluator VisitEvaluator) error {
|
||||
var keys []string
|
||||
for key := range node.Children {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, name := range keys {
|
||||
if evaluator != nil {
|
||||
if !evaluator(node) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
child := node.Children[name]
|
||||
err := child.VisitDepthChildFirst(visiter)
|
||||
err := child.VisitDepthChildFirst(visiter, evaluator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -110,10 +113,12 @@ func (node *FileNode) VisitDepthParentFirst(visiter Visiter, evaluator VisitEval
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, name := range keys {
|
||||
child := node.Children[name]
|
||||
if evaluator == nil || !evaluator(node) {
|
||||
if evaluator != nil {
|
||||
if !evaluator(node) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
child := node.Children[name]
|
||||
err = child.VisitDepthParentFirst(visiter, evaluator)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -155,8 +160,7 @@ func (node *FileNode) deriveDiffType(diffType DiffType) error {
|
||||
// THE CONTENTS ARE THE BYTES OF A FILE OR THE CHILDREN OF A DIRECTORY
|
||||
|
||||
if node.IsLeaf() {
|
||||
node.AssignDiffType(diffType)
|
||||
return nil
|
||||
return node.AssignDiffType(diffType)
|
||||
}
|
||||
myDiffType := diffType
|
||||
|
||||
@ -164,8 +168,8 @@ func (node *FileNode) deriveDiffType(diffType DiffType) error {
|
||||
myDiffType = myDiffType.merge(v.Data.DiffType)
|
||||
|
||||
}
|
||||
node.AssignDiffType(myDiffType)
|
||||
return nil
|
||||
|
||||
return node.AssignDiffType(myDiffType)
|
||||
}
|
||||
|
||||
func (node *FileNode) AssignDiffType(diffType DiffType) error {
|
||||
|
@ -109,15 +109,18 @@ func TestIsWhiteout(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiffTypeFromChildren(t *testing.T) {
|
||||
func TestDiffTypeFromAddedChildren(t *testing.T) {
|
||||
tree := NewFileTree()
|
||||
tree.AddPath("/usr", BlankFileChangeInfo("/usr", Unchanged))
|
||||
node, _ := tree.AddPath("/usr", BlankFileChangeInfo("/usr"))
|
||||
node.Data.DiffType = Unchanged
|
||||
|
||||
info1 := BlankFileChangeInfo("/usr/bin", Added)
|
||||
tree.AddPath("/usr/bin", info1)
|
||||
info1 := BlankFileChangeInfo("/usr/bin")
|
||||
node, _ = tree.AddPath("/usr/bin", info1)
|
||||
node.Data.DiffType = Added
|
||||
|
||||
info2 := BlankFileChangeInfo("/usr/bin2", Removed)
|
||||
tree.AddPath("/usr/bin2", info2)
|
||||
info2 := BlankFileChangeInfo("/usr/bin2")
|
||||
node, _ = tree.AddPath("/usr/bin2", info2)
|
||||
node.Data.DiffType = Removed
|
||||
|
||||
tree.Root.Children["usr"].deriveDiffType(Unchanged)
|
||||
|
||||
@ -125,3 +128,22 @@ func TestDiffTypeFromChildren(t *testing.T) {
|
||||
t.Errorf("Expected Changed but got %v", tree.Root.Children["usr"].Data.DiffType)
|
||||
}
|
||||
}
|
||||
func TestDiffTypeFromRemovedChildren(t *testing.T) {
|
||||
tree := NewFileTree()
|
||||
node, _ := tree.AddPath("/usr", BlankFileChangeInfo("/usr"))
|
||||
|
||||
info1 := BlankFileChangeInfo("/usr/.wh.bin")
|
||||
node, _ = tree.AddPath("/usr/.wh.bin", info1)
|
||||
node.Data.DiffType = Removed
|
||||
|
||||
info2 := BlankFileChangeInfo("/usr/.wh.bin2")
|
||||
node, _ = tree.AddPath("/usr/.wh.bin2", info2)
|
||||
node.Data.DiffType = Removed
|
||||
|
||||
tree.Root.Children["usr"].deriveDiffType(Unchanged)
|
||||
|
||||
if tree.Root.Children["usr"].Data.DiffType != Changed {
|
||||
t.Errorf("Expected Changed but got %v", tree.Root.Children["usr"].Data.DiffType)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ func (tree *FileTree) Copy() *FileTree {
|
||||
newTree.VisitDepthChildFirst(func(node *FileNode) error {
|
||||
node.Tree = newTree
|
||||
return nil
|
||||
})
|
||||
}, nil)
|
||||
|
||||
return newTree
|
||||
}
|
||||
@ -102,8 +102,8 @@ type Visiter func(*FileNode) error
|
||||
type VisitEvaluator func(*FileNode) bool
|
||||
|
||||
// DFS bubble up
|
||||
func (tree *FileTree) VisitDepthChildFirst(visiter Visiter) error {
|
||||
return tree.Root.VisitDepthChildFirst(visiter)
|
||||
func (tree *FileTree) VisitDepthChildFirst(visiter Visiter, evaluator VisitEvaluator) error {
|
||||
return tree.Root.VisitDepthChildFirst(visiter, evaluator)
|
||||
}
|
||||
|
||||
// DFS sink down
|
||||
@ -126,7 +126,7 @@ func (tree *FileTree) Stack(upper *FileTree) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return upper.VisitDepthChildFirst(graft)
|
||||
return upper.VisitDepthChildFirst(graft, nil)
|
||||
}
|
||||
|
||||
func (tree *FileTree) GetNode(path string) (*FileNode, error) {
|
||||
@ -179,30 +179,30 @@ func (tree *FileTree) RemovePath(path string) error {
|
||||
}
|
||||
|
||||
func (tree *FileTree) Compare(upper *FileTree) error {
|
||||
graft := func(node *FileNode) error {
|
||||
if node.IsWhiteout() {
|
||||
err := tree.MarkRemoved(node.Path())
|
||||
graft := func(upperNode *FileNode) error {
|
||||
if upperNode.IsWhiteout() {
|
||||
err := tree.MarkRemoved(upperNode.Path())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot remove node %s: %v", node.Path(), err.Error())
|
||||
return fmt.Errorf("Cannot remove upperNode %s: %v", upperNode.Path(), err.Error())
|
||||
}
|
||||
} else {
|
||||
existingNode, _ := tree.GetNode(node.Path())
|
||||
if existingNode == nil {
|
||||
newNode, err := tree.AddPath(node.Path(), node.Data.FileInfo)
|
||||
// fmt.Printf("added new node at %s\n", newNode.Path())
|
||||
lowerNode, _ := tree.GetNode(upperNode.Path())
|
||||
if lowerNode == nil {
|
||||
newNode, err := tree.AddPath(upperNode.Path(), upperNode.Data.FileInfo)
|
||||
// fmt.Printf("added new upperNode at %s\n", newNode.Path())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot add new node %s: %v", node.Path(), err.Error())
|
||||
return fmt.Errorf("Cannot add new upperNode %s: %v", upperNode.Path(), err.Error())
|
||||
}
|
||||
newNode.AssignDiffType(Added)
|
||||
} else {
|
||||
diffType := existingNode.compare(node)
|
||||
// fmt.Printf("found existing node at %s\n", existingNode.Path())
|
||||
return existingNode.deriveDiffType(diffType)
|
||||
diffType := lowerNode.compare(upperNode)
|
||||
// fmt.Printf("found existing upperNode at %s\n", lowerNode.Path())
|
||||
return lowerNode.deriveDiffType(diffType)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return upper.VisitDepthChildFirst(graft)
|
||||
return upper.VisitDepthChildFirst(graft, nil)
|
||||
}
|
||||
|
||||
func (tree *FileTree) MarkRemoved(path string) error {
|
||||
|
@ -5,6 +5,25 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func stringInSlice(a string, list []string) bool {
|
||||
for _, b := range list {
|
||||
if b == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func AssertDiffType(node *FileNode, expectedDiffType DiffType) error {
|
||||
if node.Data.FileInfo == nil {
|
||||
return fmt.Errorf("expected *FileInfo but got nil at Path %s", node.Path())
|
||||
}
|
||||
if node.Data.DiffType != expectedDiffType {
|
||||
return fmt.Errorf("Expecting node at %s to have DiffType %v, but had %v", node.Path(), expectedDiffType, node.Data.DiffType)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestPrintTree(t *testing.T) {
|
||||
tree := NewFileTree()
|
||||
tree.Root.AddChild("first node!", nil)
|
||||
@ -199,7 +218,7 @@ func TestCompareWithNoChanges(t *testing.T) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err := lowerTree.VisitDepthChildFirst(asserter)
|
||||
err := lowerTree.VisitDepthChildFirst(asserter, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -212,53 +231,116 @@ func TestCompareWithAdds(t *testing.T) {
|
||||
upperPaths := [...]string{"/etc", "/etc/sudoers", "/usr", "/etc/hosts", "/usr/bin", "/usr/bin/bash"}
|
||||
|
||||
for _, value := range lowerPaths {
|
||||
fakeData := FileInfo{
|
||||
lowerTree.AddPath(value, &FileInfo{
|
||||
Path: value,
|
||||
Typeflag: 1,
|
||||
MD5sum: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}
|
||||
lowerTree.AddPath(value, &fakeData)
|
||||
})
|
||||
}
|
||||
|
||||
for _, value := range upperPaths {
|
||||
fakeData := FileInfo{
|
||||
upperTree.AddPath(value, &FileInfo{
|
||||
Path: value,
|
||||
Typeflag: 1,
|
||||
MD5sum: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}
|
||||
upperTree.AddPath(value, &fakeData)
|
||||
})
|
||||
}
|
||||
|
||||
lowerTree.Compare(upperTree)
|
||||
failedAssertions := []error{}
|
||||
err := lowerTree.Compare(upperTree)
|
||||
if err != nil {
|
||||
t.Errorf("Expected tree compare to have no errors, got: %v", err)
|
||||
}
|
||||
asserter := func(n *FileNode) error {
|
||||
|
||||
p := n.Path()
|
||||
if p == "/" {
|
||||
return nil
|
||||
} else if stringInSlice(p,[]string{"/usr/bin/bash"}) {
|
||||
if err := AssertDiffType(n, Added); err != nil {
|
||||
failedAssertions = append(failedAssertions, err)
|
||||
}
|
||||
// Adding a file changes the folders it's in
|
||||
if p == "/usr/bin/bash" {
|
||||
return AssertDiffType(n, Added, t)
|
||||
} else if stringInSlice(p,[]string{"/usr/bin", "/usr"}) {
|
||||
if err := AssertDiffType(n, Changed); err != nil {
|
||||
failedAssertions = append(failedAssertions, err)
|
||||
}
|
||||
if p == "/usr/bin" {
|
||||
return AssertDiffType(n, Changed, t)
|
||||
} else {
|
||||
if err := AssertDiffType(n, Unchanged); err != nil {
|
||||
failedAssertions = append(failedAssertions, err)
|
||||
}
|
||||
if p == "/usr" {
|
||||
return AssertDiffType(n, Changed, t)
|
||||
}
|
||||
return AssertDiffType(n, Unchanged, t)
|
||||
return nil
|
||||
}
|
||||
err := lowerTree.VisitDepthChildFirst(asserter)
|
||||
err = lowerTree.VisitDepthChildFirst(asserter, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Errorf("Expected no errors when visiting nodes, got: %+v", err)
|
||||
}
|
||||
|
||||
if len(failedAssertions) > 0 {
|
||||
str := "\n"
|
||||
for _, value := range failedAssertions {
|
||||
str += fmt.Sprintf(" - %s\n", value.Error())
|
||||
}
|
||||
t.Errorf("Expected no errors when evaluating nodes, got: %s", str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompareWithChanges(t *testing.T) {
|
||||
lowerTree := NewFileTree()
|
||||
upperTree := NewFileTree()
|
||||
lowerPaths := [...]string{"/etc", "/usr", "/etc/hosts", "/etc/sudoers", "/usr/bin"}
|
||||
upperPaths := [...]string{"/etc", "/usr", "/etc/hosts", "/etc/sudoers", "/usr/bin"}
|
||||
paths := [...]string{"/etc", "/usr", "/etc/hosts", "/etc/sudoers", "/usr/bin"}
|
||||
|
||||
for _, value := range paths {
|
||||
lowerTree.AddPath(value, &FileInfo{
|
||||
Path: value,
|
||||
Typeflag: 1,
|
||||
MD5sum: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
})
|
||||
upperTree.AddPath(value, &FileInfo{
|
||||
Path: value,
|
||||
Typeflag: 1,
|
||||
MD5sum: [16]byte{1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
lowerTree.Compare(upperTree)
|
||||
failedAssertions := []error{}
|
||||
asserter := func(n *FileNode) error {
|
||||
p := n.Path()
|
||||
if p == "/" {
|
||||
return nil
|
||||
} else if stringInSlice(p, []string{"/etc", "/usr", "/etc/hosts", "/etc/sudoers", "/usr/bin"}) {
|
||||
if err := AssertDiffType(n, Changed); err != nil {
|
||||
failedAssertions = append(failedAssertions, err)
|
||||
}
|
||||
} else {
|
||||
if err := AssertDiffType(n, Unchanged); err != nil {
|
||||
failedAssertions = append(failedAssertions, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err := lowerTree.VisitDepthChildFirst(asserter, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no errors when visiting nodes, got: %+v", err)
|
||||
}
|
||||
|
||||
if len(failedAssertions) > 0 {
|
||||
str := "\n"
|
||||
for _, value := range failedAssertions {
|
||||
str += fmt.Sprintf(" - %s\n", value.Error())
|
||||
}
|
||||
t.Errorf("Expected no errors when evaluating nodes, got: %s", str)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestCompareWithRemoves(t *testing.T) {
|
||||
lowerTree := NewFileTree()
|
||||
upperTree := NewFileTree()
|
||||
lowerPaths := [...]string{"/etc", "/usr", "/etc/hosts", "/etc/sudoers", "/usr/bin", "/root", "/root/example", "/root/example/some1", "/root/example/some2"}
|
||||
upperPaths := [...]string{"/.wh.etc", "/usr", "/usr/.wh.bin", "/root/.wh.example"}
|
||||
|
||||
for _, value := range lowerPaths {
|
||||
fakeData := FileInfo{
|
||||
@ -273,22 +355,43 @@ func TestCompareWithChanges(t *testing.T) {
|
||||
fakeData := FileInfo{
|
||||
Path: value,
|
||||
Typeflag: 1,
|
||||
MD5sum: [16]byte{1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0},
|
||||
MD5sum: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}
|
||||
upperTree.AddPath(value, &fakeData)
|
||||
}
|
||||
|
||||
lowerTree.Compare(upperTree)
|
||||
failedAssertions := []error{}
|
||||
asserter := func(n *FileNode) error {
|
||||
p := n.Path()
|
||||
if p == "/" {
|
||||
return nil
|
||||
} else if stringInSlice(p,[]string{"/etc", "/usr/bin", "/etc/hosts", "/etc/sudoers", "/root/example/some1", "/root/example/some2", "/root/example"}) {
|
||||
if err := AssertDiffType(n, Removed); err != nil {
|
||||
failedAssertions = append(failedAssertions, err)
|
||||
}
|
||||
return AssertDiffType(n, Changed, t)
|
||||
} else if stringInSlice(p,[]string{"/usr", "/root"}) {
|
||||
if err := AssertDiffType(n, Changed); err != nil {
|
||||
failedAssertions = append(failedAssertions, err)
|
||||
}
|
||||
err := lowerTree.VisitDepthChildFirst(asserter)
|
||||
} else {
|
||||
if err := AssertDiffType(n, Unchanged); err != nil {
|
||||
failedAssertions = append(failedAssertions, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err := lowerTree.VisitDepthChildFirst(asserter, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Errorf("Expected no errors when visiting nodes, got: %+v", err)
|
||||
}
|
||||
|
||||
if len(failedAssertions) > 0 {
|
||||
str := "\n"
|
||||
for _, value := range failedAssertions {
|
||||
str += fmt.Sprintf(" - %s\n", value.Error())
|
||||
}
|
||||
t.Errorf("Expected no errors when evaluating nodes, got: %s", str)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ func (view *FileTreeView) setLayer(layerIndex int) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
view.Tree.VisitDepthChildFirst(visitor)
|
||||
view.Tree.VisitDepthChildFirst(visitor, nil)
|
||||
|
||||
// now that the tree has been rebuilt, keep the view seleciton in parity with the previous selection
|
||||
view.setHiddenFromDiffTypes()
|
||||
@ -154,7 +154,7 @@ func (view *FileTreeView) setHiddenFromDiffTypes() error {
|
||||
node.Data.ViewInfo.Hidden = view.HiddenDiffTypes[node.Data.DiffType]
|
||||
return nil
|
||||
}
|
||||
view.Tree.VisitDepthChildFirst(visitor)
|
||||
view.Tree.VisitDepthChildFirst(visitor, nil)
|
||||
return view.Render()
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user