|
| 1 | +// |
| 2 | +// Copyright 2022 Cristian Maglie. All rights reserved. |
| 3 | +// Use of this source code is governed by a BSD-style |
| 4 | +// license that can be found in the LICENSE file. |
| 5 | +// |
| 6 | + |
| 7 | +package requirejson |
| 8 | + |
| 9 | +import ( |
| 10 | + "encoding/json" |
| 11 | + "fmt" |
| 12 | + "testing" |
| 13 | + |
| 14 | + "github.com/itchyny/gojq" |
| 15 | + "github.com/stretchr/testify/require" |
| 16 | +) |
| 17 | + |
| 18 | +// Query performs a test on a given json output. A jq-like query is performed |
| 19 | +// on the given jsonData and the result is compared with the expected output. |
| 20 | +// If the output doesn't match the test fails. If msgAndArgs are provided they |
| 21 | +// will be used to explain the error. |
| 22 | +func Query(t *testing.T, jsonData []byte, jqQuery string, jsonExpected string, msgAndArgs ...interface{}) { |
| 23 | + var data interface{} |
| 24 | + require.NoError(t, json.Unmarshal(jsonData, &data)) |
| 25 | + var expected interface{} |
| 26 | + require.NoError(t, json.Unmarshal([]byte(jsonExpected), &expected)) |
| 27 | + q, err := gojq.Parse(jqQuery) |
| 28 | + require.NoError(t, err) |
| 29 | + i := q.Run(data) |
| 30 | + v, ok := i.Next() |
| 31 | + require.True(t, ok) |
| 32 | + require.IsType(t, expected, v) |
| 33 | + require.Equal(t, expected, v, msgAndArgs...) |
| 34 | +} |
| 35 | + |
| 36 | +// Contains check if the json object is a subset of the jsonData. |
| 37 | +// If the output doesn't match the test fails. If msgAndArgs are provided they |
| 38 | +// will be used to explain the error. |
| 39 | +func Contains(t *testing.T, jsonData []byte, jsonObject string, msgAndArgs ...interface{}) { |
| 40 | + var data interface{} |
| 41 | + require.NoError(t, json.Unmarshal(jsonData, &data)) |
| 42 | + q, err := gojq.Parse("contains(" + jsonObject + ")") |
| 43 | + require.NoError(t, err) |
| 44 | + i := q.Run(data) |
| 45 | + v, ok := i.Next() |
| 46 | + require.True(t, ok) |
| 47 | + require.IsType(t, true, v) |
| 48 | + if !v.(bool) { |
| 49 | + msg := fmt.Sprintf("json data does not contain: %s", jsonObject) |
| 50 | + require.FailNow(t, msg, msgAndArgs...) |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +// NotContains check if the json object is NOT a subset of the jsonData. |
| 55 | +// If the output match the test fails. If msgAndArgs are provided they |
| 56 | +// will be used to explain the error. |
| 57 | +func NotContains(t *testing.T, jsonData []byte, jsonObject string, msgAndArgs ...interface{}) { |
| 58 | + var data interface{} |
| 59 | + require.NoError(t, json.Unmarshal(jsonData, &data)) |
| 60 | + q, err := gojq.Parse("contains(" + jsonObject + ")") |
| 61 | + require.NoError(t, err) |
| 62 | + i := q.Run(data) |
| 63 | + v, ok := i.Next() |
| 64 | + require.True(t, ok) |
| 65 | + require.IsType(t, true, v) |
| 66 | + if v.(bool) { |
| 67 | + msg := fmt.Sprintf("json data contains: %s", jsonObject) |
| 68 | + require.FailNow(t, msg, msgAndArgs...) |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +// Len check if the size of the json object match the given value. |
| 73 | +// If the lenght doesn't match the test fails. If msgAndArgs are provided they |
| 74 | +// will be used to explain the error. |
| 75 | +func Len(t *testing.T, jsonData []byte, expectedLen int, msgAndArgs ...interface{}) { |
| 76 | + var data interface{} |
| 77 | + require.NoError(t, json.Unmarshal(jsonData, &data)) |
| 78 | + q, err := gojq.Parse("length") |
| 79 | + require.NoError(t, err) |
| 80 | + i := q.Run(data) |
| 81 | + v, ok := i.Next() |
| 82 | + require.True(t, ok) |
| 83 | + require.IsType(t, expectedLen, v) |
| 84 | + if v.(int) != expectedLen { |
| 85 | + msg := fmt.Sprintf("json data length does not match: expected=%d, actual=%d", expectedLen, v.(int)) |
| 86 | + require.FailNow(t, msg, msgAndArgs...) |
| 87 | + } |
| 88 | +} |
| 89 | + |
| 90 | +// Empty check if the size of the json object is zero. |
| 91 | +// If the lenght is not zero the test fails. If msgAndArgs are provided they |
| 92 | +// will be used to explain the error. |
| 93 | +func Empty(t *testing.T, jsonData []byte, msgAndArgs ...interface{}) { |
| 94 | + var data interface{} |
| 95 | + require.NoError(t, json.Unmarshal(jsonData, &data)) |
| 96 | + q, err := gojq.Parse("length") |
| 97 | + require.NoError(t, err) |
| 98 | + i := q.Run(data) |
| 99 | + v, ok := i.Next() |
| 100 | + require.True(t, ok) |
| 101 | + require.IsType(t, 0, v) |
| 102 | + if v.(int) != 0 { |
| 103 | + require.FailNow(t, "json data is not empty", msgAndArgs...) |
| 104 | + } |
| 105 | +} |
| 106 | + |
| 107 | +// NotEmpty check if the size of the json object is greater than zero. |
| 108 | +// If the lenght is not greater than zero the test fails. If msgAndArgs are provided they |
| 109 | +// will be used to explain the error. |
| 110 | +func NotEmpty(t *testing.T, jsonData []byte, msgAndArgs ...interface{}) { |
| 111 | + var data interface{} |
| 112 | + require.NoError(t, json.Unmarshal(jsonData, &data)) |
| 113 | + q, err := gojq.Parse("length") |
| 114 | + require.NoError(t, err) |
| 115 | + i := q.Run(data) |
| 116 | + v, ok := i.Next() |
| 117 | + require.True(t, ok) |
| 118 | + require.IsType(t, 0, v) |
| 119 | + if v.(int) == 0 { |
| 120 | + require.FailNow(t, "json data is empty", msgAndArgs...) |
| 121 | + } |
| 122 | +} |
0 commit comments