diff --git a/src/HotChocolate/Core/src/Abstractions/Properties/AbstractionResources.Designer.cs b/src/HotChocolate/Core/src/Abstractions/Properties/AbstractionResources.Designer.cs
index 6a11170a157..ccb76ff19e6 100644
--- a/src/HotChocolate/Core/src/Abstractions/Properties/AbstractionResources.Designer.cs
+++ b/src/HotChocolate/Core/src/Abstractions/Properties/AbstractionResources.Designer.cs
@@ -206,5 +206,17 @@ internal static string ThrowHelper_TryRewriteNullability_InvalidNullabilityStruc
return ResourceManager.GetString("ThrowHelper_TryRewriteNullability_InvalidNullabilityStructure", resourceCulture);
}
}
+
+ internal static string ThrowHelper_SchemaCoordinate_ArgumentNameCannotBeSetWithoutMemberName {
+ get {
+ return ResourceManager.GetString("ThrowHelper_SchemaCoordinate_ArgumentNameCannotBeSetWithoutMemberName", resourceCulture);
+ }
+ }
+
+ internal static string ThrowHelper_SchemaCoordinate_MemberNameCannotBeSetOnADirectiveCoordinate {
+ get {
+ return ResourceManager.GetString("ThrowHelper_SchemaCoordinate_MemberNameCannotBeSetOnADirectiveCoordinate", resourceCulture);
+ }
+ }
}
}
diff --git a/src/HotChocolate/Core/src/Abstractions/Properties/AbstractionResources.resx b/src/HotChocolate/Core/src/Abstractions/Properties/AbstractionResources.resx
index db623dbceae..68b27859e0a 100644
--- a/src/HotChocolate/Core/src/Abstractions/Properties/AbstractionResources.resx
+++ b/src/HotChocolate/Core/src/Abstractions/Properties/AbstractionResources.resx
@@ -198,4 +198,10 @@
The nullability modifier does not match the field type structure.
+
+ A argument name without a member name is only allowed on directive coordinates.
+
+
+ A directive cannot contain a member name.
+
diff --git a/src/HotChocolate/Core/src/Abstractions/SchemaCoordinate.cs b/src/HotChocolate/Core/src/Abstractions/SchemaCoordinate.cs
new file mode 100644
index 00000000000..31d4bc07a83
--- /dev/null
+++ b/src/HotChocolate/Core/src/Abstractions/SchemaCoordinate.cs
@@ -0,0 +1,170 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+using HotChocolate.Language;
+using static HotChocolate.Properties.AbstractionResources;
+
+namespace HotChocolate;
+
+///
+/// A is a human readable string that uniquely identifies a
+/// schema element within a GraphQL Schema.
+/// A schema element is a specific instance of a named type, field, input field, enum value,
+/// field argument, directive, or directive argument.
+/// A is always unique. Each schema element may be referenced
+/// by exactly one possible schema coordinate.
+///
+/// A may refer to either a defined or built-in schema element.
+/// For example, `String` and `@deprecated(reason:)` are both valid schema coordinates which refer
+/// to built-in schema elements. However it must not refer to a meta-field.
+/// For example, `Business.__typename` is not a valid schema coordinate.
+///
+/// SchemaCoordinate :
+/// - Name
+/// - Name . Name
+/// - Name . Name ( Name : )
+/// - @ Name
+/// - @ Name ( Name : )
+///
+public readonly struct SchemaCoordinate
+{
+ ///
+ /// Creates a new instance of
+ ///
+ ///
+ /// The is null or .
+ ///
+ ///
+ /// - A directive cannot contain a .
+ /// - A . without a is only allowed
+ /// on directive coordinates.
+ ///
+ public SchemaCoordinate(
+ NameString name,
+ NameString? memberName = null,
+ NameString? argumentName = null,
+ bool ofDirective = false)
+ {
+ memberName?.EnsureNotEmpty(nameof(memberName));
+ argumentName?.EnsureNotEmpty(nameof(argumentName));
+
+ if (ofDirective && memberName is not null)
+ {
+ throw new ArgumentException(
+ ThrowHelper_SchemaCoordinate_MemberNameCannotBeSetOnADirectiveCoordinate,
+ nameof(memberName));
+ }
+
+ if (!ofDirective && memberName is null && argumentName is not null)
+ {
+ throw new ArgumentException(
+ ThrowHelper_SchemaCoordinate_ArgumentNameCannotBeSetWithoutMemberName,
+ nameof(argumentName));
+ }
+
+ Name = name.EnsureNotEmpty(nameof(name));
+ MemberName = memberName;
+ ArgumentName = argumentName;
+ OfDirective = ofDirective;
+ }
+
+ ///
+ /// Specifies if this is a coordinate of a directive.
+ ///
+ public bool OfDirective { get; }
+
+ ///
+ /// The name of the referenced
+ ///
+ public NameString Name { get; }
+
+ ///
+ /// The optional name of the referenced field or enum value
+ ///
+ public NameString? MemberName { get; }
+
+ ///
+ /// The optional name of the referenced argument
+ ///
+ public NameString? ArgumentName { get; }
+
+ ///
+ /// Gets the syntax representation of this .
+ ///
+ public SchemaCoordinateNode ToSyntax()
+ {
+ NameNode? memberName = MemberName is null ? null : new(MemberName.Value);
+ NameNode? argumentName = ArgumentName is null ? null : new(ArgumentName.Value);
+
+ return new(null, OfDirective, new(Name.Value), memberName, argumentName);
+ }
+
+ ///
+ /// Gets the string representation of this .
+ ///
+ public override string ToString() => ToSyntax().ToString();
+
+ ///
+ /// Tries to parse a from a .
+ ///
+ /// The string that may represent a .
+ ///
+ /// If the string represented a valid schema coordinate string this
+ /// will be the parsed schema coordinate.
+ ///
+ ///
+ /// true if the string was a valid representation of a schema coordinate.
+ ///
+ public static bool TryParse(
+ string s,
+ [NotNullWhen(true)] out SchemaCoordinate? coordinate)
+ {
+ if (string.IsNullOrEmpty(s))
+ {
+ coordinate = null;
+ return false;
+ }
+
+ try
+ {
+ coordinate = Parse(s);
+ return true;
+ }
+ catch (SyntaxException)
+ {
+ coordinate = null;
+ return false;
+ }
+ }
+
+ ///
+ /// Parses a schema coordinate string representation.
+ ///
+ /// The schema coordinate string representation.
+ ///
+ /// Returns the parses schema coordinate.
+ ///
+ public static SchemaCoordinate Parse(string s)
+ => FromSyntax(Utf8GraphQLParser.Syntax.ParseSchemaCoordinate(s));
+
+ ///
+ /// Creates a from a .
+ ///
+ ///
+ /// The syntax node.
+ ///
+ ///
+ /// Returns the instance.
+ ///
+ public static SchemaCoordinate FromSyntax(SchemaCoordinateNode node)
+ {
+ NameString? memberName = node.MemberName is null
+ ? null
+ : (NameString?)node.MemberName.Value;
+
+ NameString? argumentName = node.ArgumentName is null
+ ? null
+ : (NameString?)node.ArgumentName.Value;
+
+ return new(node.Name.Value, memberName, argumentName, node.OfDirective);
+ }
+}
diff --git a/src/HotChocolate/Core/src/Types/Extensions/SchemaExtensions.cs b/src/HotChocolate/Core/src/Types/Extensions/SchemaExtensions.cs
index 62db68c8e4f..add10fd232e 100644
--- a/src/HotChocolate/Core/src/Types/Extensions/SchemaExtensions.cs
+++ b/src/HotChocolate/Core/src/Types/Extensions/SchemaExtensions.cs
@@ -1,9 +1,17 @@
using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
using HotChocolate.Language;
using HotChocolate.Types;
+using TypeThrowHelper = HotChocolate.Utilities.ThrowHelper;
+
+#nullable enable
namespace HotChocolate;
+///
+/// Provides extension methods to .
+///
public static class SchemaExtensions
{
///
@@ -14,7 +22,7 @@ public static class SchemaExtensions
///
/// Returns the root operation object type.
///
- public static ObjectType GetOperationType(this ISchema schema, OperationType operation)
+ public static ObjectType? GetOperationType(this ISchema schema, OperationType operation)
{
switch (operation)
{
@@ -28,4 +36,279 @@ public static ObjectType GetOperationType(this ISchema schema, OperationType ope
throw new NotSupportedException();
}
}
+
+ ///
+ /// Tries to resolve a by its .
+ ///
+ ///
+ /// The schema on which the shall be resolved.
+ ///
+ ///
+ /// A string representing a schema coordinate.
+ ///
+ ///
+ /// The resolved type system member.
+ ///
+ ///
+ /// true if a type system member was found with the given
+ /// ; otherwise, false .
+ ///
+ ///
+ /// is null .
+ ///
+ public static bool TryGetMember(
+ this ISchema schema,
+ string coordinateString,
+ [NotNullWhen(true)] out ITypeSystemMember? member)
+ {
+ if (SchemaCoordinate.TryParse(coordinateString, out var coordinate))
+ {
+ return TryGetMember(schema, coordinate.Value, out member);
+ }
+
+ member = null;
+ return false;
+ }
+
+ ///
+ /// Tries to resolve a by its .
+ ///
+ ///
+ /// The schema on which the shall be resolved.
+ ///
+ ///
+ /// A schema coordinate.
+ ///
+ ///
+ /// The resolved type system member.
+ ///
+ ///
+ /// true if a type system member was found with the given
+ /// ; otherwise, false .
+ ///
+ ///
+ /// is null .
+ ///
+ public static bool TryGetMember(
+ this ISchema schema,
+ SchemaCoordinate coordinate,
+ [NotNullWhen(true)] out ITypeSystemMember? member)
+ {
+ if (schema is null)
+ {
+ throw new ArgumentNullException(nameof(schema));
+ }
+
+ if (coordinate.OfDirective)
+ {
+ if (schema.TryGetDirectiveType(coordinate.Name, out var directive))
+ {
+ if (coordinate.ArgumentName is null)
+ {
+ member = directive;
+ return true;
+ }
+
+ if (directive.Arguments.TryGetField(coordinate.ArgumentName.Value, out var arg))
+ {
+ member = arg;
+ return true;
+ }
+ }
+
+ member = null;
+ return false;
+ }
+
+ if (schema.TryGetType(coordinate.Name, out var type))
+ {
+ if (coordinate.MemberName is null)
+ {
+ member = type;
+ return true;
+ }
+
+ if (coordinate.ArgumentName is null)
+ {
+ if (type.Kind is TypeKind.Enum)
+ {
+ var enumType = (EnumType)type;
+ if (enumType.TryGetValue(coordinate.MemberName.Value, out var enumValue))
+ {
+ member = enumValue;
+ return true;
+ }
+ }
+
+ if (type.Kind is TypeKind.InputObject)
+ {
+ var inputType = (InputObjectType)type;
+ if (inputType.Fields.TryGetField(coordinate.MemberName.Value, out var input))
+ {
+ member = input;
+ return true;
+ }
+ }
+ }
+
+ if (type.Kind is not TypeKind.Object and not TypeKind.Interface)
+ {
+ member = null;
+ return false;
+ }
+
+ var complexType = (IComplexOutputType)type;
+ if (complexType.Fields.TryGetField(coordinate.MemberName.Value, out var field))
+ {
+ if (coordinate.ArgumentName is null)
+ {
+ member = field;
+ return true;
+ }
+
+ if (field.Arguments.TryGetField(coordinate.ArgumentName.Value, out var fieldArg))
+ {
+ member = fieldArg;
+ return true;
+ }
+ }
+ }
+
+ member = null;
+ return false;
+ }
+
+ ///
+ /// Gets a by its .
+ ///
+ ///
+ /// The schema on which the shall be resolved.
+ ///
+ ///
+ /// A string representing a schema coordinate.
+ ///
+ ///
+ /// Returns the resolved type system member.
+ ///
+ ///
+ /// is null .
+ ///
+ ///
+ /// The has invalid syntax.
+ ///
+ ///
+ /// Unable to resolve a type system member with the
+ /// specified .
+ ///
+ public static ITypeSystemMember GetMember(
+ this ISchema schema,
+ string coordinateString)
+ => GetMember(schema, SchemaCoordinate.Parse(coordinateString));
+
+ ///
+ /// Gets a by its .
+ ///
+ ///
+ /// The schema on which the shall be resolved.
+ ///
+ ///
+ /// A schema coordinate.
+ ///
+ ///
+ /// Returns the resolved type system member.
+ ///
+ ///
+ /// is null .
+ ///
+ ///
+ /// Unable to resolve a type system member with the
+ /// specified .
+ ///
+ public static ITypeSystemMember GetMember(
+ this ISchema schema,
+ SchemaCoordinate coordinate)
+ {
+ if (schema is null)
+ {
+ throw new ArgumentNullException(nameof(schema));
+ }
+
+ if (coordinate.OfDirective)
+ {
+ if (schema.TryGetDirectiveType(coordinate.Name, out var directive))
+ {
+ if (coordinate.ArgumentName is null)
+ {
+ return directive;
+ }
+
+ if (directive.Arguments.TryGetField(coordinate.ArgumentName.Value, out var arg))
+ {
+ return arg;
+ }
+
+ throw TypeThrowHelper.Schema_GetMember_DirectiveArgumentNotFound(coordinate);
+ }
+
+ throw TypeThrowHelper.Schema_GetMember_DirectiveNotFound(coordinate);
+ }
+
+ if (schema.TryGetType(coordinate.Name, out var type))
+ {
+ if (coordinate.MemberName is null)
+ {
+ return type;
+ }
+
+ if (coordinate.ArgumentName is null)
+ {
+ if (type.Kind is TypeKind.Enum)
+ {
+ var enumType = (EnumType)type;
+ if (enumType.TryGetValue(coordinate.MemberName.Value, out var enumValue))
+ {
+ return enumValue;
+ }
+
+ throw TypeThrowHelper.Schema_GetMember_EnumValueNotFound(coordinate);
+ }
+
+ if (type.Kind is TypeKind.InputObject)
+ {
+ var inputType = (InputObjectType)type;
+ if (inputType.Fields.TryGetField(coordinate.MemberName.Value, out var input))
+ {
+ return input;
+ }
+
+ throw TypeThrowHelper.Schema_GetMember_InputFieldNotFound(coordinate);
+ }
+ }
+
+ if (type.Kind is not TypeKind.Object and not TypeKind.Interface)
+ {
+ throw TypeThrowHelper.Schema_GetMember_InvalidCoordinate(coordinate, type);
+ }
+
+ var complexType = (IComplexOutputType)type;
+ if (complexType.Fields.TryGetField(coordinate.MemberName.Value, out var field))
+ {
+ if (coordinate.ArgumentName is null)
+ {
+ return field;
+ }
+
+ if (field.Arguments.TryGetField(coordinate.ArgumentName.Value, out var fieldArg))
+ {
+ return fieldArg;
+ }
+
+ throw TypeThrowHelper.Schema_GetMember_FieldArgNotFound(coordinate);
+ }
+
+ throw TypeThrowHelper.Schema_GetMember_FieldNotFound(coordinate);
+ }
+
+ throw TypeThrowHelper.Schema_GetMember_TypeNotFound(coordinate);
+ }
}
diff --git a/src/HotChocolate/Core/src/Types/InvalidSchemaCoordinateException.cs b/src/HotChocolate/Core/src/Types/InvalidSchemaCoordinateException.cs
new file mode 100644
index 00000000000..9ebf5f6c4e8
--- /dev/null
+++ b/src/HotChocolate/Core/src/Types/InvalidSchemaCoordinateException.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Runtime.Serialization;
+
+#nullable enable
+
+namespace HotChocolate;
+
+///
+/// This exception indicates that the specified
+///
+/// could not be resolved.
+///
+[Serializable]
+public class InvalidSchemaCoordinateException : Exception
+{
+ ///
+ /// Creates new instance of .
+ ///
+ /// The error message.
+ /// The invalid schema coordinate.
+ public InvalidSchemaCoordinateException(string message, SchemaCoordinate coordinate)
+ : base(message)
+ {
+ Coordinate = coordinate;
+ }
+
+ ///
+ /// Initializes a new instance of the
+ /// class with serialized data.
+ ///
+ /// The .
+ /// The .
+ protected InvalidSchemaCoordinateException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ Coordinate = SchemaCoordinate.Parse(info.GetString(nameof(Coordinate))!);
+ }
+
+ ///
+ /// The invalid schema coordinate.
+ ///
+ ///
+ public SchemaCoordinate Coordinate { get; }
+
+ ///
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue(nameof(Coordinate), Coordinate.ToString());
+ }
+}
diff --git a/src/HotChocolate/Core/src/Types/Types/Contracts/IEnumType.cs b/src/HotChocolate/Core/src/Types/Types/Contracts/IEnumType.cs
index 67a4c2ccc49..5344ad89218 100644
--- a/src/HotChocolate/Core/src/Types/Types/Contracts/IEnumType.cs
+++ b/src/HotChocolate/Core/src/Types/Types/Contracts/IEnumType.cs
@@ -21,6 +21,24 @@ public interface IEnumType : ILeafType
///
IReadOnlyCollection Values { get; }
+ ///
+ /// Tries to get the for
+ /// the specified .
+ ///
+ ///
+ /// The GraphQL enum value name.
+ ///
+ ///
+ /// The GraphQL enum value.
+ ///
+ ///
+ /// true if the represents a value of this enum type;
+ /// otherwise, false .
+ ///
+ bool TryGetValue(
+ NameString name,
+ [NotNullWhen(true)] out IEnumValue? value);
+
///
/// Tries to get the for
/// the specified .
diff --git a/src/HotChocolate/Core/src/Types/Types/Contracts/IEnumValue.cs b/src/HotChocolate/Core/src/Types/Types/Contracts/IEnumValue.cs
index b74275f199b..744d4b1f0d6 100644
--- a/src/HotChocolate/Core/src/Types/Types/Contracts/IEnumValue.cs
+++ b/src/HotChocolate/Core/src/Types/Types/Contracts/IEnumValue.cs
@@ -10,6 +10,7 @@ namespace HotChocolate.Types;
public interface IEnumValue
: IHasDirectives
, IHasReadOnlyContextData
+ , ITypeSystemMember
{
///
/// The associated syntax node from the GraphQL SDL.
diff --git a/src/HotChocolate/Core/src/Types/Types/EnumType.cs b/src/HotChocolate/Core/src/Types/Types/EnumType.cs
index da15a33f492..0f0d59bfcab 100644
--- a/src/HotChocolate/Core/src/Types/Types/EnumType.cs
+++ b/src/HotChocolate/Core/src/Types/Types/EnumType.cs
@@ -54,21 +54,11 @@ public partial class EnumType
///
protected IReadOnlyDictionary ValueLookup => _valueLookup;
- ///
- /// Tries to resolve the runtime value of this enum type by its name.
- ///
- ///
- /// The GraphQL name for the enum value.
- ///
- ///
- /// The runtime enum runtime value.
- ///
- ///
- /// true , if there is a runtime value associated with the provided enum value name.
- ///
- public bool TryGetRuntimeValue(
- NameString name,
- [NotNullWhen(true)] out object? runtimeValue)
+ public bool TryGetValue(NameString name, [NotNullWhen(true)] out IEnumValue? value)
+ => _enumValues.TryGetValue(name, out value);
+
+ ///
+ public bool TryGetRuntimeValue(NameString name, [NotNullWhen(true)] out object? runtimeValue)
{
if (_enumValues.TryGetValue(name, out IEnumValue? value))
{
diff --git a/src/HotChocolate/Core/src/Types/Utilities/ThrowHelper.cs b/src/HotChocolate/Core/src/Types/Utilities/ThrowHelper.cs
index 54860dd9e0c..dbeffa79c35 100644
--- a/src/HotChocolate/Core/src/Types/Utilities/ThrowHelper.cs
+++ b/src/HotChocolate/Core/src/Types/Utilities/ThrowHelper.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Reflection;
using HotChocolate.Language;
@@ -405,4 +406,84 @@ public static SerializationException FormatResultLeaf_InvalidSyntaxKind(
public static InvalidOperationException RewriteNullability_InvalidNullabilityStructure()
=> new(AbstractionResources.ThrowHelper_TryRewriteNullability_InvalidNullabilityStructure);
+
+ public static InvalidSchemaCoordinateException Schema_GetMember_DirectiveArgumentNotFound(
+ SchemaCoordinate coordinate)
+ => new InvalidSchemaCoordinateException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Argument `{0}` was not found on directive `@{1}`.",
+ coordinate.ArgumentName!.Value,
+ coordinate.Name),
+ coordinate);
+
+ public static InvalidSchemaCoordinateException Schema_GetMember_DirectiveNotFound(
+ SchemaCoordinate coordinate)
+ => new InvalidSchemaCoordinateException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Directive `@{0}` not found.",
+ coordinate.Name),
+ coordinate);
+
+ public static InvalidSchemaCoordinateException Schema_GetMember_EnumValueNotFound(
+ SchemaCoordinate coordinate)
+ => new InvalidSchemaCoordinateException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Enum value `{0}` was not found on type `{1}`.",
+ coordinate.MemberName!.Value,
+ coordinate.Name),
+ coordinate);
+
+ public static InvalidSchemaCoordinateException Schema_GetMember_InputFieldNotFound(
+ SchemaCoordinate coordinate)
+ => new InvalidSchemaCoordinateException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Input field `{0}` was not found on type `{1}`.",
+ coordinate.MemberName!.Value,
+ coordinate.Name),
+ coordinate);
+
+ public static InvalidSchemaCoordinateException Schema_GetMember_InvalidCoordinate(
+ SchemaCoordinate coordinate,
+ INamedType type)
+ => new InvalidSchemaCoordinateException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "The coordinate `{0}` is invalid for the type `{1}`.",
+ coordinate.ToString(),
+ type.Name.Value),
+ coordinate);
+
+ public static InvalidSchemaCoordinateException Schema_GetMember_FieldArgNotFound(
+ SchemaCoordinate coordinate)
+ => new InvalidSchemaCoordinateException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Argument `{0}` was not found on field `{1}.{2}`.",
+ coordinate.ArgumentName!.Value,
+ coordinate.Name.Value,
+ coordinate.MemberName!.Value),
+ coordinate);
+
+ public static InvalidSchemaCoordinateException Schema_GetMember_FieldNotFound(
+ SchemaCoordinate coordinate)
+ => new InvalidSchemaCoordinateException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Field `{0}` was not found on type `{1}`.",
+ coordinate.MemberName!.Value,
+ coordinate.Name.Value),
+ coordinate);
+
+ public static InvalidSchemaCoordinateException Schema_GetMember_TypeNotFound(
+ SchemaCoordinate coordinate)
+ => new InvalidSchemaCoordinateException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "A type with the name `{0}` was not found.",
+ coordinate.Name.Value),
+ coordinate);
}
diff --git a/src/HotChocolate/Core/test/Abstractions.Tests/SchemaCoordinateTests.cs b/src/HotChocolate/Core/test/Abstractions.Tests/SchemaCoordinateTests.cs
new file mode 100644
index 00000000000..f1faabda066
--- /dev/null
+++ b/src/HotChocolate/Core/test/Abstractions.Tests/SchemaCoordinateTests.cs
@@ -0,0 +1,218 @@
+using System;
+using HotChocolate.Language;
+using Xunit;
+
+#nullable enable
+
+namespace HotChocolate;
+
+public class SchemaCoordinateTests
+{
+ [Fact]
+ public void Create_Type_SchemaCoordinate()
+ {
+ // arrange & act
+ var coordinate = new SchemaCoordinate("Abc");
+
+ // assert
+ Assert.Equal("Abc", coordinate.Name);
+ Assert.Equal("Abc", coordinate.ToString());
+ }
+
+ [Fact]
+ public void Create_Field_SchemaCoordinate()
+ {
+ // arrange & act
+ var coordinate = new SchemaCoordinate("Abc", "def");
+
+ // assert
+ Assert.Equal("Abc", coordinate.Name);
+ Assert.Equal("def", coordinate.MemberName);
+ Assert.Equal("Abc.def", coordinate.ToString());
+ }
+
+ [Fact]
+ public void Create_Field_Argument_SchemaCoordinate()
+ {
+ // arrange & act
+ var coordinate = new SchemaCoordinate("Abc", "def", "ghi");
+
+ // assert
+ Assert.Equal("Abc", coordinate.Name);
+ Assert.Equal("def", coordinate.MemberName);
+ Assert.Equal("ghi", coordinate.ArgumentName);
+ Assert.Equal("Abc.def(ghi:)", coordinate.ToString());
+ }
+
+ [Fact]
+ public void Create_Field_Argument_SchemaCoordinate_Without_MemberName()
+ {
+ // arrange & act
+ void Fail() => new SchemaCoordinate("abc", argumentName: "def");
+
+ // assert
+ ArgumentException ex = Assert.Throws(Fail);
+ Assert.Equal("argumentName", ex.ParamName);
+ Assert.StartsWith(
+ "A argument name without a member name is only allowed on directive coordinates",
+ ex.Message);
+ }
+
+ [Fact]
+ public void Create_Directive_SchemaCoordinate()
+ {
+ // arrange & act
+ var coordinate = new SchemaCoordinate("abc", ofDirective: true);
+
+ // assert
+ Assert.Equal("abc", coordinate.Name);
+ Assert.Equal("@abc", coordinate.ToString());
+ }
+
+ [Fact]
+ public void Create_Directive_Argument_SchemaCoordinate()
+ {
+ // arrange & act
+ var coordinate = new SchemaCoordinate("abc", argumentName: "def", ofDirective: true);
+
+ // assert
+ Assert.Equal("abc", coordinate.Name);
+ Assert.Equal("def", coordinate.ArgumentName);
+ Assert.Equal("@abc(def:)", coordinate.ToString());
+ }
+
+ [Fact]
+ public void Create_Directive_SchemaCoordinate_With()
+ {
+ // arrange & act
+ void Fail() => new SchemaCoordinate("abc", memberName: "def", ofDirective: true);
+
+ // assert
+ ArgumentException ex = Assert.Throws(Fail);
+ Assert.Equal("memberName", ex.ParamName);
+ Assert.StartsWith("A directive cannot contain a member name.", ex.Message);
+ }
+
+ [Fact]
+ public void Parse_SchemaCoordinate()
+ {
+ // arrange & act
+ var coordinate = SchemaCoordinate.Parse("Abc.def");
+
+ // assert
+ Assert.Equal("Abc", coordinate.Name);
+ Assert.Equal("def", coordinate.MemberName);
+ Assert.Equal("Abc.def", coordinate.ToString());
+ }
+
+ [Fact]
+ public void Parse_Invalid_SchemaCoordinate()
+ {
+ // arrange & act
+ void Fail() => SchemaCoordinate.Parse("...");
+
+ // assert
+ Assert.Throws(Fail);
+ }
+
+ [Fact]
+ public void TryParse_SchemaCoordinate()
+ {
+ // arrange & act
+ var success = SchemaCoordinate.TryParse("Abc.def", out var coordinate);
+
+ // assert
+ Assert.True(success);
+ Assert.Equal("Abc", coordinate?.Name);
+ Assert.Equal("def", coordinate?.MemberName);
+ Assert.Equal("Abc.def", coordinate?.ToString());
+ }
+
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData("...")]
+ [Theory]
+ public void TryParse_Invalid_SchemaCoordinate(string? s)
+ {
+ // arrange & act
+ var success = SchemaCoordinate.TryParse(s, out var coordinate);
+
+ // assert
+ Assert.False(success);
+ Assert.Null(coordinate);
+ }
+
+ [Fact]
+ public void FromSyntax_Type_SchemaCoordinate()
+ {
+ // arrange
+ var node = new SchemaCoordinateNode(null, false, new("Abc"), null, null);
+
+ // act
+ var coordinate = SchemaCoordinate.FromSyntax(node);
+
+ // assert
+ Assert.Equal("Abc", coordinate.Name);
+ Assert.Equal("Abc", coordinate.ToString());
+ }
+
+ [Fact]
+ public void FromSyntax_Field_SchemaCoordinate()
+ {
+ // arrange
+ var node = new SchemaCoordinateNode(null, false, new("Abc"), new("def"), null);
+
+ // act
+ var coordinate = SchemaCoordinate.FromSyntax(node);
+
+ // assert
+ Assert.Equal("Abc", coordinate.Name);
+ Assert.Equal("def", coordinate.MemberName);
+ Assert.Equal("Abc.def", coordinate.ToString());
+ }
+
+ [Fact]
+ public void FromSyntax_Field_Argument_SchemaCoordinate()
+ {
+ // arrange
+ var node = new SchemaCoordinateNode(null, false, new("Abc"), new("def"), new("ghi"));
+
+ // act
+ var coordinate = SchemaCoordinate.FromSyntax(node);
+
+ // assert
+ Assert.Equal("Abc", coordinate.Name);
+ Assert.Equal("def", coordinate.MemberName);
+ Assert.Equal("ghi", coordinate.ArgumentName);
+ Assert.Equal("Abc.def(ghi:)", coordinate.ToString());
+ }
+
+ [Fact]
+ public void FromSyntax_Directive_SchemaCoordinate()
+ {
+ // arrange
+ var node = new SchemaCoordinateNode(null, true, new("abc"), null, null);
+
+ // act
+ var coordinate = SchemaCoordinate.FromSyntax(node);
+
+ // assert
+ Assert.Equal("abc", coordinate.Name);
+ Assert.Equal("@abc", coordinate.ToString());
+ }
+
+ [Fact]
+ public void FromSyntax_Directive_Argument_SchemaCoordinate()
+ {
+ // arrange
+ var node = new SchemaCoordinateNode(null, true, new("abc"), null, new("def"));
+
+ // act
+ var coordinate = SchemaCoordinate.FromSyntax(node);
+
+ // assert
+ Assert.Equal("abc", coordinate.Name);
+ Assert.Equal("def", coordinate.ArgumentName);
+ Assert.Equal("@abc(def:)", coordinate.ToString());
+ }
+}
\ No newline at end of file
diff --git a/src/HotChocolate/Core/test/Types.Tests/SchemaCoordinateTests.cs b/src/HotChocolate/Core/test/Types.Tests/SchemaCoordinateTests.cs
new file mode 100644
index 00000000000..c96bdc5e84c
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/SchemaCoordinateTests.cs
@@ -0,0 +1,717 @@
+using ChilliCream.Testing;
+using HotChocolate.Types;
+using Snapshooter.Xunit;
+using Xunit;
+
+#nullable enable
+
+namespace HotChocolate;
+
+public class SchemaCoordinateTests
+{
+ [Fact]
+ public void GetMember_ObjectType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("Baz");
+
+ // assert
+ Assert.Equal("Baz", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void GetMember_ObjectType_Field()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("Baz.name");
+
+ // assert
+ ObjectField field = Assert.IsType(member);
+ Assert.Equal("name", field.Name);
+ Assert.Equal("Baz", field.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void GetMember_ObjectType_FieldArg()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("Baz.name(baz:)");
+
+ // assert
+ Argument arg = Assert.IsType(member);
+ Assert.Equal("baz", arg.Name);
+ Assert.Equal("name", Assert.IsType(arg.DeclaringMember).Name);
+ Assert.Equal("Baz", arg.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void GetMember_Object_Invalid_FieldName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ void Fail() => schema.GetMember("Baz.foo");
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
+ [Fact]
+ public void GetMember_Object_Invalid_FieldArgName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ void Fail() => schema.GetMember("Baz.name(bar:)");
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
+ [Fact]
+ public void GetMember_InterfaceType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("Bar");
+
+ // assert
+ Assert.Equal("Bar", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void GetMember_InterfaceType_Field()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("Bar.id");
+
+ // assert
+ InterfaceField field = Assert.IsType(member);
+ Assert.Equal("id", field.Name);
+ Assert.Equal("Bar", field.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void GetMember_InterfaceType_FieldArg()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("Bar.name(baz:)");
+
+ // assert
+ Argument arg = Assert.IsType(member);
+ Assert.Equal("baz", arg.Name);
+ Assert.Equal("name", Assert.IsType(arg.DeclaringMember).Name);
+ Assert.Equal("Bar", arg.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void GetMember_Interface_Invalid_FieldName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ void Fail() => schema.GetMember("Bar.xyz");
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
+ [Fact]
+ public void GetMember_Interface_Invalid_FieldArgName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ void Fail() => schema.GetMember("Bar.name(bar:)");
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
+ [Fact]
+ public void GetMember_UnionType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("FooOrBaz");
+
+ // assert
+ Assert.Equal("FooOrBaz", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void GetMember_UnionType_Invalid_MemberName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ void Fail() => schema.GetMember("FooOrBaz.Foo");
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
+ [Fact]
+ public void GetMember_InputObjectType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("BazInput");
+
+ // assert
+ Assert.Equal("BazInput", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void GetMember_InputObjectType_Field()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("BazInput.name");
+
+ // assert
+ InputField argument = Assert.IsType(member);
+ Assert.Equal("name", argument.Name);
+ Assert.Equal("BazInput", argument.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void GetMember_InputObjectType_Invalid_FieldName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ void Fail() => schema.GetMember("BazInput.abc");
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
+ [Fact]
+ public void GetMember_InputObjectType_Invalid_FieldArgName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ void Fail() => schema.GetMember("BazInput.name(a:)");
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
+ [Fact]
+ public void GetMember_EnumType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("Abc");
+
+ // assert
+ Assert.Equal("Abc", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void GetMember_EnumType_Value()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("Abc.DEF");
+
+ // assert
+ Assert.Equal("DEF", Assert.IsType(member).Name.Value);
+ }
+
+ [Fact]
+ public void GetMember_EnumType_Invalid_Value()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ void Fail() => schema.GetMember("Abc.XYZ");
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
+ [Fact]
+ public void GetMember_ScalarType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("String");
+
+ // assert
+ Assert.Equal("String", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void GetMember_DirectiveType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("@qux");
+
+ // assert
+ Assert.Equal("qux", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void GetMember_DirectiveType_Argument()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ ITypeSystemMember member = schema.GetMember("@qux(a:)");
+
+ // assert
+ Argument argument = Assert.IsType(member);
+ Assert.Equal("a", argument.Name);
+ Assert.Equal("qux", argument.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void GetMember_DirectiveType_Invalid_ArgumentName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ void Fail() => schema.GetMember("@qux(b:)");
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
+ [Fact]
+ public void GetMember_Invalid_TypeName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ void Fail() => schema.GetMember("Abc123");
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
+
+ [Fact]
+ public void GetMember_Invalid_DirectiveName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ void Fail() => schema.GetMember("@foo123");
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
+ [Fact]
+ public void TryGetMember_ObjectType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Baz", out var member);
+
+ // assert
+ Assert.True(success);
+ Assert.Equal("Baz", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void TryGetMember_ObjectType_Field()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Baz.name", out var member);
+
+ // assert
+ Assert.True(success);
+ ObjectField field = Assert.IsType(member);
+ Assert.Equal("name", field.Name);
+ Assert.Equal("Baz", field.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void TryGetMember_ObjectType_FieldArg()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Baz.name(baz:)", out var member);
+
+ // assert
+ Assert.True(success);
+ Argument arg = Assert.IsType(member);
+ Assert.Equal("baz", arg.Name);
+ Assert.Equal("name", Assert.IsType(arg.DeclaringMember).Name);
+ Assert.Equal("Baz", arg.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void TryGetMember_Object_Invalid_FieldName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Baz.foo", out var member);
+
+ // assert
+ Assert.False(success);
+ }
+
+ [Fact]
+ public void TryGetMember_Object_Invalid_FieldArgName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Baz.name(bar:)", out var member);
+
+ // assert
+ Assert.False(success);
+ }
+
+ [Fact]
+ public void TryGetMember_InterfaceType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Bar", out var member);
+
+ // assert
+ Assert.True(success);
+ Assert.Equal("Bar", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void TryGetMember_InterfaceType_Field()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Bar.id", out var member);
+
+ // assert
+ Assert.True(success);
+ InterfaceField field = Assert.IsType(member);
+ Assert.Equal("id", field.Name);
+ Assert.Equal("Bar", field.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void TryGetMember_InterfaceType_FieldArg()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Bar.name(baz:)", out var member);
+
+ // assert
+ Assert.True(success);
+ Argument arg = Assert.IsType(member);
+ Assert.Equal("baz", arg.Name);
+ Assert.Equal("name", Assert.IsType(arg.DeclaringMember).Name);
+ Assert.Equal("Bar", arg.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void TryGetMember_Interface_Invalid_FieldName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Baz.xyz", out var member);
+
+ // assert
+ Assert.False(success);
+ }
+
+ [Fact]
+ public void TryGetMember_Interface_Invalid_FieldArgName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Bar.name(bar:)", out var member);
+
+ // assert
+ Assert.False(success);
+ }
+
+ [Fact]
+ public void TryGetMember_UnionType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("FooOrBaz", out var member);
+
+ // assert
+ Assert.True(success);
+ }
+
+ [Fact]
+ public void TryGetMember_UnionType_Invalid_MemberName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("FooOrBaz.Foo", out var member);
+
+ // assert
+ Assert.False(success);
+ }
+
+ [Fact]
+ public void TryGetMember_InputObjectType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("BazInput", out var member);
+
+ // assert
+ Assert.True(success);
+ Assert.Equal("BazInput", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void TryGetMember_InputObjectType_Field()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("BazInput.name", out var member);
+
+ // assert
+ Assert.True(success);
+ InputField argument = Assert.IsType(member);
+ Assert.Equal("name", argument.Name);
+ Assert.Equal("BazInput", argument.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void TryGetMember_InputObjectType_Invalid_FieldName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("BazInput.abc", out var member);
+
+ // assert
+ Assert.False(success);
+ }
+
+ [Fact]
+ public void TryGetMember_InputObjectType_Invalid_FieldArgName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("BazInput.name(a:)", out var member);
+
+ // assert
+ Assert.False(success);
+ }
+
+ [Fact]
+ public void TryGetMember_EnumType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Abc", out var member);
+
+ // assert
+ Assert.True(success);
+ Assert.Equal("Abc", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void TryGetMember_EnumType_Value()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Abc.DEF", out var member);
+
+ // assert
+ Assert.True(success);
+ Assert.Equal("DEF", Assert.IsType(member).Name.Value);
+ }
+
+ [Fact]
+ public void TryGetMember_EnumType_Invalid_Value()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Abc.XYZ", out var member);
+
+ // assert
+ Assert.False(success);
+ }
+
+ [Fact]
+ public void TryGetMember_ScalarType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("String", out var member);
+
+ // assert
+ Assert.True(success);
+ Assert.Equal("String", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void TryGetMember_DirectiveType()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("@qux", out var member);
+
+ // assert
+ Assert.True(success);
+ Assert.Equal("qux", Assert.IsType(member).Name);
+ }
+
+ [Fact]
+ public void TryGetMember_DirectiveType_Argument()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("@qux(a:)", out var member);
+
+ // assert
+ Assert.True(success);
+ Argument argument = Assert.IsType(member);
+ Assert.Equal("a", argument.Name);
+ Assert.Equal("qux", argument.DeclaringType.Name);
+ }
+
+ [Fact]
+ public void TryGetMember_DirectiveType_Invalid_ArgumentName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("@qux(b:)", out var member);
+
+ // assert
+ Assert.False(success);
+ }
+
+ [Fact]
+ public void TryGetMember_Invalid_TypeName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("Abc123", out var member);
+
+ // assert
+ Assert.False(success);
+ }
+
+ [Fact]
+ public void TryGetMember_Invalid_DirectiveName()
+ {
+ // arrange
+ ISchema schema = CreateSchema();
+
+ // act
+ bool success = schema.TryGetMember("@abc", out var member);
+
+ // assert
+ Assert.False(success);
+ }
+
+ private ISchema CreateSchema()
+ {
+ return SchemaBuilder.New()
+ .AddDocumentFromString(FileResource.Open("schema_coordinates.graphql"))
+ .ModifyOptions(
+ o =>
+ {
+ o.StrictValidation = false;
+ o.RemoveUnreachableTypes = false;
+ })
+ .Use(next => context => default)
+ .Create();
+ }
+}
\ No newline at end of file
diff --git a/src/HotChocolate/Core/test/Types.Tests/__resources__/schema_coordinates.graphql b/src/HotChocolate/Core/test/Types.Tests/__resources__/schema_coordinates.graphql
new file mode 100644
index 00000000000..ee2b75a9dd6
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__resources__/schema_coordinates.graphql
@@ -0,0 +1,26 @@
+type Baz {
+ name(baz: BazInput): String
+}
+
+type Foo implements Bar {
+ id: ID!
+ name(baz: BazInput): String
+}
+
+interface Bar {
+ id: ID!
+ name(baz: BazInput): String
+}
+
+union FooOrBaz = Foo | Baz
+
+input BazInput {
+ name: String
+}
+
+enum Abc {
+ DEF
+ GHI
+}
+
+directive @qux(a: String) on FIELD_DEFINITION
diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_DirectiveType_Invalid_ArgumentName.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_DirectiveType_Invalid_ArgumentName.snap
new file mode 100644
index 00000000000..9bfd59c74e7
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_DirectiveType_Invalid_ArgumentName.snap
@@ -0,0 +1 @@
+Argument `b` was not found on directive `@qux`.
diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_EnumType_Invalid_Value.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_EnumType_Invalid_Value.snap
new file mode 100644
index 00000000000..39dd85735f4
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_EnumType_Invalid_Value.snap
@@ -0,0 +1 @@
+Enum value `XYZ` was not found on type `Abc`.
diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_InputObjectType_Invalid_FieldArgName.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_InputObjectType_Invalid_FieldArgName.snap
new file mode 100644
index 00000000000..051e4915d9e
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_InputObjectType_Invalid_FieldArgName.snap
@@ -0,0 +1 @@
+The coordinate `BazInput.name(a:)` is invalid for the type `BazInput`.
diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_InputObjectType_Invalid_FieldName.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_InputObjectType_Invalid_FieldName.snap
new file mode 100644
index 00000000000..762344dc54d
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_InputObjectType_Invalid_FieldName.snap
@@ -0,0 +1 @@
+Input field `abc` was not found on type `BazInput`.
diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Interface_Invalid_FieldArgName.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Interface_Invalid_FieldArgName.snap
new file mode 100644
index 00000000000..902af411c7c
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Interface_Invalid_FieldArgName.snap
@@ -0,0 +1 @@
+Argument `bar` was not found on field `Bar.name`.
diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Interface_Invalid_FieldName.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Interface_Invalid_FieldName.snap
new file mode 100644
index 00000000000..99ad327f746
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Interface_Invalid_FieldName.snap
@@ -0,0 +1 @@
+Field `xyz` was not found on type `Bar`.
diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Invalid_DirectiveName.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Invalid_DirectiveName.snap
new file mode 100644
index 00000000000..76fe1b35fa3
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Invalid_DirectiveName.snap
@@ -0,0 +1 @@
+Directive `@foo123` not found.
diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Invalid_TypeName.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Invalid_TypeName.snap
new file mode 100644
index 00000000000..c2b500af6e1
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Invalid_TypeName.snap
@@ -0,0 +1 @@
+A type with the name `Abc123` was not found.
diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Object_Invalid_FieldArgName.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Object_Invalid_FieldArgName.snap
new file mode 100644
index 00000000000..bdd106051cc
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Object_Invalid_FieldArgName.snap
@@ -0,0 +1 @@
+Argument `bar` was not found on field `Baz.name`.
diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Object_Invalid_FieldName.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Object_Invalid_FieldName.snap
new file mode 100644
index 00000000000..12798961166
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_Object_Invalid_FieldName.snap
@@ -0,0 +1 @@
+Field `foo` was not found on type `Baz`.
diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_UnionType_Invalid_MemberName.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_UnionType_Invalid_MemberName.snap
new file mode 100644
index 00000000000..9f028cd1508
--- /dev/null
+++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaCoordinateTests.GetMember_UnionType_Invalid_MemberName.snap
@@ -0,0 +1 @@
+The coordinate `FooOrBaz.Foo` is invalid for the type `FooOrBaz`.
diff --git a/src/HotChocolate/Language/src/Language.SyntaxTree/Properties/Resources.Designer.cs b/src/HotChocolate/Language/src/Language.SyntaxTree/Properties/Resources.Designer.cs
index b0d4e918df8..bb9efe8ce21 100644
--- a/src/HotChocolate/Language/src/Language.SyntaxTree/Properties/Resources.Designer.cs
+++ b/src/HotChocolate/Language/src/Language.SyntaxTree/Properties/Resources.Designer.cs
@@ -50,5 +50,17 @@ internal static string DirectiveLocation_Value_CannotBeNullOrEmpty {
return ResourceManager.GetString("DirectiveLocation_Value_CannotBeNullOrEmpty", resourceCulture);
}
}
+
+ internal static string ThrowHelper_SchemaCoordinate_ArgumentNameCannotBeSetWithoutMemberName {
+ get {
+ return ResourceManager.GetString("ThrowHelper_SchemaCoordinate_ArgumentNameCannotBeSetWithoutMemberName", resourceCulture);
+ }
+ }
+
+ internal static string ThrowHelper_SchemaCoordinate_MemberNameCannotBeSetOnADirectiveCoordinate {
+ get {
+ return ResourceManager.GetString("ThrowHelper_SchemaCoordinate_MemberNameCannotBeSetOnADirectiveCoordinate", resourceCulture);
+ }
+ }
}
}
diff --git a/src/HotChocolate/Language/src/Language.SyntaxTree/Properties/Resources.resx b/src/HotChocolate/Language/src/Language.SyntaxTree/Properties/Resources.resx
index 4e510f1322d..40fcf54d8ea 100644
--- a/src/HotChocolate/Language/src/Language.SyntaxTree/Properties/Resources.resx
+++ b/src/HotChocolate/Language/src/Language.SyntaxTree/Properties/Resources.resx
@@ -101,4 +101,10 @@
The value mustn't be null or empty.
+
+ A argument name without a member name is only allowed on directive coordinates.
+
+
+ A directive cannot contain a member name.
+
diff --git a/src/HotChocolate/Language/src/Language.SyntaxTree/SchemaCoordinateNode.cs b/src/HotChocolate/Language/src/Language.SyntaxTree/SchemaCoordinateNode.cs
new file mode 100644
index 00000000000..3ccbf6b8150
--- /dev/null
+++ b/src/HotChocolate/Language/src/Language.SyntaxTree/SchemaCoordinateNode.cs
@@ -0,0 +1,191 @@
+using System;
+using System.Collections.Generic;
+using HotChocolate.Language.Utilities;
+using static HotChocolate.Language.Utilities.ThrowHelper;
+
+namespace HotChocolate.Language;
+
+///
+/// A is a human readable string that uniquely identifies a
+/// schema element within a GraphQL Schema.
+/// A schema element is a specific instance of a named type, field, input field, enum value,
+/// field argument, directive, or directive argument.
+/// A is always unique. Each schema element may be referenced
+/// by exactly one possible schema coordinate.
+///
+/// A may refer to either a defined or built-in schema element.
+/// For example, `String` and `@deprecated(reason:)` are both valid schema coordinates which refer
+/// to built-in schema elements. However it must not refer to a meta-field.
+/// For example, `Business.__typename` is not a valid schema coordinate.
+///
+/// SchemaCoordinate :
+/// - Name
+/// - Name . Name
+/// - Name . Name ( Name : )
+/// - @ Name
+/// - @ Name ( Name : )
+///
+///
+/// Note: A is not a definition within a GraphQL
+/// , but a separate standalone grammar, intended to be used by tools
+/// to reference types, fields, and other schema elements. For example as references within
+/// documentation, or as lookup keys in usage frequency tracking.
+///
+///
+public sealed class SchemaCoordinateNode : ISyntaxNode
+{
+ ///
+ /// Creates a new instance of
+ ///
+ public SchemaCoordinateNode(
+ Location? location,
+ bool ofDirective,
+ NameNode name,
+ NameNode? memberName,
+ NameNode? argumentName)
+ {
+ if (ofDirective && memberName is not null)
+ {
+ throw SchemaCoordinate_MemberNameCannotBeSetOnADirectiveCoordinate(nameof(memberName));
+ }
+
+ if (!ofDirective && memberName is null && argumentName is not null)
+ {
+ throw SchemaCoordinate_ArgumentNameCannotBeSetWithoutMemberName(nameof(memberName));
+ }
+
+ Location = location;
+ OfDirective = ofDirective;
+ Name = name ?? throw new ArgumentNullException(nameof(name));
+ MemberName = memberName;
+ ArgumentName = argumentName;
+ }
+
+ ///
+ public Location? Location { get; }
+
+ ///
+ public SyntaxKind Kind => SyntaxKind.SchemaCoordinate;
+
+ ///
+ /// Specifies if this is a coordinate of a directive.
+ ///
+ public bool OfDirective { get; }
+
+ ///
+ /// The name of the referenced
+ ///
+ public NameNode Name { get; }
+
+ ///
+ /// The optional name of the referenced field or enum value
+ ///
+ public NameNode? MemberName { get; }
+
+ ///
+ /// The optional name of the referenced argument
+ ///
+ public NameNode? ArgumentName { get; }
+
+ ///
+ public IEnumerable GetNodes()
+ {
+ yield return Name;
+
+ if (MemberName is not null)
+ {
+ yield return MemberName;
+ }
+
+ if (ArgumentName is not null)
+ {
+ yield return ArgumentName;
+ }
+ }
+
+ ///
+ /// Returns the GraphQL syntax representation of this .
+ ///
+ ///
+ /// Returns the GraphQL syntax representation of this .
+ ///
+ public override string ToString() => SyntaxPrinter.Print(this, true);
+
+ ///
+ /// Returns the GraphQL syntax representation of this .
+ ///
+ ///
+ /// A value that indicates whether the GraphQL output should be formatted,
+ /// which includes indenting nested GraphQL tokens, adding
+ /// new lines, and adding white space between property names and values.
+ ///
+ ///
+ /// Returns the GraphQL syntax representation of this .
+ ///
+ public string ToString(bool indented) => SyntaxPrinter.Print(this, indented);
+
+ ///
+ /// Creates a new node from the current instance and replaces the
+ /// with .
+ ///
+ ///
+ /// The location that shall be used to replace the current location.
+ ///
+ ///
+ /// Returns the new node with the new .
+ ///
+ public SchemaCoordinateNode WithLocation(Location? location)
+ => new(location, OfDirective, Name, MemberName, ArgumentName);
+
+ ///
+ /// Creates a new node from the current instance and replaces the
+ /// with .
+ ///
+ ///
+ /// The ofDirective that shall be used to replace the current ofDirective.
+ ///
+ ///
+ /// Returns the new node with the new .
+ ///
+ public SchemaCoordinateNode WithOfDirective(bool ofDirective)
+ => new(Location, ofDirective, Name, MemberName, ArgumentName);
+
+ ///
+ /// Creates a new node from the current instance and replaces the
+ /// with .
+ ///
+ ///
+ /// The name that shall be used to replace the current name.
+ ///
+ ///
+ /// Returns the new node with the new .
+ ///
+ public SchemaCoordinateNode WithName(NameNode name)
+ => new(Location, OfDirective, name, MemberName, ArgumentName);
+
+ ///
+ /// Creates a new node from the current instance and replaces the
+ /// with .
+ ///
+ ///
+ /// The memberName that shall be used to replace the current memberName.
+ ///
+ ///
+ /// Returns the new node with the new .
+ ///
+ public SchemaCoordinateNode WithMemberName(NameNode? memberName)
+ => new(Location, OfDirective, Name, memberName, ArgumentName);
+
+ ///
+ /// Creates a new node from the current instance and replaces the
+ /// with .
+ ///
+ ///
+ /// The argumentName that shall be used to replace the current argumentName.
+ ///
+ ///
+ /// Returns the new node with the new .
+ ///
+ public SchemaCoordinateNode WithArgumentName(NameNode? argumentName)
+ => new(Location, OfDirective, Name, MemberName, argumentName);
+}
diff --git a/src/HotChocolate/Language/src/Language.SyntaxTree/SyntaxKind.cs b/src/HotChocolate/Language/src/Language.SyntaxTree/SyntaxKind.cs
index 841dc03d767..fb0289994e8 100644
--- a/src/HotChocolate/Language/src/Language.SyntaxTree/SyntaxKind.cs
+++ b/src/HotChocolate/Language/src/Language.SyntaxTree/SyntaxKind.cs
@@ -48,5 +48,6 @@ public enum SyntaxKind
PublicKeyword,
ListNullability,
RequiredDesignator,
- OptionalDesignator
+ OptionalDesignator,
+ SchemaCoordinate,
}
diff --git a/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/SyntaxSerializer.SchemaSyntax.cs b/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/SyntaxSerializer.SchemaSyntax.cs
index 9e65bbc608c..a60f628b73f 100644
--- a/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/SyntaxSerializer.SchemaSyntax.cs
+++ b/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/SyntaxSerializer.SchemaSyntax.cs
@@ -220,6 +220,30 @@ private void VisitInputObjectTypeExtension(
VisitInputObjectTypeDefinitionBase(node, writer);
}
+ private void VisitSchemaCoordinate(
+ SchemaCoordinateNode node,
+ ISyntaxWriter writer)
+ {
+ if (node.OfDirective)
+ {
+ writer.Write("@");
+ }
+
+ writer.WriteName(node.Name);
+ if (node.MemberName is not null)
+ {
+ writer.Write(".");
+ writer.WriteName(node.MemberName);
+ }
+
+ if (node.ArgumentName is not null)
+ {
+ writer.Write("(");
+ writer.WriteName(node.ArgumentName);
+ writer.Write(":)");
+ }
+ }
+
private void VisitInputObjectTypeDefinitionBase(
InputObjectTypeDefinitionNodeBase node,
ISyntaxWriter writer)
diff --git a/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/SyntaxSerializer.cs b/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/SyntaxSerializer.cs
index f97dbf133ae..d3a91808a94 100644
--- a/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/SyntaxSerializer.cs
+++ b/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/SyntaxSerializer.cs
@@ -132,6 +132,9 @@ public void Serialize(ISyntaxNode node, ISyntaxWriter writer)
case SyntaxKind.InputObjectTypeExtension:
VisitInputObjectTypeExtension((InputObjectTypeExtensionNode)node, writer);
break;
+ case SyntaxKind.SchemaCoordinate:
+ VisitSchemaCoordinate((SchemaCoordinateNode)node, writer);
+ break;
default:
ThrowHelper.NodeKindIsNotSupported(node.Kind);
break;
diff --git a/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/ThrowHelper.cs b/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/ThrowHelper.cs
index d546a0b4927..cdc3ff06f01 100644
--- a/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/ThrowHelper.cs
+++ b/src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/ThrowHelper.cs
@@ -1,4 +1,5 @@
using System;
+using HotChocolate.Language.Properties;
namespace HotChocolate.Language.Utilities;
@@ -7,4 +8,15 @@ internal static class ThrowHelper
public static void NodeKindIsNotSupported(SyntaxKind kind) =>
throw new NotSupportedException($"The node kind {kind} is not supported.");
+ public static Exception SchemaCoordinate_MemberNameCannotBeSetOnADirectiveCoordinate(
+ string argumentName) =>
+ throw new ArgumentException(
+ Resources.ThrowHelper_SchemaCoordinate_MemberNameCannotBeSetOnADirectiveCoordinate,
+ argumentName);
+
+ public static Exception SchemaCoordinate_ArgumentNameCannotBeSetWithoutMemberName(
+ string argumentName) =>
+ throw new ArgumentException(
+ Resources.ThrowHelper_SchemaCoordinate_ArgumentNameCannotBeSetWithoutMemberName,
+ argumentName);
}
diff --git a/src/HotChocolate/Language/src/Language.Utf8/Properties/LangUtf8Resources.Designer.cs b/src/HotChocolate/Language/src/Language.Utf8/Properties/LangUtf8Resources.Designer.cs
index 4a2ad6c2526..26acb0e0468 100644
--- a/src/HotChocolate/Language/src/Language.Utf8/Properties/LangUtf8Resources.Designer.cs
+++ b/src/HotChocolate/Language/src/Language.Utf8/Properties/LangUtf8Resources.Designer.cs
@@ -9,21 +9,21 @@
namespace HotChocolate.Language.Properties {
using System;
-
-
+
+
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class LangUtf8Resources {
-
+
private static System.Resources.ResourceManager resourceMan;
-
+
private static System.Globalization.CultureInfo resourceCulture;
-
+
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal LangUtf8Resources() {
}
-
+
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Resources.ResourceManager ResourceManager {
get {
@@ -34,7 +34,7 @@ internal static System.Resources.ResourceManager ResourceManager {
return resourceMan;
}
}
-
+
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Globalization.CultureInfo Culture {
get {
@@ -44,109 +44,115 @@ internal static System.Globalization.CultureInfo Culture {
resourceCulture = value;
}
}
-
+
internal static string GraphQLData_Empty {
get {
return ResourceManager.GetString("GraphQLData_Empty", resourceCulture);
}
}
-
+
internal static string ParseMany_InvalidOpenToken {
get {
return ResourceManager.GetString("ParseMany_InvalidOpenToken", resourceCulture);
}
}
-
+
internal static string Parser_InvalidScalarToken {
get {
return ResourceManager.GetString("Parser_InvalidScalarToken", resourceCulture);
}
}
-
+
internal static string Parser_InvalidToken {
get {
return ResourceManager.GetString("Parser_InvalidToken", resourceCulture);
}
}
-
+
internal static string QuerySyntaxRewriter_NotSupported {
get {
return ResourceManager.GetString("QuerySyntaxRewriter_NotSupported", resourceCulture);
}
}
-
+
internal static string Reader_InvalidToken {
get {
return ResourceManager.GetString("Reader_InvalidToken", resourceCulture);
}
}
-
+
+ internal static string Reader_UnexpectedDigitAfterDot {
+ get {
+ return ResourceManager.GetString("Reader_UnexpectedDigitAfterDot", resourceCulture);
+ }
+ }
+
internal static string Reader_UnexpectedPunctuatorToken {
get {
return ResourceManager.GetString("Reader_UnexpectedPunctuatorToken", resourceCulture);
}
}
-
+
internal static string SourceText_Empty {
get {
return ResourceManager.GetString("SourceText_Empty", resourceCulture);
}
}
-
+
internal static string Utf8Helper_InvalidEscapeChar {
get {
return ResourceManager.GetString("Utf8Helper_InvalidEscapeChar", resourceCulture);
}
}
-
+
internal static string Utf8Helper_InvalidQuoteEscapeCount {
get {
return ResourceManager.GetString("Utf8Helper_InvalidQuoteEscapeCount", resourceCulture);
}
}
-
+
internal static string NewLineMustBeGreaterOrEqualToOne {
get {
return ResourceManager.GetString("NewLineMustBeGreaterOrEqualToOne", resourceCulture);
}
}
-
+
internal static string UnexpectedDigit {
get {
return ResourceManager.GetString("UnexpectedDigit", resourceCulture);
}
}
-
+
internal static string InvalidNumber {
get {
return ResourceManager.GetString("InvalidNumber", resourceCulture);
}
}
-
+
internal static string UnexpectedCharacter {
get {
return ResourceManager.GetString("UnexpectedCharacter", resourceCulture);
}
}
-
+
internal static string InvalidCharacterEscapeSequence {
get {
return ResourceManager.GetString("InvalidCharacterEscapeSequence", resourceCulture);
}
}
-
+
internal static string InvalidCharacterWithinString {
get {
return ResourceManager.GetString("InvalidCharacterWithinString", resourceCulture);
}
}
-
+
internal static string UnterminatedString {
get {
return ResourceManager.GetString("UnterminatedString", resourceCulture);
}
}
-
+
internal static string UnexpectedToken {
get {
return ResourceManager.GetString("UnexpectedToken", resourceCulture);
diff --git a/src/HotChocolate/Language/src/Language.Utf8/Properties/LangUtf8Resources.resx b/src/HotChocolate/Language/src/Language.Utf8/Properties/LangUtf8Resources.resx
index b723f950646..c0c58ef32a9 100644
--- a/src/HotChocolate/Language/src/Language.Utf8/Properties/LangUtf8Resources.resx
+++ b/src/HotChocolate/Language/src/Language.Utf8/Properties/LangUtf8Resources.resx
@@ -36,6 +36,9 @@
Expected a `{0}`-token.
+
+ Invalid number, expected digit before ".".
+
Unexpected punctuator token `{0}`.
diff --git a/src/HotChocolate/Language/src/Language.Utf8/TokenKind.cs b/src/HotChocolate/Language/src/Language.Utf8/TokenKind.cs
index 7f081905f9f..fab6faacd0f 100644
--- a/src/HotChocolate/Language/src/Language.Utf8/TokenKind.cs
+++ b/src/HotChocolate/Language/src/Language.Utf8/TokenKind.cs
@@ -118,5 +118,10 @@ public enum TokenKind : byte
///
/// A comment token.
///
- Comment
+ Comment,
+
+ ///
+ /// .
+ ///
+ Dot,
}
diff --git a/src/HotChocolate/Language/src/Language.Utf8/TokenPrinter.cs b/src/HotChocolate/Language/src/Language.Utf8/TokenPrinter.cs
index 25e5d50baea..851b1b84c20 100644
--- a/src/HotChocolate/Language/src/Language.Utf8/TokenPrinter.cs
+++ b/src/HotChocolate/Language/src/Language.Utf8/TokenPrinter.cs
@@ -10,6 +10,7 @@ internal static class TokenPrinter
{ TokenKind.StartOfFile, "" },
{ TokenKind.EndOfFile, "" },
{ TokenKind.Bang, "!" },
+ { TokenKind.QuestionMark, "?" },
{ TokenKind.Dollar, "$" },
{ TokenKind.Ampersand, "&" },
{ TokenKind.LeftParenthesis, "(" },
@@ -28,7 +29,8 @@ internal static class TokenPrinter
{ TokenKind.Float, "Float" },
{ TokenKind.String, "String" },
{ TokenKind.BlockString, "BlockString" },
- { TokenKind.Comment, "Comment" }
+ { TokenKind.Comment, "Comment" },
+ { TokenKind.Dot, "." },
};
public static string Print(in Utf8GraphQLReader reader)
diff --git a/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.SchemaCoordinate.cs b/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.SchemaCoordinate.cs
new file mode 100644
index 00000000000..1988c72951a
--- /dev/null
+++ b/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.SchemaCoordinate.cs
@@ -0,0 +1,71 @@
+namespace HotChocolate.Language;
+
+// Implements the parsing rules in the Operations section.
+public ref partial struct Utf8GraphQLParser
+{
+ ///
+ /// Parses a single schema coordinate.
+ /// :
+ /// SchemaCoordinate :
+ /// - Name
+ /// - Name . Name
+ /// - Name . Name ( Name : )
+ /// - @ Name
+ /// - @ Name ( Name : )
+ ///
+ private SchemaCoordinateNode ParseSingleSchemaCoordinate()
+ {
+ SchemaCoordinateNode node = ParseSchemaCoordinate();
+ Expect(TokenKind.EndOfFile);
+ return node;
+ }
+
+ ///
+ /// Parses a schema coordinate.
+ /// :
+ /// SchemaCoordinate :
+ /// - Name
+ /// - Name . Name
+ /// - Name . Name ( Name : )
+ /// - @ Name
+ /// - @ Name ( Name : )
+ ///
+ private SchemaCoordinateNode ParseSchemaCoordinate()
+ {
+ TokenInfo start = Start();
+
+ bool ofDirective = SkipAt();
+ NameNode name = ParseName();
+ NameNode? memberName = null;
+ NameNode? argumentName = null;
+
+ if (SkipDot())
+ {
+ if (ofDirective)
+ {
+ throw Unexpected(TokenKind.Dot);
+ }
+
+ memberName = ParseName();
+ }
+
+ if (_reader.Kind == TokenKind.LeftParenthesis)
+ {
+ MoveNext();
+ argumentName = ParseName();
+ ExpectColon();
+ ExpectRightParenthesis();
+ }
+
+ Location? location = CreateLocation(in start);
+
+ return new SchemaCoordinateNode
+ (
+ location,
+ ofDirective,
+ name,
+ memberName,
+ argumentName
+ );
+ }
+}
diff --git a/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.Syntax.cs b/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.Syntax.cs
index 8a25bc0c4aa..43616c26b0c 100644
--- a/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.Syntax.cs
+++ b/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.Syntax.cs
@@ -121,6 +121,31 @@ public static ITypeNode ParseTypeReference(
Utf8GraphQLReader reader) =>
new Utf8GraphQLParser(reader).ParseTypeReference();
+ ///
+ /// Parses a GraphQL schema coordinate e.g. Query.userById(id:)
+ ///
+ public static SchemaCoordinateNode ParseSchemaCoordinate(
+ string sourceText) =>
+ Parse(
+ sourceText,
+ parser => parser.ParseSingleSchemaCoordinate());
+
+ ///
+ /// Parses a GraphQL schema coordinate e.g. Query.userById(id:)
+ ///
+ public static SchemaCoordinateNode ParseSchemaCoordinate(
+ ReadOnlySpan sourceText) =>
+ Parse(
+ sourceText,
+ parser => parser.ParseSingleSchemaCoordinate());
+
+ ///
+ /// Parses a GraphQL schema coordinate e.g. Query.userById(id:)
+ ///
+ public static SchemaCoordinateNode ParseSchemaCoordinate(
+ Utf8GraphQLReader reader) =>
+ new Utf8GraphQLParser(reader).ParseSchemaCoordinate();
+
private static unsafe T Parse(
string sourceText,
ParseSyntax parse,
diff --git a/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.Utilities.cs b/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.Utilities.cs
index c4c362d47f2..2e384f11dbf 100644
--- a/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.Utilities.cs
+++ b/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.Utilities.cs
@@ -136,6 +136,10 @@ private void ExpectKeyword(ReadOnlySpan keyword)
private bool SkipAmpersand() => _reader.Skip(TokenKind.Ampersand);
+ private bool SkipAt() => _reader.Skip(TokenKind.At);
+
+ private bool SkipDot() => _reader.Skip(TokenKind.Dot);
+
private bool SkipRepeatableKeyword() =>
SkipKeyword(GraphQLKeywords.Repeatable);
diff --git a/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLReader.cs b/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLReader.cs
index 7ab70746485..f2c588180b4 100644
--- a/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLReader.cs
+++ b/src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLReader.cs
@@ -201,7 +201,7 @@ private void ReadNameToken()
///
/// Reads punctuator tokens as specified in
/// http://facebook.github.io/graphql/October2016/#sec-Punctuators
- /// one of ! $ ( ) ... : = @ [ ] { | }
+ /// one of ! ? $ ( ) ... . : = @ [ ] { | }
/// additionally the reader will tokenize ampersands.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -211,22 +211,30 @@ private void ReadPunctuatorToken(byte code)
_end = ++_position;
_value = null;
- if (code == GraphQLConstants.Dot)
+ if (code is GraphQLConstants.Dot)
{
- if (_graphQLData[_position] is GraphQLConstants.Dot
- && _graphQLData[_position + 1] is GraphQLConstants.Dot)
+ if (_graphQLData[_position] is GraphQLConstants.Dot)
{
- _position += 2;
- _end = _position;
- _kind = TokenKind.Spread;
+ if (_graphQLData[_position + 1] is GraphQLConstants.Dot)
+ {
+ _position += 2;
+ _end = _position;
+ _kind = TokenKind.Spread;
+ }
+ else
+ {
+ _position--;
+ throw ThrowHelper.Reader_InvalidToken(this, TokenKind.Spread);
+ }
}
- else
+ else if (_graphQLData[_position].IsDigit())
{
_position--;
- throw new SyntaxException(this,
- string.Format(CultureInfo.InvariantCulture,
- Reader_InvalidToken,
- TokenKind.Spread));
+ throw ThrowHelper.Reader_UnexpectedDigitAfterDot(this);
+ }
+ else
+ {
+ _kind = TokenKind.Dot;
}
}
else
diff --git a/src/HotChocolate/Language/src/Language.Utf8/Utilities/ThrowHelper.cs b/src/HotChocolate/Language/src/Language.Utf8/Utilities/ThrowHelper.cs
index be15096c1af..378f39e140d 100644
--- a/src/HotChocolate/Language/src/Language.Utf8/Utilities/ThrowHelper.cs
+++ b/src/HotChocolate/Language/src/Language.Utf8/Utilities/ThrowHelper.cs
@@ -1,5 +1,6 @@
using System;
using System.Globalization;
+using HotChocolate.Language.Properties;
namespace HotChocolate.Language;
@@ -58,4 +59,17 @@ public static SyntaxException UnexpectedToken(Utf8GraphQLReader reader) =>
"Unexpected token found `{0}` " +
"while expecting a scalar value.",
reader.Kind));
+
+ public static SyntaxException Reader_UnexpectedDigitAfterDot(Utf8GraphQLReader reader) =>
+ new SyntaxException(reader, LangUtf8Resources.Reader_UnexpectedDigitAfterDot);
+
+ public static SyntaxException Reader_InvalidToken(
+ Utf8GraphQLReader reader,
+ TokenKind expected) =>
+ new SyntaxException(
+ reader,
+ string.Format(
+ CultureInfo.InvariantCulture,
+ LangUtf8Resources.Reader_InvalidToken,
+ expected));
}
diff --git a/src/HotChocolate/Language/src/Language.Visitors/SyntaxVisitorOptions.cs b/src/HotChocolate/Language/src/Language.Visitors/SyntaxVisitorOptions.cs
index 22d27e46e97..25eef2479fd 100644
--- a/src/HotChocolate/Language/src/Language.Visitors/SyntaxVisitorOptions.cs
+++ b/src/HotChocolate/Language/src/Language.Visitors/SyntaxVisitorOptions.cs
@@ -1,12 +1,27 @@
namespace HotChocolate.Language.Visitors;
+///
+/// Represents basic visitor options.
+///
public struct SyntaxVisitorOptions
{
+ ///
+ /// Specifies if the visitor shall traverse name nodes.
+ ///
public bool VisitNames { get; set; }
+ ///
+ /// Specifies if the visitor shall traverse description nodes.
+ ///
public bool VisitDescriptions { get; set; }
+ ///
+ /// Specifies if the visitor shall traverse directives nodes.
+ ///
public bool VisitDirectives { get; set; }
+ ///
+ /// Specifies if the visitor shall traverse argument nodes.
+ ///
public bool VisitArguments { get; set; }
}
diff --git a/src/HotChocolate/Language/src/Language.Visitors/SyntaxVisitor~1.VisitationMap.cs b/src/HotChocolate/Language/src/Language.Visitors/SyntaxVisitor~1.VisitationMap.cs
index 855ae376259..ea9353b5a60 100644
--- a/src/HotChocolate/Language/src/Language.Visitors/SyntaxVisitor~1.VisitationMap.cs
+++ b/src/HotChocolate/Language/src/Language.Visitors/SyntaxVisitor~1.VisitationMap.cs
@@ -90,6 +90,8 @@ protected virtual ISyntaxVisitorAction VisitChildren(
return VisitChildren((EnumTypeExtensionNode)node, context);
case SyntaxKind.InputObjectTypeExtension:
return VisitChildren((InputObjectTypeExtensionNode)node, context);
+ case SyntaxKind.SchemaCoordinate:
+ return VisitChildren((SchemaCoordinateNode)node, context);
default:
throw new NotSupportedException(node.GetType().FullName);
@@ -1127,4 +1129,30 @@ protected virtual ISyntaxVisitorAction VisitChildren(
return DefaultAction;
}
+
+ protected virtual ISyntaxVisitorAction VisitChildren(
+ SchemaCoordinateNode node,
+ TContext context)
+ {
+ if (_options.VisitNames && Visit(node.Name, node, context).IsBreak())
+ {
+ return Break;
+ }
+
+ if(_options.VisitNames &&
+ node.MemberName is not null &&
+ Visit(node.MemberName, node, context).IsBreak())
+ {
+ return Break;
+ }
+
+ if(_options.VisitNames &&
+ node.ArgumentName is not null &&
+ Visit(node.ArgumentName, node, context).IsBreak())
+ {
+ return Break;
+ }
+
+ return DefaultAction;
+ }
}
diff --git a/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker.Enter.cs b/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker.Enter.cs
index 9e85a8b984f..1ac868807a6 100644
--- a/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker.Enter.cs
+++ b/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker.Enter.cs
@@ -91,6 +91,8 @@ protected override ISyntaxVisitorAction Enter(
return Enter((EnumTypeExtensionNode)node, context);
case SyntaxKind.InputObjectTypeExtension:
return Enter((InputObjectTypeExtensionNode)node, context);
+ case SyntaxKind.SchemaCoordinate:
+ return Enter((SchemaCoordinateNode)node, context);
default:
throw new NotSupportedException(node.GetType().FullName);
}
@@ -285,4 +287,9 @@ protected virtual ISyntaxVisitorAction Enter(
InputObjectTypeExtensionNode node,
ISyntaxVisitorContext context) =>
DefaultAction;
+
+ protected virtual ISyntaxVisitorAction Enter(
+ SchemaCoordinateNode node,
+ ISyntaxVisitorContext context) =>
+ DefaultAction;
}
diff --git a/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker.Leave.cs b/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker.Leave.cs
index 9d7a8a174af..f25342a4a4e 100644
--- a/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker.Leave.cs
+++ b/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker.Leave.cs
@@ -91,6 +91,8 @@ protected override ISyntaxVisitorAction Leave(
return Leave((EnumTypeExtensionNode)node, context);
case SyntaxKind.InputObjectTypeExtension:
return Leave((InputObjectTypeExtensionNode)node, context);
+ case SyntaxKind.SchemaCoordinate:
+ return Leave((SchemaCoordinateNode)node, context);
default:
throw new NotSupportedException(node.GetType().FullName);
}
@@ -284,4 +286,9 @@ protected virtual ISyntaxVisitorAction Leave(
InputObjectTypeExtensionNode node,
ISyntaxVisitorContext context) =>
DefaultAction;
+
+ protected virtual ISyntaxVisitorAction Leave(
+ SchemaCoordinateNode node,
+ ISyntaxVisitorContext context) =>
+ DefaultAction;
}
diff --git a/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker~1.Enter.cs b/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker~1.Enter.cs
index fd478ce407d..826fb56c728 100644
--- a/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker~1.Enter.cs
+++ b/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker~1.Enter.cs
@@ -91,6 +91,8 @@ protected override ISyntaxVisitorAction Enter(
return Enter((EnumTypeExtensionNode)node, context);
case SyntaxKind.InputObjectTypeExtension:
return Enter((InputObjectTypeExtensionNode)node, context);
+ case SyntaxKind.SchemaCoordinate:
+ return Enter((SchemaCoordinateNode)node, context);
default:
throw new NotSupportedException(node.GetType().FullName);
}
@@ -285,4 +287,9 @@ protected virtual ISyntaxVisitorAction Enter(
InputObjectTypeExtensionNode node,
TContext context) =>
DefaultAction;
+
+ protected virtual ISyntaxVisitorAction Enter(
+ SchemaCoordinateNode node,
+ ISyntaxVisitorContext context) =>
+ DefaultAction;
}
diff --git a/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker~1.Leave.cs b/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker~1.Leave.cs
index 8975affed4b..112c5bd9e68 100644
--- a/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker~1.Leave.cs
+++ b/src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker~1.Leave.cs
@@ -91,6 +91,8 @@ protected override ISyntaxVisitorAction Leave(
return Leave((EnumTypeExtensionNode)node, context);
case SyntaxKind.InputObjectTypeExtension:
return Leave((InputObjectTypeExtensionNode)node, context);
+ case SyntaxKind.SchemaCoordinate:
+ return Leave((SchemaCoordinateNode)node, context);
default:
throw new NotSupportedException(node.GetType().FullName);
}
@@ -284,4 +286,9 @@ protected virtual ISyntaxVisitorAction Leave(
InputObjectTypeExtensionNode node,
TContext context) =>
DefaultAction;
+
+ protected virtual ISyntaxVisitorAction Leave(
+ SchemaCoordinateNode node,
+ ISyntaxVisitorContext context) =>
+ DefaultAction;
}
diff --git a/src/HotChocolate/Language/test/Language.Tests/AST/SchemaCoordinateTests.cs b/src/HotChocolate/Language/test/Language.Tests/AST/SchemaCoordinateTests.cs
new file mode 100644
index 00000000000..002724b53ed
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/AST/SchemaCoordinateTests.cs
@@ -0,0 +1,275 @@
+using System;
+using Snapshooter.Xunit;
+using Xunit;
+
+namespace HotChocolate.Language;
+
+public class SchemaCoordinateTests
+{
+ [Fact]
+ public void CreateSchemaCoordinateWithLocation()
+ {
+ // arrange
+ var location = new Location(0, 0, 0, 0);
+ bool ofDirective = false;
+ NameNode name = new NameNode("Foo");
+ NameNode memberName = new NameNode("bar");
+ NameNode argumentName = new NameNode("baz");
+
+ // act
+ var coordinate =
+ new SchemaCoordinateNode(location, ofDirective, name, memberName, argumentName);
+
+ // assert
+ Assert.Equal(SyntaxKind.SchemaCoordinate, coordinate.Kind);
+ Assert.Equal(location, coordinate.Location);
+ Assert.False(coordinate.OfDirective);
+ Assert.Equal(name, coordinate.Name);
+ Assert.Equal(memberName, coordinate.MemberName);
+ Assert.Equal(argumentName, coordinate.ArgumentName);
+ coordinate.ToString().MatchSnapshot();
+ }
+
+ [Fact]
+ public void CreateSchemaCoordinateWithoutLocation()
+ {
+ // arrange
+ bool ofDirective = false;
+ NameNode name = new NameNode("Foo");
+ NameNode memberName = new NameNode("bar");
+ NameNode argumentName = new NameNode("baz");
+
+ // act
+ var coordinate =
+ new SchemaCoordinateNode(null, ofDirective, name, memberName, argumentName);
+
+ // assert
+ Assert.Equal(SyntaxKind.SchemaCoordinate, coordinate.Kind);
+ Assert.Null(coordinate.Location);
+ Assert.False(coordinate.OfDirective);
+ Assert.Equal(name, coordinate.Name);
+ Assert.Equal(memberName, coordinate.MemberName);
+ Assert.Equal(argumentName, coordinate.ArgumentName);
+ coordinate.ToString().MatchSnapshot();
+ }
+
+ [Fact]
+ public void CreateSchemaCoordinateWithoutArgumentName()
+ {
+ // arrange
+ var location = new Location(0, 0, 0, 0);
+ bool ofDirective = false;
+ NameNode name = new NameNode("Foo");
+ NameNode memberName = new NameNode("bar");
+
+ // act
+ var coordinate =
+ new SchemaCoordinateNode(location, ofDirective, name, memberName, null);
+
+ // assert
+ Assert.Equal(SyntaxKind.SchemaCoordinate, coordinate.Kind);
+ Assert.Equal(location, coordinate.Location);
+ Assert.False(coordinate.OfDirective);
+ Assert.Equal(name, coordinate.Name);
+ Assert.Equal(memberName, coordinate.MemberName);
+ Assert.Null(coordinate.ArgumentName);
+ coordinate.ToString().MatchSnapshot();
+ }
+
+ [Fact]
+ public void CreateSchemaCoordinateWithoutArgumentAndMemberName()
+ {
+ // arrange
+ var location = new Location(0, 0, 0, 0);
+ bool ofDirective = false;
+ NameNode name = new NameNode("Foo");
+
+ // act
+ var coordinate =
+ new SchemaCoordinateNode(location, ofDirective, name, null, null);
+
+ // assert
+ Assert.Equal(SyntaxKind.SchemaCoordinate, coordinate.Kind);
+ Assert.Equal(location, coordinate.Location);
+ Assert.False(coordinate.OfDirective);
+ Assert.Equal(name, coordinate.Name);
+ Assert.Null(coordinate.MemberName);
+ Assert.Null(coordinate.ArgumentName);
+ coordinate.ToString().MatchSnapshot();
+ }
+
+ [Fact]
+ public void CreateSchemaCoordinateOfDirectiveWithArgumentName()
+ {
+ // arrange
+ var location = new Location(0, 0, 0, 0);
+ bool ofDirective = true;
+ NameNode name = new NameNode("Foo");
+ NameNode argumentName = new NameNode("baz");
+
+ // act
+ var coordinate =
+ new SchemaCoordinateNode(location, ofDirective, name, null, argumentName);
+
+ // assert
+ Assert.Equal(SyntaxKind.SchemaCoordinate, coordinate.Kind);
+ Assert.Equal(location, coordinate.Location);
+ Assert.True(coordinate.OfDirective);
+ Assert.Equal(name, coordinate.Name);
+ Assert.Null(coordinate.MemberName);
+ Assert.Equal(argumentName, coordinate.ArgumentName);
+ coordinate.ToString().MatchSnapshot();
+ }
+
+ [Fact]
+ public void CreateSchemaCoordinateOfDirectiveWithoutArgumentName()
+ {
+ // arrange
+ var location = new Location(0, 0, 0, 0);
+ bool ofDirective = true;
+ NameNode name = new NameNode("Foo");
+
+ // act
+ var coordinate =
+ new SchemaCoordinateNode(location, ofDirective, name, null, null);
+
+ // assert
+ Assert.Equal(SyntaxKind.SchemaCoordinate, coordinate.Kind);
+ Assert.Equal(location, coordinate.Location);
+ Assert.True(coordinate.OfDirective);
+ Assert.Equal(name, coordinate.Name);
+ Assert.Null(coordinate.MemberName);
+ Assert.Null(coordinate.ArgumentName);
+ coordinate.ToString().MatchSnapshot();
+ }
+
+ [Fact]
+ public void CreateSchemaCoordinateOfDirectiveWithMemberName()
+ {
+ // arrange
+ var location = new Location(0, 0, 0, 0);
+ bool ofDirective = true;
+ NameNode name = new NameNode("Foo");
+ NameNode memberName = new NameNode("Foo");
+
+ // act
+ Exception ex = Record.Exception(() =>
+ {
+ new SchemaCoordinateNode(location, ofDirective, name, memberName, null);
+ });
+
+ // assert
+ Assert.IsType(ex);
+ }
+
+ [Fact]
+ public void CreateSchemaCoordinateOfTypeWithArgumentNameButNoMemberName()
+ {
+ // arrange
+ var location = new Location(0, 0, 0, 0);
+ bool ofDirective = false;
+ NameNode name = new NameNode("Foo");
+ NameNode argumentName = new NameNode("baz");
+
+ // act
+ Exception ex = Record.Exception(() =>
+ {
+ new SchemaCoordinateNode(location, ofDirective, name, null, argumentName);
+ });
+
+ // assert
+ Assert.IsType(ex);
+ }
+
+ [Fact]
+ public void CreateSchemaCoordinateWithoutName()
+ {
+ // arrange
+ var location = new Location(0, 0, 0, 0);
+ bool ofDirective = false;
+
+ // act
+ Exception ex = Record.Exception(() =>
+ {
+ new SchemaCoordinateNode(location, ofDirective, null!, null, null);
+ });
+
+ // assert
+ Assert.IsType(ex);
+ }
+
+ [Fact]
+ public void SchemaCoordinate_With_Location()
+ {
+ // arrange
+ var location = new Location(0, 0, 0, 0);
+ NameNode name = new NameNode("Foo");
+ var node = new SchemaCoordinateNode(null, false, name, null, null);
+
+ // act
+ SchemaCoordinateNode rewrittenNode = node.WithLocation(location);
+
+ // assert
+ Assert.Equal(location, rewrittenNode.Location);
+ }
+
+ [Fact]
+ public void SchemaCoordinate_With_Name()
+ {
+ // arrange
+ NameNode name = new NameNode("Foo");
+ NameNode newName = new NameNode("newName");
+ var node = new SchemaCoordinateNode(null, false, name, null, null);
+
+ // act
+ SchemaCoordinateNode rewrittenNode = node.WithName(newName);
+
+ // assert
+ Assert.Equal(newName, rewrittenNode.Name);
+ }
+
+ [Fact]
+ public void SchemaCoordinate_With_MemberName()
+ {
+ // arrange
+ NameNode name = new NameNode("Foo");
+ NameNode memberName = new NameNode("foo");
+ var node = new SchemaCoordinateNode(null, false, name, null, null);
+
+ // act
+ SchemaCoordinateNode rewrittenNode = node.WithMemberName(memberName);
+
+ // assert
+ Assert.Equal(memberName, rewrittenNode.MemberName);
+ }
+
+ [Fact]
+ public void SchemaCoordinate_With_ArgumentName()
+ {
+ // arrange
+ NameNode name = new NameNode("Foo");
+ NameNode memberName = new NameNode("foo");
+ NameNode argumentName = new NameNode("baz");
+ var node = new SchemaCoordinateNode(null, false, name, memberName, null);
+
+ // act
+ SchemaCoordinateNode rewrittenNode = node.WithArgumentName(argumentName);
+
+ // assert
+ Assert.Equal(argumentName, rewrittenNode.ArgumentName);
+ }
+
+ [Fact]
+ public void SchemaCoordinate_With_OfDirective()
+ {
+ // arrange
+ NameNode name = new NameNode("Foo");
+ var node = new SchemaCoordinateNode(null, false, name, null, null);
+
+ // act
+ SchemaCoordinateNode rewrittenNode = node.WithOfDirective(true);
+
+ // assert
+ Assert.True(rewrittenNode.OfDirective);
+ }
+}
diff --git a/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateOfDirectiveWithArgumentName.snap b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateOfDirectiveWithArgumentName.snap
new file mode 100644
index 00000000000..fe9b1f8e497
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateOfDirectiveWithArgumentName.snap
@@ -0,0 +1 @@
+@Foo(baz:)
diff --git a/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateOfDirectiveWithoutArgumentName.snap b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateOfDirectiveWithoutArgumentName.snap
new file mode 100644
index 00000000000..85b245d50cf
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateOfDirectiveWithoutArgumentName.snap
@@ -0,0 +1 @@
+@Foo
diff --git a/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithLocation.snap b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithLocation.snap
new file mode 100644
index 00000000000..ae3a2444b67
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithLocation.snap
@@ -0,0 +1 @@
+Foo.bar(baz:)
diff --git a/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithoutArgumentAndMemberName.snap b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithoutArgumentAndMemberName.snap
new file mode 100644
index 00000000000..ad32471d9ac
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithoutArgumentAndMemberName.snap
@@ -0,0 +1 @@
+Foo
diff --git a/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithoutArgumentName.snap b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithoutArgumentName.snap
new file mode 100644
index 00000000000..3d76c813507
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithoutArgumentName.snap
@@ -0,0 +1 @@
+Foo.bar
diff --git a/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithoutLocation.snap b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithoutLocation.snap
new file mode 100644
index 00000000000..ae3a2444b67
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/AST/__snapshots__/SchemaCoordinateTests.CreateSchemaCoordinateWithoutLocation.snap
@@ -0,0 +1 @@
+Foo.bar(baz:)
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8BlockStringTokenReaderTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/BlockStringTokenReaderTests.cs
similarity index 99%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8BlockStringTokenReaderTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/BlockStringTokenReaderTests.cs
index 9e92a621630..5babc2f0d41 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8BlockStringTokenReaderTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/BlockStringTokenReaderTests.cs
@@ -5,7 +5,7 @@
namespace HotChocolate.Language;
-public class Utf8BlockStringTokenReaderTests
+public class BlockStringTokenReaderTests
{
[Fact]
private void ReadToken()
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8CommentTokenReaderTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/CommentTokenReaderTests.cs
similarity index 96%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8CommentTokenReaderTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/CommentTokenReaderTests.cs
index 17d80756497..776ffdc7c6b 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8CommentTokenReaderTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/CommentTokenReaderTests.cs
@@ -3,7 +3,7 @@
namespace HotChocolate.Language;
-public class Utf8CommentTokenReaderTests
+public class CommentTokenReaderTests
{
[InlineData("# my comment foo bar")]
[InlineData("#my comment foo bar")]
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8DirectiveParserTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/DirectiveParserTests.cs
similarity index 98%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8DirectiveParserTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/DirectiveParserTests.cs
index 0e54409e1fa..b2fa0e86d22 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8DirectiveParserTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/DirectiveParserTests.cs
@@ -5,7 +5,7 @@
namespace HotChocolate.Language;
-public class Utf8DirectiveParserTests
+public class DirectiveParserTests
{
[Fact]
public void ParseUniqueDirective()
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8GraphQLParserSyntaxTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/GraphQLParserSyntaxTests.cs
similarity index 98%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8GraphQLParserSyntaxTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/GraphQLParserSyntaxTests.cs
index ac4851de948..d06692d2670 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8GraphQLParserSyntaxTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/GraphQLParserSyntaxTests.cs
@@ -4,7 +4,7 @@
namespace HotChocolate.Language;
-public class Utf8GraphQLParserSyntaxTests
+public class GraphQLParserSyntaxTests
{
[Fact]
public void Parse_FieldNode_From_String() =>
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8GraphQLRequestParserTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/GraphQLRequestParserTests.cs
similarity index 96%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8GraphQLRequestParserTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/GraphQLRequestParserTests.cs
index 689deca14d4..99ace9a8ce2 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8GraphQLRequestParserTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/GraphQLRequestParserTests.cs
@@ -11,7 +11,7 @@
namespace HotChocolate.Language;
-public class Utf8GraphQLRequestParserTests
+public class GraphQLRequestParserTests
{
[Fact]
public void Utf8GraphQLRequestParser_Parse()
@@ -647,9 +647,9 @@ public void Parse_Invalid_Query()
Assert.Throws(
() =>
{
- // arrange
- var source = Encoding.UTF8.GetBytes("{\"query\":\"\"}"
- .NormalizeLineBreaks());
+ // arrange
+ var source = Encoding.UTF8.GetBytes("{\"query\":\"\"}"
+ .NormalizeLineBreaks());
var parserOptions = new ParserOptions();
var requestParser = new Utf8GraphQLRequestParser(
source,
@@ -657,8 +657,8 @@ public void Parse_Invalid_Query()
new DocumentCache(),
new Sha256DocumentHashProvider());
- // act
- requestParser.Parse();
+ // act
+ requestParser.Parse();
});
}
@@ -669,9 +669,9 @@ public void Parse_Empty_Json()
Assert.Throws(
() =>
{
- // arrange
- var source = Encoding.UTF8.GetBytes("{ }"
- .NormalizeLineBreaks());
+ // arrange
+ var source = Encoding.UTF8.GetBytes("{ }"
+ .NormalizeLineBreaks());
var parserOptions = new ParserOptions();
var requestParser = new Utf8GraphQLRequestParser(
source,
@@ -679,8 +679,8 @@ public void Parse_Empty_Json()
new DocumentCache(),
new Sha256DocumentHashProvider());
- // act
- requestParser.Parse();
+ // act
+ requestParser.Parse();
});
}
@@ -691,8 +691,8 @@ public void Parse_Empty_String()
Assert.Throws(
() =>
{
- // arrange
- var source = Encoding.UTF8.GetBytes(string.Empty);
+ // arrange
+ var source = Encoding.UTF8.GetBytes(string.Empty);
var parserOptions = new ParserOptions();
var requestParser = new Utf8GraphQLRequestParser(
source,
@@ -700,8 +700,8 @@ public void Parse_Empty_String()
new DocumentCache(),
new Sha256DocumentHashProvider());
- // act
- requestParser.Parse();
+ // act
+ requestParser.Parse();
});
}
@@ -712,8 +712,8 @@ public void Parse_Space_String()
Assert.Throws(
() =>
{
- // arrange
- var source = Encoding.UTF8.GetBytes(" ");
+ // arrange
+ var source = Encoding.UTF8.GetBytes(" ");
var parserOptions = new ParserOptions();
var requestParser = new Utf8GraphQLRequestParser(
source,
@@ -721,8 +721,8 @@ public void Parse_Space_String()
new DocumentCache(),
new Sha256DocumentHashProvider());
- // act
- requestParser.Parse();
+ // act
+ requestParser.Parse();
});
}
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8KitchenSinkParserTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/KitchenSinkParserTests.cs
similarity index 97%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8KitchenSinkParserTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/KitchenSinkParserTests.cs
index 550531397a7..005a1a546e0 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8KitchenSinkParserTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/KitchenSinkParserTests.cs
@@ -6,7 +6,7 @@
namespace HotChocolate.Language;
-public class Utf8KitchenSinkParserTests
+public class KitchenSinkParserTests
{
[Fact]
public void ParseFacebookKitchenSinkSchema()
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8NameTokenReaderTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/NameTokenReaderTests.cs
similarity index 94%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8NameTokenReaderTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/NameTokenReaderTests.cs
index 742ecb183b1..ec1f37ee6d8 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8NameTokenReaderTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/NameTokenReaderTests.cs
@@ -3,7 +3,7 @@
namespace HotChocolate.Language;
-public class Utf8NameTokenReaderTests
+public class NameTokenReaderTests
{
[InlineData(" \nhelloWorld_123")]
[InlineData(" \nhelloWorld_123\n ")]
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8NumberTokenReaderTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/NumberTokenReaderTests.cs
similarity index 71%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8NumberTokenReaderTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/NumberTokenReaderTests.cs
index 1495712a156..ae9dc51eb5d 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8NumberTokenReaderTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/NumberTokenReaderTests.cs
@@ -1,9 +1,10 @@
using System.Text;
+using Snapshooter.Xunit;
using Xunit;
namespace HotChocolate.Language;
-public class Utf8NumberTokenReaderTests
+public class NumberTokenReaderTests
{
[InlineData("1234.123", true)]
[InlineData("-1234.123", true)]
@@ -31,4 +32,17 @@ private void ReadToken(string sourceBody, bool isFloat)
Assert.Equal(0, reader.Start);
Assert.Equal(sourceBody.Length, reader.End);
}
+
+ [Fact]
+ public void InvalidNumberToken()
+ {
+ // arrange
+ byte[] source = Encoding.UTF8.GetBytes(".1");
+
+ // act
+ void Fail() => new Utf8GraphQLReader(source).Read();
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
}
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8PunctuatorTokenReaderTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/PunctuatorTokenReaderTests.cs
similarity index 82%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8PunctuatorTokenReaderTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/PunctuatorTokenReaderTests.cs
index 33000fcc042..6ba63863bc6 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8PunctuatorTokenReaderTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/PunctuatorTokenReaderTests.cs
@@ -1,9 +1,10 @@
using System.Text;
+using Snapshooter.Xunit;
using Xunit;
namespace HotChocolate.Language;
-public class Utf8PunctuatorTokenReaderTests
+public class PunctuatorTokenReaderTests
{
[Fact]
public void ReadBangToken()
@@ -89,6 +90,23 @@ public void ReadSpreadToken()
ReadToken("...", TokenKind.Spread);
}
+ [InlineData("..!")]
+ [InlineData("..1")]
+ [InlineData(".._")]
+ [InlineData("..a")]
+ [Theory]
+ public void SpreadExpected(string s)
+ {
+ // arrange
+ byte[] source = Encoding.UTF8.GetBytes(s);
+
+ // act
+ void Fail() => new Utf8GraphQLReader(source).Read();
+
+ // assert
+ Assert.Throws(Fail).Message.MatchSnapshot();
+ }
+
private void ReadToken(char code, TokenKind kind)
{
ReadToken(code.ToString(), kind);
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8QueryParserTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/QueryParserTests.cs
similarity index 99%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8QueryParserTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/QueryParserTests.cs
index e7f2df692f0..ff8973f40f6 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8QueryParserTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/QueryParserTests.cs
@@ -7,7 +7,7 @@
namespace HotChocolate.Language;
-public class Utf8QueryParserTests
+public class QueryParserTests
{
[Fact]
public void ParseSimpleShortHandFormQuery()
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8ReaderTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/ReaderTests.cs
similarity index 99%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8ReaderTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/ReaderTests.cs
index 1b09de4a9d5..4c87f5bd358 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8ReaderTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/ReaderTests.cs
@@ -7,7 +7,7 @@
namespace HotChocolate.Language;
-public class Utf8ReaderTests
+public class ReaderTests
{
[Fact]
public void Read_Two_NameTokens()
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/SchemCoordinateParserTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/SchemCoordinateParserTests.cs
new file mode 100644
index 00000000000..0801ccc8925
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/SchemCoordinateParserTests.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Text;
+using Snapshooter.Xunit;
+using Xunit;
+
+namespace HotChocolate.Language;
+
+public class SchemaCoordinateParserTests
+{
+ [Fact]
+ public void ParseName()
+ {
+ // arrange
+ string sourceText = "MyType";
+ byte[] source = Encoding.UTF8.GetBytes(sourceText);
+
+ // act
+ SchemaCoordinateNode result = Utf8GraphQLParser.Syntax.ParseSchemaCoordinate(source);
+
+ // assert
+ result.MatchSnapshot();
+ }
+
+ [Fact]
+ public void ParseNameAndMemberName()
+ {
+ // arrange
+ string sourceText = "MyType.MemberName";
+ byte[] source = Encoding.UTF8.GetBytes(sourceText);
+
+ // act
+ SchemaCoordinateNode result = Utf8GraphQLParser.Syntax.ParseSchemaCoordinate(source);
+
+ // assert
+ result.MatchSnapshot();
+ }
+
+ [Fact]
+ public void ParseNameNameName()
+ {
+ // arrange
+ string sourceText = "Name.Name.Name";
+ byte[] source = Encoding.UTF8.GetBytes(sourceText);
+
+ // act
+ void Fail() => Utf8GraphQLParser.Syntax.ParseSchemaCoordinate(source);
+
+ // assert
+ Assert.Throws(Fail);
+ }
+
+ [Fact]
+ public void ParseNameAndMemberNameAndArg()
+ {
+ // arrange
+ string sourceText = "MyType.MemberName(arg:)";
+ byte[] source = Encoding.UTF8.GetBytes(sourceText);
+
+ // act
+ SchemaCoordinateNode result = Utf8GraphQLParser.Syntax.ParseSchemaCoordinate(source);
+
+ // assert
+ result.MatchSnapshot();
+ }
+
+ [Fact]
+ public void ParseDirectiveName()
+ {
+ // arrange
+ string sourceText = "@foo";
+ byte[] source = Encoding.UTF8.GetBytes(sourceText);
+
+ // act
+ SchemaCoordinateNode result = Utf8GraphQLParser.Syntax.ParseSchemaCoordinate(source);
+
+ // assert
+ result.MatchSnapshot();
+ }
+
+ [Fact]
+ public void ParseDirectiveNameAndArg()
+ {
+ // arrange
+ string sourceText = "@foo(arg:)";
+ byte[] source = Encoding.UTF8.GetBytes(sourceText);
+
+ // act
+ SchemaCoordinateNode result = Utf8GraphQLParser.Syntax.ParseSchemaCoordinate(source);
+
+ // assert
+ result.MatchSnapshot();
+ }
+
+ [Theory]
+ [InlineData("MyType.field(arg: value)")]
+ [InlineData("@myDirective.field")]
+ public void RejectsInvalidPatterns(string sourceText)
+ {
+ // arrange
+ byte[] source = Encoding.UTF8.GetBytes(sourceText);
+
+ // act
+ Exception ex = Record.Exception(() =>
+ {
+ Utf8GraphQLParser.Syntax.ParseSchemaCoordinate(source);
+ });
+
+ // assert
+ Assert.IsType(ex);
+ }
+
+ [InlineData(null)]
+ [InlineData("")]
+ [Theory]
+ public void ParseSourceTextIsEmptyOrNull(string s)
+ {
+ // arrange;
+ // act
+ void Fail() => Utf8GraphQLParser.Syntax.ParseSchemaCoordinate(s);
+
+ // assert
+ Assert.Equal("sourceText", Assert.Throws(Fail).ParamName);
+ }
+}
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8SchemaParserTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/SchemaParserTests.cs
similarity index 99%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8SchemaParserTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/SchemaParserTests.cs
index 8b87ae5ac51..1481593bb1c 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8SchemaParserTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/SchemaParserTests.cs
@@ -5,7 +5,7 @@
namespace HotChocolate.Language;
-public class Utf8SchemaParserTests
+public class SchemaParserTests
{
[Fact]
public void ParserSimpleObjectType()
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8StringTokenReaderTests.cs b/src/HotChocolate/Language/test/Language.Tests/Parser/StringTokenReaderTests.cs
similarity index 97%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/Utf8StringTokenReaderTests.cs
rename to src/HotChocolate/Language/test/Language.Tests/Parser/StringTokenReaderTests.cs
index 64f1517021c..946a01725ea 100644
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/Utf8StringTokenReaderTests.cs
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/StringTokenReaderTests.cs
@@ -3,7 +3,7 @@
namespace HotChocolate.Language;
-public class Utf8StringTokenReaderTests
+public class StringTokenReaderTests
{
[InlineData(" \n\"üähelloWorld_123\"")]
[InlineData("\"üähelloWorld_123\"\n ")]
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8BlockStringTokenReaderTests.InvalidDigit.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/BlockStringTokenReaderTests.InvalidDigit.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8BlockStringTokenReaderTests.InvalidDigit.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/BlockStringTokenReaderTests.InvalidDigit.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8BlockStringTokenReaderTests.NoDigitAfterZeroException.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/BlockStringTokenReaderTests.NoDigitAfterZeroException.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8BlockStringTokenReaderTests.NoDigitAfterZeroException.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/BlockStringTokenReaderTests.NoDigitAfterZeroException.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8BlockStringTokenReaderTests.UnexpectedSyntaxException.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/BlockStringTokenReaderTests.UnexpectedSyntaxException.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8BlockStringTokenReaderTests.UnexpectedSyntaxException.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/BlockStringTokenReaderTests.UnexpectedSyntaxException.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8DirectiveParserTests.ParseQueryDirective.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/DirectiveParserTests.ParseQueryDirective.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8DirectiveParserTests.ParseQueryDirective.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/DirectiveParserTests.ParseQueryDirective.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_FieldNode_From_ByteArray.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_FieldNode_From_ByteArray.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_FieldNode_From_ByteArray.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_FieldNode_From_ByteArray.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_FieldNode_From_Reader.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_FieldNode_From_Reader.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_FieldNode_From_Reader.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_FieldNode_From_Reader.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_FieldNode_From_String.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_FieldNode_From_String.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_FieldNode_From_String.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_FieldNode_From_String.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_ByteArray.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_ByteArray.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_ByteArray.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_ByteArray.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_Reader.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_Reader.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_Reader.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_Reader.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_String.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_String.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_String.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ObjectValueNode_From_String.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_ByteArray.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_ByteArray.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_ByteArray.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_ByteArray.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_Reader.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_Reader.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_Reader.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_Reader.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_String.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_String.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_String.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_SelectionSetNode_From_String.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ValueNode_From_ByteArray.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ValueNode_From_ByteArray.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ValueNode_From_ByteArray.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ValueNode_From_ByteArray.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ValueNode_From_Reader.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ValueNode_From_Reader.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ValueNode_From_Reader.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ValueNode_From_Reader.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ValueNode_From_String.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ValueNode_From_String.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLParserSyntaxTests.Parse_ValueNode_From_String.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLParserSyntaxTests.Parse_ValueNode_From_String.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Float_Exponent_Format.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Float_Exponent_Format.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Float_Exponent_Format.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Float_Exponent_Format.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Id_As_Name.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Id_As_Name.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Id_As_Name.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Id_As_Name.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Json.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Json.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Json.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Json.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Extensions.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Extensions.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Extensions.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Extensions.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Query.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Query.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Query.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Query.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Variables.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Variables.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Variables.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_AllProps_No_Cache_Variables.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_No_Cache.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_No_Cache.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_No_Cache.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_No_Cache.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Cache.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Cache.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Cache.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Cache.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Russian_Characters.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Russian_Characters.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Russian_Characters.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Russian_Characters.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Russian_Escaped_Characters.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Russian_Escaped_Characters.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Russian_Escaped_Characters.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Kitchen_Sink_Query_With_Russian_Escaped_Characters.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Skip_Custom_Property.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Skip_Custom_Property.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Skip_Custom_Property.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Skip_Custom_Property.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Socket_Message.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Socket_Message.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Parse_Socket_Message.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Parse_Socket_Message.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Utf8GraphQLRequestParser_Parse.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Utf8GraphQLRequestParser_Parse.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Utf8GraphQLRequestParser_Parse.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Utf8GraphQLRequestParser_Parse.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJson.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJson.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJson.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJson.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJsonObject.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJsonObject.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJsonObject.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJsonObject.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJsonObject_FromString.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJsonObject_FromString.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJsonObject_FromString.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJsonObject_FromString.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJson_FromString.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJson_FromString.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJson_FromString.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/GraphQLRequestParserTests.Utf8GraphQLRequestParser_ParseJson_FromString.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkQuery.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkQuery.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkQuery.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkQuery.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkQueryNullability.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkQueryNullability.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkQueryNullability.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkQueryNullability.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkQueryNullability_sdl.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkQueryNullability_sdl.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkQueryNullability_sdl.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkQueryNullability_sdl.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkQuery_sdl.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkQuery_sdl.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkQuery_sdl.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkQuery_sdl.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkSchema.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkSchema.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkSchema.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkSchema.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkSchema_sdl.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkSchema_sdl.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8KitchenSinkParserTests.ParseFacebookKitchenSinkSchema_sdl.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/KitchenSinkParserTests.ParseFacebookKitchenSinkSchema_sdl.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/NumberTokenReaderTests.InvalidNumberToken.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/NumberTokenReaderTests.InvalidNumberToken.snap
new file mode 100644
index 00000000000..a6e8c4b4fb1
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/NumberTokenReaderTests.InvalidNumberToken.snap
@@ -0,0 +1 @@
+Invalid number, expected digit before ".".
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/PunctuatorTokenReaderTests.SpreadExpected.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/PunctuatorTokenReaderTests.SpreadExpected.snap
new file mode 100644
index 00000000000..0abc39cdd18
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/PunctuatorTokenReaderTests.SpreadExpected.snap
@@ -0,0 +1 @@
+Expected a `Spread`-token.
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.IntrospectionQuery.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.IntrospectionQuery.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.IntrospectionQuery.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.IntrospectionQuery.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.KitchenSinkQueryQuery.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.KitchenSinkQueryQuery.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.KitchenSinkQueryQuery.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.KitchenSinkQueryQuery.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.QueryWithComments.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.QueryWithComments.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.QueryWithComments.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.QueryWithComments.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.QueryWithComments_serialized.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.QueryWithComments_serialized.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.QueryWithComments_serialized.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.QueryWithComments_serialized.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.QueryWithStringArg.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.QueryWithStringArg.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.QueryWithStringArg.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.QueryWithStringArg.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.RussianLiterals.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.RussianLiterals.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.RussianLiterals.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/QueryParserTests.RussianLiterals.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_BlockStringValue.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_BlockStringValue.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_BlockStringValue.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_BlockStringValue.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_BlockString_SkipEscapes.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_BlockString_SkipEscapes.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_BlockString_SkipEscapes.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_BlockString_SkipEscapes.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_Comment.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_Comment.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_Comment.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_Comment.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_KitchenSinkQuery.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_KitchenSinkQuery.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_KitchenSinkQuery.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_KitchenSinkQuery.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_NameBraceTokens.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_NameBraceTokens.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_NameBraceTokens.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_NameBraceTokens.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_StringValue.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_StringValue.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_StringValue.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_StringValue.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_String_SkipEscapes.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_String_SkipEscapes.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8ReaderTests.Read_String_SkipEscapes.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/ReaderTests.Read_String_SkipEscapes.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseDirectiveName.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseDirectiveName.snap
new file mode 100644
index 00000000000..a86d3e7d070
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseDirectiveName.snap
@@ -0,0 +1,22 @@
+{
+ "Location": {
+ "Start": 0,
+ "End": 4,
+ "Line": 1,
+ "Column": 1
+ },
+ "Kind": "SchemaCoordinate",
+ "OfDirective": true,
+ "Name": {
+ "Kind": "Name",
+ "Location": {
+ "Start": 1,
+ "End": 4,
+ "Line": 1,
+ "Column": 2
+ },
+ "Value": "foo"
+ },
+ "MemberName": null,
+ "ArgumentName": null
+}
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseDirectiveNameAndArg.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseDirectiveNameAndArg.snap
new file mode 100644
index 00000000000..365116a45af
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseDirectiveNameAndArg.snap
@@ -0,0 +1,31 @@
+{
+ "Location": {
+ "Start": 0,
+ "End": 10,
+ "Line": 1,
+ "Column": 1
+ },
+ "Kind": "SchemaCoordinate",
+ "OfDirective": true,
+ "Name": {
+ "Kind": "Name",
+ "Location": {
+ "Start": 1,
+ "End": 5,
+ "Line": 1,
+ "Column": 2
+ },
+ "Value": "foo"
+ },
+ "MemberName": null,
+ "ArgumentName": {
+ "Kind": "Name",
+ "Location": {
+ "Start": 5,
+ "End": 9,
+ "Line": 1,
+ "Column": 6
+ },
+ "Value": "arg"
+ }
+}
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseName.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseName.snap
new file mode 100644
index 00000000000..a0951d74386
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseName.snap
@@ -0,0 +1,22 @@
+{
+ "Location": {
+ "Start": 0,
+ "End": 6,
+ "Line": 1,
+ "Column": 1
+ },
+ "Kind": "SchemaCoordinate",
+ "OfDirective": false,
+ "Name": {
+ "Kind": "Name",
+ "Location": {
+ "Start": 0,
+ "End": 6,
+ "Line": 1,
+ "Column": 1
+ },
+ "Value": "MyType"
+ },
+ "MemberName": null,
+ "ArgumentName": null
+}
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseNameAndMemberName.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseNameAndMemberName.snap
new file mode 100644
index 00000000000..426e0074b85
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseNameAndMemberName.snap
@@ -0,0 +1,31 @@
+{
+ "Location": {
+ "Start": 0,
+ "End": 17,
+ "Line": 1,
+ "Column": 1
+ },
+ "Kind": "SchemaCoordinate",
+ "OfDirective": false,
+ "Name": {
+ "Kind": "Name",
+ "Location": {
+ "Start": 0,
+ "End": 7,
+ "Line": 1,
+ "Column": 1
+ },
+ "Value": "MyType"
+ },
+ "MemberName": {
+ "Kind": "Name",
+ "Location": {
+ "Start": 7,
+ "End": 17,
+ "Line": 1,
+ "Column": 8
+ },
+ "Value": "MemberName"
+ },
+ "ArgumentName": null
+}
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseNameAndMemberNameAndArg.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseNameAndMemberNameAndArg.snap
new file mode 100644
index 00000000000..6d4a124afe3
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaCoordinateParserTests.ParseNameAndMemberNameAndArg.snap
@@ -0,0 +1,40 @@
+{
+ "Location": {
+ "Start": 0,
+ "End": 23,
+ "Line": 1,
+ "Column": 1
+ },
+ "Kind": "SchemaCoordinate",
+ "OfDirective": false,
+ "Name": {
+ "Kind": "Name",
+ "Location": {
+ "Start": 0,
+ "End": 7,
+ "Line": 1,
+ "Column": 1
+ },
+ "Value": "MyType"
+ },
+ "MemberName": {
+ "Kind": "Name",
+ "Location": {
+ "Start": 7,
+ "End": 18,
+ "Line": 1,
+ "Column": 8
+ },
+ "Value": "MemberName"
+ },
+ "ArgumentName": {
+ "Kind": "Name",
+ "Location": {
+ "Start": 18,
+ "End": 22,
+ "Line": 1,
+ "Column": 19
+ },
+ "Value": "arg"
+ }
+}
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.OneGraph_Schema.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.OneGraph_Schema.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.OneGraph_Schema.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.OneGraph_Schema.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParseEnum.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParseEnum.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParseEnum.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParseEnum.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParseSchemaDefinition.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParseSchemaDefinition.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParseSchemaDefinition.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParseSchemaDefinition.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParseUnion.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParseUnion.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParseUnion.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParseUnion.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParseUnion_LeadingPipe.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParseUnion_LeadingPipe.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParseUnion_LeadingPipe.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParseUnion_LeadingPipe.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParserInputObjectType.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParserInputObjectType.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParserInputObjectType.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParserInputObjectType.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParserScalarType.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParserScalarType.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParserScalarType.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParserScalarType.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParserSimpleInterfaceType.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParserSimpleInterfaceType.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParserSimpleInterfaceType.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParserSimpleInterfaceType.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParserSimpleObjectType.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParserSimpleObjectType.snap
similarity index 100%
rename from src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8SchemaParserTests.ParserSimpleObjectType.snap
rename to src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/SchemaParserTests.ParserSimpleObjectType.snap
diff --git a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.RussionLiterals.snap b/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.RussionLiterals.snap
deleted file mode 100644
index 4cbed770fbf..00000000000
--- a/src/HotChocolate/Language/test/Language.Tests/Parser/__snapshots__/Utf8QueryParserTests.RussionLiterals.snap
+++ /dev/null
@@ -1,122 +0,0 @@
-{
- "Kind": "Document",
- "Location": {
- "Start": 0,
- "End": 64,
- "Line": 1,
- "Column": 1
- },
- "Definitions": [
- {
- "Kind": "OperationDefinition",
- "Location": {
- "Start": 0,
- "End": 64,
- "Line": 1,
- "Column": 1
- },
- "Name": null,
- "Operation": "Query",
- "VariableDefinitions": [],
- "Directives": [],
- "SelectionSet": {
- "Kind": "SelectionSet",
- "Location": {
- "Start": 6,
- "End": 64,
- "Line": 1,
- "Column": 7
- },
- "Selections": [
- {
- "Kind": "Field",
- "Alias": null,
- "Arguments": [
- {
- "Kind": "Argument",
- "Location": {
- "Start": 16,
- "End": 42,
- "Line": 2,
- "Column": 9
- },
- "Name": {
- "Kind": "Name",
- "Location": {
- "Start": 16,
- "End": 26,
- "Line": 2,
- "Column": 9
- },
- "Value": "parameter"
- },
- "Value": {
- "Kind": "StringValue",
- "Location": {
- "Start": 27,
- "End": 42,
- "Line": 2,
- "Column": 20
- },
- "Value": "привет",
- "Block": false
- }
- }
- ],
- "SelectionSet": {
- "Kind": "SelectionSet",
- "Location": {
- "Start": 43,
- "End": 63,
- "Line": 2,
- "Column": 36
- },
- "Selections": [
- {
- "Kind": "Field",
- "Alias": null,
- "Arguments": [],
- "SelectionSet": null,
- "Location": {
- "Start": 49,
- "End": 61,
- "Line": 3,
- "Column": 5
- },
- "Name": {
- "Kind": "Name",
- "Location": {
- "Start": 49,
- "End": 61,
- "Line": 3,
- "Column": 5
- },
- "Value": "subField"
- },
- "Directives": []
- }
- ]
- },
- "Location": {
- "Start": 10,
- "End": 63,
- "Line": 2,
- "Column": 3
- },
- "Name": {
- "Kind": "Name",
- "Location": {
- "Start": 10,
- "End": 16,
- "Line": 2,
- "Column": 3
- },
- "Value": "field"
- },
- "Directives": []
- }
- ]
- }
- }
- ]
-}
diff --git a/src/HotChocolate/Language/test/Language.Tests/Visitors/SchemaCoordinateVisitorTests.cs b/src/HotChocolate/Language/test/Language.Tests/Visitors/SchemaCoordinateVisitorTests.cs
new file mode 100644
index 00000000000..5c050bfdc79
--- /dev/null
+++ b/src/HotChocolate/Language/test/Language.Tests/Visitors/SchemaCoordinateVisitorTests.cs
@@ -0,0 +1,118 @@
+using System.Collections.Generic;
+using Xunit;
+using HotChocolate.Language.Visitors;
+
+namespace HotChocolate.Language;
+
+public class SchemaCoordinateVisitorTests
+{
+ [Fact]
+ public static void VisitAllNodes()
+ {
+ // arrange
+ var node = new SchemaCoordinateNode(null, false, new("Abc"), new("def"), new("ghi"));
+
+ // act
+ var list = new List();
+
+ SyntaxVisitor
+ .Create
+ (node =>
+ {
+ if (node is NameNode n)
+ {
+ list.Add(n.Value);
+ }
+ return SyntaxVisitor.Continue;
+ },
+ options: new() { VisitNames = true })
+ .Visit(node);
+
+ // assert
+ Assert.Collection(
+ list,
+ s => Assert.Equal("Abc", s),
+ s => Assert.Equal("def", s),
+ s => Assert.Equal("ghi", s));
+ }
+
+ [Fact]
+ public static void VisitAllNodes_With_Walker()
+ {
+ // arrange
+ var node = new SchemaCoordinateNode(null, false, new("Abc"), new("def"), new("ghi"));
+
+ // act
+ var list = new List();
+ var walker = new CustomSyntaxWalker(list);
+ walker.Visit(node);
+
+ // assert
+ Assert.Collection(
+ list,
+ s => Assert.Equal("Abc", s),
+ s => Assert.Equal("def", s),
+ s => Assert.Equal("ghi", s));
+ }
+
+ [Fact]
+ public static void VisitAllNodes_With_Generic_Walker()
+ {
+ // arrange
+ var node = new SchemaCoordinateNode(null, false, new("Abc"), new("def"), new("ghi"));
+
+ // act
+ var list = new List();
+ var context = new CustomContext(list);
+ var walker = new CustomGenericSyntaxWalker();
+ walker.Visit(node, context);
+
+ // assert
+ Assert.Collection(
+ list,
+ s => Assert.Equal("Abc", s),
+ s => Assert.Equal("def", s),
+ s => Assert.Equal("ghi", s));
+ }
+
+ public class CustomSyntaxWalker : SyntaxWalker
+ {
+ private readonly List _list;
+
+ public CustomSyntaxWalker(List list)
+ : base(new() { VisitNames = true })
+ {
+ _list = list;
+ }
+
+ protected override ISyntaxVisitorAction Enter(NameNode node, ISyntaxVisitorContext context)
+ {
+ _list.Add(node.Value);
+ return DefaultAction;
+ }
+ }
+
+ public class CustomGenericSyntaxWalker : SyntaxWalker
+ {
+ public CustomGenericSyntaxWalker()
+ : base(new() { VisitNames = true })
+ {
+ }
+
+ protected override ISyntaxVisitorAction Enter(NameNode node, CustomContext context)
+ {
+ context.List.Add(node.Value);
+ return DefaultAction;
+ }
+ }
+
+ public class CustomContext : ISyntaxVisitorContext
+ {
+ public CustomContext(List list)
+ {
+ List = list;
+ }
+
+ public List List { get; }
+ }
+}