From 236332f9bfd9cb0688815142237f299939b2d80a Mon Sep 17 00:00:00 2001 From: nsfisis Date: Fri, 20 Feb 2026 21:03:57 +0900 Subject: feat: add parsing tests --- .gitmodules | 3 ++ src/lib.rs | 3 ++ tests/JSONTestSuite | 1 + tests/json_test_suite.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 .gitmodules create mode 160000 tests/JSONTestSuite create mode 100644 tests/json_test_suite.rs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b8ec319 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "tests/JSONTestSuite"] + path = tests/JSONTestSuite + url = https://github.com/nst/JSONTestSuite diff --git a/src/lib.rs b/src/lib.rs index 5d80297..3143032 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,11 +3,13 @@ use std::iter::Peekable; pub type RepairResult = Result; +#[derive(Debug)] pub enum RepairOk { Valid, Repaired, } +#[derive(Debug)] pub enum RepairErr { Invalid(SyntaxError), IoErr(std::io::Error), @@ -25,6 +27,7 @@ impl From for RepairErr { } } +#[derive(Debug)] pub enum SyntaxError { UnexpectedEof, InvalidValue, diff --git a/tests/JSONTestSuite b/tests/JSONTestSuite new file mode 160000 index 0000000..1ef36fa --- /dev/null +++ b/tests/JSONTestSuite @@ -0,0 +1 @@ +Subproject commit 1ef36fa01286573e846ac449e8683f8833c5b26a diff --git a/tests/json_test_suite.rs b/tests/json_test_suite.rs new file mode 100644 index 0000000..7bb67f4 --- /dev/null +++ b/tests/json_test_suite.rs @@ -0,0 +1,71 @@ +#[test] +fn y_json_files_should_be_valid() { + let test_suite_dir: std::path::PathBuf = [ + env!("CARGO_MANIFEST_DIR"), + "tests", + "JSONTestSuite", + "test_parsing", + ] + .iter() + .collect(); + + for entry in std::fs::read_dir(&test_suite_dir).expect("failed to read test suite directory") { + let entry = entry.expect("failed to read directory entry"); + let path = entry.path(); + let name = path.file_name().unwrap().to_string_lossy(); + if !name.starts_with("y_") || !name.ends_with(".json") { + continue; + } + + let input = std::fs::read(&path).expect("failed to read file"); + let mut output = Vec::new(); + let result = reparojson::repair(&input[..], &mut output); + + assert!( + matches!(result, Ok(reparojson::RepairOk::Valid)), + "{}: expected valid JSON, but {:?}", + name, + result + ); + assert_eq!(input, output, "{name}: output differs from input"); + } +} + +#[test] +fn n_json_files_should_be_invalid() { + let test_suite_dir: std::path::PathBuf = [ + env!("CARGO_MANIFEST_DIR"), + "tests", + "JSONTestSuite", + "test_parsing", + ] + .iter() + .collect(); + + for entry in std::fs::read_dir(&test_suite_dir).expect("failed to read test suite directory") { + let entry = entry.expect("failed to read directory entry"); + let path = entry.path(); + let name = path.file_name().unwrap().to_string_lossy(); + if !name.starts_with("n_") || !name.ends_with(".json") { + continue; + } + + // Skip test cases that cause stack overflow. + if *name == *"n_structure_100000_opening_arrays.json" + || *name == *"n_structure_open_array_object.json" + { + continue; + } + + let input = std::fs::read(&path).expect("failed to read file"); + let mut output = Vec::new(); + let result = reparojson::repair(&input[..], &mut output); + + assert!( + !matches!(result, Ok(reparojson::RepairOk::Valid)), + "{}: expected invalid JSON, but {:?}", + name, + result + ); + } +} -- cgit v1.3-1-g0d28