func Test8(t *testing.T) {
	inputNodes := make([]map[string]interface{}, 0)
	inputNodes = append(inputNodes, map[string]interface{}{"id": "1", "parents": []string{"3", "2"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "2", "parents": []string{"4"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "3", "parents": []string{"4", "5"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "4", "parents": []string{"6"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "5", "parents": []string{"6"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "6", "parents": []string{}})
	out, _ := BuildTree(inputNodes, customColors)
	expectedColumns := []int{0, 1, 0, 0, 1, 0}
	expectedPaths := []map[string]Path{
		{
			"3": Path{"3", []Point{{0, 0, 0}, {0, 2, 0}}, "color1"},
			"2": Path{"2", []Point{{0, 0, 0}, {1, 0, 2}, {1, 1, 0}}, "color2"},
		},
		{
			"4": Path{"4", []Point{{1, 1, 0}, {1, 3, 1}, {0, 3, 0}}, "color2"},
		},
		{
			"4": Path{"4", []Point{{0, 2, 0}, {0, 3, 0}}, "color1"},
			"5": Path{"5", []Point{{0, 2, 0}, {2, 2, 2}, {2, 3, 1}, {1, 3, 0}, {1, 4, 0}}, "color3"},
		},
		{
			"6": Path{"6", []Point{{0, 3, 0}, {0, 5, 0}}, "color1"},
		},
		{
			"6": Path{"6", []Point{{1, 4, 0}, {1, 5, 1}, {0, 5, 0}}, "color3"},
		},
	}
	validateColumns(t, expectedColumns, out)
	validatePaths(t, expectedPaths, out)
	validateColors(t, expectedPaths, out)
}
1
|\
| 2
3 |
|\|
| |\
|/ /
4 |
| 5
|/
6
package git2graph
import (
	"testing"
)
func validateColumns(t *testing.T, expectedColumns []int, data []map[string]interface{}) {
	for idx, row := range data {
		if row["column"] != expectedColumns[idx] {
			t.Fail()
			t.Logf("ID: %s, Expected column: %d, Actual column: %d", row["id"], expectedColumns[idx], row["column"])
		}
	}
}
func validatePaths(t *testing.T, expectedPaths []map[string]Path, data []map[string]interface{}) {
	for nodeIdx, node := range data {
		for _, parentID := range node["parents"].([]string) {
			if len(expectedPaths)-1 < nodeIdx {
				continue
			}
			if len(node["parentsPaths"].(map[string]Path)[parentID].Path) != len(expectedPaths[nodeIdx][parentID].Path) {
				t.Fail()
				t.Logf("ID: %s, Expected nb paths: %d, Actual nb paths: %d", node["id"], len(expectedPaths[nodeIdx][parentID].Path), len(node["parentsPaths"].(map[string]Path)[parentID].Path))
				t.Logf("ID: %s, Expected: %v, Actual: %v", node["id"], expectedPaths[nodeIdx][parentID], node["parentsPaths"].(map[string]Path)[parentID])
				return
			}
			for pathIdx, pathNode := range node["parentsPaths"].(map[string]Path)[parentID].Path {
				if pathNode != expectedPaths[nodeIdx][parentID].Path[pathIdx] {
					t.Fail()
					t.Logf("ID: %s, Expected path: %d, Actual path: %d", node["id"], expectedPaths[nodeIdx][parentID].Path[pathIdx], pathNode)
					t.Logf("ID: %s, Expected: %v, Actual: %v", node["id"], expectedPaths[nodeIdx][parentID].Path, node["parentsPaths"].(map[string]Path)[parentID].Path)
				}
			}
		}
	}
}
func validateColors(t *testing.T, expectedPaths []map[string]Path, data []map[string]interface{}) {
	for nodeIdx, node := range data {
		for _, parentID := range node["parents"].([]string) {
			if len(expectedPaths)-1 < nodeIdx {
				continue
			}
			if expectedPaths[nodeIdx][parentID].Color != node["parentsPaths"].(map[string]Path)[parentID].Color {
				t.Logf("ID: %s, Expected: %v, Actual: %v", node["id"], expectedPaths[nodeIdx][parentID].Color, node["parentsPaths"].(map[string]Path)[parentID].Color)
				t.Fail()
			}
		}
	}
}
var customColors = []string{
	"color1",
	"color2",
	"color3",
	"color4",
	"color5",
	"color6",
	"color7",
	"color8",
	"color9",
	"color10",
}
func TestDebug(t *testing.T) {
	DebugMode = true
	inputNodes := make([]map[string]interface{}, 0)
	inputNodes = append(inputNodes, map[string]interface{}{"id": "1", "parents": []string{"2"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "2", "parents": []string{"3"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "3", "parents": []string{}})
	out, _ := BuildTree(inputNodes, customColors)
	if len(out[0]["debug"].([]string)) <= 0 {
		t.Fail()
	}
}
func TestNotEnoughColors(t *testing.T) {
	var colors = []string{
		"color1",
		"color2",
	}
	inputNodes := make([]map[string]interface{}, 0)
	inputNodes = append(inputNodes, map[string]interface{}{"id": "0", "parents": []string{"3"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "1", "parents": []string{"3"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "2", "parents": []string{"3"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "3", "parents": []string{}})
	out, _ := BuildTree(inputNodes, colors)
	if out[2]["color"] != "#000" {
		t.Fail()
	}
}
func TestGetInputNodesFromJson(t *testing.T) {
	json := `[{"id": "1", "parents": ["2"]}, {"id": "2", "parents": ["3"]}, {"id": "3", "parents": []}]`
	inputNodes, _ := GetInputNodesFromJSON([]byte(json))
	out, _ := BuildTree(inputNodes, customColors)
	expectedColumns := []int{0, 0, 0}
	expectedPaths := []map[string]Path{
		{"2": Path{"2", []Point{{0, 0, 0}, {0, 1, 0}}, "color1"}},
		{"3": Path{"3", []Point{{0, 1, 0}, {0, 2, 0}}, "color1"}},
	}
	validateColumns(t, expectedColumns, out)
	validatePaths(t, expectedPaths, out)
	validateColors(t, expectedPaths, out)
}
func TestGetInputNodesFromJsonWithBadJson(t *testing.T) {
	json := `[{"id": "1", "parents": ["2"]}, {"id": "2", "parents": ["3"]}, {"id": "3", "parents": []}`
	_, err := GetInputNodesFromJSON([]byte(json))
	if err == nil {
		t.Fail()
	}
}
func Test1(t *testing.T) {
	inputNodes := make([]map[string]interface{}, 0)
	inputNodes = append(inputNodes, map[string]interface{}{"id": "1", "parents": []string{"2"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "2", "parents": []string{"3"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "3", "parents": []string{}})
	out, _ := BuildTree(inputNodes, customColors)
	expectedColumns := []int{0, 0, 0}
	expectedPaths := []map[string]Path{
		{
			"2": Path{"2", []Point{{0, 0, 0}, {0, 1, 0}}, "color1"},
		},
		{
			"3": Path{"3", []Point{{0, 1, 0}, {0, 2, 0}}, "color1"},
		},
	}
	validateColumns(t, expectedColumns, out)
	validatePaths(t, expectedPaths, out)
	validateColors(t, expectedPaths, out)
}
func Test2(t *testing.T) {
	inputNodes := make([]map[string]interface{}, 0)
	inputNodes = append(inputNodes, map[string]interface{}{"id": "1", "parents": []string{"3"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "2", "parents": []string{"3"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "3", "parents": []string{}})
	out, _ := BuildTree(inputNodes, customColors)
	expectedColumns := []int{0, 1, 0}
	expectedPaths := []map[string]Path{
		{
			"3": Path{"3", []Point{{0, 0, 0}, {0, 2, 0}}, "color1"},
		},
		{
			"3": Path{"3", []Point{{1, 1, 0}, {1, 2, 1}, {0, 2, 0}}, "color2"},
		},
	}
	validateColumns(t, expectedColumns, out)
	validatePaths(t, expectedPaths, out)
	validateColors(t, expectedPaths, out)
}
func Test3(t *testing.T) {
	inputNodes := make([]map[string]interface{}, 0)
	inputNodes = append(inputNodes, map[string]interface{}{"id": "1", "parents": []string{"3", "2"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "2", "parents": []string{"3"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "3", "parents": []string{}})
	out, _ := BuildTree(inputNodes, customColors)
	expectedColumns := []int{0, 1, 0}
	expectedPaths := []map[string]Path{
		{
			"3": Path{"3", []Point{{0, 0, 0}, {0, 2, 0}}, "color1"},
			"2": Path{"2", []Point{{0, 0, 0}, {1, 0, 2}, {1, 1, 0}}, "color2"},
		},
		{
			"3": Path{"3", []Point{{1, 1, 0}, {1, 2, 1}, {0, 2, 0}}, "color2"},
		},
	}
	validateColumns(t, expectedColumns, out)
	validatePaths(t, expectedPaths, out)
	validateColors(t, expectedPaths, out)
}
func Test4(t *testing.T) {
	inputNodes := make([]map[string]interface{}, 0)
	inputNodes = append(inputNodes, map[string]interface{}{"id": "1", "parents": []string{"3", "2"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "2", "parents": []string{"5"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "3", "parents": []string{"5", "4"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "4", "parents": []string{"5"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "5", "parents": []string{}})
	out, _ := BuildTree(inputNodes, customColors)
	expectedColumns := []int{0, 1, 0, 2, 0}
	expectedPaths := []map[string]Path{
		{
			"3": Path{"3", []Point{{0, 0, 0}, {0, 2, 0}}, "color1"},
			"2": Path{"2", []Point{{0, 0, 0}, {1, 0, 2}, {1, 1, 0}}, "color2"},
		},
		{
			"5": Path{"5", []Point{{1, 1, 0}, {1, 4, 1}, {0, 4, 0}}, "color2"},
		},
		{
			"5": Path{"5", []Point{{0, 2, 0}, {0, 4, 0}}, "color1"},
			"4": Path{"4", []Point{{0, 2, 0}, {2, 2, 2}, {2, 3, 0}}, "color3"},
		},
		{
			"5": Path{"5", []Point{{2, 3, 0}, {2, 4, 1}, {0, 4, 0}}, "color3"},
		},
	}
	validateColumns(t, expectedColumns, out)
	validatePaths(t, expectedPaths, out)
	validateColors(t, expectedPaths, out)
}
func Test5(t *testing.T) {
	inputNodes := make([]map[string]interface{}, 0)
	inputNodes = append(inputNodes, map[string]interface{}{"id": "1", "parents": []string{"4"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "2", "parents": []string{"4"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "3", "parents": []string{"4"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "4", "parents": []string{"6"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "5", "parents": []string{"6"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "6", "parents": []string{}})
	out, _ := BuildTree(inputNodes, customColors)
	expectedColumns := []int{0, 1, 2, 0, 1, 0}
	expectedPaths := []map[string]Path{
		{
			"4": {"4", []Point{{0, 0, 0}, {0, 3, 0}}, "color1"},
		},
		{
			"4": {"4", []Point{{1, 1, 0}, {1, 3, 1}, {0, 3, 0}}, "color2"},
		},
		{
			"4": Path{"4", []Point{{2, 2, 0}, {2, 3, 1}, {0, 3, 0}}, "color3"},
		},
		{
			"6": {"6", []Point{{0, 3, 0}, {0, 5, 0}}, "color1"},
		},
		{
			"6": Path{"6", []Point{{1, 4, 0}, {1, 5, 1}, {0, 5, 0}}, "color4"},
		},
	}
	validateColumns(t, expectedColumns, out)
	validatePaths(t, expectedPaths, out)
	validateColors(t, expectedPaths, out)
}
func Test6(t *testing.T) {
	inputNodes := make([]map[string]interface{}, 0)
	inputNodes = append(inputNodes, map[string]interface{}{"id": "1", "parents": []string{"3", "2"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "2", "parents": []string{"3", "4"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "3", "parents": []string{"5"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "4", "parents": []string{"5"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "5", "parents": []string{}})
	out, _ := BuildTree(inputNodes, customColors)
	expectedColumns := []int{0, 1, 0, 1, 0}
	expectedPaths := []map[string]Path{
		{
			"3": Path{"3", []Point{{0, 0, 0}, {0, 2, 0}}, "color1"},
			"2": Path{"2", []Point{{0, 0, 0}, {1, 0, 2}, {1, 1, 0}}, "color2"},
		},
		{
			"3": Path{"3", []Point{{1, 1, 0}, {0, 1, 3}, {0, 2, 0}}, "color1"},
			"4": Path{"4", []Point{{1, 1, 0}, {1, 3, 0}}, "color2"},
		},
		{
			"5": Path{"5", []Point{{0, 2, 0}, {0, 4, 0}}, "color1"},
		},
		{
			"5": Path{"5", []Point{{1, 3, 0}, {1, 4, 1}, {0, 4, 0}}, "color2"},
		},
	}
	validateColumns(t, expectedColumns, out)
	validatePaths(t, expectedPaths, out)
	validateColors(t, expectedPaths, out)
}
func Test7(t *testing.T) {
	inputNodes := make([]map[string]interface{}, 0)
	inputNodes = append(inputNodes, map[string]interface{}{"id": "1", "parents": []string{"3", "2"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "2", "parents": []string{"4", "5"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "3", "parents": []string{"5"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "4", "parents": []string{"6"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "5", "parents": []string{"6"}})
	inputNodes = append(inputNodes, map[string]interface{}{"id": "6", "parents": []string{}})
	out, _ := BuildTree(inputNodes, customColors)
	expectedColumns := []int{0, 1, 0, 1, 0, 0}
	expectedPaths := []map[string]Path{
		{
			"3": Path{"3", []Point{{0, 0, 0}, {0, 2, 0}}, "color1"},
			"2": Path{"2", []Point{{0, 0, 0}, {1, 0, 2}, {1, 1, 0}}, "color2"},
		},
		{
			"4": Path{"4", []Point{{1, 1, 0}, {1, 3, 0}}, "color2"},
			"5": Path{"5", []Point{{1, 1, 0}, {2, 1, 2}, {2, 4, 1}, {0, 4, 0}}, "color3"},
		},
		{
			"5": Path{"5", []Point{{0, 2, 0}, {0, 4, 0}}, "color1"},
		},
		{
			"6": Path{"6", []Point{{1, 3, 0}, {1, 5, 1}, {0, 5, 0}}, "color2"},
		},
		{
			"6": Path{"6", []Point{{0, 4, 0}, {0, 5, 0}}, "color1"},
		},
	}
	validateColumns(t, expectedColumns, out)
	validatePaths(t, expectedPaths, out)
	validateColors(t, expectedPaths, out)
}