diffator

package module
v0.0.0-...-18c353d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 14, 2024 License: Apache-2.0 Imports: 8 Imported by: 1

README

go-diffator

Diffator is a Go package to provide a difference string for comparing during testing.

Diffator does NOT output a standard format diff but is instead is optimized for a developer to recognize the difference between a value they want in their test compared with the value they got in their test, where want==expected and got==actual.

Usage

Diffator (currently) offers two (2) types of comparisons:

  1. String-to-string comparison
  2. Object-to-object comparison
Usage for String-to-string comparison
result := diffator.CompareStrings(string1, string2, nil)
println(result)
result := diffator.CompareStrings(string1,string2,&diffator.StringOpts{
  MinSubstrLen: diffator.Int(3),
})
println(result)
c := NewStringComparator(v1, v2, nil)
result := c.Compare()
println(result)
c := NewStringComparator(v1, v2, &diffator.StringOpts{
  MinSubstrLen: diffator.Int(3),
})
result := c.Compare()
println(result)

To understand diffator.Int(3), see Nillable Option Values.

Diff Output
// Assuming:
string1 := "ABC"
string2 := ""

// Result: "<(ABC/)>"
// Assuming:
string1 := ""
string2 := "ABC"

// Result: "<(/ABC)>"
// Assuming:
string1 := "ABC"
string2 := "XYZ"

// Result: "<(ABC/XYZ)>"
// Assuming:
string1 := "ABCDEF"
string2 := "ABCDXYZ"

// Result: "ABCD<(EF/XYZ)>"
// Assuming:
string1 := "ABCDXYZ"
string2 := "123XYZ"

// Result: "<(ABCD/123)>XYZ"
// Assuming:
string1 := "ABCDEF123GHI456JKLMNOP"
string2 := "ABCDEFGHIJKLMNOP"
opts := &StringOpts{
  MatchingPadLen: diffator.Int(5),
  MinSubstrLen:   diffator.Int(2),
}
// Result: "BCDEF<(123/)>GHI<(456/)>JKLMN"
// Assuming:
string1 := "Look, it's Batman!!!"
string2 := "Look, it's Superman!!!"

// Result: "Look, it's <(Bat/Super)>man!!!"
Usage for Object-to-object comparison
result := diffator.CompareObjects(value1, value2, nil)
println(result)
result := diffator.CompareObjects(value1,value2,&diffator.ObjectOpts{
  OutputFormat: diffator.String("Diff: %s"),
})
println(result)
c := NewObjectComparator(v1, v2, nil)
result := c.Compare()
println(result)
c := NewObjectComparator(v1, v2, &diffator.ObjectOpts{
  OutputFormat: diffator.String("Diff: %s"),
})
result := c.Compare()
println(result)

To understand diffator.String("Diff: %s"), see Nillable Option Values.

Diff Output
// Assuming:
value1 := 100
value2 := 99

// Result: (100!=99)
// Assuming:
type TestStruct struct {
	Int    int
	String string
}
value1 := &TestStruct{}
value2 := &TestStruct{
  Int:    1,
  String: "hello",
}

// Result: *TestStruct{Int:(0!=1),String:(!=hello),}
// Assuming:
value1 := map[string]int{"Foo": 1, "Bar": 2, "Baz": 3}
value2 := map[string]int{"Foo": 1, "Bar": 20, "Baz": 3}

// Result: map[string]int{Bar:(2!=20),}
// Assuming:
value1 := map[string]int{"Foo": 1, "Bar": 2, "Baz": 3, "Superman": 0}
value2 := map[string]int{"Foo": 10, "Bar": 20, "Baz": 30, "Batman": 0}

// Result: map[string]int{Bar:(2!=20),Baz:(3!=30),Foo:(1!=10),Superman:<missing:expected>,Batman:<missing:actual>,}

Note that the above is without ObjectOps.PrettyPrint := true.

Nillable Option Values

We decided that in order to allow for setting of default values for StringOpts and ObjectOpts we would use values of *diffator.IntValue, *diffator.BoolValue, *diffator.StringValue instead of int, bool, and string, respectively.

To set the values, use the object constructors diffator.Int(), diffator.Bool(), and diffator.String(), respectively.

To see example usage, visit the Usage sections, above.

Status

In active use, but only addresses those data types that the author has needed to address his use-case.

If you would like to use this and you find it generates a panic for an unimplemented type, pull requests are accepted and appreciated.

License

Apache 2.0

Documentation

Index

Constants

View Source
const LeftRightFormat = "<(%s/%s)>"

LeftRightFormat is default format used to format the differences found by `CompareStrings()` inline within the output string, would be the formatted when comparing these two (2) strings with the default format below:

Left String:    "this shows left content inline"
Right String:   "this shows right content inline"
Compare Output: "this shows (left/right) content inline"
View Source
const MinSubstrLen = 3

MinSubstrLen is the default length of a "common substring" as defined by being longer than 3 characters and not being a space.

Variables

This section is empty.

Functions

func CompareObjects

func CompareObjects(v1, v2 any, opts *ObjectOpts) string

func CompareStrings

func CompareStrings(s1, s2 string, opts *StringOpts) (s string)

func Equivalent

func Equivalent(v1, v2 any) (same bool)

func ReflectorsToNameString

func ReflectorsToNameString[S ~[]E, E any](in S) (names string)

func SliceReduceFunc

func SliceReduceFunc[S ~[]E, E any, R any](s S, f func(any, R) R) (r R)

func SortReflectValues

func SortReflectValues(rvs []reflect.Value) []reflect.Value

func SortedMapKeys

func SortedMapKeys(a any) (keys []reflect.Value)

Types

type BoolValue

type BoolValue struct {
	Value bool
}

BoolValue enables a nil length, so we can set defaults on nil

func Bool

func Bool(b bool) *BoolValue

type Comparator

type Comparator interface {
	Compare() string
}

type Diffator

type Diffator struct {
	Comparator
}

func NewDiffator

func NewDiffator(c Comparator) *Diffator

type IntValue

type IntValue struct {
	Value int
}

IntValue enables a nil length, so we can set defaults on nil

func Int

func Int(n int) *IntValue

type ObjectComparator

type ObjectComparator struct {
	// contains filtered or unexported fields
}

func NewObjectComparator

func NewObjectComparator(v1, v2 any, opts *ObjectOpts) *ObjectComparator

func (*ObjectComparator) Compare

func (o *ObjectComparator) Compare() string

func (*ObjectComparator) ReflectValuesDiff

func (o *ObjectComparator) ReflectValuesDiff(rv1, rv2 *reflect.Value, format string) (diff string)

type ObjectOpts

type ObjectOpts struct {
	LevelIndent  *StringValue
	OutputFormat *StringValue
	PrettyPrint  *BoolValue
	CompareFuncs bool
	FormatFunc   func(reflect.Type, any) string
}

func (*ObjectOpts) SetDefaults

func (opts *ObjectOpts) SetDefaults()

type Reflector

type Reflector struct {
	*reflect.Value
	// contains filtered or unexported fields
}

func NewReflector

func NewReflector(value any) *Reflector

func NewReflectorFromValue

func NewReflectorFromValue(rv *reflect.Value) *Reflector

func (*Reflector) Any

func (r *Reflector) Any() any

func (*Reflector) AsAny

func (r *Reflector) AsAny(rv *reflect.Value) (a any)

func (*Reflector) AsString

func (r *Reflector) AsString(rv *reflect.Value) (s string)

func (*Reflector) Child

func (r *Reflector) Child() *reflect.Value

func (*Reflector) ChildOf

func (r *Reflector) ChildOf(rv *reflect.Value) (c *reflect.Value)

func (*Reflector) String

func (r *Reflector) String() (s string)

func (*Reflector) Typename

func (r *Reflector) Typename() string

func (*Reflector) TypenameOf

func (r *Reflector) TypenameOf(rv *reflect.Value) (n string)

type StringComparator

type StringComparator struct {
	// contains filtered or unexported fields
}

func NewStringComparator

func NewStringComparator(s1, s2 string, opts *StringOpts) *StringComparator

func (*StringComparator) Compare

func (c *StringComparator) Compare() (s string)

func (StringComparator) Fixer

func (StringComparator) Fixer()

func (*StringComparator) Opts

func (c *StringComparator) Opts() *StringOpts

func (StringComparator) String

func (t StringComparator) String() string

type StringOpts

type StringOpts struct {
	MatchingPadLen  *IntValue
	MinSubstrLen    *IntValue
	LeftRightFormat *StringValue
}

func (*StringOpts) SetDefaults

func (opts *StringOpts) SetDefaults()

type StringValue

type StringValue struct {
	Value string
}

StringValue enables a nil length so we can set defaults on nil

func String

func String(s string) *StringValue

type Tracker

type Tracker struct {
	SortedKeys []reflect.Value
	// contains filtered or unexported fields
}

func NewTracker

func NewTracker() *Tracker

func NewTrackerWithKeys

func NewTrackerWithKeys(rv *reflect.Value) *Tracker

NewTrackerWithKeys returns sorted map keys as a slice, and a ValueIdTracker for the Value

func (*Tracker) Delete

func (vId *Tracker) Delete(id ValueId)

func (*Tracker) HaveSeen

func (vId *Tracker) HaveSeen(rv *reflect.Value) (seen bool, id ValueId)

func (*Tracker) HaveSeenId

func (vId *Tracker) HaveSeenId(id ValueId) (seen bool)

func (*Tracker) Pop

func (vId *Tracker) Pop(id ValueId)

func (*Tracker) Push

func (vId *Tracker) Push(rv *reflect.Value) (seen bool, id ValueId)

func (*Tracker) Seen

func (vId *Tracker) Seen() (seen ValueIdMap)

func (*Tracker) SetSeen

func (vId *Tracker) SetSeen(seen ValueIdMap)

type ValueId

type ValueId struct {
	reflect.Type
	// contains filtered or unexported fields
}

ValueId is used to compare the source value for original pointers

func NewValueId

func NewValueId(rv *reflect.Value) (id ValueId)

NewValueId returns a comparable struct for any reflect type.

type ValueIdMap

type ValueIdMap map[ValueId]struct{}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL