Skip to content

swaggest/assertjson

Repository files navigation

JSON assertions

Build Status Coverage Status GoDevDoc time tracker

This library extends awesome github.com/stretchr/testify/assert with nice JSON equality assertions built with github.com/yudai/gojsondiff.

Also it provides JSON marshaler with compact indentation.

Usage

Default comparer is set up to ignore difference against "<ignore-diff>" values. It is accessible with package functions Equal and EqualMarshal.

package my_test

import (
	"testing"

	"github.com/swaggest/assertjson"
)

func Test(t *testing.T) {
	assertjson.Equal(t,
		[]byte(`{"a": [1, {"val": "<ignore-diff>"}, 3], "b": 2, "c": 3}`),
		[]byte(`{"a": [1, {"val": 123}, 3], "c": 2, "b": 3}`),
	)

	// Output:
	// Error Trace:	....
	//	Error:      	Not equal:
	//	            	 {
	//	            	   "a": [
	//	            	     1,
	//	            	     {
	//	            	       "val": "<ignore-diff>"
	//	            	     },
	//	            	     3
	//	            	   ],
	//	            	-  "b": 2,
	//	            	+  "b": 3,
	//	            	-  "c": 3
	//	            	+  "c": 2
	//	            	 }
}

Custom Comparer can be created and used to control ignore behavior and formatter options.

Variables

Custom Comparer also supports shared.Vars to collect or check variables. This can be helpful in case of asserting equality of dynamic data in different payloads.

v := &shared.Vars{}
v.Set("$varB", []int{1, 2, 3})
v.Set("$varC", "abc")

// Properties "b" and "c" are checked against values defined in vars.
// Properties "a" and "d" are not checked, but their values are assigned to missing vars.
expected := []byte(`{"a": "$varA", "b": "$varB", "c": "$varC", "d": "$varD"}`)
actual := []byte(`{"a": 1.23, "b": [1, 2, 3], "c": "abc", "d": 4}`)

c := assertjson.Comparer{Vars: v}

c.Equal(t, expected, actual)

Variable reference should look like double quote enclosed name of variable, e.g. "$var1".

  • Variables that were set before JSON comparison will be used by their value in equality check.
  • Variables that were not set before JSON comparison will be assigned with values from actual JSON, equality check will be skipped.

Compact Indentation

Often json.MarshalIndent produces result, that is not easy to comprehend due to high count of lines that requires massive scrolling effort to read.

This library provides an alternative assertjson.MarshalIndentCompact which keeps indentation and line breaks only for major part of JSON document, while compacting smaller pieces.

j, err := assertjson.MarshalIndentCompact(v, "", "  ", 100) // 100 is line width limit.
{
  "openapi":"3.0.2","info":{"title":"","version":""},
  "paths":{
    "/test/{in-path}":{
      "post":{
        "summary":"Title","description":"","operationId":"name",
        "x-some-array":[
          "abc","def",123456,7890123456,[],{"foo":"bar"},
          "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!"
        ],
        "parameters":[
          {"name":"in_query","in":"query","schema":{"type":"integer"}},
          {"name":"in-path","in":"path","required":true,"schema":{"type":"boolean"}},
          {"name":"in_cookie","in":"cookie","schema":{"type":"number"}},
          {"name":"X-In-Header","in":"header","schema":{"type":"string"}}
        ],
        "requestBody":{
          "content":{
            "application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/FormDataOpenapiTestInput"}}
          }
        },
        "responses":{"200":{"description":"OK","content":{"application/json":{"schema":{}}}}},
        "deprecated":true
      }
    }
  },
  "components":{
    "schemas":{"FormDataOpenapiTestInput":{"type":"object","properties":{"in_form_data":{"type":"string"}}}}
  }
}

CLI Tool

Available as jsoncompact CLI tool.

go get github.com/swaggest/assertjson/cmd/jsoncompact

You can invoke the tool against one or more JSON files, for example:

jsoncompact some-*.json path/to/another/*.json

Or paste JSON into stdin.

jsoncompact -

Additional flags.

Usage of jsoncompact:
  -indent string
        Set indent. (default " ")
  -len int
        Line length limit. (default 100)
  -output string
        Path to output json file, if not specified input file is used.
  -prefix string
        Set prefix.
  -v    Verbose mode.
  -version
        Print version and exit.