1 use std::iter::FromIterator;
2
3 use snapbox::assert_data_eq;
4 use snapbox::prelude::*;
5 use snapbox::str;
6 use toml_edit::{array, table, value, DocumentMut, Item, Key, Table, Value};
7
8 macro_rules! parse_key {
9 ($s:expr) => {{
10 let key = $s.parse::<Key>();
11 assert!(key.is_ok());
12 key.unwrap()
13 }};
14 }
15
16 macro_rules! as_table {
17 ($e:ident) => {{
18 assert!($e.is_table());
19 $e.as_table_mut().unwrap()
20 }};
21 }
22
23 struct Test {
24 doc: DocumentMut,
25 }
26
given(input: &str) -> Test27 fn given(input: &str) -> Test {
28 let doc = input.parse::<DocumentMut>();
29 assert!(doc.is_ok());
30 Test { doc: doc.unwrap() }
31 }
32
33 impl Test {
running<F>(&mut self, func: F) -> &mut Self where F: Fn(&mut Table),34 fn running<F>(&mut self, func: F) -> &mut Self
35 where
36 F: Fn(&mut Table),
37 {
38 {
39 let root = self.doc.as_table_mut();
40 func(root);
41 }
42 self
43 }
running_on_doc<F>(&mut self, func: F) -> &mut Self where F: Fn(&mut DocumentMut),44 fn running_on_doc<F>(&mut self, func: F) -> &mut Self
45 where
46 F: Fn(&mut DocumentMut),
47 {
48 {
49 func(&mut self.doc);
50 }
51 self
52 }
53
54 #[track_caller]
produces_display(&self, expected: snapbox::data::Inline) -> &Self55 fn produces_display(&self, expected: snapbox::data::Inline) -> &Self {
56 assert_data_eq!(self.doc.to_string(), expected.raw());
57 self
58 }
59 }
60
61 #[test]
test_add_root_decor()62 fn test_add_root_decor() {
63 given(
64 r#"[package]
65 name = "hello"
66 version = "1.0.0"
67
68 [[bin]]
69 name = "world"
70 path = "src/bin/world/main.rs"
71
72 [dependencies]
73 nom = "4.0" # future is here
74
75 [[bin]]
76 name = "delete me please"
77 path = "src/bin/dmp/main.rs""#,
78 )
79 .running_on_doc(|document| {
80 document.decor_mut().set_prefix("# Some Header\n\n");
81 document.decor_mut().set_suffix("# Some Footer");
82 document.set_trailing("\n\ntrailing...");
83 })
84 .produces_display(str![[r#"
85 # Some Header
86
87 [package]
88 name = "hello"
89 version = "1.0.0"
90
91 [[bin]]
92 name = "world"
93 path = "src/bin/world/main.rs"
94
95 [dependencies]
96 nom = "4.0" # future is here
97
98 [[bin]]
99 name = "delete me please"
100 path = "src/bin/dmp/main.rs"
101 # Some Footer
102
103 trailing...
104 "#]]);
105 }
106
107 /// Tests that default decor is None for both suffix and prefix and that this means empty strings
108 #[test]
test_no_root_decor()109 fn test_no_root_decor() {
110 given(
111 r#"[package]
112 name = "hello"
113 version = "1.0.0"
114
115 [[bin]]
116 name = "world"
117 path = "src/bin/world/main.rs"
118
119 [dependencies]
120 nom = "4.0" # future is here
121
122 [[bin]]
123 name = "delete me please"
124 path = "src/bin/dmp/main.rs""#,
125 )
126 .running_on_doc(|document| {
127 assert!(document.decor().prefix().is_none());
128 assert!(document.decor().suffix().is_none());
129 document.set_trailing("\n\ntrailing...");
130 })
131 .produces_display(str![[r#"
132 [package]
133 name = "hello"
134 version = "1.0.0"
135
136 [[bin]]
137 name = "world"
138 path = "src/bin/world/main.rs"
139
140 [dependencies]
141 nom = "4.0" # future is here
142
143 [[bin]]
144 name = "delete me please"
145 path = "src/bin/dmp/main.rs"
146
147
148 trailing...
149 "#]]);
150 }
151
152 // insertion
153
154 #[test]
test_insert_leaf_table()155 fn test_insert_leaf_table() {
156 given(
157 r#"[servers]
158
159 [servers.alpha]
160 ip = "10.0.0.1"
161 dc = "eqdc10"
162
163 [other.table]"#,
164 )
165 .running(|root| {
166 root["servers"]["beta"] = table();
167 root["servers"]["beta"]["ip"] = value("10.0.0.2");
168 root["servers"]["beta"]["dc"] = value("eqdc10");
169 })
170 .produces_display(str![[r#"
171 [servers]
172
173 [servers.alpha]
174 ip = "10.0.0.1"
175 dc = "eqdc10"
176
177 [servers.beta]
178 ip = "10.0.0.2"
179 dc = "eqdc10"
180
181 [other.table]
182
183 "#]]);
184 }
185
186 #[test]
test_inserted_leaf_table_goes_after_last_sibling()187 fn test_inserted_leaf_table_goes_after_last_sibling() {
188 given(
189 r#"
190 [package]
191 [dependencies]
192 [[example]]
193 [dependencies.opencl]
194 [dev-dependencies]"#,
195 )
196 .running(|root| {
197 root["dependencies"]["newthing"] = table();
198 })
199 .produces_display(str![[r#"
200
201 [package]
202 [dependencies]
203 [[example]]
204 [dependencies.opencl]
205
206 [dependencies.newthing]
207 [dev-dependencies]
208
209 "#]]);
210 }
211
212 #[test]
test_inserting_tables_from_different_parsed_docs()213 fn test_inserting_tables_from_different_parsed_docs() {
214 given("[a]")
215 .running(|root| {
216 let other = "[b]".parse::<DocumentMut>().unwrap();
217 root["b"] = other["b"].clone();
218 })
219 .produces_display(str![[r#"
220 [a]
221 [b]
222
223 "#]]);
224 }
225 #[test]
test_insert_nonleaf_table()226 fn test_insert_nonleaf_table() {
227 given(
228 r#"
229 [other.table]"#,
230 )
231 .running(|root| {
232 root["servers"] = table();
233 root["servers"]["alpha"] = table();
234 root["servers"]["alpha"]["ip"] = value("10.0.0.1");
235 root["servers"]["alpha"]["dc"] = value("eqdc10");
236 })
237 .produces_display(str![[r#"
238
239 [other.table]
240
241 [servers]
242
243 [servers.alpha]
244 ip = "10.0.0.1"
245 dc = "eqdc10"
246
247 "#]]);
248 }
249
250 #[test]
test_insert_array()251 fn test_insert_array() {
252 given(
253 r#"
254 [package]
255 title = "withoutarray""#,
256 )
257 .running(|root| {
258 root["bin"] = array();
259 assert!(root["bin"].is_array_of_tables());
260 let array = root["bin"].as_array_of_tables_mut().unwrap();
261 {
262 let mut table = Table::new();
263 table["hello"] = value("world");
264 array.push(table);
265 }
266 array.push(Table::new());
267 })
268 .produces_display(str![[r#"
269
270 [package]
271 title = "withoutarray"
272
273 [[bin]]
274 hello = "world"
275
276 [[bin]]
277
278 "#]]);
279 }
280
281 #[test]
test_insert_values()282 fn test_insert_values() {
283 given(
284 r#"
285 [tbl.son]"#,
286 )
287 .running(|root| {
288 root["tbl"]["key1"] = value("value1");
289 root["tbl"]["key2"] = value(42);
290 root["tbl"]["key3"] = value(8.1415926);
291 })
292 .produces_display(str![[r#"
293 [tbl]
294 key1 = "value1"
295 key2 = 42
296 key3 = 8.1415926
297
298 [tbl.son]
299
300 "#]]);
301 }
302
303 #[test]
test_insert_key_with_quotes()304 fn test_insert_key_with_quotes() {
305 given(
306 r#"
307 [package]
308 name = "foo"
309
310 [target]
311 "#,
312 )
313 .running(|root| {
314 root["target"]["cfg(target_os = \"linux\")"] = table();
315 root["target"]["cfg(target_os = \"linux\")"]["dependencies"] = table();
316 root["target"]["cfg(target_os = \"linux\")"]["dependencies"]["name"] = value("dep");
317 })
318 .produces_display(str![[r#"
319
320 [package]
321 name = "foo"
322
323 [target]
324
325 [target.'cfg(target_os = "linux")']
326
327 [target.'cfg(target_os = "linux")'.dependencies]
328 name = "dep"
329
330 "#]]);
331 }
332
333 // removal
334
335 #[test]
test_remove_leaf_table()336 fn test_remove_leaf_table() {
337 given(
338 r#"
339 [servers]
340
341 # Indentation (tabs and/or spaces) is allowed but not required
342 [servers.alpha]
343 ip = "10.0.0.1"
344 dc = "eqdc10"
345
346 [servers.beta]
347 ip = "10.0.0.2"
348 dc = "eqdc10""#,
349 )
350 .running(|root| {
351 let servers = root.get_mut("servers").unwrap();
352 let servers = as_table!(servers);
353 assert!(servers.remove("alpha").is_some());
354 })
355 .produces_display(str![[r#"
356
357 [servers]
358
359 [servers.beta]
360 ip = "10.0.0.2"
361 dc = "eqdc10"
362
363 "#]]);
364 }
365
366 #[test]
test_remove_nonleaf_table()367 fn test_remove_nonleaf_table() {
368 given(
369 r#"
370 title = "not relevant"
371
372 # comment 1
373 [a.b.c] # comment 1.1
374 key1 = 1 # comment 1.2
375 # comment 2
376 [b] # comment 2.1
377 key2 = 2 # comment 2.2
378
379 # comment 3
380 [a] # comment 3.1
381 key3 = 3 # comment 3.2
382 [[a.'array']]
383 b = 1
384
385 [[a.b.c.trololololololo]] # ohohohohoho
386 c = 2
387 key3 = 42
388
389 # comment on some other table
390 [some.other.table]
391
392
393
394
395 # comment 4
396 [a.b] # comment 4.1
397 key4 = 4 # comment 4.2
398 key41 = 41 # comment 4.3
399
400
401 "#,
402 )
403 .running(|root| {
404 assert!(root.remove("a").is_some());
405 })
406 .produces_display(str![[r#"
407
408 title = "not relevant"
409 # comment 2
410 [b] # comment 2.1
411 key2 = 2 # comment 2.2
412
413 # comment on some other table
414 [some.other.table]
415
416
417 "#]]);
418 }
419
420 #[test]
test_remove_array_entry()421 fn test_remove_array_entry() {
422 given(
423 r#"
424 [package]
425 name = "hello"
426 version = "1.0.0"
427
428 [[bin]]
429 name = "world"
430 path = "src/bin/world/main.rs"
431
432 [dependencies]
433 nom = "4.0" # future is here
434
435 [[bin]]
436 name = "delete me please"
437 path = "src/bin/dmp/main.rs""#,
438 )
439 .running(|root| {
440 let dmp = root.get_mut("bin").unwrap();
441 assert!(dmp.is_array_of_tables());
442 let dmp = dmp.as_array_of_tables_mut().unwrap();
443 assert_eq!(dmp.len(), 2);
444 dmp.remove(1);
445 assert_eq!(dmp.len(), 1);
446 })
447 .produces_display(str![[r#"
448
449 [package]
450 name = "hello"
451 version = "1.0.0"
452
453 [[bin]]
454 name = "world"
455 path = "src/bin/world/main.rs"
456
457 [dependencies]
458 nom = "4.0" # future is here
459
460 "#]]);
461 }
462
463 #[test]
test_remove_array()464 fn test_remove_array() {
465 given(
466 r#"
467 [package]
468 name = "hello"
469 version = "1.0.0"
470
471 [[bin]]
472 name = "world"
473 path = "src/bin/world/main.rs"
474
475 [dependencies]
476 nom = "4.0" # future is here
477
478 [[bin]]
479 name = "delete me please"
480 path = "src/bin/dmp/main.rs""#,
481 )
482 .running(|root| {
483 assert!(root.remove("bin").is_some());
484 })
485 .produces_display(str![[r#"
486
487 [package]
488 name = "hello"
489 version = "1.0.0"
490
491 [dependencies]
492 nom = "4.0" # future is here
493
494 "#]]);
495 }
496
497 #[test]
test_remove_value()498 fn test_remove_value() {
499 given(
500 r#"
501 name = "hello"
502 # delete this
503 version = "1.0.0" # please
504 documentation = "https://docs.rs/hello""#,
505 )
506 .running(|root| {
507 let value = root.remove("version");
508 assert!(value.is_some());
509 let value = value.unwrap();
510 assert!(value.is_value());
511 let value = value.as_value().unwrap();
512 assert!(value.is_str());
513 let value = value.as_str().unwrap();
514 assert_data_eq!(value, str!["1.0.0"].raw());
515 })
516 .produces_display(str![[r#"
517
518 name = "hello"
519 documentation = "https://docs.rs/hello"
520
521 "#]]);
522 }
523
524 #[test]
test_remove_last_value_from_implicit()525 fn test_remove_last_value_from_implicit() {
526 given(
527 r#"
528 [a]
529 b = 1"#,
530 )
531 .running(|root| {
532 let a = root.get_mut("a").unwrap();
533 assert!(a.is_table());
534 let a = as_table!(a);
535 a.set_implicit(true);
536 let value = a.remove("b");
537 assert!(value.is_some());
538 let value = value.unwrap();
539 assert!(value.is_value());
540 let value = value.as_value().unwrap();
541 assert_eq!(value.as_integer(), Some(1));
542 })
543 .produces_display(str![]);
544 }
545
546 // values
547
548 #[test]
test_sort_values()549 fn test_sort_values() {
550 given(
551 r#"
552 [a.z]
553
554 [a]
555 # this comment is attached to b
556 b = 2 # as well as this
557 a = 1
558 c = 3
559
560 [a.y]"#,
561 )
562 .running(|root| {
563 let a = root.get_mut("a").unwrap();
564 let a = as_table!(a);
565 a.sort_values();
566 })
567 .produces_display(str![[r#"
568
569 [a.z]
570
571 [a]
572 a = 1
573 # this comment is attached to b
574 b = 2 # as well as this
575 c = 3
576
577 [a.y]
578
579 "#]]);
580 }
581
582 #[test]
test_sort_values_by()583 fn test_sort_values_by() {
584 given(
585 r#"
586 [a.z]
587
588 [a]
589 # this comment is attached to b
590 b = 2 # as well as this
591 a = 1
592 "c" = 3
593
594 [a.y]"#,
595 )
596 .running(|root| {
597 let a = root.get_mut("a").unwrap();
598 let a = as_table!(a);
599 // Sort by the representation, not the value. So "\"c\"" sorts before "a" because '"' sorts
600 // before 'a'.
601 a.sort_values_by(|k1, _, k2, _| k1.display_repr().cmp(&k2.display_repr()));
602 })
603 .produces_display(str![[r#"
604
605 [a.z]
606
607 [a]
608 "c" = 3
609 a = 1
610 # this comment is attached to b
611 b = 2 # as well as this
612
613 [a.y]
614
615 "#]]);
616 }
617
618 #[test]
test_set_position()619 fn test_set_position() {
620 given(
621 r#"
622 [package]
623 [dependencies]
624 [dependencies.opencl]
625 [dev-dependencies]"#,
626 )
627 .running(|root| {
628 for (header, table) in root.iter_mut() {
629 if header == "dependencies" {
630 let tab = as_table!(table);
631 tab.set_position(0);
632 let (_, segmented) = tab.iter_mut().next().unwrap();
633 as_table!(segmented).set_position(5);
634 }
635 }
636 })
637 .produces_display(str![[r#"
638 [dependencies]
639
640 [package]
641 [dev-dependencies]
642 [dependencies.opencl]
643
644 "#]]);
645 }
646
647 #[test]
test_multiple_zero_positions()648 fn test_multiple_zero_positions() {
649 given(
650 r#"
651 [package]
652 [dependencies]
653 [dependencies.opencl]
654 a=""
655 [dev-dependencies]"#,
656 )
657 .running(|root| {
658 for (_, table) in root.iter_mut() {
659 as_table!(table).set_position(0);
660 }
661 })
662 .produces_display(str![[r#"
663
664 [package]
665 [dependencies]
666 [dev-dependencies]
667 [dependencies.opencl]
668 a=""
669
670 "#]]);
671 }
672
673 #[test]
test_multiple_max_usize_positions()674 fn test_multiple_max_usize_positions() {
675 given(
676 r#"
677 [package]
678 [dependencies]
679 [dependencies.opencl]
680 a=""
681 [dev-dependencies]"#,
682 )
683 .running(|root| {
684 for (_, table) in root.iter_mut() {
685 as_table!(table).set_position(usize::MAX);
686 }
687 })
688 .produces_display(str![[r#"
689 [dependencies.opencl]
690 a=""
691
692 [package]
693 [dependencies]
694 [dev-dependencies]
695
696 "#]]);
697 }
698
699 macro_rules! as_array {
700 ($entry:ident) => {{
701 assert!($entry.is_value());
702 let a = $entry.as_value_mut().unwrap();
703 assert!(a.is_array());
704 a.as_array_mut().unwrap()
705 }};
706 }
707
708 #[test]
test_insert_replace_into_array()709 fn test_insert_replace_into_array() {
710 given(
711 r#"
712 a = [1,2,3]
713 b = []"#,
714 )
715 .running(|root| {
716 {
717 let a = root.get_mut("a").unwrap();
718 let a = as_array!(a);
719 assert_eq!(a.len(), 3);
720 assert!(a.get(2).is_some());
721 a.push(4);
722 assert_eq!(a.len(), 4);
723 a.fmt();
724 }
725 let b = root.get_mut("b").unwrap();
726 let b = as_array!(b);
727 assert!(b.is_empty());
728 b.push("hello");
729 assert_eq!(b.len(), 1);
730
731 b.push_formatted(Value::from("world").decorated("\n", "\n"));
732 b.push_formatted(Value::from("test").decorated("", ""));
733
734 b.insert(1, "beep");
735 b.insert_formatted(2, Value::from("boop").decorated(" ", " "));
736
737 // This should preserve formatting.
738 assert_eq!(b.replace(2, "zoink").as_str(), Some("boop"));
739 // This should replace formatting.
740 assert_eq!(
741 b.replace_formatted(4, Value::from("yikes").decorated(" ", ""))
742 .as_str(),
743 Some("test")
744 );
745 dbg!(root);
746 })
747 .produces_display(str![[r#"
748
749 a = [1, 2, 3, 4]
750 b = ["hello", "beep", "zoink" ,
751 "world"
752 , "yikes"]
753
754 "#]]);
755 }
756
757 #[test]
test_remove_from_array()758 fn test_remove_from_array() {
759 given(
760 r#"
761 a = [1, 2, 3, 4]
762 b = ["hello"]"#,
763 )
764 .running(|root| {
765 {
766 let a = root.get_mut("a").unwrap();
767 let a = as_array!(a);
768 assert_eq!(a.len(), 4);
769 assert!(a.remove(3).is_integer());
770 assert_eq!(a.len(), 3);
771 }
772 let b = root.get_mut("b").unwrap();
773 let b = as_array!(b);
774 assert_eq!(b.len(), 1);
775 assert!(b.remove(0).is_str());
776 assert!(b.is_empty());
777 })
778 .produces_display(str![[r#"
779
780 a = [1, 2, 3]
781 b = []
782
783 "#]]);
784 }
785
786 #[test]
test_format_array()787 fn test_format_array() {
788 given(
789 r#"
790 a = [
791 1,
792 "2",
793 3.0,
794 ]
795 "#,
796 )
797 .running(|root| {
798 for (_, v) in root.iter_mut() {
799 if let Item::Value(Value::Array(array)) = v {
800 array.fmt();
801 }
802 }
803 })
804 .produces_display(str![[r#"
805
806 a = [1, "2", 3.0]
807 "#]]);
808 }
809
810 macro_rules! as_inline_table {
811 ($entry:ident) => {{
812 assert!($entry.is_value());
813 let a = $entry.as_value_mut().unwrap();
814 assert!(a.is_inline_table());
815 a.as_inline_table_mut().unwrap()
816 }};
817 }
818
819 #[test]
test_insert_into_inline_table()820 fn test_insert_into_inline_table() {
821 given(
822 r#"
823 a = {a=2, c = 3}
824 b = {}"#,
825 )
826 .running(|root| {
827 {
828 let a = root.get_mut("a").unwrap();
829 let a = as_inline_table!(a);
830 assert_eq!(a.len(), 2);
831 assert!(a.contains_key("a") && a.get("c").is_some() && a.get_mut("c").is_some());
832 a.get_or_insert("b", 42);
833 assert_eq!(a.len(), 3);
834 a.fmt();
835 }
836 let b = root.get_mut("b").unwrap();
837 let b = as_inline_table!(b);
838 assert!(b.is_empty());
839 b.get_or_insert("hello", "world");
840 assert_eq!(b.len(), 1);
841 b.fmt();
842 })
843 .produces_display(str![[r#"
844
845 a = { a = 2, c = 3, b = 42 }
846 b = { hello = "world" }
847
848 "#]]);
849 }
850
851 #[test]
test_remove_from_inline_table()852 fn test_remove_from_inline_table() {
853 given(
854 r#"
855 a = {a=2, c = 3, b = 42}
856 b = {'hello' = "world"}"#,
857 )
858 .running(|root| {
859 {
860 let a = root.get_mut("a").unwrap();
861 let a = as_inline_table!(a);
862 assert_eq!(a.len(), 3);
863 assert!(a.remove("c").is_some());
864 assert_eq!(a.len(), 2);
865 }
866 let b = root.get_mut("b").unwrap();
867 let b = as_inline_table!(b);
868 assert_eq!(b.len(), 1);
869 assert!(b.remove("hello").is_some());
870 assert!(b.is_empty());
871 })
872 .produces_display(str![[r#"
873
874 a = {a=2, b = 42}
875 b = {}
876
877 "#]]);
878 }
879
880 #[test]
test_as_table_like()881 fn test_as_table_like() {
882 given(
883 r#"
884 a = {a=2, c = 3, b = 42}
885 x = {}
886 [[bin]]
887 [b]
888 x = "y"
889 [empty]"#,
890 )
891 .running(|root| {
892 let a = root["a"].as_table_like();
893 assert!(a.is_some());
894 let a = a.unwrap();
895 assert_eq!(a.iter().count(), 3);
896 assert_eq!(a.len(), 3);
897 assert_eq!(a.get("a").and_then(Item::as_integer), Some(2));
898
899 let b = root["b"].as_table_like();
900 assert!(b.is_some());
901 let b = b.unwrap();
902 assert_eq!(b.iter().count(), 1);
903 assert_eq!(b.len(), 1);
904 assert_eq!(b.get("x").and_then(Item::as_str), Some("y"));
905
906 assert_eq!(root["x"].as_table_like().map(|t| t.iter().count()), Some(0));
907 assert_eq!(
908 root["empty"].as_table_like().map(|t| t.is_empty()),
909 Some(true)
910 );
911
912 assert!(root["bin"].as_table_like().is_none());
913 });
914 }
915
916 #[test]
test_inline_table_append()917 fn test_inline_table_append() {
918 let mut a = Value::from_iter(vec![
919 (parse_key!("a"), 1),
920 (parse_key!("b"), 2),
921 (parse_key!("c"), 3),
922 ]);
923 let a = a.as_inline_table_mut().unwrap();
924
925 let mut b = Value::from_iter(vec![
926 (parse_key!("c"), 4),
927 (parse_key!("d"), 5),
928 (parse_key!("e"), 6),
929 ]);
930 let b = b.as_inline_table_mut().unwrap();
931
932 a.extend(b.iter());
933 assert_eq!(a.len(), 5);
934 assert!(a.contains_key("e"));
935 assert_eq!(b.len(), 3);
936 }
937
938 #[test]
test_insert_dotted_into_std_table()939 fn test_insert_dotted_into_std_table() {
940 given("")
941 .running(|root| {
942 root["nixpkgs"] = table();
943
944 root["nixpkgs"]["src"] = table();
945 root["nixpkgs"]["src"]
946 .as_table_like_mut()
947 .unwrap()
948 .set_dotted(true);
949 root["nixpkgs"]["src"]["git"] = value("https://github.com/nixos/nixpkgs");
950 })
951 .produces_display(str![[r#"
952 [nixpkgs]
953 src.git = "https://github.com/nixos/nixpkgs"
954
955 "#]]);
956 }
957
958 #[test]
test_insert_dotted_into_implicit_table()959 fn test_insert_dotted_into_implicit_table() {
960 given("")
961 .running(|root| {
962 root["nixpkgs"] = table();
963
964 root["nixpkgs"]["src"]["git"] = value("https://github.com/nixos/nixpkgs");
965 root["nixpkgs"]["src"]
966 .as_table_like_mut()
967 .unwrap()
968 .set_dotted(true);
969 })
970 .produces_display(str![[r#"
971 [nixpkgs]
972 src.git = "https://github.com/nixos/nixpkgs"
973
974 "#]]);
975 }
976
977 #[test]
sorting_with_references()978 fn sorting_with_references() {
979 let values = vec!["foo", "qux", "bar"];
980 let mut array = toml_edit::Array::from_iter(values);
981 array.sort_by(|lhs, rhs| lhs.as_str().cmp(&rhs.as_str()));
982 }
983