Skip to content

Commit

Permalink
Fix parsing of input objects as default values for input params (#3074)
Browse files Browse the repository at this point in the history
Co-authored-by: Zach FettersMoore <4425109+BobaFetters@users.noreply.github.com>
  • Loading branch information
AnthonyMDev and BobaFetters authored Jun 15, 2023
1 parent ff49bec commit 077430a
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Apollo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@
DE100B202887415D00BE11C2 /* Documentation.docc in Sources */ = {isa = PBXBuildFile; fileRef = DE100B1F2887415D00BE11C2 /* Documentation.docc */; };
DE12B2D7273B204B003371CC /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE12B2D6273B204B003371CC /* TestError.swift */; };
DE12B2D9273C4338003371CC /* MockIRSubscripts.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE12B2D8273C4338003371CC /* MockIRSubscripts.swift */; };
DE1540DC2A3A76F700A5A8B6 /* IRInputObjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1540DB2A3A76F700A5A8B6 /* IRInputObjectTests.swift */; };
DE1696D4298C51CF00345E1A /* SelectionSetTemplate_Initializers_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1696D3298C51CF00345E1A /* SelectionSetTemplate_Initializers_Tests.swift */; };
DE181A2C26C5C0CB000C0B9C /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE181A2B26C5C0CB000C0B9C /* WebSocket.swift */; };
DE181A2E26C5C299000C0B9C /* SSLClientCertificate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE181A2D26C5C299000C0B9C /* SSLClientCertificate.swift */; };
Expand Down Expand Up @@ -1372,6 +1373,7 @@
DE100B1F2887415D00BE11C2 /* Documentation.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = Documentation.docc; sourceTree = "<group>"; };
DE12B2D6273B204B003371CC /* TestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestError.swift; sourceTree = "<group>"; };
DE12B2D8273C4338003371CC /* MockIRSubscripts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockIRSubscripts.swift; sourceTree = "<group>"; };
DE1540DB2A3A76F700A5A8B6 /* IRInputObjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IRInputObjectTests.swift; sourceTree = "<group>"; };
DE1696D3298C51CF00345E1A /* SelectionSetTemplate_Initializers_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectionSetTemplate_Initializers_Tests.swift; sourceTree = "<group>"; };
DE181A2B26C5C0CB000C0B9C /* WebSocket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebSocket.swift; sourceTree = "<group>"; };
DE181A2D26C5C299000C0B9C /* SSLClientCertificate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSLClientCertificate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3851,6 +3853,7 @@
DEA9A22F27CD990500F96C36 /* IRSelectionSet_IncludeSkip_Tests.swift */,
E66935322804AFE5004E1FFC /* IRCustomScalarTests.swift */,
DEFE694F28133E9B001CF4E8 /* IRFieldCollectorTests.swift */,
DE1540DB2A3A76F700A5A8B6 /* IRInputObjectTests.swift */,
);
path = CodeGenIR;
sourceTree = "<group>";
Expand Down Expand Up @@ -5123,6 +5126,7 @@
E6B42D0D27A4749100A3BD58 /* SwiftPackageManagerModuleTemplateTests.swift in Sources */,
DE296539279B3B8200BF9B49 /* SelectionSetTemplateTests.swift in Sources */,
E66F8897276C136B0000BDA8 /* ObjectFileGeneratorTests.swift in Sources */,
DE1540DC2A3A76F700A5A8B6 /* IRInputObjectTests.swift in Sources */,
DE79642B276999E700978A03 /* IRNamedFragmentBuilderTests.swift in Sources */,
E69BEDA72798B89600000D10 /* InputObjectTemplateTests.swift in Sources */,
E6EE62F327DBE75A00627257 /* SchemaModuleNamespaceTemplateTests.swift in Sources */,
Expand Down
17 changes: 16 additions & 1 deletion Sources/ApolloCodegenLib/Frontend/GraphQLValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,22 @@ extension GraphQLValue: JavaScriptValueDecodable {
}
self = .list(.fromJSValue(value, bridge: bridge))
case "ObjectValue":
self = .object(.fromJSValue(jsValue["value"], bridge: bridge))
let value = jsValue["value"]

/// The JS frontend does not do value conversions of the default values for input objects,
/// because no other compilation is needed, these are passed through as is from `graphql-js`.
/// We need to handle both converted object values and default values and represented by
/// `graphql-js`.
if !value.isUndefined {
self = .object(.fromJSValue(value, bridge: bridge))

} else {
let fields = jsValue["fields"].toOrderedDictionary { field in
(field["name"]["value"].toString(), GraphQLValue(field["value"], bridge: bridge))
}
self = .object(fields)
}

default:
preconditionFailure("""
Unknown GraphQL value of kind "\(kind)"
Expand Down
19 changes: 19 additions & 0 deletions Sources/ApolloCodegenLib/Frontend/JavaScriptBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,25 @@ extension JSValue {

return dictionary
}

// The regular `toDictionary()` creates an `NSDictionary` that while it preserves the order of
// `keys` from JavaScript during initialization, there is no order afterwards. `OrderedDictionary`
// provides for the preservation and subsequent use of ordering in the collection.
func toOrderedDictionary<Value>(_ transform: (JSValue) throws -> (String, Value)) rethrows -> OrderedDictionary<String, Value> {
precondition(isArray, "Expected JavaScript array but found: \(self)")

let length = self["length"].toInt()

var dictionary = OrderedDictionary<String, Value>()
dictionary.reserveCapacity(length)

for index in 0..<length {
let (key, value) = try transform(self[index])
dictionary[key] = value
}

return dictionary
}
}

private func checkedDowncast<ExpectedType: AnyObject>(_ object: AnyObject) -> ExpectedType {
Expand Down
68 changes: 68 additions & 0 deletions Tests/ApolloCodegenTests/CodeGenIR/IRInputObjectTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import Foundation
import XCTest
import Nimble
import OrderedCollections
@testable import ApolloCodegenLib

class IRInputObjectTests: XCTestCase {

var subject: GraphQLInputObjectType!
var schemaSDL: String!
var document: String!

override func tearDown() {
subject = nil
schemaSDL = nil
document = nil

super.tearDown()
}

// MARK: - Helpers

func buildSubject() throws {
let ir: IR = try .mock(schema: schemaSDL, document: document)
subject = ir.schema.referencedTypes.inputObjects.first!
}

// MARK: - Tests

func test__compileInputObject__givenNestedInputObjectParameterWithDefaultValue_compilesInputTypeWithDefaultValue() throws {
// given
schemaSDL = """
type Query {
exampleQuery(input: Input!): String!
}
input ChildInput {
a: String
b: String
c: String
}
input Input {
child: ChildInput = { a: "a", b: "b", c: "c" }
}
"""

document = """
query TestOperation($input: Input!) {
exampleQuery(input: $input)
}
"""

// when
try buildSubject()
let childField = subject.fields["child"]

let expectedDefaultValue = GraphQLValue.object([
"a": .string("a"),
"b": .string("b"),
"c": .string("c")
])

// then
expect(childField?.defaultValue).to(equal(expectedDefaultValue))
}

}

0 comments on commit 077430a

Please sign in to comment.