@@ -29,7 +29,7 @@ func TestAssertf(t *testing.T) {
2929 "strings" : {`"hello world"` , `"hello world"` , nil },
3030 } {
3131 tc := tc
32- t .Run (name , func (t * testing.T ) { tc .check (t ) })
32+ t .Run (name , func (t * testing.T ) { tc .checkAssertf (t ) })
3333 }
3434 })
3535
@@ -45,7 +45,7 @@ func TestAssertf(t *testing.T) {
4545 "empty v non-empty string" : {`""` , `"world"` , []string {`expected string at '$' to be 'world' but was ''` }},
4646 } {
4747 tc := tc
48- t .Run (name , func (t * testing.T ) { tc .check (t ) })
48+ t .Run (name , func (t * testing.T ) { tc .checkAssertf (t ) })
4949 }
5050 })
5151 })
@@ -83,7 +83,7 @@ func TestAssertf(t *testing.T) {
8383 },
8484 } {
8585 tc := tc
86- t .Run (name , func (t * testing.T ) { tc .check (t ) })
86+ t .Run (name , func (t * testing.T ) { tc .checkAssertf (t ) })
8787 }
8888 })
8989
@@ -113,7 +113,7 @@ func TestAssertf(t *testing.T) {
113113 },
114114 } {
115115 tc := tc
116- t .Run (name , func (t * testing.T ) { tc .check (t ) })
116+ t .Run (name , func (t * testing.T ) { tc .checkAssertf (t ) })
117117 }
118118 })
119119
@@ -152,7 +152,7 @@ func TestAssertf(t *testing.T) {
152152 },
153153 } {
154154 tc := tc
155- t .Run (name , func (t * testing.T ) { tc .check (t ) })
155+ t .Run (name , func (t * testing.T ) { tc .checkAssertf (t ) })
156156 }
157157 })
158158 })
@@ -196,17 +196,14 @@ but expected JSON was:
196196 `["world"]` ,
197197 []string {`expected string at '$[0]' to be 'world' but was 'hello'` },
198198 },
199- "different length non-empty arrays" : {
199+ "identical non-empty unsorted arrays" : {
200200 `["hello", "world"]` ,
201- `["world"]` ,
202- []string {
203- `length of arrays at '$' were different. Expected array to be of length 1, but contained 2 element(s)` ,
204- `actual JSON at '$' was: ["hello","world"], but expected JSON was: ["world"]` ,
205- },
201+ `["<<UNORDERED>>", "world", "hello"]` ,
202+ []string {},
206203 },
207204 } {
208205 tc := tc
209- t .Run (name , func (t * testing.T ) { tc .check (t ) })
206+ t .Run (name , func (t * testing.T ) { tc .checkAssertf (t ) })
210207 }
211208 })
212209
@@ -248,7 +245,7 @@ but expected JSON was:
248245 },
249246 } {
250247 tc := tc
251- t .Run (name , func (t * testing.T ) { tc .check (t ) })
248+ t .Run (name , func (t * testing.T ) { tc .checkAssertf (t ) })
252249 }
253250 })
254251
@@ -314,7 +311,7 @@ but expected JSON was:
314311 },
315312 } {
316313 tc := tc
317- t .Run (name , func (t * testing.T ) { tc .check (t ) })
314+ t .Run (name , func (t * testing.T ) { tc .checkAssertf (t ) })
318315 }
319316 })
320317 })
@@ -346,7 +343,7 @@ potentially in a different order`,
346343 },
347344 } {
348345 tc := tc
349- t .Run (name , func (t * testing.T ) { tc .check (t ) })
346+ t .Run (name , func (t * testing.T ) { tc .checkAssertf (t ) })
350347 }
351348 })
352349
@@ -449,20 +446,96 @@ but was
449446was missing from actual payload` ,
450447 },
451448 }
452- tc .check (t )
449+ tc .checkAssertf (t )
453450 })
454451}
455452
453+ func TestContainsf (t * testing.T ) {
454+ t .Parallel ()
455+ tt := map [string ]* testCase {
456+ "actual not valid json" : {
457+ `foo` ,
458+ `"foo"` ,
459+ []string {`'actual' JSON is not valid JSON: unable to identify JSON type of "foo"` },
460+ },
461+ "expected not valid json" : {`"foo"` , `foo` , []string {`'expected' JSON is not valid JSON: unable to identify JSON type of "foo"` }},
462+ "number contains a number" : {`5` , `5` , nil },
463+ "number does not contain a different number" : {`5` , `-2` , []string {"expected number at '$' to be '-2.0000000' but was '5.0000000'" }},
464+ "string contains a string" : {`"foo"` , `"foo"` , nil },
465+ "string does not contain a different string" : {`"foo"` , `"bar"` , []string {"expected string at '$' to be 'bar' but was 'foo'" }},
466+ "boolean contains a boolean" : {`true` , `true` , nil },
467+ "boolean does not contain a different boolean" : {`true` , `false` , []string {"expected boolean at '$' to be false but was true" }},
468+ "empty array contains empty array" : {`[]` , `[]` , nil },
469+ "single-element array contains empty array" : {`["fish"]` , `[]` , nil },
470+ "unordered empty array contains empty array" : {`[]` , `["<<UNORDERED>>"]` , nil },
471+ "unordered single-element array contains empty array" : {`["fish"]` , `["<<UNORDERED>>"]` , nil },
472+ "empty array contains single-element array" : {`[]` , `["fish"]` , []string {"length of expected array at '$' was longer (length 1) than the actual array (length 0)" , `actual JSON at '$' was: [], but expected JSON to contain: ["fish"]` }},
473+ "unordered multi-element array contains subset" : {`["alpha", "beta", "gamma"]` , `["<<UNORDERED>>", "beta", "alpha"]` , nil },
474+ "unordered multi-element array does not contain single element" : {`["alpha", "beta", "gamma"]` , `["<<UNORDERED>>", "delta", "alpha"]` , []string {
475+ `element at $[1] in the expected payload was not found anywhere in the actual JSON array:
476+ "delta"
477+ not found in
478+ ["alpha","beta","gamma"]` ,
479+ }},
480+ "unordered multi-element array contains none of multi-element array" : {`["alpha", "beta", "gamma"]` , `["<<UNORDERED>>", "delta", "pi", "omega"]` , []string {
481+ `element at $[1] in the expected payload was not found anywhere in the actual JSON array:
482+ "delta"
483+ not found in
484+ ["alpha","beta","gamma"]` ,
485+ `element at $[2] in the expected payload was not found anywhere in the actual JSON array:
486+ "pi"
487+ not found in
488+ ["alpha","beta","gamma"]` ,
489+ `element at $[3] in the expected payload was not found anywhere in the actual JSON array:
490+ "omega"
491+ not found in
492+ ["alpha","beta","gamma"]` ,
493+ }},
494+ "multi-element array contains itself" : {`["alpha", "beta"]` , `["alpha", "beta"]` , nil },
495+ "multi-element array does not contain itself permuted" : {`["alpha", "beta"]` , `["beta" ,"alpha"]` , []string {
496+ "expected string at '$[0]' to be 'beta' but was 'alpha'" ,
497+ "expected string at '$[1]' to be 'alpha' but was 'beta'" ,
498+ }},
499+ // Allow users to test against a subset of the payload without erroring out.
500+ // This is to avoid the frustraion and unintuitive solution of adding "<<UNORDERED>>" in order to "enable" subsetting,
501+ // which is really implied with the `contains` part of the API name.
502+ "multi-element array does contain its subset" : {`["alpha", "beta"]` , `["alpha"]` , []string {}},
503+ "multi-element array does not contain its superset" : {`["alpha", "beta"]` , `["alpha", "beta", "gamma"]` , []string {"length of expected array at '$' was longer (length 3) than the actual array (length 2)" , `actual JSON at '$' was: ["alpha","beta"], but expected JSON to contain: ["alpha","beta","gamma"]` }},
504+ "expected and actual have different types" : {`{"foo": "bar"}` , `null` , []string {"actual JSON (object) and expected JSON (null) were of different types at '$'" }},
505+ "expected any value but got null" : {`{"foo": null}` , `{"foo": "<<PRESENCE>>"}` , []string {"expected the presence of any value at '$.foo', but was absent" }},
506+ "unordered multi-element array of different types contains subset" : {`["alpha", 5, false, ["foo"], {"bar": "baz"}]` , `["<<UNORDERED>>", 5, "alpha", {"bar": "baz"}]` , nil },
507+ "object contains its subset" : {`{"foo": "bar", "alpha": "omega"}` , `{"alpha": "omega"}` , nil },
508+ }
509+ for name , tc := range tt {
510+ tc := tc
511+ t .Run (name , func (t * testing.T ) {
512+ t .Parallel ()
513+ tc .checkContainsf (t )
514+ })
515+ }
516+ }
517+
456518type testCase struct {
457519 act , exp string
458520 msgs []string
459521}
460522
461- func (tc * testCase ) check (t * testing.T ) {
523+ func (tc * testCase ) checkContainsf (t * testing.T ) {
524+ t .Helper ()
525+ tp := & testPrinter {messages : nil }
526+ jsonassert .New (tp ).Containsf (tc .act , tc .exp )
527+ tc .check (t , tp )
528+ }
529+
530+ func (tc * testCase ) checkAssertf (t * testing.T ) {
462531 t .Helper ()
463532 tp := & testPrinter {messages : nil }
464533 jsonassert .New (tp ).Assertf (tc .act , tc .exp )
534+ tc .check (t , tp )
535+ }
465536
537+ func (tc * testCase ) check (t * testing.T , tp * testPrinter ) {
538+ t .Helper ()
466539 if got := len (tp .messages ); got != len (tc .msgs ) {
467540 t .Errorf ("expected %d assertion message(s) but got %d" , len (tc .msgs ), got )
468541 }
0 commit comments