From 34e58bc5d65b5f10e0e1cd0ec66f0b031ea41975 Mon Sep 17 00:00:00 2001 From: pwygab <88221256+merelymyself@users.noreply.github.com> Date: Thu, 1 Sep 2022 20:08:19 +0800 Subject: [PATCH] add tests, deal with pipes, newlines, tabs for `to nuon` (#6391) * remove unnecessary FlatShape * add proptest * remove files that belonged in another PR * more tests, more chars * add exception for parser error unrelated ot PR --- Cargo.lock | 50 ++++++++++++++++++- crates/nu-command/Cargo.toml | 1 + .../format_conversions/nuon.txt | 23 +++++++++ crates/nu-command/src/formats/to/nuon.rs | 18 +++++-- .../tests/format_conversions/nuon.rs | 37 ++++++++++++++ 5 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 crates/nu-command/proptest-regressions/format_conversions/nuon.txt diff --git a/Cargo.lock b/Cargo.lock index 06bbfaf1f3..83475cc4de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2723,6 +2723,7 @@ dependencies = [ "pathdiff", "polars", "powierza-coefficient", + "proptest", "quick-xml 0.23.0", "quickcheck", "quickcheck_macros", @@ -3795,6 +3796,26 @@ dependencies = [ "rustix", ] +[[package]] +name = "proptest" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0d9cc07f18492d879586c92b485def06bc850da3118075cd45d50e9c95b0e5" +dependencies = [ + "bit-set", + "bitflags", + "byteorder", + "lazy_static", + "num-traits", + "quick-error 2.0.1", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", +] + [[package]] name = "pure-rust-locales" version = "0.5.6" @@ -3817,6 +3838,12 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-xml" version = "0.19.0" @@ -3986,6 +4013,15 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.3", +] + [[package]] name = "rayon" version = "1.5.3" @@ -4330,6 +4366,18 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8" +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error 1.2.3", + "tempfile", + "wait-timeout", +] + [[package]] name = "ryu" version = "1.0.10" @@ -4885,7 +4933,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36e39da5d30887b5690e29de4c5ebb8ddff64ebd9933f98a01daaa4fd11b36ea" dependencies = [ "peresil", - "quick-error", + "quick-error 1.2.3", "sxd-document", ] diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index 20ec4cf0ef..6c21dfbc65 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -152,6 +152,7 @@ shadow-rs = { version = "0.16.1", default-features = false } [dev-dependencies] hamcrest2 = "0.3.0" dirs-next = "2.0.0" +proptest = "1.0.0" quickcheck = "1.0.3" quickcheck_macros = "1.0.0" rstest = {version = "0.15.0", default-features = false} diff --git a/crates/nu-command/proptest-regressions/format_conversions/nuon.txt b/crates/nu-command/proptest-regressions/format_conversions/nuon.txt new file mode 100644 index 0000000000..863d533b36 --- /dev/null +++ b/crates/nu-command/proptest-regressions/format_conversions/nuon.txt @@ -0,0 +1,23 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 96a80ecd19729fb43a7b7bb2766b37d6083ba73b16abb97075875e3cfcdc763f # shrinks to c = '"' +cc 4146602559ea717a02bcef3c6d73cdf613c30d0c3f92c48e26c79b9a1544e027 # shrinks to c = '\\' +cc 80532a0ee73df456a719b9e3cce1ae5f3d26009dde819cbaf16f8e0cb6709705 # shrinks to c = ':' +cc cdb88505686eea3c74c36f282fd29b2b68bc118ded4ebfc36f9838d174bd7653 # shrinks to c = '`' +cc 0f534d55f9771e8810b9c4252a4168abfaec1a35e1b0cac12dbaf726d295a08c # shrinks to c = '\0' +cc 5d31bcbab722acd1f4e23ca3a4f95ff309a636b45a73ca8ae9f820d93ff57acc # shrinks to c = '{' +cc 5afec063bc96160d681d77f90041b67ef5cfdea4dcbd12d984fd828fbeb4b421 # shrinks to c = '#' +cc f919beb3ee5c70e756a15635d65ded7d44f3ae58b5e86b6c09e814d5d8cdd506 # shrinks to c = ';' +cc ec00f39b8d45dfd8808947a56af5e50ba5a0ef7c951723b45377815a02e515b1 # shrinks to c = '(' +cc 25b773cdf4c24179151fa86244c7de4136e05df9e94e6ee77a336ebfd8764444 # shrinks to c = '|' +cc 94dc0d54b97d59e1c0f4cb11bdccb3823a1bb908cbc3fd643ee8f067169fad72 # shrinks to c = '0' +cc c9d0051fb1e5a8bdc1d4f5a3dceac1b4b465827d1dff4fc3a3755baae6a7bb48 # shrinks to c = '$' +cc 14ec40d2eb5bd2663e9b11bb49fb2120852f9ea71678c69d732161412b55a3ec # shrinks to s = "" +cc d4afccc51ed9d421bdb7e1723e273dfb6e77c3a449489671a496db234e87c5ed # shrinks to c = '\r' +cc 515a56d73eb1b69290ef4c714b629421989879aebd57991bd2c2bf11294353b1 # shrinks to s = "\\\\𐊀{" +cc 111566990fffa432acd2dbc845141b0e7870f97125c7621e3ddf142204568246 # shrinks to s = "'\":`" +cc 0424c33000d9188be96b3049046eb052770b2158bf5ebb0c98656d7145e8aca9 # shrinks to s = "0" diff --git a/crates/nu-command/src/formats/to/nuon.rs b/crates/nu-command/src/formats/to/nuon.rs index e2eb39176b..1d0ea435a8 100644 --- a/crates/nu-command/src/formats/to/nuon.rs +++ b/crates/nu-command/src/formats/to/nuon.rs @@ -192,15 +192,23 @@ fn to_nuon(call: &Call, input: PipelineData) -> Result { fn needs_quotes(string: &str) -> bool { string.contains(' ') - || string.contains(',') + || string.contains('[') + || string.contains(']') || string.contains(':') + || string.contains('`') + || string.contains('{') + || string.contains('}') + || string.contains('#') + || string.contains('\'') || string.contains(';') || string.contains('(') || string.contains(')') - || string.contains('[') - || string.contains(']') - || string.contains('{') - || string.contains('}') + || string.contains('|') + || string.contains('$') + || string.contains(',') + || string.contains('\t') + || string.contains('\n') + || string.contains('\r') } #[cfg(test)] diff --git a/crates/nu-command/tests/format_conversions/nuon.rs b/crates/nu-command/tests/format_conversions/nuon.rs index 626cb05bfd..42729d8376 100644 --- a/crates/nu-command/tests/format_conversions/nuon.rs +++ b/crates/nu-command/tests/format_conversions/nuon.rs @@ -1,4 +1,5 @@ use nu_test_support::{nu, pipeline}; +use proptest::prelude::*; #[test] fn to_nuon_correct_compaction() { @@ -267,3 +268,39 @@ fn to_nuon_does_not_quote_unnecessarily() { )); assert_eq!(actual.out, "{\"ro name\": sam, rank: 10}"); } + +proptest! { + #[test] + fn to_nuon_from_nuon(c: char) { + if c != '\0' && c!='\r' { + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + format!(r#" + {{"prop{0}test": "sam"}} | to nuon | from nuon; + [ [ "prop{0}test" ]; [ 'test' ] ] | to nuon | from nuon; + [ [ "{0}" ]; [ 'test' ] ] | to nuon | from nuon; + {{"{0}": "sam"}} | to nuon | from nuon; + "#, c).as_ref() + )); + assert!(actual.err.is_empty() || actual.err.contains("Unexpected end of code") || actual.err.contains("only strings can be keys")); + // The second is for weird escapes due to backslashes + // The third is for chars like '0' + } + } + #[test] + fn to_nuon_from_nuon_string(s: String) { + if s != "\\0" && s!= "" && !s.contains('\\') && !s.contains('"'){ + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + format!(r#" + {{"prop{0}test": "sam"}} | to nuon | from nuon; + [ [ "prop{0}test" ]; [ 'test' ] ] | to nuon | from nuon; + [ [ "{0}" ]; [ 'test' ] ] | to nuon | from nuon; + {{"{0}": "sam"}} | to nuon | from nuon; + "#, s).as_ref() + )); + assert!(actual.err.is_empty() || actual.err.contains("only strings can be keys") || actual.err.contains("unknown command")); + // TODO: fix parser error for "unknown command" when '=$' is the name + } + } +}