Skip to content

Commit

Permalink
fix: fixes two issues in the generation of mocks. (#3120)
Browse files Browse the repository at this point in the history
  • Loading branch information
TizianoCoroneo authored Jul 19, 2023
1 parent efdae87 commit 9961d2b
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 2 deletions.
4 changes: 3 additions & 1 deletion Sources/ApolloCodegenLib/Templates/MockObjectTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ struct MockObjectTemplate: TemplateRenderer {

private func mockFunctionDescriptor(_ graphQLType: GraphQLType) -> String {
switch graphQLType {
case .list(.nonNull(.scalar(_))):
return "ScalarList"
case .list(_):
return "List"
case .scalar(_), .enum(_):
Expand All @@ -95,7 +97,7 @@ struct MockObjectTemplate: TemplateRenderer {
\(if: $0.propertyName.isConflictingTestMockFieldName, """
var \($0.propertyName): \($0.mockType)? {
get { _data["\($0.propertyName)"] as? \($0.mockType) }
set { _set(newValue, for: \\.\($0.propertyName)) }
set { _set\(mockFunctionDescriptor($0.type))(newValue, for: \\.\($0.propertyName)) }
}
""")
""" }, separator: "\n", terminator: "\n")
Expand Down
20 changes: 20 additions & 0 deletions Sources/ApolloTestSupport/TestMock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,26 @@ public class Mock<O: MockObject>: AnyMock, Hashable {
_data[field.key.description] = value?._unsafelyConvertToMockValue()
}

public subscript<T: AnyScalarType & Hashable>(
dynamicMember keyPath: KeyPath<O.MockFields, Field<Array<T>>>
) -> [T]? {
get {
let field = O._mockFields[keyPath: keyPath]
return _data[field.key.description] as? [T]
}
set {
_setScalarList(newValue, for: keyPath)
}
}

public func _setScalarList<T: AnyScalarType & Hashable>(
_ value: [T]?,
for keyPath: KeyPath<O.MockFields, Field<Array<T>>>
) {
let field = O._mockFields[keyPath: keyPath]
_data[field.key.description] = value?._unsafelyConvertToMockValue()
}

public var _selectionSetMockData: JSONObject {
_data.mapValues {
if let mock = $0 as? AnyMock {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ class MockObjectTemplateTests: XCTestCase {
let expected = """
var hash: String? {
get { _data["hash"] as? String }
set { _set(newValue, for: \\.hash) }
set { _setScalar(newValue, for: \\.hash) }
}
"""
Expand All @@ -487,6 +487,7 @@ class MockObjectTemplateTests: XCTestCase {
subject.graphqlObject.fields = [
"string": .mock("string", type: .nonNull(.string())),
"customScalar": .mock("customScalar", type: .nonNull(.scalar(.mock(name: "CustomScalar")))),
"customScalarList": .mock("customScalarList", type: .list(.nonNull(.scalar(.mock(name: "CustomScalar"))))),
"optionalString": .mock("optionalString", type: .string()),
"object": .mock("object", type: Cat),
"objectList": .mock("objectList", type: .list(.nonNull(Cat))),
Expand Down Expand Up @@ -516,6 +517,7 @@ class MockObjectTemplateTests: XCTestCase {
public extension Mock where O == Dog {
convenience init(
customScalar: TestSchema.CustomScalar? = nil,
customScalarList: [TestSchema.CustomScalar]? = nil,
enumType: GraphQLEnum<TestSchema.EnumType>? = nil,
interface: AnyMock? = nil,
interfaceList: [AnyMock]? = nil,
Expand All @@ -534,6 +536,7 @@ class MockObjectTemplateTests: XCTestCase {
) {
self.init()
_setScalar(customScalar, for: \\.customScalar)
_setScalarList(customScalarList, for: \\.customScalarList)
_setScalar(enumType, for: \\.enumType)
_setEntity(interface, for: \\.interface)
_setList(interfaceList, for: \\.interfaceList)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Overview

When a field has a list type containing custom scalars, the generated initializer for mock objects should use a version of the `_set` function that is appropriate for that type.
Previously, the `_setList` function was used for all lists of objects, even if it would not compile since custom scalars do not conform to `GraphQLField`.

## Reference Issue: https://github.com/apollographql/apollo-ios/pull/3120

## Solution

All properties that are lists of scalars should use the `_setScalarList` function when initialized inside mock objects.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
query TestMeWithMocks {
testMeWithMocks {
scalarList
nullableScalarList
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type Query {
testMeWithMocks: Event!
}

type Event {
scalarList: [Text!]!
nullableScalarList: [Text]!
}

scalar Text

0 comments on commit 9961d2b

Please sign in to comment.