From 866629ef71e82b038abea1f9308d70c3826aaf00 Mon Sep 17 00:00:00 2001 From: Graham Esau Date: Mon, 9 Sep 2024 12:07:06 +0100 Subject: [PATCH] Port (most) enum tests to new integration test style --- schemars/tests/enum.rs | 185 ---------- .../expected/enum-rename-all-fields.json | 26 -- schemars/tests/expected/enum-rename-all.json | 26 -- schemars/tests/expected/enum-rename-attr.json | 26 -- schemars/tests/integration/enums.rs | 337 ++++++++++++++++++ schemars/tests/integration/main.rs | 1 + .../enums.rs~adjacently_tagged_enum.de.json} | 77 ++-- .../enums.rs~adjacently_tagged_enum.ser.json | 192 ++++++++++ .../enums.rs~externally_tagged_enum.de.json} | 19 +- .../enums.rs~externally_tagged_enum.ser.json | 147 ++++++++ .../enums.rs~internally_tagged_enum.de.json} | 37 +- .../enums.rs~internally_tagged_enum.ser.json | 99 +++++ .../integration/enums.rs~no_variants.de.json | 5 + .../integration/enums.rs~no_variants.ser.json | 5 + .../integration/enums.rs~renamed.de.json | 46 +++ .../integration/enums.rs~renamed.ser.json | 46 +++ ...s~unit_variants_with_doc_comments.de.json} | 0 ...s~unit_variants_with_doc_comments.ser.json | 22 ++ .../enums.rs~untagged_enum.de.json} | 10 +- .../enums.rs~untagged_enum.ser.json | 84 +++++ 20 files changed, 1068 insertions(+), 322 deletions(-) delete mode 100644 schemars/tests/enum.rs delete mode 100644 schemars/tests/expected/enum-rename-all-fields.json delete mode 100644 schemars/tests/expected/enum-rename-all.json delete mode 100644 schemars/tests/expected/enum-rename-attr.json create mode 100644 schemars/tests/integration/enums.rs rename schemars/tests/{expected/enum-adjacent-tagged.json => integration/snapshots/schemars/tests/integration/enums.rs~adjacently_tagged_enum.de.json} (75%) create mode 100644 schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~adjacently_tagged_enum.ser.json rename schemars/tests/{expected/enum-external.json => integration/snapshots/schemars/tests/integration/enums.rs~externally_tagged_enum.de.json} (88%) create mode 100644 schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~externally_tagged_enum.ser.json rename schemars/tests/{expected/enum-internal.json => integration/snapshots/schemars/tests/integration/enums.rs~internally_tagged_enum.de.json} (73%) create mode 100644 schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~internally_tagged_enum.ser.json create mode 100644 schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~no_variants.de.json create mode 100644 schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~no_variants.ser.json create mode 100644 schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~renamed.de.json create mode 100644 schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~renamed.ser.json rename schemars/tests/{expected/enum-unit-doc.json => integration/snapshots/schemars/tests/integration/enums.rs~unit_variants_with_doc_comments.de.json} (100%) create mode 100644 schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~unit_variants_with_doc_comments.ser.json rename schemars/tests/{expected/enum-untagged.json => integration/snapshots/schemars/tests/integration/enums.rs~untagged_enum.de.json} (88%) create mode 100644 schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~untagged_enum.ser.json diff --git a/schemars/tests/enum.rs b/schemars/tests/enum.rs deleted file mode 100644 index 45698a78..00000000 --- a/schemars/tests/enum.rs +++ /dev/null @@ -1,185 +0,0 @@ -mod util; -use std::collections::BTreeMap; - -use schemars::JsonSchema; -use util::*; - -// Ensure that schemars_derive uses the full path to std::string::String -pub struct String; - -#[derive(JsonSchema)] -struct UnitStruct; - -#[allow(dead_code)] -#[derive(JsonSchema)] -struct Struct { - foo: i32, - bar: bool, -} - -#[allow(dead_code)] -#[derive(JsonSchema)] -#[schemars(rename_all = "camelCase")] -enum External { - UnitOne, - StringMap(BTreeMap<&'static str, &'static str>), - UnitStructNewType(UnitStruct), - StructNewType(Struct), - Struct { - foo: i32, - bar: bool, - }, - UnitTwo, - Tuple(i32, bool), - #[schemars(with = "i32")] - WithInt, -} - -#[test] -fn enum_external_tag() -> TestResult { - test_default_generated_schema::("enum-external") -} - -#[allow(dead_code)] -#[derive(JsonSchema)] -#[schemars(tag = "typeProperty")] -enum Internal { - UnitOne, - StringMap(BTreeMap<&'static str, &'static str>), - UnitStructNewType(UnitStruct), - StructNewType(Struct), - Struct { - foo: i32, - bar: bool, - }, - UnitTwo, - #[schemars(with = "i32")] - WithInt, -} - -#[test] -fn enum_internal_tag() -> TestResult { - test_default_generated_schema::("enum-internal") -} - -#[allow(dead_code)] -#[derive(JsonSchema)] -#[schemars(untagged)] -enum Untagged { - UnitOne, - StringMap(BTreeMap<&'static str, &'static str>), - UnitStructNewType(UnitStruct), - StructNewType(Struct), - Struct { - foo: i32, - bar: bool, - }, - Tuple(i32, bool), - #[schemars(with = "i32")] - WithInt, -} - -#[test] -fn enum_untagged() -> TestResult { - test_default_generated_schema::("enum-untagged") -} - -#[allow(dead_code)] -#[derive(JsonSchema)] -#[schemars(tag = "t", content = "c")] -enum Adjacent { - UnitOne, - StringMap(BTreeMap<&'static str, &'static str>), - UnitStructNewType(UnitStruct), - StructNewType(Struct), - Struct { - foo: i32, - bar: bool, - }, - Tuple(i32, bool), - UnitTwo, - #[schemars(with = "i32")] - WithInt, -} - -#[test] -fn enum_adjacent_tagged() -> TestResult { - test_default_generated_schema::("enum-adjacent-tagged") -} - -#[allow(dead_code)] -#[derive(JsonSchema)] -#[schemars(tag = "typeProperty")] -enum SimpleInternal { - A, - B, - C, -} - -#[test] -fn enum_simple_internal_tag() -> TestResult { - test_default_generated_schema::("enum-simple-internal") -} - -#[allow(dead_code)] -#[derive(JsonSchema)] -enum SoundOfMusic { - /// # A deer - /// - /// A female deer - Do, - /// A drop of golden sun - Re, - /// A name I call myself - Mi, -} - -#[test] -fn enum_unit_with_doc_comments() -> TestResult { - test_default_generated_schema::("enum-unit-doc") -} - -#[derive(JsonSchema)] -enum NoVariants {} - -#[test] -fn enum_no_variants() -> TestResult { - test_default_generated_schema::("no-variants") -} - -#[derive(JsonSchema)] -#[serde(rename_all_fields = "PascalCase")] -pub enum RenameAllFields { - First { - nested_attribute: std::string::String, - }, -} - -#[derive(JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum RenameAll { - First { nested_attribute: bool }, -} - -#[derive(JsonSchema)] -pub enum RenameAttribute { - First { - #[serde(rename = "RenamedAttribute")] - nested_attribute: std::string::String, - }, -} - -#[test] -fn enum_unit_rename_attribute() -> TestResult { - test_default_generated_schema::("enum-rename-attr") -} - -#[test] -fn enum_unit_rename_all_fields() -> TestResult { - test_default_generated_schema::("enum-rename-all-fields") -} - -#[test] -fn enum_unit_rename_all() -> TestResult { - test_default_generated_schema::("enum-rename-all") -} diff --git a/schemars/tests/expected/enum-rename-all-fields.json b/schemars/tests/expected/enum-rename-all-fields.json deleted file mode 100644 index 422a6944..00000000 --- a/schemars/tests/expected/enum-rename-all-fields.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "RenameAllFields", - "oneOf": [ - { - "type": "object", - "properties": { - "First": { - "type": "object", - "properties": { - "NestedAttribute": { - "type": "string" - } - }, - "required": [ - "NestedAttribute" - ] - } - }, - "required": [ - "First" - ], - "additionalProperties": false - } - ] -} \ No newline at end of file diff --git a/schemars/tests/expected/enum-rename-all.json b/schemars/tests/expected/enum-rename-all.json deleted file mode 100644 index eb237be4..00000000 --- a/schemars/tests/expected/enum-rename-all.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "RenameAll", - "oneOf": [ - { - "type": "object", - "properties": { - "first": { - "type": "object", - "properties": { - "nested_attribute": { - "type": "boolean" - } - }, - "required": [ - "nested_attribute" - ] - } - }, - "required": [ - "first" - ], - "additionalProperties": false - } - ] -} \ No newline at end of file diff --git a/schemars/tests/expected/enum-rename-attr.json b/schemars/tests/expected/enum-rename-attr.json deleted file mode 100644 index a9f3706a..00000000 --- a/schemars/tests/expected/enum-rename-attr.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "RenameAttribute", - "oneOf": [ - { - "type": "object", - "properties": { - "First": { - "type": "object", - "properties": { - "RenamedAttribute": { - "type": "string" - } - }, - "required": [ - "RenamedAttribute" - ] - } - }, - "required": [ - "First" - ], - "additionalProperties": false - } - ] -} \ No newline at end of file diff --git a/schemars/tests/integration/enums.rs b/schemars/tests/integration/enums.rs new file mode 100644 index 00000000..bd223814 --- /dev/null +++ b/schemars/tests/integration/enums.rs @@ -0,0 +1,337 @@ +use std::collections::BTreeMap; + +use crate::prelude::*; + +#[derive(JsonSchema, Deserialize, Serialize)] +struct UnitStruct; + +#[derive(JsonSchema, Deserialize, Serialize, Default)] +struct Struct { + foo: i32, + bar: bool, +} + +#[derive(JsonSchema, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +enum External { + UnitOne, + StringMap(BTreeMap), + UnitStructNewType(UnitStruct), + StructNewType(Struct), + Struct { + foo: i32, + bar: bool, + }, + Tuple(i32, bool), + UnitTwo, + #[serde(with = "unit_variant_as_u64")] + #[schemars(with = "u64")] + UnitAsInt, + #[serde(with = "tuple_variant_as_str")] + #[schemars(with = "str")] + TupleAsStr(i32, bool), +} + +impl External { + fn values() -> impl IntoIterator { + [ + Self::UnitOne, + Self::StringMap( + [("hello".to_owned(), "world".to_owned())] + .into_iter() + .collect(), + ), + Self::UnitStructNewType(UnitStruct), + Self::Struct { + foo: 123, + bar: true, + }, + Self::Tuple(456, false), + Self::UnitTwo, + Self::UnitAsInt, + Self::TupleAsStr(789, true), + ] + } +} + +#[derive(JsonSchema, Deserialize, Serialize)] +#[serde(tag = "tag")] +enum Internal { + UnitOne, + StringMap(BTreeMap), + UnitStructNewType(UnitStruct), + StructNewType(Struct), + Struct { foo: i32, bar: bool }, + // Internally-tagged enums don't support tuple variants + // Tuple(i32, bool), + UnitTwo, + // Internally-tagged enum variants don't support non-object "payloads" + // #[serde(with = "unit_variant_as_u64")] + // #[schemars(with = "u64")] + // UnitAsInt, + // Internally-tagged enums don't support tuple variants + // #[serde(with = "tuple_variant_as_str")] + // #[schemars(with = "str")] + // TupleAsStr(i32, bool), +} + +impl Internal { + fn values() -> impl IntoIterator { + [ + Self::UnitOne, + Self::StringMap( + [("hello".to_owned(), "world".to_owned())] + .into_iter() + .collect(), + ), + Self::UnitStructNewType(UnitStruct), + Self::Struct { + foo: 123, + bar: true, + }, + // Self::Tuple(456, false), + Self::UnitTwo, + // Self::UnitAsInt, + // Self::TupleAsStr(789, true), + ] + } +} + +#[derive(JsonSchema, Deserialize, Serialize)] +#[serde(tag = "tag", content = "content")] +enum Adjacent { + UnitOne, + StringMap(BTreeMap), + UnitStructNewType(UnitStruct), + StructNewType(Struct), + Struct { + foo: i32, + bar: bool, + }, + Tuple(i32, bool), + UnitTwo, + #[serde(with = "unit_variant_as_u64")] + #[schemars(with = "u64")] + UnitAsInt, + #[serde(with = "tuple_variant_as_str")] + #[schemars(with = "str")] + TupleAsStr(i32, bool), +} + +impl Adjacent { + fn values() -> impl IntoIterator { + [ + Self::UnitOne, + Self::StringMap( + [("hello".to_owned(), "world".to_owned())] + .into_iter() + .collect(), + ), + Self::UnitStructNewType(UnitStruct), + Self::Struct { + foo: 123, + bar: true, + }, + Self::Tuple(456, false), + Self::UnitTwo, + Self::UnitAsInt, + Self::TupleAsStr(789, true), + ] + } +} + +#[derive(JsonSchema, Deserialize, Serialize)] +#[serde(untagged)] +enum Untagged { + UnitOne, + StringMap(BTreeMap), + UnitStructNewType(UnitStruct), + StructNewType(Struct), + Struct { + foo: i32, + bar: bool, + }, + Tuple(i32, bool), + UnitTwo, + #[serde(with = "unit_variant_as_u64")] + #[schemars(with = "u64")] + UnitAsInt, + #[serde(with = "tuple_variant_as_str")] + #[schemars(with = "str", extend("pattern" = r"^\d+ (true|false)$"))] + TupleAsStr(i32, bool), +} + +impl Untagged { + fn values() -> impl IntoIterator { + [ + Self::UnitOne, + Self::StringMap( + [("hello".to_owned(), "world".to_owned())] + .into_iter() + .collect(), + ), + Self::UnitStructNewType(UnitStruct), + Self::Struct { + foo: 123, + bar: true, + }, + Self::Tuple(456, false), + Self::UnitTwo, + Self::UnitAsInt, + Self::TupleAsStr(789, true), + ] + } +} + +mod unit_variant_as_u64 { + pub(super) fn serialize(ser: S) -> Result + where + S: serde::Serializer, + { + ser.serialize_u64(42) + } + + pub(super) fn deserialize<'de, D>(deser: D) -> Result<(), D::Error> + where + D: serde::Deserializer<'de>, + { + use serde::de::Deserialize; + + u64::deserialize(deser).map(|_| ()) + } +} + +mod tuple_variant_as_str { + pub(super) fn serialize(i: &i32, b: &bool, ser: S) -> Result + where + S: serde::Serializer, + { + ser.collect_str(&format_args!("{i} {b}")) + } + + pub(super) fn deserialize<'de, D>(deser: D) -> Result<(i32, bool), D::Error> + where + D: serde::Deserializer<'de>, + { + use serde::de::{Deserialize, Error}; + let error = || Error::custom("invalid string"); + + let (i, b) = <&str>::deserialize(deser)? + .split_once(' ') + .ok_or_else(error)?; + + Ok(( + i.parse().map_err(|_| error())?, + b.parse().map_err(|_| error())?, + )) + } +} + +#[test] +fn externally_tagged_enum() { + test!(External) + .assert_snapshot() + .assert_allows_ser_roundtrip(External::values()) + .assert_matches_de_roundtrip(arbitrary_values()); +} + +#[test] +fn internally_tagged_enum() { + test!(Internal) + .assert_snapshot() + .assert_allows_ser_roundtrip(Internal::values()) + .assert_matches_de_roundtrip(arbitrary_values()); +} + +#[test] +fn adjacently_tagged_enum() { + test!(Adjacent) + .assert_snapshot() + .assert_allows_ser_roundtrip(Adjacent::values()) + .assert_matches_de_roundtrip(arbitrary_values()); +} + +#[test] +fn untagged_enum() { + test!(Untagged) + .assert_snapshot() + .assert_allows_ser_roundtrip(Untagged::values()) + .assert_matches_de_roundtrip(arbitrary_values()); +} + +#[derive(JsonSchema, Serialize, Deserialize)] +enum NoVariants {} + +#[test] +fn no_variants() { + test!(NoVariants) + .assert_snapshot() + .assert_rejects_de(arbitrary_values()); +} + +#[derive(JsonSchema, Serialize, Deserialize)] +#[serde(rename_all_fields = "UPPERCASE", rename_all = "snake_case")] +enum Renamed { + StructVariant { + field: String, + }, + #[serde(rename = "custom name variant")] + RenamedStructVariant { + #[serde(rename = "custom name field")] + field: String, + }, +} + +#[test] +fn renamed() { + test!(Renamed) + .assert_snapshot() + .assert_allows_ser_roundtrip([ + Renamed::StructVariant { + field: "foo".to_owned(), + }, + Renamed::RenamedStructVariant { + field: "bar".to_owned(), + }, + ]) + .assert_rejects_de(arbitrary_values()); +} + +#[allow(dead_code)] +#[derive(JsonSchema, Deserialize, Serialize)] +enum SoundOfMusic { + /// # A deer + /// + /// A female deer + Do, + /// A drop of golden sun + Re, + /// A name I call myself + Mi, +} + +#[test] +fn unit_variants_with_doc_comments() { + test!(SoundOfMusic) + .assert_snapshot() + .assert_allows_ser_roundtrip([SoundOfMusic::Do, SoundOfMusic::Re, SoundOfMusic::Mi]) + .assert_rejects_de(arbitrary_values()) + .custom(|schema, _| { + assert_eq!( + schema.as_value().pointer("/oneOf/0/title"), + Some(&("A deer".into())), + ); + assert_eq!( + schema.as_value().pointer("/oneOf/0/description"), + Some(&("A female deer".into())), + ); + assert_eq!( + schema.as_value().pointer("/oneOf/1/description"), + Some(&("A drop of golden sun".into())), + ); + assert_eq!( + schema.as_value().pointer("/oneOf/2/description"), + Some(&("A name I call myself".into())), + ); + }); +} diff --git a/schemars/tests/integration/main.rs b/schemars/tests/integration/main.rs index d733a865..ade7ce32 100644 --- a/schemars/tests/integration/main.rs +++ b/schemars/tests/integration/main.rs @@ -17,6 +17,7 @@ mod docs; #[cfg(feature = "either1")] mod either; mod enum_repr; +mod enums; mod prelude { pub use crate::test; diff --git a/schemars/tests/expected/enum-adjacent-tagged.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~adjacently_tagged_enum.de.json similarity index 75% rename from schemars/tests/expected/enum-adjacent-tagged.json rename to schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~adjacently_tagged_enum.de.json index 7599fd10..42f40ba3 100644 --- a/schemars/tests/expected/enum-adjacent-tagged.json +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~adjacently_tagged_enum.de.json @@ -5,23 +5,23 @@ { "type": "object", "properties": { - "t": { + "tag": { "type": "string", "const": "UnitOne" } }, "required": [ - "t" + "tag" ] }, { "type": "object", "properties": { - "t": { + "tag": { "type": "string", "const": "StringMap" }, - "c": { + "content": { "type": "object", "additionalProperties": { "type": "string" @@ -29,50 +29,50 @@ } }, "required": [ - "t", - "c" + "tag", + "content" ] }, { "type": "object", "properties": { - "t": { + "tag": { "type": "string", "const": "UnitStructNewType" }, - "c": { + "content": { "$ref": "#/$defs/UnitStruct" } }, "required": [ - "t", - "c" + "tag", + "content" ] }, { "type": "object", "properties": { - "t": { + "tag": { "type": "string", "const": "StructNewType" }, - "c": { + "content": { "$ref": "#/$defs/Struct" } }, "required": [ - "t", - "c" + "tag", + "content" ] }, { "type": "object", "properties": { - "t": { + "tag": { "type": "string", "const": "Struct" }, - "c": { + "content": { "type": "object", "properties": { "foo": { @@ -90,18 +90,18 @@ } }, "required": [ - "t", - "c" + "tag", + "content" ] }, { "type": "object", "properties": { - "t": { + "tag": { "type": "string", "const": "Tuple" }, - "c": { + "content": { "type": "array", "prefixItems": [ { @@ -117,37 +117,54 @@ } }, "required": [ - "t", - "c" + "tag", + "content" ] }, { "type": "object", "properties": { - "t": { + "tag": { "type": "string", "const": "UnitTwo" } }, "required": [ - "t" + "tag" ] }, { "type": "object", "properties": { - "t": { + "tag": { "type": "string", - "const": "WithInt" + "const": "UnitAsInt" }, - "c": { + "content": { "type": "integer", - "format": "int32" + "format": "uint64", + "minimum": 0 + } + }, + "required": [ + "tag", + "content" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "TupleAsStr" + }, + "content": { + "type": "string" } }, "required": [ - "t", - "c" + "tag", + "content" ] } ], diff --git a/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~adjacently_tagged_enum.ser.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~adjacently_tagged_enum.ser.json new file mode 100644 index 00000000..42f40ba3 --- /dev/null +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~adjacently_tagged_enum.ser.json @@ -0,0 +1,192 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Adjacent", + "oneOf": [ + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "UnitOne" + } + }, + "required": [ + "tag" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "StringMap" + }, + "content": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": [ + "tag", + "content" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "UnitStructNewType" + }, + "content": { + "$ref": "#/$defs/UnitStruct" + } + }, + "required": [ + "tag", + "content" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "StructNewType" + }, + "content": { + "$ref": "#/$defs/Struct" + } + }, + "required": [ + "tag", + "content" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "Struct" + }, + "content": { + "type": "object", + "properties": { + "foo": { + "type": "integer", + "format": "int32" + }, + "bar": { + "type": "boolean" + } + }, + "required": [ + "foo", + "bar" + ] + } + }, + "required": [ + "tag", + "content" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "Tuple" + }, + "content": { + "type": "array", + "prefixItems": [ + { + "type": "integer", + "format": "int32" + }, + { + "type": "boolean" + } + ], + "minItems": 2, + "maxItems": 2 + } + }, + "required": [ + "tag", + "content" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "UnitTwo" + } + }, + "required": [ + "tag" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "UnitAsInt" + }, + "content": { + "type": "integer", + "format": "uint64", + "minimum": 0 + } + }, + "required": [ + "tag", + "content" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "TupleAsStr" + }, + "content": { + "type": "string" + } + }, + "required": [ + "tag", + "content" + ] + } + ], + "$defs": { + "UnitStruct": { + "type": "null" + }, + "Struct": { + "type": "object", + "properties": { + "foo": { + "type": "integer", + "format": "int32" + }, + "bar": { + "type": "boolean" + } + }, + "required": [ + "foo", + "bar" + ] + } + } +} \ No newline at end of file diff --git a/schemars/tests/expected/enum-external.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~externally_tagged_enum.de.json similarity index 88% rename from schemars/tests/expected/enum-external.json rename to schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~externally_tagged_enum.de.json index 3c660fb9..a0aed5fe 100644 --- a/schemars/tests/expected/enum-external.json +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~externally_tagged_enum.de.json @@ -99,13 +99,26 @@ { "type": "object", "properties": { - "withInt": { + "unitAsInt": { "type": "integer", - "format": "int32" + "format": "uint64", + "minimum": 0 + } + }, + "required": [ + "unitAsInt" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "tupleAsStr": { + "type": "string" } }, "required": [ - "withInt" + "tupleAsStr" ], "additionalProperties": false } diff --git a/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~externally_tagged_enum.ser.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~externally_tagged_enum.ser.json new file mode 100644 index 00000000..a0aed5fe --- /dev/null +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~externally_tagged_enum.ser.json @@ -0,0 +1,147 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "External", + "oneOf": [ + { + "type": "string", + "enum": [ + "unitOne", + "unitTwo" + ] + }, + { + "type": "object", + "properties": { + "stringMap": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": [ + "stringMap" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "unitStructNewType": { + "$ref": "#/$defs/UnitStruct" + } + }, + "required": [ + "unitStructNewType" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "structNewType": { + "$ref": "#/$defs/Struct" + } + }, + "required": [ + "structNewType" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "struct": { + "type": "object", + "properties": { + "foo": { + "type": "integer", + "format": "int32" + }, + "bar": { + "type": "boolean" + } + }, + "required": [ + "foo", + "bar" + ] + } + }, + "required": [ + "struct" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "tuple": { + "type": "array", + "prefixItems": [ + { + "type": "integer", + "format": "int32" + }, + { + "type": "boolean" + } + ], + "minItems": 2, + "maxItems": 2 + } + }, + "required": [ + "tuple" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "unitAsInt": { + "type": "integer", + "format": "uint64", + "minimum": 0 + } + }, + "required": [ + "unitAsInt" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "tupleAsStr": { + "type": "string" + } + }, + "required": [ + "tupleAsStr" + ], + "additionalProperties": false + } + ], + "$defs": { + "UnitStruct": { + "type": "null" + }, + "Struct": { + "type": "object", + "properties": { + "foo": { + "type": "integer", + "format": "int32" + }, + "bar": { + "type": "boolean" + } + }, + "required": [ + "foo", + "bar" + ] + } + } +} \ No newline at end of file diff --git a/schemars/tests/expected/enum-internal.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~internally_tagged_enum.de.json similarity index 73% rename from schemars/tests/expected/enum-internal.json rename to schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~internally_tagged_enum.de.json index 2fd9770f..e91dcb6a 100644 --- a/schemars/tests/expected/enum-internal.json +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~internally_tagged_enum.de.json @@ -5,19 +5,19 @@ { "type": "object", "properties": { - "typeProperty": { + "tag": { "type": "string", "const": "UnitOne" } }, "required": [ - "typeProperty" + "tag" ] }, { "type": "object", "properties": { - "typeProperty": { + "tag": { "type": "string", "const": "StringMap" } @@ -26,19 +26,19 @@ "type": "string" }, "required": [ - "typeProperty" + "tag" ] }, { "type": "object", "properties": { - "typeProperty": { + "tag": { "type": "string", "const": "UnitStructNewType" } }, "required": [ - "typeProperty" + "tag" ] }, { @@ -51,13 +51,13 @@ "bar": { "type": "boolean" }, - "typeProperty": { + "tag": { "type": "string", "const": "StructNewType" } }, "required": [ - "typeProperty", + "tag", "foo", "bar" ] @@ -72,13 +72,13 @@ "bar": { "type": "boolean" }, - "typeProperty": { + "tag": { "type": "string", "const": "Struct" } }, "required": [ - "typeProperty", + "tag", "foo", "bar" ] @@ -86,26 +86,13 @@ { "type": "object", "properties": { - "typeProperty": { + "tag": { "type": "string", "const": "UnitTwo" } }, "required": [ - "typeProperty" - ] - }, - { - "type": "object", - "format": "int32", - "properties": { - "typeProperty": { - "type": "string", - "const": "WithInt" - } - }, - "required": [ - "typeProperty" + "tag" ] } ] diff --git a/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~internally_tagged_enum.ser.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~internally_tagged_enum.ser.json new file mode 100644 index 00000000..e91dcb6a --- /dev/null +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~internally_tagged_enum.ser.json @@ -0,0 +1,99 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Internal", + "oneOf": [ + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "UnitOne" + } + }, + "required": [ + "tag" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "StringMap" + } + }, + "additionalProperties": { + "type": "string" + }, + "required": [ + "tag" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "UnitStructNewType" + } + }, + "required": [ + "tag" + ] + }, + { + "type": "object", + "properties": { + "foo": { + "type": "integer", + "format": "int32" + }, + "bar": { + "type": "boolean" + }, + "tag": { + "type": "string", + "const": "StructNewType" + } + }, + "required": [ + "tag", + "foo", + "bar" + ] + }, + { + "type": "object", + "properties": { + "foo": { + "type": "integer", + "format": "int32" + }, + "bar": { + "type": "boolean" + }, + "tag": { + "type": "string", + "const": "Struct" + } + }, + "required": [ + "tag", + "foo", + "bar" + ] + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "const": "UnitTwo" + } + }, + "required": [ + "tag" + ] + } + ] +} \ No newline at end of file diff --git a/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~no_variants.de.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~no_variants.de.json new file mode 100644 index 00000000..6e801379 --- /dev/null +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~no_variants.de.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "NoVariants", + "not": {} +} \ No newline at end of file diff --git a/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~no_variants.ser.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~no_variants.ser.json new file mode 100644 index 00000000..6e801379 --- /dev/null +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~no_variants.ser.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "NoVariants", + "not": {} +} \ No newline at end of file diff --git a/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~renamed.de.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~renamed.de.json new file mode 100644 index 00000000..f2f52778 --- /dev/null +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~renamed.de.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Renamed", + "oneOf": [ + { + "type": "object", + "properties": { + "struct_variant": { + "type": "object", + "properties": { + "FIELD": { + "type": "string" + } + }, + "required": [ + "FIELD" + ] + } + }, + "required": [ + "struct_variant" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "custom name variant": { + "type": "object", + "properties": { + "custom name field": { + "type": "string" + } + }, + "required": [ + "custom name field" + ] + } + }, + "required": [ + "custom name variant" + ], + "additionalProperties": false + } + ] +} \ No newline at end of file diff --git a/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~renamed.ser.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~renamed.ser.json new file mode 100644 index 00000000..f2f52778 --- /dev/null +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~renamed.ser.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Renamed", + "oneOf": [ + { + "type": "object", + "properties": { + "struct_variant": { + "type": "object", + "properties": { + "FIELD": { + "type": "string" + } + }, + "required": [ + "FIELD" + ] + } + }, + "required": [ + "struct_variant" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "custom name variant": { + "type": "object", + "properties": { + "custom name field": { + "type": "string" + } + }, + "required": [ + "custom name field" + ] + } + }, + "required": [ + "custom name variant" + ], + "additionalProperties": false + } + ] +} \ No newline at end of file diff --git a/schemars/tests/expected/enum-unit-doc.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~unit_variants_with_doc_comments.de.json similarity index 100% rename from schemars/tests/expected/enum-unit-doc.json rename to schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~unit_variants_with_doc_comments.de.json diff --git a/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~unit_variants_with_doc_comments.ser.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~unit_variants_with_doc_comments.ser.json new file mode 100644 index 00000000..10004354 --- /dev/null +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~unit_variants_with_doc_comments.ser.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "SoundOfMusic", + "oneOf": [ + { + "title": "A deer", + "description": "A female deer", + "type": "string", + "const": "Do" + }, + { + "description": "A drop of golden sun", + "type": "string", + "const": "Re" + }, + { + "description": "A name I call myself", + "type": "string", + "const": "Mi" + } + ] +} \ No newline at end of file diff --git a/schemars/tests/expected/enum-untagged.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~untagged_enum.de.json similarity index 88% rename from schemars/tests/expected/enum-untagged.json rename to schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~untagged_enum.de.json index 643cd20c..e744d555 100644 --- a/schemars/tests/expected/enum-untagged.json +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~untagged_enum.de.json @@ -47,9 +47,17 @@ "minItems": 2, "maxItems": 2 }, + { + "type": "null" + }, { "type": "integer", - "format": "int32" + "format": "uint64", + "minimum": 0 + }, + { + "type": "string", + "pattern": "^\\d+ (true|false)$" } ], "$defs": { diff --git a/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~untagged_enum.ser.json b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~untagged_enum.ser.json new file mode 100644 index 00000000..e744d555 --- /dev/null +++ b/schemars/tests/integration/snapshots/schemars/tests/integration/enums.rs~untagged_enum.ser.json @@ -0,0 +1,84 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Untagged", + "anyOf": [ + { + "type": "null" + }, + { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + { + "$ref": "#/$defs/UnitStruct" + }, + { + "$ref": "#/$defs/Struct" + }, + { + "type": "object", + "properties": { + "foo": { + "type": "integer", + "format": "int32" + }, + "bar": { + "type": "boolean" + } + }, + "required": [ + "foo", + "bar" + ] + }, + { + "type": "array", + "prefixItems": [ + { + "type": "integer", + "format": "int32" + }, + { + "type": "boolean" + } + ], + "minItems": 2, + "maxItems": 2 + }, + { + "type": "null" + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + { + "type": "string", + "pattern": "^\\d+ (true|false)$" + } + ], + "$defs": { + "UnitStruct": { + "type": "null" + }, + "Struct": { + "type": "object", + "properties": { + "foo": { + "type": "integer", + "format": "int32" + }, + "bar": { + "type": "boolean" + } + }, + "required": [ + "foo", + "bar" + ] + } + } +} \ No newline at end of file