1use crate::expect_op;
2use crate::ops::expect_array::ExpectArraySubOp;
3use crate::Context;
4use crate::ExpectOp;
5use crate::ExpectOpResult;
6use crate::JsonType;
7use serde_json::Value;
8use std::fmt::Debug;
9
10#[expect_op(internal, name = "array")]
11#[derive(Debug, Clone, Default, PartialEq)]
12pub struct ExpectArray {
13 sub_ops: Vec<ExpectArraySubOp>,
14}
15
16impl ExpectArray {
17 pub(crate) fn new() -> Self {
18 Self { sub_ops: vec![] }
19 }
20
21 pub fn is_empty(mut self) -> Self {
22 self.sub_ops.push(ExpectArraySubOp::IsEmpty);
23 self
24 }
25
26 pub fn is_not_empty(mut self) -> Self {
27 self.sub_ops.push(ExpectArraySubOp::IsNotEmpty);
28 self
29 }
30
31 pub fn min_len(mut self, min_len: usize) -> Self {
32 self.sub_ops.push(ExpectArraySubOp::MinLen(min_len));
33 self
34 }
35
36 pub fn len(mut self, len: usize) -> Self {
37 self.sub_ops.push(ExpectArraySubOp::Len(len));
38 self
39 }
40
41 pub fn max_len(mut self, max_len: usize) -> Self {
42 self.sub_ops.push(ExpectArraySubOp::MaxLen(max_len));
43 self
44 }
45
46 pub fn contains<I, V>(mut self, expected_values: I) -> Self
47 where
48 I: IntoIterator<Item = V>,
49 V: Into<Value>,
50 {
51 let inner_expected_values = expected_values
52 .into_iter()
53 .map(Into::into)
54 .collect::<Vec<_>>();
55 self.sub_ops
56 .push(ExpectArraySubOp::Contains(inner_expected_values));
57 self
58 }
59
60 pub fn all<V>(mut self, expected: V) -> Self
92 where
93 V: Into<Value>,
94 {
95 self.sub_ops
96 .push(ExpectArraySubOp::AllEqual(expected.into()));
97 self
98 }
99
100 pub fn unique(mut self) -> Self {
129 self.sub_ops.push(ExpectArraySubOp::AllUnique);
130 self
131 }
132}
133
134impl ExpectOp for ExpectArray {
135 fn on_array(&self, context: &mut Context, received: &[Value]) -> ExpectOpResult<()> {
136 for sub_op in &self.sub_ops {
137 sub_op.on_array(self, context, received)?;
138 }
139
140 Ok(())
141 }
142
143 fn supported_types(&self) -> &'static [JsonType] {
144 &[JsonType::Array]
145 }
146}
147
148#[cfg(test)]
149mod test_contains {
150 use crate::expect;
151 use crate::expect_json_eq;
152 use pretty_assertions::assert_eq;
153 use serde_json::json;
154
155 #[test]
156 fn it_should_be_equal_for_identical_numeric_arrays() {
157 let left = json!([1, 2, 3]);
158 let right = json!(expect::array().contains([1, 2, 3]));
159
160 let output = expect_json_eq(&left, &right);
161 assert!(output.is_ok());
162 }
163
164 #[test]
165 fn it_should_be_equal_for_reversed_identical_numeric_arrays() {
166 let left = json!([1, 2, 3]);
167 let right = json!(expect::array().contains([3, 2, 1]));
168
169 let output = expect_json_eq(&left, &right);
170 assert!(output.is_ok());
171 }
172
173 #[test]
174 fn it_should_be_equal_for_partial_contains() {
175 let left = json!([0, 1, 2, 3, 4, 5]);
176 let right = json!(expect::array().contains([1, 2, 3]));
177
178 let output = expect_json_eq(&left, &right);
179 assert!(output.is_ok());
180 }
181
182 #[test]
183 fn it_should_error_for_totall_different_values() {
184 let left = json!([0, 1, 2, 3]);
185 let right = json!(expect::array().contains([4, 5, 6]));
186
187 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
188 assert_eq!(
189 output,
190 r#"Json array at root does not contain expected value:
191 expected array to contain 4, but it was not found.
192 received [0, 1, 2, 3]"#
193 );
194 }
195
196 #[test]
197 fn it_should_be_ok_for_empty_contains() {
198 let left = json!([0, 1, 2, 3]);
199 let right = json!(expect::array().contains([] as [u32; 0]));
200
201 let output = expect_json_eq(&left, &right);
202 assert!(output.is_ok());
203 }
204
205 #[test]
206 fn it_should_error_if_used_against_the_wrong_type() {
207 let left = json!("🦊");
208 let right = json!(expect::array().contains([4, 5, 6]));
209
210 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
211 assert_eq!(
212 output,
213 r#"Json expect::array() at root, received wrong type:
214 expected array
215 received string "🦊""#
216 );
217 }
218
219 #[test]
220 fn it_should_handle_nested_contains() {
221 let left = json!([
222 {
223 "text": "Hello",
224 "author": "Jane Candle"
225 },
226 {
227 "text": "Goodbye",
228 "author": "John Lighthouse"
229 }
230 ]);
231
232 let right = json!(expect::array().contains([json!({
233 "text": "Hello",
234 "author": expect::string().contains("Jane"),
235 }),]));
236
237 let output = expect_json_eq(&left, &right);
238 assert!(output.is_ok(), "{}", output.unwrap_err().to_string());
239 }
240}
241
242#[cfg(test)]
243mod test_is_empty {
244 use crate::expect;
245 use crate::expect_json_eq;
246 use pretty_assertions::assert_eq;
247 use serde_json::json;
248
249 #[test]
250 fn it_should_pass_when_array_is_empty() {
251 let left = json!([]);
252 let right = json!(expect::array().is_empty());
253
254 let output = expect_json_eq(&left, &right);
255 assert!(output.is_ok(), "assertion error: {output:#?}");
256 }
257
258 #[test]
259 fn it_should_fail_when_array_is_not_empty() {
260 let left = json!([1, 2, 3]);
261 let right = json!(expect::array().is_empty());
262
263 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
264 assert_eq!(
265 output,
266 format!(
267 r#"Json expect::array() error at root:
268 expected empty array
269 received [1, 2, 3]"#
270 )
271 );
272 }
273}
274
275#[cfg(test)]
276mod test_is_not_empty {
277 use crate::expect;
278 use crate::expect_json_eq;
279 use pretty_assertions::assert_eq;
280 use serde_json::json;
281
282 #[test]
283 fn it_should_pass_when_array_is_not_empty() {
284 let left = json!([1]);
285 let right = json!(expect::array().is_not_empty());
286
287 let output = expect_json_eq(&left, &right);
288 assert!(output.is_ok(), "assertion error: {output:#?}");
289 }
290
291 #[test]
292 fn it_should_fail_when_array_is_empty() {
293 let left = json!([]);
294 let right = json!(expect::array().is_not_empty());
295
296 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
297 assert_eq!(
298 output,
299 format!(
300 r#"Json expect::array() error at root:
301 expected non-empty array
302 received []"#
303 )
304 );
305 }
306}
307
308#[cfg(test)]
309mod test_min_len {
310 use crate::expect;
311 use crate::expect_json_eq;
312 use pretty_assertions::assert_eq;
313 use serde_json::json;
314
315 #[test]
316 fn it_should_pass_when_array_has_exactly_enough_elements() {
317 let left = json!([1, 2, 3]);
318 let right = json!(expect::array().min_len(3));
319
320 let output = expect_json_eq(&left, &right);
321 assert!(output.is_ok(), "assertion error: {output:#?}");
322 }
323
324 #[test]
325 fn it_should_pass_when_array_has_more_than_enough_elements() {
326 let left = json!([1, 2, 3, 4, 5]);
327 let right = json!(expect::array().min_len(3));
328
329 let output = expect_json_eq(&left, &right);
330 assert!(output.is_ok(), "assertion error: {output:#?}");
331 }
332
333 #[test]
334 fn it_should_fail_when_array_has_too_few_elements() {
335 let left = json!([1, 2, 3]);
336 let right = json!(expect::array().min_len(4));
337
338 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
339 assert_eq!(
340 output,
341 format!(
342 r#"Json expect::array() error at root:
343 expected array to have at least 4 elements, but it has 3.
344 received [1, 2, 3]"#
345 )
346 );
347 }
348}
349
350#[cfg(test)]
351mod test_len {
352 use crate::expect;
353 use crate::expect_json_eq;
354 use pretty_assertions::assert_eq;
355 use serde_json::json;
356
357 #[test]
358 fn it_should_pass_when_array_has_exactly_enough_elements() {
359 let left = json!([1, 2, 3]);
360 let right = json!(expect::array().len(3));
361
362 let output = expect_json_eq(&left, &right);
363 assert!(output.is_ok(), "assertion error: {output:#?}");
364 }
365
366 #[test]
367 fn it_should_fail_when_array_has_more_than_enough_elements() {
368 let left = json!([1, 2, 3, 4, 5]);
369 let right = json!(expect::array().len(3));
370
371 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
372 assert_eq!(
373 output,
374 format!(
375 r#"Json expect::array() error at root:
376 expected array to have 3 elements, but it has 5.
377 received [1, 2, 3, 4, 5]"#
378 )
379 );
380 }
381
382 #[test]
383 fn it_should_fail_when_array_has_too_few_elements() {
384 let left = json!([1, 2, 3]);
385 let right = json!(expect::array().len(4));
386
387 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
388 assert_eq!(
389 output,
390 format!(
391 r#"Json expect::array() error at root:
392 expected array to have 4 elements, but it has 3.
393 received [1, 2, 3]"#
394 )
395 );
396 }
397}
398
399#[cfg(test)]
400mod test_max_len {
401 use crate::expect;
402 use crate::expect_json_eq;
403 use pretty_assertions::assert_eq;
404 use serde_json::json;
405
406 #[test]
407 fn it_should_pass_when_array_has_exactly_enough_elements() {
408 let left = json!([1, 2, 3]);
409 let right = json!(expect::array().max_len(3));
410
411 let output = expect_json_eq(&left, &right);
412 assert!(output.is_ok(), "assertion error: {output:#?}");
413 }
414
415 #[test]
416 fn it_should_pass_when_array_has_less_than_enough_elements() {
417 let left = json!([1, 2]);
418 let right = json!(expect::array().max_len(6));
419
420 let output = expect_json_eq(&left, &right);
421 assert!(output.is_ok(), "assertion error: {output:#?}");
422 }
423
424 #[test]
425 fn it_should_fail_when_array_has_too_few_elements() {
426 let left = json!([1, 2, 3, 4]);
427 let right = json!(expect::array().max_len(3));
428
429 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
430 assert_eq!(
431 output,
432 format!(
433 r#"Json expect::array() error at root:
434 expected array to have at most 3 elements, but it has 4.
435 received [1, 2, 3, 4]"#
436 )
437 );
438 }
439}
440
441#[cfg(test)]
442mod test_all {
443 use crate::expect;
444 use crate::expect_json_eq;
445 use pretty_assertions::assert_eq;
446 use serde_json::json;
447
448 #[test]
449 fn it_should_pass_when_array_is_empty() {
450 let left = json!([]);
451 let right = json!(expect::array().all(expect::string()));
452
453 let output = expect_json_eq(&left, &right);
454 assert!(output.is_ok(), "assertion error: {output:#?}");
455 }
456
457 #[test]
458 fn it_should_pass_with_mix_of_operations() {
459 let left = json!([
460 "123e4567-e89b-12d3-a456-426614174000",
461 "123e4567-e89b-12d3-a456-426614174001",
462 "123e4567-e89b-12d3-a456-426614174002",
463 ]);
464 let right = json!(expect::array().all(expect::uuid()).len(3).unique());
465
466 let output = expect_json_eq(&left, &right);
467 assert!(output.is_ok(), "assertion error: {output:#?}");
468 }
469
470 #[test]
471 fn it_should_fail_with_mix_of_operations() {
472 let left = json!([
473 "123e4567-e89b-12d3-a456-426614174000",
474 "123e4567-e89b-12d3-a456-426614174001",
475 "123e4567-e89b-12d3-a456-426614174002",
476 "123e4567-e89b-12d3-a456-426614174003",
477 ]);
478 let right = json!(expect::array().all(expect::uuid()).len(3).unique());
479
480 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
481 assert_eq!(
482 output,
483 format!(
484 r#"Json expect::array() error at root:
485 expected array to have 3 elements, but it has 4.
486 received ["123e4567-e89b-12d3-a456-426614174000", "123e4567-e89b-12d3-a456-426614174001", "123e4567-e89b-12d3-a456-426614174002", "123e4567-e89b-12d3-a456-426614174003"]"#
487 )
488 );
489 }
490
491 #[test]
492 fn it_should_fail_when_array_values_do_not_match_expect_op() {
493 let left = json!([1, 2, 3]);
494 let right = json!(expect::array().all(expect::string()));
495
496 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
497 assert_eq!(
498 output,
499 format!(
500 r#"Json expect::string() at root[0], received wrong type:
501 expected string
502 received integer 1
503 received full array [1, 2, 3]"#
504 )
505 );
506 }
507
508 #[test]
509 fn it_should_fail_when_array_values_do_not_match_values() {
510 let left = json!([1, 2, 3]);
511 let right = json!(expect::array().all("🦊"));
512
513 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
514 assert_eq!(
515 output,
516 format!(
517 r#"Json values at root[0] are different types:
518 expected string "🦊"
519 received integer 1
520 received full array [1, 2, 3]"#
521 )
522 );
523 }
524
525 #[test]
526 fn it_should_pass_when_array_values_do_match_expect_op() {
527 let left = json!(["alice@example.com", "bob@example.com"]);
528 let right = json!(expect::array().all(expect::email()));
529
530 let output = expect_json_eq(&left, &right);
531 assert!(output.is_ok(), "assertion error: {output:#?}");
532 }
533
534 #[test]
535 fn it_should_pass_when_array_values_do_match_values() {
536 let left = json!([1, 1, 1]);
537 let right = json!(expect::array().all(1));
538
539 let output = expect_json_eq(&left, &right);
540 assert!(output.is_ok(), "assertion error: {output:#?}");
541 }
542
543 #[test]
544 fn it_should_pass_when_array_values_do_match_complex_objects() {
545 let left = json!([
546 {
547 "name": "Alice Candles",
548 "email": "alice@example.com"
549 },
550 {
551 "name": "Bob Kettles",
552 "email": "bob@example.com"
553 },
554 ]);
555
556 let right = json!(expect::array().all(json!({
557 "name": expect::string().is_not_empty(),
558 "email": expect::email(),
559 })));
560
561 let output = expect_json_eq(&left, &right);
562 assert!(output.is_ok(), "assertion error: {output:#?}");
563 }
564
565 #[test]
566 fn it_should_not_pass_when_array_values_do_not_match_complex_objects() {
567 let left = json!([
568 {
569 "name": "Alice Candles",
570 "email": "alice@example.com"
571 },
572 {
573 "name": "",
574 "email": "bob@example.com"
575 },
576 ]);
577
578 let right = json!(expect::array().all(json!({
579 "name": expect::string().is_not_empty(),
580 "email": expect::email(),
581 })));
582
583 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
584 assert_eq!(
585 output,
586 format!(
587 r#"Json expect::string() error at root[1].name:
588 expected non-empty string
589 received ""
590 received full array [
591 {{
592 "email": "alice@example.com",
593 "name": "Alice Candles"
594 }},
595 {{
596 "email": "bob@example.com",
597 "name": ""
598 }}
599 ]"#
600 )
601 );
602 }
603}
604
605#[cfg(test)]
606mod test_unique {
607 use crate::expect;
608 use crate::expect_json_eq;
609 use pretty_assertions::assert_eq;
610 use serde_json::json;
611
612 #[test]
613 fn it_should_pass_when_array_is_empty() {
614 let left = json!([]);
615 let right = json!(expect::array().unique());
616
617 let output = expect_json_eq(&left, &right);
618 assert!(output.is_ok(), "assertion error: {output:#?}");
619 }
620
621 #[test]
622 fn it_should_fail_when_array_is_not_unique() {
623 let left = json!([1, 1, 2]);
624 let right = json!(expect::array().unique());
625
626 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
627 assert_eq!(
628 output,
629 format!(
630 r#"Json expect::array() error at root[1],
631 expected array to contain all unique values.
632 found duplicate 1
633 received full array [1, 1, 2]"#
634 )
635 );
636 }
637}