gojsondiff icon indicating copy to clipboard operation
gojsondiff copied to clipboard

Identical JSON samples with nested arrays are sometimes identified as different

Open guscarreon opened this issue 4 years ago • 0 comments

A Json test in our codebase sometimes fails and sometimes passes. This is probably due to the nested struct arrays root.seatbid[i].bid[j] because the same thing happens with another JSON test in our repo.

╰─➤  go test
--- FAIL: TestJsonSampleRequests (1.94s)
    auction_test.go:123: sample-requests/valid-whole/exemplary/all-ext.json json did not match expected.

         {
           "bidid": "test bid id",
           "id": "some-request-id",
           "nbr": 0,
           "seatbid": [
             0: {
               "bid": [
                 1: {
                   "id": "rubicon-bid",
                   "impid": "",
                   "price": 0
                 },
                 2: {
                   "id": "appnexus-bid",
                   "impid": "",
                   "price": 0
                 },
               ],
               "seat": "seat-id"
             }
           ]
         }
+--  6 lines: E0925 15:09:33.730896   -----------------------------------------------------
FAIL
exit status 1
FAIL    github.com/prebid/prebid-server/endpoints/openrtb2      3.215s

But if we are lucky we get:

╰─➤  go test
+--  5 lines: E0925 15:16:30.083508   -----------------------------------------------------
PASS
ok      github.com/prebid/prebid-server/endpoints/openrtb2      3.318s

In summary, this is the test that I've been using:

func diffJson(t *testing.T, description string, actual []byte, expected []byte) {
	t.Helper()
	diff, err := gojsondiff.New().Compare(actual, expected)
	if err != nil {
		t.Fatalf("%s json diff failed. %v", description, err)
	}

	if diff.Modified() {
		var left interface{}
		if err := json.Unmarshal(actual, &left); err != nil {
			t.Fatalf("%s json did not match, but unmarshalling failed. %v", description, err)
		}
		printer := formatter.NewAsciiFormatter(left, formatter.AsciiFormatterConfig{
			ShowArrayIndex: true,
		})
		output, err := printer.Format(diff)
		if err != nil {
			t.Errorf("%s did not match, but diff formatting failed. %v", description, err)
		} else {
			t.Errorf("%s json did not match expected.\n\n%s", description, output)
		}
	}
}

And these are the actual (left) and expected (right):

 1 {                                    |  1  {
 2   "id": "some-request-id",           |  2   "id": "some-request-id",
 3   "seatbid": [                       |  3   "seatbid": [
 4     {                                |  4     {
 5       "bid": [                       |  5       "bid": [
 6         {                            |  6         {
 7           "id": "appnexus-bid",      |  7           "id": "appnexus-bid",
 8           "impid": "",               |  8           "impid": "",
 9           "price": 0                 |  9           "price": 0
10         }                            | 10         }
11       ],                             | 11       ],
12       "seat": "seat-id"              | 12       "seat": "seat-id"
13     }                                | 13     }
14   ],                                 | 14   ],
15   "bidid": "test bid id",            | 15   "bidid": "test bid id",
16   "nbr": 0                           | 16   "nbr": 0
17 }                                    | 17 }

I'm using the latest version.

guscarreon avatar Sep 28 '20 14:09 guscarreon