Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"sort"
"strconv"
"strings"
"time"
)

var (
Expand Down Expand Up @@ -40,6 +41,9 @@ type Options struct {
// when it's safe. This is useful for diffing two structures, where pointer variables would cause
// false changes. However, circular graphs are still detected and elided to avoid infinite output.
DisablePointerReplacement bool

// FormatTime, if true, will format [time.Time] values.
FormatTime bool
}

// Config is the default config used when calling Dump
Expand All @@ -59,6 +63,7 @@ type dumpState struct {
parentPointers ptrmap
currentPointer *ptrinfo
homePackageRegexp *regexp.Regexp
timeFormatter func(t time.Time) string
}

func (s *dumpState) write(b []byte) {
Expand Down Expand Up @@ -129,6 +134,12 @@ func (s *dumpState) dumpSlice(v reflect.Value) {
}

func (s *dumpState) dumpStruct(v reflect.Value) {
val := v.Interface()
if t, ok := val.(time.Time); ok && s.timeFormatter != nil {
s.writeString(s.timeFormatter(t))
return
}

dumpPreamble := func() {
s.dumpType(v)
s.write([]byte("{"))
Expand Down Expand Up @@ -246,7 +257,6 @@ func (s *dumpState) dumpChan(v reflect.Value) {
}

func (s *dumpState) dumpCustom(v reflect.Value, buf *bytes.Buffer) {

// Dump the type
s.dumpType(v)

Expand Down Expand Up @@ -293,6 +303,8 @@ func (s *dumpState) dump(value interface{}) {
s.dumpVal(v)
}

var dumperType = reflect.TypeOf((*Dumper)(nil)).Elem()

func (s *dumpState) descendIntoPossiblePointer(value reflect.Value, f func()) {
canonicalize := true
if isPointerValue(value) {
Expand Down Expand Up @@ -345,7 +357,6 @@ func (s *dumpState) dumpVal(value reflect.Value) {
}

// Handle custom dumpers
dumperType := reflect.TypeOf((*Dumper)(nil)).Elem()
if v.Type().Implements(dumperType) {
s.descendIntoPossiblePointer(v, func() {
// Run the custom dumper buffering the output
Expand Down Expand Up @@ -464,6 +475,16 @@ func newDumpState(value reflect.Value, options *Options, writer io.Writer) *dump
w: writer,
}

if options.FormatTime {
result.timeFormatter = func(t time.Time) string {
t = t.In(time.UTC)
return fmt.Sprintf(
`time.Date(%d, %d, %d, %d, %d, %d, %d, time.UTC)`,
t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(),
)
}
}

if options.HomePackage != "" {
result.homePackageRegexp = regexp.MustCompile(fmt.Sprintf("\\b%s\\.", options.HomePackage))
}
Expand Down
28 changes: 19 additions & 9 deletions dump_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
package litter_test

import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"reflect"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/sanity-io/litter"
)

func Function(arg1 string, arg2 int) (string, error) {
func Function(string, int) (string, error) {
return "", nil
}

Expand Down Expand Up @@ -163,6 +164,7 @@ func TestSdump_config(t *testing.T) {
(func(v IntAlias) *IntAlias { return &v })(20),
litter.Dump,
func(s string, i int) (bool, error) { return false, nil },
time.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
}

runTestWithCfg(t, "config_Compact", &litter.Options{
Expand Down Expand Up @@ -204,6 +206,9 @@ func TestSdump_config(t *testing.T) {
return false
},
}, data)
runTestWithCfg(t, "config_FormatTime", &litter.Options{
FormatTime: true,
}, data)

basic := &BasicStruct{1, 2}
runTestWithCfg(t, "config_DisablePointerReplacement_simpleReusedStruct", &litter.Options{
Expand Down Expand Up @@ -238,7 +243,7 @@ func TestSdump_maps(t *testing.T) {
2: "two",
},
map[int]*BlankStruct{
2: &BlankStruct{},
2: {},
},
})
}
Expand All @@ -263,16 +268,19 @@ var standardCfg = litter.Options{}
func runTestWithCfg(t *testing.T, name string, cfg *litter.Options, cases ...interface{}) {
t.Run(name, func(t *testing.T) {
fileName := fmt.Sprintf("testdata/%s.dump", name)

dump := cfg.Sdump(cases...)
reference, err := ioutil.ReadFile(fileName)

reference, err := os.ReadFile(fileName)
if os.IsNotExist(err) {
t.Logf("Note: Test data file %s does not exist, writing it; verify contents!", fileName)
err := ioutil.WriteFile(fileName, []byte(dump), 0644)
err := os.WriteFile(fileName, []byte(dump), 0644)
if err != nil {
t.Error(err)
}
return
}

assertEqualStringsWithDiff(t, string(reference), dump)
})
}
Expand All @@ -286,17 +294,19 @@ func diffStrings(t *testing.T, expected, actual string) (*string, bool) {
return nil, true
}

dir, err := ioutil.TempDir("", "test")
dir, err := os.MkdirTemp("", "test")
require.NoError(t, err)
defer os.RemoveAll(dir)

require.NoError(t, ioutil.WriteFile(fmt.Sprintf("%s/expected", dir), []byte(expected), 0644))
require.NoError(t, ioutil.WriteFile(fmt.Sprintf("%s/actual", dir), []byte(actual), 0644))
require.NoError(t, os.WriteFile(fmt.Sprintf("%s/expected", dir), []byte(expected), 0644))
require.NoError(t, os.WriteFile(fmt.Sprintf("%s/actual", dir), []byte(actual), 0644))

out, err := exec.Command("diff", "--side-by-side",
fmt.Sprintf("%s/expected", dir),
fmt.Sprintf("%s/actual", dir)).Output()
if _, ok := err.(*exec.ExitError); !ok {

var exitErr *exec.ExitError
if !errors.As(err, &exitErr) {
require.NoError(t, err)
}

Expand Down
2 changes: 1 addition & 1 deletion testdata/config_Compact.dump
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[]interface{}{litter_test.options{Compact:false,StripPackageNames:false,HidePrivateFields:true,HomePackage:"",Separator:" ",StrictGo:false},&litter_test.BasicStruct{Public:1,private:2},litter_test.Function,&20,&20,litter.Dump,func(string,int)(bool,error)}
[]interface{}{litter_test.options{Compact:false,StripPackageNames:false,HidePrivateFields:true,HomePackage:"",Separator:" ",StrictGo:false},&litter_test.BasicStruct{Public:1,private:2},litter_test.Function,&20,&20,litter.Dump,func(string,int)(bool,error),time.Time{wall:0,ext:63650361600,loc:nil}}
5 changes: 5 additions & 0 deletions testdata/config_DumpFunc.dump
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@
&20,
litter.Dump,
func(string, int) (bool, error),
time.Time{
wall: 0,
ext: 63650361600,
loc: nil,
},
}
1 change: 1 addition & 0 deletions testdata/config_FieldFilter.dump
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
&20,
litter.Dump,
func(string, int) (bool, error),
time.Time{},
}
20 changes: 20 additions & 0 deletions testdata/config_FormatTime.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[]interface {}{
litter_test.options{
Compact: false,
StripPackageNames: false,
HidePrivateFields: true,
HomePackage: "",
Separator: " ",
StrictGo: false,
},
&litter_test.BasicStruct{
Public: 1,
private: 2,
},
litter_test.Function,
&20,
&20,
litter.Dump,
func(string, int) (bool, error),
time.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC),
}
1 change: 1 addition & 0 deletions testdata/config_HidePrivateFields.dump
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
&20,
litter.Dump,
func(string, int) (bool, error),
time.Time{},
}
4 changes: 4 additions & 0 deletions testdata/config_HideZeroValues.dump
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@
&20,
litter.Dump,
func(string, int) (bool, error),
time.Time{
wall: 0,
ext: 63650361600,
},
}
5 changes: 5 additions & 0 deletions testdata/config_HomePackage.dump
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@
&20,
litter.Dump,
func(string, int) (bool, error),
time.Time{
wall: 0,
ext: 63650361600,
loc: nil,
},
}
5 changes: 5 additions & 0 deletions testdata/config_StrictGo.dump
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@
(func(v litter_test.IntAlias) *litter_test.IntAlias { return &v })(20),
litter.Dump,
func(string, int) (bool, error),
time.Time{
wall: 0,
ext: 63650361600,
loc: nil,
},
}
5 changes: 5 additions & 0 deletions testdata/config_StripPackageNames.dump
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@
&20,
Dump,
func(string, int) (bool, error),
Time{
wall: 0,
ext: 63650361600,
loc: nil,
},
}