Skip to content

Commit

Permalink
Merge pull request #136 from GraphQLSwift/feature/oneOfAndSpecifiedBy
Browse files Browse the repository at this point in the history
Adds `oneOf` and `specifiedBy` directive support
  • Loading branch information
NeedleInAJayStack authored Jun 10, 2024
2 parents 3f15434 + ca69acc commit 927ebb1
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 7 deletions.
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"repositoryURL": "https://github.com/GraphQLSwift/GraphQL.git",
"state": {
"branch": null,
"revision": "3cf2dbce764e7ccff8447d0b7d4634c0438449d3",
"version": "2.9.2"
"revision": "87649dbc3cdab0be0256c86235f2aec22ec1bfc1",
"version": "2.10.0"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ let package = Package(
.library(name: "Graphiti", targets: ["Graphiti"]),
],
dependencies: [
.package(url: "https://github.com/GraphQLSwift/GraphQL.git", from: "2.9.2"),
.package(url: "https://github.com/GraphQLSwift/GraphQL.git", from: "2.10.0"),
],
targets: [
.target(name: "Graphiti", dependencies: ["GraphQL"]),
Expand Down
12 changes: 9 additions & 3 deletions Sources/Graphiti/Input/Input.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ public final class Input<
Resolver,
Context
> {
let isOneOf: Bool
let fields: [InputFieldComponent<InputObjectType, Context>]

override func update(typeProvider: SchemaTypeProvider, coders _: Coders) throws {
let inputObjectType = try GraphQLInputObjectType(
name: name,
description: description,
fields: fields(typeProvider: typeProvider)
fields: fields(typeProvider: typeProvider),
isOneOf: isOneOf
)

try typeProvider.add(type: InputObjectType.self, as: inputObjectType)
Expand All @@ -38,8 +40,10 @@ public final class Input<
init(
type _: InputObjectType.Type,
name: String?,
isOneOf: Bool,
fields: [InputFieldComponent<InputObjectType, Context>]
) {
self.isOneOf = isOneOf
self.fields = fields
super.init(
name: name ?? Reflection.name(for: InputObjectType.self),
Expand All @@ -52,18 +56,20 @@ public extension Input {
convenience init(
_ type: InputObjectType.Type,
as name: String? = nil,
isOneOf: Bool = false,
@InputFieldComponentBuilder<InputObjectType, Context> _ fields: ()
-> InputFieldComponent<InputObjectType, Context>
) {
self.init(type: type, name: name, fields: [fields()])
self.init(type: type, name: name, isOneOf: isOneOf, fields: [fields()])
}

convenience init(
_ type: InputObjectType.Type,
as name: String? = nil,
isOneOf: Bool = false,
@InputFieldComponentBuilder<InputObjectType, Context> _ fields: ()
-> [InputFieldComponent<InputObjectType, Context>]
) {
self.init(type: type, name: name, fields: fields())
self.init(type: type, name: name, isOneOf: isOneOf, fields: fields())
}
}
6 changes: 6 additions & 0 deletions Sources/Graphiti/Scalar/Scalar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import OrderedCollections
/// you may provide your own serialize, parseValue, and parseLiteral implementations.
open class Scalar<Resolver, Context, ScalarType: Codable>: TypeComponent<Resolver, Context> {
// TODO: Change this no longer be an open class
let specifiedByURL: String?

override func update(typeProvider: SchemaTypeProvider, coders: Coders) throws {
let scalarType = try GraphQLScalarType(
name: name,
description: description,
specifiedByURL: specifiedByURL,
serialize: { value in
if let serialize = self.serialize {
return try serialize(value, coders)
Expand Down Expand Up @@ -70,10 +72,12 @@ open class Scalar<Resolver, Context, ScalarType: Codable>: TypeComponent<Resolve
init(
type _: ScalarType.Type,
name: String?,
specifiedBy: String? = nil,
serialize: ((Any, Coders) throws -> Map)? = nil,
parseValue: ((Map, Coders) throws -> Map)? = nil,
parseLiteral: ((GraphQL.Value, Coders) throws -> Map)? = nil
) {
specifiedByURL = specifiedBy
self.serialize = serialize
self.parseValue = parseValue
self.parseLiteral = parseLiteral
Expand All @@ -88,13 +92,15 @@ public extension Scalar {
convenience init(
_ type: ScalarType.Type,
as name: String? = nil,
specifiedBy: String? = nil,
serialize: ((Any, Coders) throws -> Map)? = nil,
parseValue: ((Map, Coders) throws -> Map)? = nil,
parseLiteral: ((GraphQL.Value, Coders) throws -> Map)? = nil
) {
self.init(
type: type,
name: name,
specifiedBy: specifiedBy,
serialize: serialize,
parseValue: parseValue,
parseLiteral: parseLiteral
Expand Down
85 changes: 85 additions & 0 deletions Tests/GraphitiTests/DirectiveTests/DirectiveTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,89 @@ class DirectiveTests: XCTestCase {

XCTAssertEqual(response, expected)
}

func testOneOfAcceptsGoodValue() throws {
try XCTAssertEqual(
OneOfAPI().execute(
request: """
query {
test(input: {a: "abc"}) {
a
b
}
}
""",
context: NoContext(),
on: group
).wait(),
GraphQLResult(
data: [
"test": [
"a": "abc",
"b": .null,
],
]
)
)
}

func testOneOfRejectsBadValue() throws {
try XCTAssertEqual(
OneOfAPI().execute(
request: """
query {
test(input: {a: "abc", b: 123}) {
a
b
}
}
""",
context: NoContext(),
on: group
).wait().errors[0].message,
#"OneOf Input Object "TestInputObject" must specify exactly one key."#
)
}

struct OneOfAPI: API {
struct TestObject: Codable {
let a: String?
let b: Int?
}

struct TestInputObject: Codable {
let a: String?
let b: Int?
}

struct TestArguments: Codable {
let input: TestInputObject
}

struct OneOfResolver {
func test(context _: NoContext, arguments: TestArguments) -> TestObject {
return TestObject(a: arguments.input.a, b: arguments.input.b)
}
}

let resolver = OneOfResolver()

let schema = try! Schema<OneOfResolver, NoContext> {
Type(TestObject.self) {
Field("a", at: \.a)
Field("b", at: \.b)
}

Input(TestInputObject.self, isOneOf: true) {
InputField("a", at: \.a)
InputField("b", at: \.b)
}

Query {
Field("test", at: OneOfResolver.test, as: TestObject.self) {
Argument("input", at: \.input)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ import XCTest
)
subscribers.append(subscriber)
}
return ConcurrentEventStream<T>.init(asyncStream)
return ConcurrentEventStream<T>(asyncStream)
}
}

Expand Down

0 comments on commit 927ebb1

Please sign in to comment.