yudai / gojsondiff

Go JSON Diff
Other
535 stars 81 forks source link

Identical JSON samples with nested arrays are sometimes identified as different #39

Open guscarreon opened 3 years ago

guscarreon commented 3 years ago

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.