mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-09 18:59:12 -06:00
stretchr has fixed a bug with the -count flag. I could merge these changes into attic-labs, but it's easier to just use strechr. We forked stretchr a long time ago so that we didn't link in the HTTP testing libraries into the noms binaries (because we were using d.Chk in production code). The HTTP issue doesn't seem to happen anymore, even though we're still using d.Chk.
496 lines
11 KiB
Go
496 lines
11 KiB
Go
// Copyright 2016 Attic Labs, Inc. All rights reserved.
|
|
// Licensed under the Apache License, version 2.0:
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
package diff
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/attic-labs/noms/go/types"
|
|
"github.com/attic-labs/noms/go/util/test"
|
|
"github.com/attic-labs/noms/go/util/writers"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
var (
|
|
aa1 = createMap("a1", "a-one", "a2", "a-two", "a3", "a-three", "a4", "a-four")
|
|
aa1x = createMap("a1", "a-one-diff", "a2", "a-two", "a3", "a-three", "a4", "a-four")
|
|
|
|
mm1 = createMap("k1", "k-one", "k2", "k-two", "k3", "k-three", "k4", aa1)
|
|
mm2 = createMap("l1", "l-one", "l2", "l-two", "l3", "l-three", "l4", aa1)
|
|
mm3 = createMap("m1", "m-one", "v2", "m-two", "m3", "m-three", "m4", aa1)
|
|
mm3x = createMap("m1", "m-one", "v2", "m-two", "m3", "m-three-diff", "m4", aa1x)
|
|
mm4 = createMap("n1", "n-one", "n2", "n-two", "n3", "n-three", "n4", aa1)
|
|
)
|
|
|
|
func valToTypesValue(v interface{}) types.Value {
|
|
var v1 types.Value
|
|
switch t := v.(type) {
|
|
case string:
|
|
v1 = types.String(t)
|
|
case int:
|
|
v1 = types.Number(t)
|
|
case types.Value:
|
|
v1 = t
|
|
}
|
|
return v1
|
|
}
|
|
|
|
func valsToTypesValues(kv ...interface{}) []types.Value {
|
|
keyValues := []types.Value{}
|
|
for _, e := range kv {
|
|
v := valToTypesValue(e)
|
|
keyValues = append(keyValues, v)
|
|
}
|
|
return keyValues
|
|
}
|
|
|
|
func createMap(kv ...interface{}) types.Map {
|
|
vs := newTestValueStore()
|
|
defer vs.Close()
|
|
keyValues := valsToTypesValues(kv...)
|
|
return types.NewMap(vs, keyValues...)
|
|
}
|
|
|
|
func createSet(kv ...interface{}) types.Set {
|
|
vs := newTestValueStore()
|
|
defer vs.Close()
|
|
keyValues := valsToTypesValues(kv...)
|
|
return types.NewSet(vs, keyValues...)
|
|
}
|
|
|
|
func createList(kv ...interface{}) types.List {
|
|
vs := newTestValueStore()
|
|
defer vs.Close()
|
|
keyValues := valsToTypesValues(kv...)
|
|
return types.NewList(vs, keyValues...)
|
|
}
|
|
|
|
func createStruct(name string, kv ...interface{}) types.Struct {
|
|
fields := types.StructData{}
|
|
for i := 0; i < len(kv); i += 2 {
|
|
fields[kv[i].(string)] = valToTypesValue(kv[i+1])
|
|
}
|
|
return types.NewStruct(name, fields)
|
|
}
|
|
|
|
func pathsFromDiff(v1, v2 types.Value, leftRight bool) []string {
|
|
dChan := make(chan Difference)
|
|
sChan := make(chan struct{})
|
|
|
|
go func() {
|
|
Diff(v1, v2, dChan, sChan, leftRight)
|
|
close(dChan)
|
|
}()
|
|
|
|
var paths []string
|
|
for d := range dChan {
|
|
paths = append(paths, d.Path.String())
|
|
}
|
|
return paths
|
|
}
|
|
|
|
func mustParsePath(assert *assert.Assertions, s string) types.Path {
|
|
if s == "" {
|
|
return nil
|
|
}
|
|
p, err := types.ParsePath(s)
|
|
assert.NoError(err)
|
|
return p
|
|
}
|
|
|
|
func TestNomsDiffPrintMap(t *testing.T) {
|
|
assert := assert.New(t)
|
|
expected := `["map-3"] {
|
|
- "m3": "m-three"
|
|
+ "m3": "m-three-diff"
|
|
}
|
|
["map-3"]["m4"] {
|
|
- "a1": "a-one"
|
|
+ "a1": "a-one-diff"
|
|
}
|
|
`
|
|
expectedPaths := []string{
|
|
`["map-3"]["m3"]`,
|
|
`["map-3"]["m4"]["a1"]`,
|
|
}
|
|
|
|
tf := func(leftRight bool) {
|
|
m1 := createMap("map-1", mm1, "map-2", mm2, "map-3", mm3, "map-4", mm4)
|
|
m2 := createMap("map-1", mm1, "map-2", mm2, "map-3", mm3x, "map-4", mm4)
|
|
buf := &bytes.Buffer{}
|
|
PrintDiff(buf, m1, m2, leftRight)
|
|
assert.Equal(expected, buf.String())
|
|
|
|
paths := pathsFromDiff(m1, m2, leftRight)
|
|
assert.Equal(expectedPaths, paths)
|
|
}
|
|
|
|
tf(true)
|
|
tf(false)
|
|
}
|
|
|
|
func TestNomsDiffPrintSet(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
expected1 := `(root) {
|
|
- "five"
|
|
+ "five-diff"
|
|
}
|
|
`
|
|
expectedPaths1 := []string{
|
|
`["five"]`,
|
|
`["five-diff"]`,
|
|
}
|
|
|
|
expected2 := `(root) {
|
|
- map { // 4 items
|
|
- "m1": "m-one",
|
|
- "m3": "m-three",
|
|
- "m4": map { // 4 items
|
|
- "a1": "a-one",
|
|
- "a2": "a-two",
|
|
- "a3": "a-three",
|
|
- "a4": "a-four",
|
|
- },
|
|
- "v2": "m-two",
|
|
- }
|
|
+ map { // 4 items
|
|
+ "m1": "m-one",
|
|
+ "m3": "m-three-diff",
|
|
+ "m4": map { // 4 items
|
|
+ "a1": "a-one-diff",
|
|
+ "a2": "a-two",
|
|
+ "a3": "a-three",
|
|
+ "a4": "a-four",
|
|
+ },
|
|
+ "v2": "m-two",
|
|
+ }
|
|
}
|
|
`
|
|
expectedPaths2 := []string{
|
|
fmt.Sprintf("[#%s]", mm3.Hash()),
|
|
fmt.Sprintf("[#%s]", mm3x.Hash()),
|
|
}
|
|
|
|
s1 := createSet("one", "three", "five", "seven", "nine")
|
|
s2 := createSet("one", "three", "five-diff", "seven", "nine")
|
|
s3 := createSet(mm1, mm2, mm3, mm4)
|
|
s4 := createSet(mm1, mm2, mm3x, mm4)
|
|
|
|
tf := func(leftRight bool) {
|
|
buf := &bytes.Buffer{}
|
|
PrintDiff(buf, s1, s2, leftRight)
|
|
assert.Equal(expected1, buf.String())
|
|
|
|
paths := pathsFromDiff(s1, s2, leftRight)
|
|
assert.Equal(expectedPaths1, paths)
|
|
|
|
buf = &bytes.Buffer{}
|
|
PrintDiff(buf, s3, s4, leftRight)
|
|
assert.Equal(expected2, buf.String())
|
|
|
|
paths = pathsFromDiff(s3, s4, leftRight)
|
|
assert.Equal(expectedPaths2, paths)
|
|
}
|
|
|
|
tf(true)
|
|
tf(false)
|
|
}
|
|
|
|
// This function tests stop functionality in PrintDiff and Diff.
|
|
func TestNomsDiffPrintStop(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
expected1 := `(root) {
|
|
- "five"
|
|
`
|
|
|
|
expected2 := `(root) {
|
|
- map { // 4 items
|
|
`
|
|
|
|
s1 := createSet("one", "three", "five", "seven", "nine")
|
|
s2 := createSet("one", "three", "five-diff", "seven", "nine")
|
|
s3 := createSet(mm1, mm2, mm3, mm4)
|
|
s4 := createSet(mm1, mm2, mm3x, mm4)
|
|
|
|
tf := func(leftRight bool) {
|
|
buf := &bytes.Buffer{}
|
|
mlw := &writers.MaxLineWriter{Dest: buf, MaxLines: 2}
|
|
PrintDiff(mlw, s1, s2, leftRight)
|
|
assert.Equal(expected1, buf.String())
|
|
|
|
buf = &bytes.Buffer{}
|
|
mlw = &writers.MaxLineWriter{Dest: buf, MaxLines: 2}
|
|
PrintDiff(mlw, s3, s4, leftRight)
|
|
assert.Equal(expected2, buf.String())
|
|
}
|
|
|
|
tf(true)
|
|
tf(false)
|
|
}
|
|
|
|
func TestNomsDiffPrintStruct(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
expected1 := `(root) {
|
|
- "four": "four"
|
|
+ "four": "four-diff"
|
|
}
|
|
["three"] {
|
|
- field1: "field1-data"
|
|
- field3: "field3-data"
|
|
+ field3: "field3-data-diff"
|
|
+ field4: "field4-data"
|
|
}
|
|
`
|
|
expectedPaths1 := []string{
|
|
`["four"]`,
|
|
`["three"].field1`,
|
|
`["three"].field3`,
|
|
`["three"].field4`,
|
|
}
|
|
|
|
expected2 := `(root) {
|
|
- four: "four"
|
|
+ four: "four-diff"
|
|
}
|
|
.three {
|
|
- field1: "field1-data"
|
|
- field3: "field3-data"
|
|
+ field3: "field3-data-diff"
|
|
+ field4: "field4-data"
|
|
}
|
|
`
|
|
expectedPaths2 := []string{
|
|
`.four`,
|
|
`.three.field1`,
|
|
`.three.field3`,
|
|
`.three.field4`,
|
|
}
|
|
|
|
s1 := createStruct("TestData",
|
|
"field1", "field1-data",
|
|
"field2", "field2-data",
|
|
"field3", "field3-data",
|
|
)
|
|
s2 := createStruct("TestData",
|
|
"field2", "field2-data",
|
|
"field3", "field3-data-diff",
|
|
"field4", "field4-data",
|
|
)
|
|
|
|
m1 := createMap("one", 1, "two", 2, "three", s1, "four", "four")
|
|
m2 := createMap("one", 1, "two", 2, "three", s2, "four", "four-diff")
|
|
|
|
s3 := createStruct("", "one", 1, "two", 2, "three", s1, "four", "four")
|
|
s4 := createStruct("", "one", 1, "two", 2, "three", s2, "four", "four-diff")
|
|
|
|
tf := func(leftRight bool) {
|
|
buf := &bytes.Buffer{}
|
|
PrintDiff(buf, m1, m2, leftRight)
|
|
assert.Equal(expected1, buf.String())
|
|
|
|
paths := pathsFromDiff(m1, m2, leftRight)
|
|
assert.Equal(expectedPaths1, paths)
|
|
|
|
buf = &bytes.Buffer{}
|
|
PrintDiff(buf, s3, s4, leftRight)
|
|
assert.Equal(expected2, buf.String())
|
|
|
|
paths = pathsFromDiff(s3, s4, leftRight)
|
|
assert.Equal(expectedPaths2, paths)
|
|
}
|
|
|
|
tf(true)
|
|
tf(false)
|
|
}
|
|
|
|
func TestNomsDiffPrintMapWithStructKeys(t *testing.T) {
|
|
a := assert.New(t)
|
|
|
|
vs := newTestValueStore()
|
|
defer vs.Close()
|
|
|
|
k1 := createStruct("TestKey", "name", "n1", "label", "l1")
|
|
|
|
expected1 := `(root) {
|
|
- struct TestKey {
|
|
- label: "l1",
|
|
- name: "n1",
|
|
- }: true
|
|
+ struct TestKey {
|
|
+ label: "l1",
|
|
+ name: "n1",
|
|
+ }: false
|
|
}
|
|
`
|
|
|
|
m1 := types.NewMap(vs, k1, types.Bool(true))
|
|
m2 := types.NewMap(vs, k1, types.Bool(false))
|
|
tf := func(leftRight bool) {
|
|
buf := &bytes.Buffer{}
|
|
PrintDiff(buf, m1, m2, leftRight)
|
|
a.Equal(expected1, buf.String())
|
|
}
|
|
tf(true)
|
|
tf(false)
|
|
}
|
|
|
|
func TestNomsDiffPrintList(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
expected1 := `(root) {
|
|
- 2
|
|
+ 22
|
|
- 44
|
|
}
|
|
`
|
|
expectedPaths1 := []string{
|
|
`[1]`,
|
|
`[4]`,
|
|
}
|
|
|
|
l1 := createList(1, 2, 3, 4, 44, 5, 6)
|
|
l2 := createList(1, 22, 3, 4, 5, 6)
|
|
|
|
expected2 := `(root) {
|
|
+ "seven"
|
|
}
|
|
`
|
|
expectedPaths2 := []string{
|
|
`[6]`,
|
|
}
|
|
|
|
l3 := createList("one", "two", "three", "four", "five", "six")
|
|
l4 := createList("one", "two", "three", "four", "five", "six", "seven")
|
|
|
|
expected3 := `[2] {
|
|
- "m3": "m-three"
|
|
+ "m3": "m-three-diff"
|
|
}
|
|
[2]["m4"] {
|
|
- "a1": "a-one"
|
|
+ "a1": "a-one-diff"
|
|
}
|
|
`
|
|
expectedPaths3 := []string{
|
|
`[2]["m3"]`,
|
|
`[2]["m4"]["a1"]`,
|
|
}
|
|
|
|
l5 := createList(mm1, mm2, mm3, mm4)
|
|
l6 := createList(mm1, mm2, mm3x, mm4)
|
|
|
|
tf := func(leftRight bool) {
|
|
buf := &bytes.Buffer{}
|
|
PrintDiff(buf, l1, l2, leftRight)
|
|
assert.Equal(expected1, buf.String())
|
|
|
|
paths := pathsFromDiff(l1, l2, leftRight)
|
|
assert.Equal(expectedPaths1, paths)
|
|
|
|
buf = &bytes.Buffer{}
|
|
PrintDiff(buf, l3, l4, leftRight)
|
|
assert.Equal(expected2, buf.String())
|
|
|
|
paths = pathsFromDiff(l3, l4, leftRight)
|
|
assert.Equal(expectedPaths2, paths)
|
|
|
|
buf = &bytes.Buffer{}
|
|
PrintDiff(buf, l5, l6, leftRight)
|
|
assert.Equal(expected3, buf.String())
|
|
|
|
paths = pathsFromDiff(l5, l6, leftRight)
|
|
assert.Equal(expectedPaths3, paths)
|
|
}
|
|
|
|
tf(true)
|
|
tf(false)
|
|
}
|
|
|
|
func TestNomsDiffPrintBlob(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
vs := newTestValueStore()
|
|
defer vs.Close()
|
|
|
|
expected := "- Blob (2.0 kB)\n+ Blob (11 B)\n"
|
|
expectedPaths1 := []string{``}
|
|
b1 := types.NewBlob(vs, strings.NewReader(strings.Repeat("x", 2*1024)))
|
|
b2 := types.NewBlob(vs, strings.NewReader("Hello World"))
|
|
|
|
tf := func(leftRight bool) {
|
|
buf := &bytes.Buffer{}
|
|
PrintDiff(buf, b1, b2, leftRight)
|
|
assert.Equal(expected, buf.String())
|
|
|
|
paths := pathsFromDiff(b1, b2, leftRight)
|
|
assert.Equal(expectedPaths1, paths)
|
|
}
|
|
|
|
tf(true)
|
|
tf(false)
|
|
}
|
|
|
|
func TestNomsDiffPrintType(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
expected1 := "- List<Number>\n+ List<String>\n"
|
|
expectedPaths1 := []string{""}
|
|
t1 := types.MakeListType(types.NumberType)
|
|
t2 := types.MakeListType(types.StringType)
|
|
|
|
expected2 := "- List<Number>\n+ Set<String>\n"
|
|
expectedPaths2 := []string{``}
|
|
t3 := types.MakeListType(types.NumberType)
|
|
t4 := types.MakeSetType(types.StringType)
|
|
|
|
tf := func(leftRight bool) {
|
|
buf := &bytes.Buffer{}
|
|
PrintDiff(buf, t1, t2, leftRight)
|
|
assert.Equal(expected1, buf.String())
|
|
|
|
paths := pathsFromDiff(t1, t2, leftRight)
|
|
assert.Equal(expectedPaths1, paths)
|
|
|
|
buf = &bytes.Buffer{}
|
|
PrintDiff(buf, t3, t4, leftRight)
|
|
assert.Equal(expected2, buf.String())
|
|
|
|
paths = pathsFromDiff(t3, t4, leftRight)
|
|
assert.Equal(expectedPaths2, paths)
|
|
}
|
|
|
|
tf(true)
|
|
tf(false)
|
|
}
|
|
|
|
func TestNomsDiffPrintRef(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
expected := "- #fckcbt7nk5jl4arco2dk7r9nj7abb6ci\n+ #i7d3u5gekm48ot419t2cot6cnl7ltcah\n"
|
|
expectedPaths1 := []string{``}
|
|
l1 := createList(1)
|
|
l2 := createList(2)
|
|
r1 := types.NewRef(l1)
|
|
r2 := types.NewRef(l2)
|
|
|
|
tf := func(leftRight bool) {
|
|
buf := &bytes.Buffer{}
|
|
PrintDiff(buf, r1, r2, leftRight)
|
|
test.EqualsIgnoreHashes(t, expected, buf.String())
|
|
|
|
paths := pathsFromDiff(r1, r2, leftRight)
|
|
assert.Equal(expectedPaths1, paths)
|
|
}
|
|
|
|
tf(true)
|
|
tf(false)
|
|
}
|