Skip to content

Commit

Permalink
Adding indices to slices and supporting json output in report
Browse files Browse the repository at this point in the history
  • Loading branch information
yazgazan committed Jul 5, 2018
1 parent f6b7278 commit 74fcdd4
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 36 deletions.
15 changes: 9 additions & 6 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ type config struct {
}

type output struct {
Indent string `long:"indent" description:"indent string" default:"\t"`
ShowTypes bool `long:"show-types" short:"t" description:"show types"`
Colorized bool
JSON bool `long:"json" description:"json-style output"`
Indent string `long:"indent" description:"indent string" default:"\t"`
ShowTypes bool `long:"show-types" short:"t" description:"show types"`
Colorized bool
JSON bool `long:"json" description:"json-style output"`
JSONValues bool
}

func readConfig() config {
Expand All @@ -52,9 +53,11 @@ func readConfig() config {
fmt.Fprintf(os.Stderr, "Incompatible options --json and --show-types\n")
os.Exit(statusUsage)
}
if c.JSON {
c.JSONValues = true
}
if c.JSON && c.OutputReport {
fmt.Fprintf(os.Stderr, "Incompatible options --json and --report\n")
os.Exit(statusUsage)
c.JSON = false
}

c.output.Colorized = terminal.IsTerminal(int(os.Stdout.Fd()))
Expand Down
15 changes: 8 additions & 7 deletions diff/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ import (

// Output is used to configure the output of the Strings and StringIndent functions.
type Output struct {
Indent string
ShowTypes bool
Colorized bool
JSON bool
Indent string
ShowTypes bool
Colorized bool
JSON bool
JSONValues bool
}

func (o Output) red(v interface{}) string {
var s string

if o.ShowTypes {
s = fmt.Sprintf("%T %v", v, v)
} else if o.JSON {
} else if o.JSONValues {
s = jsonString(v)
} else {
s = fmt.Sprintf("%v", v)
Expand All @@ -38,7 +39,7 @@ func (o Output) green(v interface{}) string {

if o.ShowTypes {
s = fmt.Sprintf("%T %v", v, v)
} else if o.JSON {
} else if o.JSONValues {
s = jsonString(v)
} else {
s = fmt.Sprintf("%v", v)
Expand All @@ -56,7 +57,7 @@ func (o Output) white(v interface{}) string {

if o.ShowTypes {
s = fmt.Sprintf("%T %v", v, v)
} else if o.JSON {
} else if o.JSONValues {
s = jsonString(v)
} else {
s = fmt.Sprintf("%v", v)
Expand Down
9 changes: 5 additions & 4 deletions diff/output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ func TestOutput(t *testing.T) {
},
{
Output: Output{
Indent: "\t",
Colorized: true,
ShowTypes: false,
JSON: true,
Indent: "\t",
Colorized: true,
ShowTypes: false,
JSON: true,
JSONValues: true,
},
WantVal: []string{"5"},
WantType: []string{},
Expand Down
56 changes: 37 additions & 19 deletions diff/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ package diff
import (
"fmt"
"reflect"
"strconv"
"strings"

myersdiff "github.com/mb0/diff"
)

type slice struct {
diffs []Differ
lhs interface{}
rhs interface{}
diffs []Differ
indices []int
lhs interface{}
rhs interface{}
}

type sliceMissing struct {
Expand Down Expand Up @@ -40,39 +42,45 @@ func (d *diffData) Equal(i, j int) bool {
return diff.Diff() == Identical
}

func myersToDiff(conf config, lhs, rhs reflect.Value, changes []myersdiff.Change) []Differ {
func myersToDiff(conf config, lhs, rhs reflect.Value, changes []myersdiff.Change) ([]Differ, []int) {
res := []Differ{}
indices := []int{}

lhsIdx := 0
rhsIdx := 0
for _, c := range changes {
for i := 0; lhsIdx+i < c.A; i++ {
diff, _ := diff(conf, lhs.Index(lhsIdx+i).Interface(), rhs.Index(rhsIdx+i).Interface(), &visited{})
res = append(res, diff)
indices = append(indices, lhsIdx+i)
}
lhsIdx = c.A
rhsIdx = c.B
for d := 0; d < c.Del; d++ {
res = append(res, sliceMissing{lhs.Index(lhsIdx + d).Interface()})
indices = append(indices, lhsIdx+d)
}
lhsIdx += c.Del
for i := 0; i < c.Ins; i++ {
res = append(res, sliceExcess{rhs.Index(rhsIdx + i).Interface()})
indices = append(indices, rhsIdx+i)
}
rhsIdx += c.Ins
}

for lhsIdx < lhs.Len() && rhsIdx < rhs.Len() {
diff, _ := diff(conf, lhs.Index(lhsIdx).Interface(), rhs.Index(rhsIdx).Interface(), &visited{})
res = append(res, diff)
indices = append(indices, lhsIdx)
lhsIdx++
rhsIdx++
}
return res
return res, indices
}

func newMyersSlice(c config, lhs, rhs interface{}, visited *visited) (Differ, error) {
var diffs []Differ
var indices []int

lhsVal := reflect.ValueOf(lhs)
rhsVal := reflect.ValueOf(rhs)
Expand All @@ -91,25 +99,28 @@ func newMyersSlice(c config, lhs, rhs interface{}, visited *visited) (Differ, er
}
myers := myersdiff.Diff(lhsVal.Len(), rhsVal.Len(), &dData)

diffs = myersToDiff(c, lhsVal, rhsVal, myers)
diffs, indices = myersToDiff(c, lhsVal, rhsVal, myers)
if dData.lastError != nil {
return slice{
lhs: lhs,
rhs: rhs,
diffs: diffs,
lhs: lhs,
rhs: rhs,
diffs: diffs,
indices: indices,
}, dData.lastError
}
}

return slice{
lhs: lhs,
rhs: rhs,
diffs: diffs,
lhs: lhs,
rhs: rhs,
diffs: diffs,
indices: indices,
}, nil
}

func newSlice(c config, lhs, rhs interface{}, visited *visited) (Differ, error) {
var diffs []Differ
var indices []int

lhsVal := reflect.ValueOf(lhs)
rhsVal := reflect.ValueOf(rhs)
Expand All @@ -126,15 +137,17 @@ func newSlice(c config, lhs, rhs interface{}, visited *visited) (Differ, error)
}

for i := 0; i < nElems; i++ {
indices = append(indices, i)
if i < lhsVal.Len() && i < rhsVal.Len() {
diff, err := diff(c, lhsVal.Index(i).Interface(), rhsVal.Index(i).Interface(), visited)
diffs = append(diffs, diff)

if err != nil {
return slice{
lhs: lhs,
rhs: rhs,
diffs: diffs,
lhs: lhs,
rhs: rhs,
diffs: diffs,
indices: indices,
}, err
}
continue
Expand All @@ -148,9 +161,10 @@ func newSlice(c config, lhs, rhs interface{}, visited *visited) (Differ, error)
}

return slice{
lhs: lhs,
rhs: rhs,
diffs: diffs,
lhs: lhs,
rhs: rhs,
diffs: diffs,
indices: indices,
}, nil
}

Expand Down Expand Up @@ -247,7 +261,7 @@ func (s slice) openString(key, prefix string, conf Output) string {

func (s slice) Walk(path string, fn WalkFn) error {
for i, diff := range s.diffs {
d, err := walk(s, diff, path+"[]", fn)
d, err := walk(s, diff, path+"["+strconv.Itoa(s.lhsIndex(i))+"]", fn)
if err != nil {
return err
}
Expand All @@ -259,6 +273,10 @@ func (s slice) Walk(path string, fn WalkFn) error {
return nil
}

func (s slice) lhsIndex(i int) int {
return s.indices[i]
}

func (s slice) LHS() interface{} {
return s.lhs
}
Expand Down

0 comments on commit 74fcdd4

Please sign in to comment.