From b020ce5aeee9cc0de51bf251bf16a61a457b7435 Mon Sep 17 00:00:00 2001 From: Dominik Spicher Date: Mon, 29 Aug 2022 22:14:59 +0200 Subject: [PATCH 1/2] tests/federation: compare export_sdl against expected schema This commit adds logic to two unit tests where the schema export is compared against expected output cached in two schema files. This is intended to help prevent bugs like the ones fixed in faf407b or the immediately succeeding commit, as unexpected changes to schema export will become apparent in the commit diff, easing reviews. When legitimately changing the export output behaviour, the test suite just needs to be run twice, as the unit-tests automatically overwrite the files with the new version. This unit-test approach is inspired by https://matklad.github.io/2022/03/26/self-modifying-code.html --- tests/federation.rs | 18 +++++ .../test_entity_inaccessible.schema.graphql | 67 +++++++++++++++++++ tests/schemas/test_entity_tag.schema.graphql | 67 +++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 tests/schemas/test_entity_inaccessible.schema.graphql create mode 100644 tests/schemas/test_entity_tag.schema.graphql diff --git a/tests/federation.rs b/tests/federation.rs index 0bfc6091..8b36594c 100644 --- a/tests/federation.rs +++ b/tests/federation.rs @@ -536,6 +536,15 @@ pub async fn test_entity_inaccessible() { assert!(schema_sdl.contains("inputFieldInaccessibleA: Int! @inaccessible")); // no trailing spaces assert!(!schema_sdl.contains(" \n")); + + // compare to expected schema + let path = std::path::Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()) + .join("tests/schemas/test_entity_inaccessible.schema.graphql"); + let expected_schema = std::fs::read_to_string(&path).unwrap(); + if schema_sdl != expected_schema { + std::fs::write(path, schema_sdl).unwrap(); + panic!("schema was not up-to-date. rerun") + } } #[tokio::test] @@ -737,4 +746,13 @@ pub async fn test_entity_tag() { ); // no trailing spaces assert!(!schema_sdl.contains(" \n")); + + // compare to expected schema + let path = std::path::Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()) + .join("tests/schemas/test_entity_tag.schema.graphql"); + let expected_schema = std::fs::read_to_string(&path).unwrap(); + if schema_sdl != expected_schema { + std::fs::write(path, schema_sdl).unwrap(); + panic!("schema was not up-to-date. rerun") + } } diff --git a/tests/schemas/test_entity_inaccessible.schema.graphql b/tests/schemas/test_entity_inaccessible.schema.graphql new file mode 100644 index 00000000..40f488c8 --- /dev/null +++ b/tests/schemas/test_entity_inaccessible.schema.graphql @@ -0,0 +1,67 @@ + + + + +type MyCustomObjInaccessible @inaccessible { + a: Int! + customObjectInaccessible: Int! @inaccessible +} + +enum MyEnumInaccessible @inaccessible{ + OPTION_A + OPTION_B + OPTION_C +} + +enum MyEnumVariantInaccessible{ + OPTION_A_INACCESSIBLE @inaccessible + OPTION_B + OPTION_C +} + +input MyInputObjFieldInaccessible{ + inputFieldInaccessibleA: Int! @inaccessible +} + +input MyInputObjInaccessible @inaccessible{ + a: Int! +} + +interface MyInterfaceInaccessible @inaccessible { + inaccessibleInterfaceValue: String! @inaccessible +} + +type MyInterfaceObjA implements MyInterfaceInaccessible { + inaccessibleInterfaceValue: String! +} + +type MyInterfaceObjB implements MyInterfaceInaccessible @inaccessible { + inaccessibleInterfaceValue: String! +} + +scalar MyNumberInaccessible @inaccessible + +type MyObjFieldInaccessible @key(fields: "id") { + objFieldInaccessibleA: Int! @inaccessible +} + +type MyObjInaccessible @key(fields: "id") @inaccessible { + a: Int! +} + +union MyUnionInaccessible @inaccessible = MyInterfaceObjA | MyInterfaceObjB + +extend type Query { + enumVariantInaccessible(id: Int!): MyEnumVariantInaccessible! + enumInaccessible(id: Int!): MyEnumInaccessible! + inaccessibleField(id: Int!): Int! @inaccessible + inaccessibleArgument(id: Int! @inaccessible): Int! + inaccessibleInterface: MyInterfaceInaccessible! + inaccessibleUnion: MyUnionInaccessible! + inaccessibleScalar: MyNumberInaccessible! + inaccessibleInputField(value: MyInputObjFieldInaccessible!): Int! + inaccessibleInput(value: MyInputObjInaccessible!): Int! + inaccessibleCustomObject: MyCustomObjInaccessible! +} + + diff --git a/tests/schemas/test_entity_tag.schema.graphql b/tests/schemas/test_entity_tag.schema.graphql new file mode 100644 index 00000000..6c0396e2 --- /dev/null +++ b/tests/schemas/test_entity_tag.schema.graphql @@ -0,0 +1,67 @@ + + + + +type MyCustomObjTagged @tag(name: "tagged") @tag(name: "object") @tag(name: "with") @tag(name: "multiple") @tag(name: "tags") { + a: Int! + customObjectTagged: Int! @tag(name: "tagged_custom_object_field") +} + +enum MyEnumTagged @tag(name: "tagged_num"){ + OPTION_A + OPTION_B + OPTION_C +} + +enum MyEnumVariantTagged{ + OPTION_A_TAGGED @tag(name: "tagged_enum_option") + OPTION_B + OPTION_C +} + +input MyInputObjFieldTagged{ + inputFieldTaggedA: Int! @tag(name: "tagged_input_object_field") +} + +input MyInputObjTagged @tag(name: "input_object_tag"){ + a: Int! +} + +type MyInterfaceObjA implements MyInterfaceTagged { + taggedInterfaceValue: String! +} + +type MyInterfaceObjB implements MyInterfaceTagged @tag(name: "interface_object") { + taggedInterfaceValue: String! +} + +interface MyInterfaceTagged @tag(name: "tagged_interface") { + taggedInterfaceValue: String! @tag(name: "tagged_interface_field") +} + +scalar MyNumberTagged @tag(name: "tagged_scalar") + +type MyObjFieldTagged @key(fields: "id") { + objFieldTaggedA: Int! @tag(name: "tagged_field") +} + +type MyObjTagged @key(fields: "id") @tag(name: "tagged_simple_object") { + a: Int! +} + +union MyUnionTagged @tag(name: "tagged_union") = MyInterfaceObjA | MyInterfaceObjB + +extend type Query { + enumVariantTagged(id: Int!): MyEnumVariantTagged! + enumTagged(id: Int!): MyEnumTagged! + taggedField(id: Int!): Int! @tag(name: "tagged_\"field\"") + taggedArgument(id: Int! @tag(name: "tagged_argument")): Int! + taggedInterface: MyInterfaceTagged! + taggedUnion: MyUnionTagged! + taggedScalar: MyNumberTagged! + taggedInputField(value: MyInputObjFieldTagged!): Int! + taggedInput(value: MyInputObjTagged!): Int! + taggedCustomObject: MyCustomObjTagged! +} + + From e42778393685c1e539f7d6b6081232005318ec61 Mon Sep 17 00:00:00 2001 From: Dominik Spicher Date: Mon, 29 Aug 2022 22:13:58 +0200 Subject: [PATCH 2/2] export_sdl: add missing space before opening braces --- src/registry/export_sdl.rs | 4 ++-- tests/schemas/test_entity_inaccessible.schema.graphql | 8 ++++---- tests/schemas/test_entity_tag.schema.graphql | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/registry/export_sdl.rs b/src/registry/export_sdl.rs index faa22946..ddd76e83 100644 --- a/src/registry/export_sdl.rs +++ b/src/registry/export_sdl.rs @@ -367,7 +367,7 @@ impl Registry { write!(sdl, " @tag(name: \"{}\")", tag.replace('"', "\\\"")).ok(); } } - writeln!(sdl, "{{").ok(); + writeln!(sdl, " {{").ok(); let mut values = enum_values.values().collect::>(); if options.sorted_enum_values { @@ -418,7 +418,7 @@ impl Registry { write!(sdl, " @tag(name: \"{}\")", tag.replace('"', "\\\"")).ok(); } } - writeln!(sdl, "{{").ok(); + writeln!(sdl, " {{").ok(); let mut fields = input_fields.values().collect::>(); if options.sorted_fields { diff --git a/tests/schemas/test_entity_inaccessible.schema.graphql b/tests/schemas/test_entity_inaccessible.schema.graphql index 40f488c8..7da5863f 100644 --- a/tests/schemas/test_entity_inaccessible.schema.graphql +++ b/tests/schemas/test_entity_inaccessible.schema.graphql @@ -7,23 +7,23 @@ type MyCustomObjInaccessible @inaccessible { customObjectInaccessible: Int! @inaccessible } -enum MyEnumInaccessible @inaccessible{ +enum MyEnumInaccessible @inaccessible { OPTION_A OPTION_B OPTION_C } -enum MyEnumVariantInaccessible{ +enum MyEnumVariantInaccessible { OPTION_A_INACCESSIBLE @inaccessible OPTION_B OPTION_C } -input MyInputObjFieldInaccessible{ +input MyInputObjFieldInaccessible { inputFieldInaccessibleA: Int! @inaccessible } -input MyInputObjInaccessible @inaccessible{ +input MyInputObjInaccessible @inaccessible { a: Int! } diff --git a/tests/schemas/test_entity_tag.schema.graphql b/tests/schemas/test_entity_tag.schema.graphql index 6c0396e2..d7bdf7aa 100644 --- a/tests/schemas/test_entity_tag.schema.graphql +++ b/tests/schemas/test_entity_tag.schema.graphql @@ -7,23 +7,23 @@ type MyCustomObjTagged @tag(name: "tagged") @tag(name: "object") @tag(name: "wit customObjectTagged: Int! @tag(name: "tagged_custom_object_field") } -enum MyEnumTagged @tag(name: "tagged_num"){ +enum MyEnumTagged @tag(name: "tagged_num") { OPTION_A OPTION_B OPTION_C } -enum MyEnumVariantTagged{ +enum MyEnumVariantTagged { OPTION_A_TAGGED @tag(name: "tagged_enum_option") OPTION_B OPTION_C } -input MyInputObjFieldTagged{ +input MyInputObjFieldTagged { inputFieldTaggedA: Int! @tag(name: "tagged_input_object_field") } -input MyInputObjTagged @tag(name: "input_object_tag"){ +input MyInputObjTagged @tag(name: "input_object_tag") { a: Int! }