Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Preserve dotted-key ordering #808

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions crates/toml_edit/src/parser/inline_table.rs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this commit type would be test

Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,25 @@ mod test {
}
}

#[test]
fn inline_table_reordering() {
let inputs = [
(
r#"{ hello.world = "a", goodbye = "b", hello.moon = "c" }"#,
// note the stylistic change, hello.moon has a space before its comma
r#"{ hello.world = "a", hello.moon = "c" , goodbye = "b"}"#,
)
];
for (input, expected) in inputs {
dbg!(input);
let mut parsed = inline_table.parse(new_input(input));
if let Ok(parsed) = &mut parsed {
parsed.despan(input);
}
assert_eq!(parsed.map(|a| a.to_string()), Ok(expected.to_owned()));
}
}

#[test]
fn invalid_inline_tables() {
let invalid_inputs = [r#"{a = 1e165"#, r#"{ hello = "world", a = 2, hello = 1}"#];
Expand Down
49 changes: 49 additions & 0 deletions crates/toml_edit/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,55 @@ key = "value"
assert_data_eq!(doc.to_string(), input.raw());
}
}
#[test]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newline

fn documents_reordering() {
let documents = [
(
r#"
hello.world = "a"
goodbye = "b"
hello.moon = "c"
"#,
r#"
hello.world = "a"
hello.moon = "c"
goodbye = "b"
"#,
),
(r#"
tool1.featureA = "foo"
# note this must match the above line, ask Dave why
tool2.featureA = "foo"

# these two values must always add to 9 because reasons
tool1.featureB = -1
tool3.featureB = 10
"#,
// these comments have now completely lost their meaning
r#"
tool1.featureA = "foo"

# these two values must always add to 9 because reasons
tool1.featureB = -1
# note this must match the above line, ask Dave why
tool2.featureA = "foo"
tool3.featureB = 10
"#
),
];
for (input, expected) in documents {
dbg!(input);
let parsed = parse_document(input).map(|d| d.into_mut());
let doc = match parsed {
Ok(doc) => doc,
Err(err) => {
panic!("Parse error: {err:?}\nFailed to parse:\n```\n{input}\n```")
}
};

assert_data_eq!(doc.to_string(), expected.raw());
}
}

#[test]
fn documents_parse_only() {
Expand Down
88 changes: 88 additions & 0 deletions crates/toml_edit/tests/testsuite/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,42 @@ fn test_sort_values() {
"#]]);
}

#[test]
fn test_sort_dotted_values() {
given(
r#"
[a.z]

[a]
a.b = 2
# this comment is attached to b
b = 3 # as well as this
a.a = 1
c = 4

[a.y]"#,
)
.running(|root| {
let a = root.get_mut("a").unwrap();
let a = as_table!(a);
a.sort_values();
})
.produces_display(str![[r#"

[a.z]

[a]
a.a = 1
a.b = 2
# this comment is attached to b
b = 3 # as well as this
c = 4

[a.y]

"#]]);
}

#[test]
fn test_sort_values_by() {
given(
Expand Down Expand Up @@ -1026,3 +1062,55 @@ name = "test.swf"
"#]]
);
}

#[test]
fn modify_dotted_keys() {
given(r#"
tool1.featureA = "foo"
# note this must match the above line, ask Dave why
tool2.featureA = "foo"

# these two values must always add to 9 because reasons
tool1.featureB = -1
tool3.featureB = 10
"#)
//language=none
.running_on_doc(|doc| {
let first_tool_k = "tool1";
let second_tool_k = "tool3";
let feature_k = "featureB";
let root = doc.as_table_mut();

let tool1_v = root.get_mut(first_tool_k).unwrap();
let tool1: &mut Table = as_table!(tool1_v);
let tool1_b = tool1.get_mut(feature_k).unwrap().as_integer().unwrap();

let tool3_v = root.get_mut(second_tool_k).unwrap();
let tool3: &mut Table = as_table!(tool3_v);
let tool3_b = tool3.get_mut(feature_k).unwrap().as_integer().unwrap();

let total = (tool1_b + tool3_b) as f64;
let split_val = (total / 2.0) as i64;
let mut split_val2 = split_val;
if split_val * 2 != total as i64 {
split_val2 += 1
}

root[first_tool_k][feature_k] = Item::from(split_val);
root[second_tool_k][feature_k] = Item::from(split_val2);
})
// these comments have now completely lost their meaning
.produces_display(str![[
r#"

tool1.featureA = "foo"

# these two values must always add to 9 because reasons
tool1.featureB = 4
# note this must match the above line, ask Dave why
tool2.featureA = "foo"
tool3.featureB = 5

"#
]]);
}
27 changes: 27 additions & 0 deletions crates/toml_edit/tests/testsuite/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1605,6 +1605,33 @@ clippy.exhaustive_enums = "warn"
assert_data_eq!(actual, expected.raw());
}

#[test]
fn dotted_key_interspersed_roundtrip() {
let input = r###"
rust.unsafe_op_in_unsafe_fn = "deny"

clippy.cast_lossless = "warn"
rust.explicit_outlives_requirements = "warn"

clippy.doc_markdown = "warn"
clippy.exhaustive_enums = "warn"
"###;
let expected = r###"
rust.unsafe_op_in_unsafe_fn = "deny"
rust.explicit_outlives_requirements = "warn"

clippy.cast_lossless = "warn"

clippy.doc_markdown = "warn"
clippy.exhaustive_enums = "warn"
"###;

let manifest: DocumentMut = input.parse().unwrap();
let actual = manifest.to_string();

assert_data_eq!(actual, expected.raw());
}

#[test]
fn string_repr_roundtrip() {
assert_string_repr_roundtrip(r#""""#, str![[r#""""#]]);
Expand Down