diff --git a/README.md b/README.md index dba22ea..4906d5a 100644 --- a/README.md +++ b/README.md @@ -274,6 +274,10 @@ You can see more [examples](./examples/matchJSON_test.go#L96). - the filename where snapshots are stored - the snapshot file's extension (_regardless the extension the filename will include the `.snaps` inside the filename_) - programmatically control whether to update snapshots. _You can find an example usage at [examples](/examples/examples_test.go#13)_ +- json config's json format configuration: + - `Width`: The maximum width in characters before wrapping json output (default: 80) + - `Indent`: The indentation string to use for nested structures (default: 1 spaces) + - `SortKeys`: Whether to sort json object keys alphabetically (default: true) ```go t.Run("snapshot tests", func(t *testing.T) { @@ -283,7 +287,12 @@ t.Run("snapshot tests", func(t *testing.T) { snaps.Dir("my_dir"), snaps.Filename("json_file"), snaps.Ext(".json"), - snaps.Update(false) + snaps.Update(false), + snaps.JSON(snaps.JSONConfig{ + Width: 80, + Indent: " ", + SortKeys: false, + }), ) s.MatchJSON(t, `{"hello":"world"}`) diff --git a/examples/__snapshots__/TestMatchStandaloneJSON_should_create_a_prettyJSON_snap_following_by_config_1.snap.json b/examples/__snapshots__/TestMatchStandaloneJSON_should_create_a_prettyJSON_snap_following_by_config_1.snap.json new file mode 100755 index 0000000..cb72227 --- /dev/null +++ b/examples/__snapshots__/TestMatchStandaloneJSON_should_create_a_prettyJSON_snap_following_by_config_1.snap.json @@ -0,0 +1,5 @@ +{ + "user": "mock-user", + "age": 10, + "email": "mock@email.com" +} \ No newline at end of file diff --git a/examples/__snapshots__/TestMatchStandaloneJSON_should_create_a_prettyJSON_snap_following_by_config_2.snap.json b/examples/__snapshots__/TestMatchStandaloneJSON_should_create_a_prettyJSON_snap_following_by_config_2.snap.json new file mode 100755 index 0000000..cb72227 --- /dev/null +++ b/examples/__snapshots__/TestMatchStandaloneJSON_should_create_a_prettyJSON_snap_following_by_config_2.snap.json @@ -0,0 +1,5 @@ +{ + "user": "mock-user", + "age": 10, + "email": "mock@email.com" +} \ No newline at end of file diff --git a/examples/__snapshots__/matchJSON_test.snap b/examples/__snapshots__/matchJSON_test.snap index 48d0f8b..41798a1 100755 --- a/examples/__snapshots__/matchJSON_test.snap +++ b/examples/__snapshots__/matchJSON_test.snap @@ -100,3 +100,19 @@ "metadata": "" } --- + +[TestMatchJSON/should_create_a_prettyJSON_snap_following_by_config - 1] +{ + "user": "mock-user", + "age": 10, + "email": "mock@email.com" +} +--- + +[TestMatchJSON/should_create_a_prettyJSON_snap_following_by_config - 2] +{ + "user": "mock-user", + "age": 10, + "email": "mock@email.com" +} +--- diff --git a/examples/matchJSON_test.go b/examples/matchJSON_test.go index 5be6d32..ba2aa5f 100644 --- a/examples/matchJSON_test.go +++ b/examples/matchJSON_test.go @@ -91,6 +91,16 @@ func TestMatchJSON(t *testing.T) { snaps.MatchJSON(t, u) }) + + t.Run("should create a prettyJSON snap following by config", func(t *testing.T) { + value := `{"user":"mock-user","age":10,"email":"mock@email.com"}` + s := snaps.WithConfig(snaps.JSON(snaps.JSONConfig{ + Indent: " ", + SortKeys: false, + })) + s.MatchJSON(t, value) + s.MatchJSON(t, []byte(value)) + }) } func TestMatchers(t *testing.T) { diff --git a/examples/matchStandaloneJSON_test.go b/examples/matchStandaloneJSON_test.go index 1350d40..bee3838 100644 --- a/examples/matchStandaloneJSON_test.go +++ b/examples/matchStandaloneJSON_test.go @@ -43,6 +43,16 @@ func TestMatchStandaloneJSON(t *testing.T) { snaps.MatchStandaloneJSON(t, u) }) + t.Run("should create a prettyJSON snap following by config", func(t *testing.T) { + value := `{"user":"mock-user","age":10,"email":"mock@email.com"}` + s := snaps.WithConfig(snaps.JSON(snaps.JSONConfig{ + Indent: " ", + SortKeys: false, + })) + s.MatchStandaloneJSON(t, value) + s.MatchStandaloneJSON(t, []byte(value)) + }) + t.Run("matchers", func(t *testing.T) { t.Run("Custom matcher", func(t *testing.T) { t.Run("struct marshalling", func(t *testing.T) { diff --git a/snaps/matchJSON.go b/snaps/matchJSON.go index f451c78..3a40860 100644 --- a/snaps/matchJSON.go +++ b/snaps/matchJSON.go @@ -13,7 +13,7 @@ import ( ) var ( - jsonOptions = &pretty.Options{ + defaultPrettyJSONOptions = &pretty.Options{ SortKeys: true, Indent: " ", } @@ -97,7 +97,7 @@ func matchJSON(c *Config, t testingT, input any, matchers ...match.JSONMatcher) return } - snapshot := takeJSONSnapshot(j) + snapshot := takeJSONSnapshot(c, j) prevSnapshot, line, err := getPrevSnapshot(testID, snapPath) if errors.Is(err, errSnapNotFound) { if !shouldCreate(c.update) { @@ -159,8 +159,8 @@ func validateJSON(input any) ([]byte, error) { } } -func takeJSONSnapshot(b []byte) string { - return strings.TrimSuffix(string(pretty.PrettyOptions(b, jsonOptions)), "\n") +func takeJSONSnapshot(c *Config, b []byte) string { + return strings.TrimSuffix(string(pretty.PrettyOptions(b, c.json.getPrettyJSONOptions())), "\n") } func applyJSONMatchers(b []byte, matchers ...match.JSONMatcher) ([]byte, []match.MatcherError) { diff --git a/snaps/matchStandaloneJSON.go b/snaps/matchStandaloneJSON.go index 1c83794..701e81b 100644 --- a/snaps/matchStandaloneJSON.go +++ b/snaps/matchStandaloneJSON.go @@ -67,7 +67,7 @@ func matchStandaloneJSON(c *Config, t testingT, input any, matchers ...match.JSO return } - snapshot := takeJSONSnapshot(j) + snapshot := takeJSONSnapshot(c, j) prevSnapshot, err := getPrevStandaloneSnapshot(snapPath) if errors.Is(err, errSnapNotFound) { if !shouldCreate(c.update) { diff --git a/snaps/snapshot.go b/snaps/snapshot.go index 8001b6a..ee63b2c 100644 --- a/snaps/snapshot.go +++ b/snaps/snapshot.go @@ -11,6 +11,7 @@ import ( "sync" "github.com/gkampitakis/go-snaps/internal/colors" + "github.com/tidwall/pretty" ) var ( @@ -30,6 +31,30 @@ type Config struct { snapsDir string extension string update *bool + json *JSONConfig +} + +type JSONConfig struct { + // Width is a max column width for single line arrays + // Default: see defaultPrettyJSONOptions.Width for detail + Width int + // Indent is the nested indentation + // Default: see defaultPrettyJSONOptions.Indent for detail + Indent string + // SortKeys will sort the keys alphabetically + // Default: see defaultPrettyJSONOptions.SortKeys for detail + SortKeys bool +} + +func (j *JSONConfig) getPrettyJSONOptions() *pretty.Options { + if j == nil { + return defaultPrettyJSONOptions + } + return &pretty.Options{ + Width: j.Width, + Indent: j.Indent, + SortKeys: j.SortKeys, + } } // Update determines whether to update snapshots or not @@ -75,6 +100,15 @@ func Ext(ext string) func(*Config) { } } +// Specify json format configuration +// +// default: see defaultPrettyJSONOptions for default json config +func JSON(json JSONConfig) func(*Config) { + return func(c *Config) { + c.json = &json + } +} + // Create snaps with configuration // // e.g snaps.WithConfig(snaps.Filename("my_test")).MatchSnapshot(t, "hello world")