summaryrefslogtreecommitdiffstats
path: root/vendor/toml_edit/tests/testsuite/edit.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/toml_edit/tests/testsuite/edit.rs')
-rw-r--r--vendor/toml_edit/tests/testsuite/edit.rs855
1 files changed, 855 insertions, 0 deletions
diff --git a/vendor/toml_edit/tests/testsuite/edit.rs b/vendor/toml_edit/tests/testsuite/edit.rs
new file mode 100644
index 0000000..28f73c1
--- /dev/null
+++ b/vendor/toml_edit/tests/testsuite/edit.rs
@@ -0,0 +1,855 @@
+use std::fmt;
+use std::iter::FromIterator;
+
+use snapbox::assert_eq;
+use toml_edit::{array, table, value, Document, Item, Key, Table, Value};
+
+macro_rules! parse_key {
+ ($s:expr) => {{
+ let key = $s.parse::<Key>();
+ assert!(key.is_ok());
+ key.unwrap()
+ }};
+}
+
+macro_rules! as_table {
+ ($e:ident) => {{
+ assert!($e.is_table());
+ $e.as_table_mut().unwrap()
+ }};
+}
+
+// Copied from https://github.com/colin-kiegel/rust-pretty-assertions/issues/24
+/// Wrapper around string slice that makes debug output `{:?}` to print string same way as `{}`.
+/// Used in different `assert*!` macros in combination with `pretty_assertions` crate to make
+/// test failures to show nice diffs.
+#[derive(PartialEq, Eq)]
+struct PrettyString<'a>(pub &'a str);
+/// Make diff to display string as multi-line string
+impl<'a> fmt::Debug for PrettyString<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(self.0)
+ }
+}
+
+struct Test {
+ doc: Document,
+}
+
+fn given(input: &str) -> Test {
+ let doc = input.parse::<Document>();
+ assert!(doc.is_ok());
+ Test { doc: doc.unwrap() }
+}
+
+impl Test {
+ fn running<F>(&mut self, func: F) -> &mut Self
+ where
+ F: Fn(&mut Table),
+ {
+ {
+ let root = self.doc.as_table_mut();
+ func(root);
+ }
+ self
+ }
+
+ #[track_caller]
+ fn produces_display(&self, expected: &str) -> &Self {
+ assert_eq(expected, self.doc.to_string());
+ self
+ }
+}
+
+// insertion
+
+#[test]
+fn test_insert_leaf_table() {
+ given(
+ r#"[servers]
+
+ [servers.alpha]
+ ip = "10.0.0.1"
+ dc = "eqdc10"
+
+ [other.table]"#,
+ )
+ .running(|root| {
+ root["servers"]["beta"] = table();
+ root["servers"]["beta"]["ip"] = value("10.0.0.2");
+ root["servers"]["beta"]["dc"] = value("eqdc10");
+ })
+ .produces_display(
+ r#"[servers]
+
+ [servers.alpha]
+ ip = "10.0.0.1"
+ dc = "eqdc10"
+
+[servers.beta]
+ip = "10.0.0.2"
+dc = "eqdc10"
+
+ [other.table]
+"#,
+ );
+}
+
+#[test]
+fn test_inserted_leaf_table_goes_after_last_sibling() {
+ given(
+ r#"
+ [package]
+ [dependencies]
+ [[example]]
+ [dependencies.opencl]
+ [dev-dependencies]"#,
+ )
+ .running(|root| {
+ root["dependencies"]["newthing"] = table();
+ })
+ .produces_display(
+ r#"
+ [package]
+ [dependencies]
+ [[example]]
+ [dependencies.opencl]
+
+[dependencies.newthing]
+ [dev-dependencies]
+"#,
+ );
+}
+
+#[test]
+fn test_inserting_tables_from_different_parsed_docs() {
+ given("[a]")
+ .running(|root| {
+ let other = "[b]".parse::<Document>().unwrap();
+ root["b"] = other["b"].clone();
+ })
+ .produces_display("[a]\n[b]\n");
+}
+#[test]
+fn test_insert_nonleaf_table() {
+ given(
+ r#"
+ [other.table]"#,
+ )
+ .running(|root| {
+ root["servers"] = table();
+ root["servers"]["alpha"] = table();
+ root["servers"]["alpha"]["ip"] = value("10.0.0.1");
+ root["servers"]["alpha"]["dc"] = value("eqdc10");
+ })
+ .produces_display(
+ r#"
+ [other.table]
+
+[servers]
+
+[servers.alpha]
+ip = "10.0.0.1"
+dc = "eqdc10"
+"#,
+ );
+}
+
+#[test]
+fn test_insert_array() {
+ given(
+ r#"
+ [package]
+ title = "withoutarray""#,
+ )
+ .running(|root| {
+ root["bin"] = array();
+ assert!(root["bin"].is_array_of_tables());
+ let array = root["bin"].as_array_of_tables_mut().unwrap();
+ {
+ let mut table = Table::new();
+ table["hello"] = value("world");
+ array.push(table);
+ }
+ array.push(Table::new());
+ })
+ .produces_display(
+ r#"
+ [package]
+ title = "withoutarray"
+
+[[bin]]
+hello = "world"
+
+[[bin]]
+"#,
+ );
+}
+
+#[test]
+fn test_insert_values() {
+ given(
+ r#"
+ [tbl.son]"#,
+ )
+ .running(|root| {
+ root["tbl"]["key1"] = value("value1");
+ root["tbl"]["key2"] = value(42);
+ root["tbl"]["key3"] = value(8.1415926);
+ })
+ .produces_display(
+ r#"[tbl]
+key1 = "value1"
+key2 = 42
+key3 = 8.1415926
+
+ [tbl.son]
+"#,
+ );
+}
+
+// removal
+
+#[test]
+fn test_remove_leaf_table() {
+ given(
+ r#"
+ [servers]
+
+ # Indentation (tabs and/or spaces) is allowed but not required
+[servers.alpha]
+ ip = "10.0.0.1"
+ dc = "eqdc10"
+
+ [servers.beta]
+ ip = "10.0.0.2"
+ dc = "eqdc10""#,
+ )
+ .running(|root| {
+ let servers = root.get_mut("servers").unwrap();
+ let servers = as_table!(servers);
+ assert!(servers.remove("alpha").is_some());
+ })
+ .produces_display(
+ r#"
+ [servers]
+
+ [servers.beta]
+ ip = "10.0.0.2"
+ dc = "eqdc10"
+"#,
+ );
+}
+
+#[test]
+fn test_remove_nonleaf_table() {
+ given(
+ r#"
+ title = "not relevant"
+
+ # comment 1
+ [a.b.c] # comment 1.1
+ key1 = 1 # comment 1.2
+ # comment 2
+ [b] # comment 2.1
+ key2 = 2 # comment 2.2
+
+ # comment 3
+ [a] # comment 3.1
+ key3 = 3 # comment 3.2
+ [[a.'array']]
+ b = 1
+
+ [[a.b.c.trololololololo]] # ohohohohoho
+ c = 2
+ key3 = 42
+
+ # comment on some other table
+ [some.other.table]
+
+
+
+
+ # comment 4
+ [a.b] # comment 4.1
+ key4 = 4 # comment 4.2
+ key41 = 41 # comment 4.3
+
+
+ "#,
+ )
+ .running(|root| {
+ assert!(root.remove("a").is_some());
+ })
+ .produces_display(
+ r#"
+ title = "not relevant"
+ # comment 2
+ [b] # comment 2.1
+ key2 = 2 # comment 2.2
+
+ # comment on some other table
+ [some.other.table]
+
+
+ "#,
+ );
+}
+
+#[test]
+fn test_remove_array_entry() {
+ given(
+ r#"
+ [package]
+ name = "hello"
+ version = "1.0.0"
+
+ [[bin]]
+ name = "world"
+ path = "src/bin/world/main.rs"
+
+ [dependencies]
+ nom = "4.0" # future is here
+
+ [[bin]]
+ name = "delete me please"
+ path = "src/bin/dmp/main.rs""#,
+ )
+ .running(|root| {
+ let dmp = root.get_mut("bin").unwrap();
+ assert!(dmp.is_array_of_tables());
+ let dmp = dmp.as_array_of_tables_mut().unwrap();
+ assert_eq!(dmp.len(), 2);
+ dmp.remove(1);
+ assert_eq!(dmp.len(), 1);
+ })
+ .produces_display(
+ r#"
+ [package]
+ name = "hello"
+ version = "1.0.0"
+
+ [[bin]]
+ name = "world"
+ path = "src/bin/world/main.rs"
+
+ [dependencies]
+ nom = "4.0" # future is here
+"#,
+ );
+}
+
+#[test]
+fn test_remove_array() {
+ given(
+ r#"
+ [package]
+ name = "hello"
+ version = "1.0.0"
+
+ [[bin]]
+ name = "world"
+ path = "src/bin/world/main.rs"
+
+ [dependencies]
+ nom = "4.0" # future is here
+
+ [[bin]]
+ name = "delete me please"
+ path = "src/bin/dmp/main.rs""#,
+ )
+ .running(|root| {
+ assert!(root.remove("bin").is_some());
+ })
+ .produces_display(
+ r#"
+ [package]
+ name = "hello"
+ version = "1.0.0"
+
+ [dependencies]
+ nom = "4.0" # future is here
+"#,
+ );
+}
+
+#[test]
+fn test_remove_value() {
+ given(
+ r#"
+ name = "hello"
+ # delete this
+ version = "1.0.0" # please
+ documentation = "https://docs.rs/hello""#,
+ )
+ .running(|root| {
+ let value = root.remove("version");
+ assert!(value.is_some());
+ let value = value.unwrap();
+ assert!(value.is_value());
+ let value = value.as_value().unwrap();
+ assert!(value.is_str());
+ let value = value.as_str().unwrap();
+ assert_eq(value, "1.0.0");
+ })
+ .produces_display(
+ r#"
+ name = "hello"
+ documentation = "https://docs.rs/hello"
+"#,
+ );
+}
+
+#[test]
+fn test_remove_last_value_from_implicit() {
+ given(
+ r#"
+ [a]
+ b = 1"#,
+ )
+ .running(|root| {
+ let a = root.get_mut("a").unwrap();
+ assert!(a.is_table());
+ let a = as_table!(a);
+ a.set_implicit(true);
+ let value = a.remove("b");
+ assert!(value.is_some());
+ let value = value.unwrap();
+ assert!(value.is_value());
+ let value = value.as_value().unwrap();
+ assert_eq!(value.as_integer(), Some(1));
+ })
+ .produces_display(r#""#);
+}
+
+// values
+
+#[test]
+fn test_sort_values() {
+ given(
+ r#"
+ [a.z]
+
+ [a]
+ # this comment is attached to b
+ b = 2 # as well as this
+ a = 1
+ c = 3
+
+ [a.y]"#,
+ )
+ .running(|root| {
+ let a = root.get_mut("a").unwrap();
+ let a = as_table!(a);
+ a.sort_values();
+ })
+ .produces_display(
+ r#"
+ [a.z]
+
+ [a]
+ a = 1
+ # this comment is attached to b
+ b = 2 # as well as this
+ c = 3
+
+ [a.y]
+"#,
+ );
+}
+
+#[test]
+fn test_sort_values_by() {
+ given(
+ r#"
+ [a.z]
+
+ [a]
+ # this comment is attached to b
+ b = 2 # as well as this
+ a = 1
+ "c" = 3
+
+ [a.y]"#,
+ )
+ .running(|root| {
+ let a = root.get_mut("a").unwrap();
+ let a = as_table!(a);
+ // Sort by the representation, not the value. So "\"c\"" sorts before "a" because '"' sorts
+ // before 'a'.
+ a.sort_values_by(|k1, _, k2, _| k1.display_repr().cmp(&k2.display_repr()));
+ })
+ .produces_display(
+ r#"
+ [a.z]
+
+ [a]
+ "c" = 3
+ a = 1
+ # this comment is attached to b
+ b = 2 # as well as this
+
+ [a.y]
+"#,
+ );
+}
+
+#[test]
+fn test_set_position() {
+ given(
+ r#"
+ [package]
+ [dependencies]
+ [dependencies.opencl]
+ [dev-dependencies]"#,
+ )
+ .running(|root| {
+ for (header, table) in root.iter_mut() {
+ if header == "dependencies" {
+ let tab = as_table!(table);
+ tab.set_position(0);
+ let (_, segmented) = tab.iter_mut().next().unwrap();
+ as_table!(segmented).set_position(5)
+ }
+ }
+ })
+ .produces_display(
+ r#" [dependencies]
+
+ [package]
+ [dev-dependencies]
+ [dependencies.opencl]
+"#,
+ );
+}
+
+#[test]
+fn test_multiple_zero_positions() {
+ given(
+ r#"
+ [package]
+ [dependencies]
+ [dependencies.opencl]
+ a=""
+ [dev-dependencies]"#,
+ )
+ .running(|root| {
+ for (_, table) in root.iter_mut() {
+ as_table!(table).set_position(0)
+ }
+ })
+ .produces_display(
+ r#"
+ [package]
+ [dependencies]
+ [dev-dependencies]
+ [dependencies.opencl]
+ a=""
+"#,
+ );
+}
+
+#[test]
+fn test_multiple_max_usize_positions() {
+ given(
+ r#"
+ [package]
+ [dependencies]
+ [dependencies.opencl]
+ a=""
+ [dev-dependencies]"#,
+ )
+ .running(|root| {
+ for (_, table) in root.iter_mut() {
+ as_table!(table).set_position(usize::MAX)
+ }
+ })
+ .produces_display(
+ r#" [dependencies.opencl]
+ a=""
+
+ [package]
+ [dependencies]
+ [dev-dependencies]
+"#,
+ );
+}
+
+macro_rules! as_array {
+ ($entry:ident) => {{
+ assert!($entry.is_value());
+ let a = $entry.as_value_mut().unwrap();
+ assert!(a.is_array());
+ a.as_array_mut().unwrap()
+ }};
+}
+
+#[test]
+fn test_insert_replace_into_array() {
+ given(
+ r#"
+ a = [1,2,3]
+ b = []"#,
+ )
+ .running(|root| {
+ {
+ let a = root.get_mut("a").unwrap();
+ let a = as_array!(a);
+ assert_eq!(a.len(), 3);
+ assert!(a.get(2).is_some());
+ a.push(4);
+ assert_eq!(a.len(), 4);
+ a.fmt();
+ }
+ let b = root.get_mut("b").unwrap();
+ let b = as_array!(b);
+ assert!(b.is_empty());
+ b.push("hello");
+ assert_eq!(b.len(), 1);
+
+ b.push_formatted(Value::from("world").decorated("\n", "\n"));
+ b.push_formatted(Value::from("test").decorated("", ""));
+
+ b.insert(1, "beep");
+ b.insert_formatted(2, Value::from("boop").decorated(" ", " "));
+
+ // This should preserve formatting.
+ assert_eq!(b.replace(2, "zoink").as_str(), Some("boop"));
+ // This should replace formatting.
+ assert_eq!(
+ b.replace_formatted(4, Value::from("yikes").decorated(" ", ""))
+ .as_str(),
+ Some("test")
+ );
+ dbg!(root);
+ })
+ .produces_display(
+ r#"
+ a = [1, 2, 3, 4]
+ b = ["hello", "beep", "zoink" ,
+"world"
+, "yikes"]
+"#,
+ );
+}
+
+#[test]
+fn test_remove_from_array() {
+ given(
+ r#"
+ a = [1, 2, 3, 4]
+ b = ["hello"]"#,
+ )
+ .running(|root| {
+ {
+ let a = root.get_mut("a").unwrap();
+ let a = as_array!(a);
+ assert_eq!(a.len(), 4);
+ assert!(a.remove(3).is_integer());
+ assert_eq!(a.len(), 3);
+ }
+ let b = root.get_mut("b").unwrap();
+ let b = as_array!(b);
+ assert_eq!(b.len(), 1);
+ assert!(b.remove(0).is_str());
+ assert!(b.is_empty());
+ })
+ .produces_display(
+ r#"
+ a = [1, 2, 3]
+ b = []
+"#,
+ );
+}
+
+#[test]
+fn test_format_array() {
+ given(
+ r#"
+ a = [
+ 1,
+ "2",
+ 3.0,
+ ]
+ "#,
+ )
+ .running(|root| {
+ for (_, v) in root.iter_mut() {
+ if let Item::Value(Value::Array(array)) = v {
+ array.fmt();
+ }
+ }
+ })
+ .produces_display(
+ r#"
+ a = [1, "2", 3.0]
+ "#,
+ );
+}
+
+macro_rules! as_inline_table {
+ ($entry:ident) => {{
+ assert!($entry.is_value());
+ let a = $entry.as_value_mut().unwrap();
+ assert!(a.is_inline_table());
+ a.as_inline_table_mut().unwrap()
+ }};
+}
+
+#[test]
+fn test_insert_into_inline_table() {
+ given(
+ r#"
+ a = {a=2, c = 3}
+ b = {}"#,
+ )
+ .running(|root| {
+ {
+ let a = root.get_mut("a").unwrap();
+ let a = as_inline_table!(a);
+ assert_eq!(a.len(), 2);
+ assert!(a.contains_key("a") && a.get("c").is_some() && a.get_mut("c").is_some());
+ a.get_or_insert("b", 42);
+ assert_eq!(a.len(), 3);
+ a.fmt();
+ }
+ let b = root.get_mut("b").unwrap();
+ let b = as_inline_table!(b);
+ assert!(b.is_empty());
+ b.get_or_insert("hello", "world");
+ assert_eq!(b.len(), 1);
+ b.fmt()
+ })
+ .produces_display(
+ r#"
+ a = { a = 2, c = 3, b = 42 }
+ b = { hello = "world" }
+"#,
+ );
+}
+
+#[test]
+fn test_remove_from_inline_table() {
+ given(
+ r#"
+ a = {a=2, c = 3, b = 42}
+ b = {'hello' = "world"}"#,
+ )
+ .running(|root| {
+ {
+ let a = root.get_mut("a").unwrap();
+ let a = as_inline_table!(a);
+ assert_eq!(a.len(), 3);
+ assert!(a.remove("c").is_some());
+ assert_eq!(a.len(), 2);
+ }
+ let b = root.get_mut("b").unwrap();
+ let b = as_inline_table!(b);
+ assert_eq!(b.len(), 1);
+ assert!(b.remove("hello").is_some());
+ assert!(b.is_empty());
+ })
+ .produces_display(
+ r#"
+ a = {a=2, b = 42}
+ b = {}
+"#,
+ );
+}
+
+#[test]
+fn test_as_table_like() {
+ given(
+ r#"
+ a = {a=2, c = 3, b = 42}
+ x = {}
+ [[bin]]
+ [b]
+ x = "y"
+ [empty]"#,
+ )
+ .running(|root| {
+ let a = root["a"].as_table_like();
+ assert!(a.is_some());
+ let a = a.unwrap();
+ assert_eq!(a.iter().count(), 3);
+ assert_eq!(a.len(), 3);
+ assert_eq!(a.get("a").and_then(Item::as_integer), Some(2));
+
+ let b = root["b"].as_table_like();
+ assert!(b.is_some());
+ let b = b.unwrap();
+ assert_eq!(b.iter().count(), 1);
+ assert_eq!(b.len(), 1);
+ assert_eq!(b.get("x").and_then(Item::as_str), Some("y"));
+
+ assert_eq!(root["x"].as_table_like().map(|t| t.iter().count()), Some(0));
+ assert_eq!(
+ root["empty"].as_table_like().map(|t| t.is_empty()),
+ Some(true)
+ );
+
+ assert!(root["bin"].as_table_like().is_none());
+ });
+}
+
+#[test]
+fn test_inline_table_append() {
+ let mut a = Value::from_iter(vec![
+ (parse_key!("a"), 1),
+ (parse_key!("b"), 2),
+ (parse_key!("c"), 3),
+ ]);
+ let a = a.as_inline_table_mut().unwrap();
+
+ let mut b = Value::from_iter(vec![
+ (parse_key!("c"), 4),
+ (parse_key!("d"), 5),
+ (parse_key!("e"), 6),
+ ]);
+ let b = b.as_inline_table_mut().unwrap();
+
+ a.extend(b.iter());
+ assert_eq!(a.len(), 5);
+ assert!(a.contains_key("e"));
+ assert_eq!(b.len(), 3);
+}
+
+#[test]
+fn test_insert_dotted_into_std_table() {
+ given("")
+ .running(|root| {
+ root["nixpkgs"] = table();
+
+ root["nixpkgs"]["src"] = table();
+ root["nixpkgs"]["src"]
+ .as_table_like_mut()
+ .unwrap()
+ .set_dotted(true);
+ root["nixpkgs"]["src"]["git"] = value("https://github.com/nixos/nixpkgs");
+ })
+ .produces_display(
+ r#"[nixpkgs]
+src.git = "https://github.com/nixos/nixpkgs"
+"#,
+ );
+}
+
+#[test]
+fn test_insert_dotted_into_implicit_table() {
+ given("")
+ .running(|root| {
+ root["nixpkgs"] = table();
+
+ root["nixpkgs"]["src"]["git"] = value("https://github.com/nixos/nixpkgs");
+ root["nixpkgs"]["src"]
+ .as_table_like_mut()
+ .unwrap()
+ .set_dotted(true);
+ })
+ .produces_display(
+ r#"[nixpkgs]
+src.git = "https://github.com/nixos/nixpkgs"
+"#,
+ );
+}