aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-20 21:03:57 +0900
committernsfisis <nsfisis@gmail.com>2026-02-20 21:03:57 +0900
commit236332f9bfd9cb0688815142237f299939b2d80a (patch)
tree63af7169467235daa444d1a2e913264f7e057498
parent4fffacaeed6b35cb75132df4629a26183d752492 (diff)
downloadreparojson-236332f9bfd9cb0688815142237f299939b2d80a.tar.gz
reparojson-236332f9bfd9cb0688815142237f299939b2d80a.tar.zst
reparojson-236332f9bfd9cb0688815142237f299939b2d80a.zip
feat: add parsing tests
-rw-r--r--.gitmodules3
-rw-r--r--src/lib.rs3
m---------tests/JSONTestSuite0
-rw-r--r--tests/json_test_suite.rs71
4 files changed, 77 insertions, 0 deletions
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<RepairOk, RepairErr>;
+#[derive(Debug)]
pub enum RepairOk {
Valid,
Repaired,
}
+#[derive(Debug)]
pub enum RepairErr {
Invalid(SyntaxError),
IoErr(std::io::Error),
@@ -25,6 +27,7 @@ impl From<SyntaxError> for RepairErr {
}
}
+#[derive(Debug)]
pub enum SyntaxError {
UnexpectedEof,
InvalidValue,
diff --git a/tests/JSONTestSuite b/tests/JSONTestSuite
new file mode 160000
+Subproject 1ef36fa01286573e846ac449e8683f8833c5b26
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
+ );
+ }
+}