From e33f9c10b3fe320b97f695bdc0a230023fdae8ab Mon Sep 17 00:00:00 2001 From: Graham Esau Date: Mon, 9 Sep 2024 23:07:33 +0100 Subject: [PATCH] Port std::* tests to new integration test style --- schemars/Cargo.toml | 8 -- schemars/src/json_schema_impls/ffi.rs | 31 +++++- .../expected/duration_and_systemtime.json | 57 ----------- schemars/tests/expected/no-variants.json | 5 - schemars/tests/expected/os_strings.json | 55 ----------- schemars/tests/expected/range.json | 89 ----------------- schemars/tests/expected/result.json | 86 ---------------- schemars/tests/ffi.rs | 16 --- schemars/tests/integration/enums_flattened.rs | 3 +- schemars/tests/integration/main.rs | 1 + schemars/tests/integration/std_types.rs | 97 +++++++++++++++++++ schemars/tests/range.rs | 17 ---- schemars/tests/result.rs | 21 ---- schemars/tests/std_time.rs | 16 --- 14 files changed, 128 insertions(+), 374 deletions(-) delete mode 100644 schemars/tests/expected/duration_and_systemtime.json delete mode 100644 schemars/tests/expected/no-variants.json delete mode 100644 schemars/tests/expected/os_strings.json delete mode 100644 schemars/tests/expected/range.json delete mode 100644 schemars/tests/expected/result.json delete mode 100644 schemars/tests/ffi.rs create mode 100644 schemars/tests/integration/std_types.rs delete mode 100644 schemars/tests/range.rs delete mode 100644 schemars/tests/result.rs delete mode 100644 schemars/tests/std_time.rs diff --git a/schemars/Cargo.toml b/schemars/Cargo.toml index c53ff20c..69742a9f 100644 --- a/schemars/Cargo.toml +++ b/schemars/Cargo.toml @@ -69,14 +69,6 @@ raw_value = ["serde_json/raw_value"] # For internal/CI use only _ui_test = [] -[[test]] -name = "std_time" -required-features = ["std"] - -[[test]] -name = "ffi" -required-features = ["std"] - [[test]] name = "ui" required-features = ["_ui_test"] diff --git a/schemars/src/json_schema_impls/ffi.rs b/schemars/src/json_schema_impls/ffi.rs index cf2efe5a..638fb6c0 100644 --- a/schemars/src/json_schema_impls/ffi.rs +++ b/schemars/src/json_schema_impls/ffi.rs @@ -2,6 +2,7 @@ use crate::SchemaGenerator; use crate::_alloc_prelude::*; use crate::{json_schema, JsonSchema, Schema}; use alloc::borrow::Cow; +use serde_json::json; use std::ffi::{CStr, CString, OsStr, OsString}; impl JsonSchema for OsString { @@ -37,5 +38,31 @@ impl JsonSchema for OsString { forward_impl!(OsStr => OsString); -forward_impl!(CString => Vec); -forward_impl!(CStr => Vec); +impl JsonSchema for CString { + fn schema_name() -> Cow<'static, str> { + "CString".into() + } + + fn schema_id() -> Cow<'static, str> { + "std::ffi::CString".into() + } + + fn json_schema(generator: &mut SchemaGenerator) -> Schema { + let ty = if generator.contract().is_deserialize() { + json!(["array", "string"]) + } else { + json!("array") + }; + + json_schema!({ + "type": ty, + "items": { + "type": "integer", + "minimum": 1, + "maximum": 255 + }, + }) + } +} + +forward_impl!(CStr => CString); diff --git a/schemars/tests/expected/duration_and_systemtime.json b/schemars/tests/expected/duration_and_systemtime.json deleted file mode 100644 index 7e301e5b..00000000 --- a/schemars/tests/expected/duration_and_systemtime.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "MyStruct", - "type": "object", - "properties": { - "duration": { - "$ref": "#/$defs/Duration" - }, - "time": { - "$ref": "#/$defs/SystemTime" - } - }, - "required": [ - "duration", - "time" - ], - "$defs": { - "Duration": { - "type": "object", - "properties": { - "secs": { - "type": "integer", - "format": "uint64", - "minimum": 0 - }, - "nanos": { - "type": "integer", - "format": "uint32", - "minimum": 0 - } - }, - "required": [ - "secs", - "nanos" - ] - }, - "SystemTime": { - "type": "object", - "properties": { - "secs_since_epoch": { - "type": "integer", - "format": "uint64", - "minimum": 0 - }, - "nanos_since_epoch": { - "type": "integer", - "format": "uint32", - "minimum": 0 - } - }, - "required": [ - "secs_since_epoch", - "nanos_since_epoch" - ] - } - } -} \ No newline at end of file diff --git a/schemars/tests/expected/no-variants.json b/schemars/tests/expected/no-variants.json deleted file mode 100644 index 6e801379..00000000 --- a/schemars/tests/expected/no-variants.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "NoVariants", - "not": {} -} \ No newline at end of file diff --git a/schemars/tests/expected/os_strings.json b/schemars/tests/expected/os_strings.json deleted file mode 100644 index 72e0be10..00000000 --- a/schemars/tests/expected/os_strings.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "OsStrings", - "type": "object", - "properties": { - "owned": { - "$ref": "#/$defs/OsString" - }, - "borrowed": { - "$ref": "#/$defs/OsString" - } - }, - "required": [ - "owned", - "borrowed" - ], - "$defs": { - "OsString": { - "oneOf": [ - { - "type": "object", - "properties": { - "Unix": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0 - } - } - }, - "required": [ - "Unix" - ] - }, - { - "type": "object", - "properties": { - "Windows": { - "type": "array", - "items": { - "type": "integer", - "format": "uint16", - "minimum": 0 - } - } - }, - "required": [ - "Windows" - ] - } - ] - } - } -} \ No newline at end of file diff --git a/schemars/tests/expected/range.json b/schemars/tests/expected/range.json deleted file mode 100644 index 64db4bdc..00000000 --- a/schemars/tests/expected/range.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "MyStruct", - "type": "object", - "properties": { - "range": { - "$ref": "#/$defs/Range_of_uint" - }, - "inclusive": { - "$ref": "#/$defs/Range_of_double" - }, - "bound": { - "$ref": "#/$defs/Bound_of_string" - } - }, - "required": [ - "range", - "inclusive", - "bound" - ], - "$defs": { - "Range_of_uint": { - "type": "object", - "properties": { - "start": { - "type": "integer", - "format": "uint", - "minimum": 0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0 - } - }, - "required": [ - "start", - "end" - ] - }, - "Range_of_double": { - "type": "object", - "properties": { - "start": { - "type": "number", - "format": "double" - }, - "end": { - "type": "number", - "format": "double" - } - }, - "required": [ - "start", - "end" - ] - }, - "Bound_of_string": { - "oneOf": [ - { - "type": "object", - "properties": { - "Included": { - "type": "string" - } - }, - "required": [ - "Included" - ] - }, - { - "type": "object", - "properties": { - "Excluded": { - "type": "string" - } - }, - "required": [ - "Excluded" - ] - }, - { - "type": "string", - "const": "Unbounded" - } - ] - } - } -} \ No newline at end of file diff --git a/schemars/tests/expected/result.json b/schemars/tests/expected/result.json deleted file mode 100644 index b468835c..00000000 --- a/schemars/tests/expected/result.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "Container", - "type": "object", - "properties": { - "result1": { - "$ref": "#/$defs/Result_of_MyStruct_or_Array_of_string" - }, - "result2": { - "$ref": "#/$defs/Result_of_boolean_or_null" - } - }, - "required": [ - "result1", - "result2" - ], - "$defs": { - "Result_of_MyStruct_or_Array_of_string": { - "oneOf": [ - { - "type": "object", - "properties": { - "Ok": { - "$ref": "#/$defs/MyStruct" - } - }, - "required": [ - "Ok" - ] - }, - { - "type": "object", - "properties": { - "Err": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "Err" - ] - } - ] - }, - "MyStruct": { - "type": "object", - "properties": { - "foo": { - "type": "integer", - "format": "int32" - } - }, - "required": [ - "foo" - ] - }, - "Result_of_boolean_or_null": { - "oneOf": [ - { - "type": "object", - "properties": { - "Ok": { - "type": "boolean" - } - }, - "required": [ - "Ok" - ] - }, - { - "type": "object", - "properties": { - "Err": { - "type": "null" - } - }, - "required": [ - "Err" - ] - } - ] - } - } -} \ No newline at end of file diff --git a/schemars/tests/ffi.rs b/schemars/tests/ffi.rs deleted file mode 100644 index 41bb8ce6..00000000 --- a/schemars/tests/ffi.rs +++ /dev/null @@ -1,16 +0,0 @@ -mod util; -use schemars::JsonSchema; -use std::ffi::{OsStr, OsString}; -use util::*; - -#[allow(dead_code)] -#[derive(JsonSchema)] -struct OsStrings { - owned: OsString, - borrowed: &'static OsStr, -} - -#[test] -fn os_strings() -> TestResult { - test_default_generated_schema::("os_strings") -} diff --git a/schemars/tests/integration/enums_flattened.rs b/schemars/tests/integration/enums_flattened.rs index 930fe47f..dd0f2f7f 100644 --- a/schemars/tests/integration/enums_flattened.rs +++ b/schemars/tests/integration/enums_flattened.rs @@ -1,6 +1,5 @@ -use schemars::generate::SchemaSettings; - use crate::prelude::*; +use schemars::generate::SchemaSettings; macro_rules! fn_values { () => { diff --git a/schemars/tests/integration/main.rs b/schemars/tests/integration/main.rs index 365fc457..43fdaea3 100644 --- a/schemars/tests/integration/main.rs +++ b/schemars/tests/integration/main.rs @@ -20,6 +20,7 @@ mod enum_repr; mod enums; mod enums_deny_unknown_fields; mod enums_flattened; +mod std_types; mod prelude { pub use crate::test; diff --git a/schemars/tests/integration/std_types.rs b/schemars/tests/integration/std_types.rs new file mode 100644 index 00000000..46bf5000 --- /dev/null +++ b/schemars/tests/integration/std_types.rs @@ -0,0 +1,97 @@ +use crate::prelude::*; +use std::ffi::{CStr, CString, OsStr, OsString}; +use std::marker::PhantomData; +use std::ops::{Bound, Range, RangeInclusive}; +use std::time::{Duration, SystemTime}; + +#[test] +fn option() { + test!(Option) + .assert_allows_ser_roundtrip([Some(true), None]) + .assert_matches_de_roundtrip(arbitrary_values()); +} + +#[test] +fn result() { + test!(Result) + .assert_allows_ser_roundtrip([Ok(true), Err("oh no!".to_owned())]) + .assert_matches_de_roundtrip(arbitrary_values()); +} + +#[test] +fn time() { + test!(SystemTime) + .assert_allows_ser_roundtrip([SystemTime::UNIX_EPOCH, SystemTime::now()]) + .assert_matches_de_roundtrip(arbitrary_values()); + + test!(Duration) + .assert_allows_ser_roundtrip([Duration::from_secs(0), Duration::from_secs_f64(123.456)]) + .assert_matches_de_roundtrip(arbitrary_values()); +} + +#[test] +fn c_strings() { + let strings = [ + CString::default(), + CString::new("test").unwrap(), + CString::new([255]).unwrap(), + ]; + + test!(CString) + .assert_allows_ser_roundtrip(strings.clone()) + .assert_matches_de_roundtrip(arbitrary_values_except( + |v| v.as_str().is_some_and(|s| s.contains('\0')), + "CString cannot contain null bytes, but schema does not enforce this", + )); + + test!(Box) + .assert_identical::() + .assert_allows_ser_roundtrip(strings.into_iter().map(Into::into)) + .assert_matches_de_roundtrip(arbitrary_values_except( + |v| v.as_str().is_some_and(|s| s.contains('\0')), + "CString cannot contain null bytes, but schema does not enforce this", + )); +} + +#[test] +fn os_strings() { + let strings = [OsString::new(), OsString::from("test")]; + + test!(OsString) + .assert_allows_ser_roundtrip(strings.clone()) + .assert_matches_de_roundtrip(arbitrary_values()); + + test!(Box) + .assert_identical::() + .assert_allows_ser_roundtrip(strings.into_iter().map(Into::into)) + .assert_matches_de_roundtrip(arbitrary_values()); +} + +#[test] +fn bound() { + test!(Bound).assert_allows_ser_roundtrip([ + Bound::Included(123), + Bound::Excluded(456), + Bound::Unbounded, + ]); +} + +#[test] +fn ranges() { + test!(Range) + .assert_allows_ser_roundtrip([0..0, 123..456]) + .assert_matches_de_roundtrip(arbitrary_values()); + + test!(RangeInclusive) + .assert_allows_ser_roundtrip([0..=0, 123..=456]) + .assert_matches_de_roundtrip(arbitrary_values()); +} + +#[test] +fn phantom_data() { + struct DoesNotImplementJsonSchema; + + test!(PhantomData) + .assert_allows_ser_roundtrip_default() + .assert_matches_de_roundtrip(arbitrary_values()); +} diff --git a/schemars/tests/range.rs b/schemars/tests/range.rs deleted file mode 100644 index 0dad2190..00000000 --- a/schemars/tests/range.rs +++ /dev/null @@ -1,17 +0,0 @@ -mod util; -use schemars::JsonSchema; -use std::ops::{Bound, Range, RangeInclusive}; -use util::*; - -#[allow(dead_code)] -#[derive(JsonSchema)] -struct MyStruct { - range: Range, - inclusive: RangeInclusive, - bound: Bound, -} - -#[test] -fn result() -> TestResult { - test_default_generated_schema::("range") -} diff --git a/schemars/tests/result.rs b/schemars/tests/result.rs deleted file mode 100644 index b0657e0b..00000000 --- a/schemars/tests/result.rs +++ /dev/null @@ -1,21 +0,0 @@ -mod util; -use schemars::JsonSchema; -use util::*; - -#[allow(dead_code)] -#[derive(JsonSchema)] -struct MyStruct { - foo: i32, -} - -#[allow(dead_code)] -#[derive(JsonSchema)] -struct Container { - result1: Result>, - result2: Result, -} - -#[test] -fn result() -> TestResult { - test_default_generated_schema::("result") -} diff --git a/schemars/tests/std_time.rs b/schemars/tests/std_time.rs deleted file mode 100644 index 7f70a59b..00000000 --- a/schemars/tests/std_time.rs +++ /dev/null @@ -1,16 +0,0 @@ -mod util; -use schemars::JsonSchema; -use std::time::{Duration, SystemTime}; -use util::*; - -#[allow(dead_code)] -#[derive(JsonSchema)] -struct MyStruct { - duration: Duration, - time: SystemTime, -} - -#[test] -fn duration_and_systemtime() -> TestResult { - test_default_generated_schema::("duration_and_systemtime") -}