Skip to content

Commit b91fed7

Browse files
authored
Fix test mock custom scalar and double nested array execution (#2939)
1 parent 95db1b3 commit b91fed7

16 files changed

+151
-19
lines changed

Apollo.xcodeproj/project.pbxproj

+5-1
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,7 @@
637637
DE9CEAF1282C632B00959AF9 /* MockObjectTemplateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE9CEAF0282C632B00959AF9 /* MockObjectTemplateTests.swift */; };
638638
DE9CEAF3282C6AC300959AF9 /* TemplateRenderer_TestMockFile_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE9CEAF2282C6AC300959AF9 /* TemplateRenderer_TestMockFile_Tests.swift */; };
639639
DEA6A83426F298660091AF8A /* ParentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEA6A83326F298660091AF8A /* ParentType.swift */; };
640+
DEA7604429DF75B60001544B /* TestMockSelectionSetMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEA7604329DF75B60001544B /* TestMockSelectionSetMapper.swift */; };
640641
DEA9A23027CD990500F96C36 /* IRSelectionSet_IncludeSkip_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEA9A22F27CD990500F96C36 /* IRSelectionSet_IncludeSkip_Tests.swift */; };
641642
DEA9A23227D822E600F96C36 /* IR+InclusionConditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEA9A23127D822E600F96C36 /* IR+InclusionConditions.swift */; };
642643
DEAFB77B2706444B00BE02F3 /* IRRootFieldBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEAFB77A2706444B00BE02F3 /* IRRootFieldBuilderTests.swift */; };
@@ -1831,6 +1832,7 @@
18311832
DE9CEAF2282C6AC300959AF9 /* TemplateRenderer_TestMockFile_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateRenderer_TestMockFile_Tests.swift; sourceTree = "<group>"; };
18321833
DEA34AF6260E821F00F95F86 /* Apollo-Target-AnimalKingdomAPI.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Apollo-Target-AnimalKingdomAPI.xcconfig"; sourceTree = "<group>"; };
18331834
DEA6A83326F298660091AF8A /* ParentType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParentType.swift; sourceTree = "<group>"; };
1835+
DEA7604329DF75B60001544B /* TestMockSelectionSetMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestMockSelectionSetMapper.swift; sourceTree = "<group>"; };
18341836
DEA9A22F27CD990500F96C36 /* IRSelectionSet_IncludeSkip_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IRSelectionSet_IncludeSkip_Tests.swift; sourceTree = "<group>"; };
18351837
DEA9A23127D822E600F96C36 /* IR+InclusionConditions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IR+InclusionConditions.swift"; sourceTree = "<group>"; };
18361838
DEAFB77A2706444B00BE02F3 /* IRRootFieldBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IRRootFieldBuilderTests.swift; sourceTree = "<group>"; };
@@ -3771,6 +3773,7 @@
37713773
children = (
37723774
DE9CEAED282C207F00959AF9 /* Info.plist */,
37733775
DE9CEAE52829A2FE00959AF9 /* TestMock.swift */,
3776+
DEA7604329DF75B60001544B /* TestMockSelectionSetMapper.swift */,
37743777
DE2FCF2626E8083A0057EA67 /* Field.swift */,
37753778
);
37763779
name = ApolloTestSupport;
@@ -4610,7 +4613,7 @@
46104613
"starwars-graphql",
46114614
);
46124615
LastSwiftUpdateCheck = 1340;
4613-
LastUpgradeCheck = 1400;
4616+
LastUpgradeCheck = 1430;
46144617
ORGANIZATIONNAME = "Apollo GraphQL";
46154618
TargetAttributes = {
46164619
9B2DFBB524E1FA0D00ED3AE6 = {
@@ -5697,6 +5700,7 @@
56975700
isa = PBXSourcesBuildPhase;
56985701
buildActionMask = 2147483647;
56995702
files = (
5703+
DEA7604429DF75B60001544B /* TestMockSelectionSetMapper.swift in Sources */,
57005704
DE9CEAEA2829A45500959AF9 /* Field.swift in Sources */,
57015705
DE9CEAE62829A2FE00959AF9 /* TestMock.swift in Sources */,
57025706
);

Apollo.xcodeproj/xcshareddata/xcschemes/AnimalKingdomAPI.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1430"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

Apollo.xcodeproj/xcshareddata/xcschemes/Apollo.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1430"
44
version = "1.7">
55
<BuildAction
66
parallelizeBuildables = "YES"

Apollo.xcodeproj/xcshareddata/xcschemes/ApolloAPI.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1430"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

Apollo.xcodeproj/xcshareddata/xcschemes/ApolloCodegenLib.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1430"
44
version = "1.7">
55
<BuildAction
66
parallelizeBuildables = "YES"

Apollo.xcodeproj/xcshareddata/xcschemes/ApolloPerformanceTests.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1430"
44
version = "2.1">
55
<BuildAction
66
parallelizeBuildables = "YES"

Apollo.xcodeproj/xcshareddata/xcschemes/ApolloSQLite.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1430"
44
version = "1.7">
55
<BuildAction
66
parallelizeBuildables = "YES"

Apollo.xcodeproj/xcshareddata/xcschemes/ApolloServerIntegrationTests.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1430"
44
version = "1.7">
55
<BuildAction
66
parallelizeBuildables = "YES"

Apollo.xcodeproj/xcshareddata/xcschemes/ApolloUtils.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1430"
44
version = "1.7">
55
<BuildAction
66
parallelizeBuildables = "YES"

Apollo.xcodeproj/xcshareddata/xcschemes/ApolloWebSocket.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1430"
44
version = "1.7">
55
<BuildAction
66
parallelizeBuildables = "YES"

Apollo.xcodeproj/xcshareddata/xcschemes/CodegenCLI.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1430"
44
version = "1.7">
55
<BuildAction
66
parallelizeBuildables = "YES"

Apollo.xcodeproj/xcshareddata/xcschemes/CodegenCLITests.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1430"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

Sources/Apollo/GraphQLSelectionSetMapper.swift

+1-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ final class GraphQLSelectionSetMapper<T: SelectionSet>: GraphQLResultAccumulator
2929
func accept(scalar: AnyHashable, info: FieldExecutionInfo) throws -> AnyHashable? {
3030
switch info.field.type.namedType {
3131
case let .scalar(decodable as any JSONDecodable.Type):
32-
// This will convert a JSON value to the expected value type,
33-
// which could be a custom scalar or an enum.
32+
// This will convert a JSON value to the expected value type.
3433
return try decodable.init(_jsonValue: scalar)._asAnyHashable
3534
default:
3635
preconditionFailure()

Sources/ApolloTestSupport/TestMock.swift

+21-5
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ public class Mock<O: MockObject>: AnyMock, Hashable {
5757
if let mock = $0 as? AnyMock {
5858
return mock._selectionSetMockData
5959
}
60-
if let mockArray = $0 as? [AnyMock?] {
61-
return mockArray.map(\.?._selectionSetMockData)
60+
if let mockArray = $0 as? Array<Any> {
61+
return mockArray._unsafelyConvertToSelectionSetData()
6262
}
6363
return $0
6464
}
@@ -82,9 +82,7 @@ public extension RootSelectionSet {
8282
_ mock: Mock<O>,
8383
withVariables variables: GraphQLOperation.Variables? = nil
8484
) -> Self {
85-
let accumulator = GraphQLSelectionSetMapper<Self>(
86-
handleMissingValues: .allowForAllFields
87-
)
85+
let accumulator = TestMockSelectionSetMapper<Self>()
8886
let executor = GraphQLExecutor { object, info in
8987
return object[info.responseKeyForField]
9088
}
@@ -148,4 +146,22 @@ fileprivate extension Array {
148146
}
149147
}
150148
}
149+
150+
func _unsafelyConvertToSelectionSetData() -> [AnyHashable?] {
151+
map { element in
152+
switch element {
153+
case let element as AnyMock:
154+
return element._selectionSetMockData
155+
156+
case let innerArray as Array<Any>:
157+
return innerArray._unsafelyConvertToSelectionSetData()
158+
159+
case let element as AnyHashable:
160+
return element
161+
162+
default:
163+
return nil
164+
}
165+
}
166+
}
151167
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#if !COCOAPODS
2+
@testable import ApolloAPI
3+
@testable import Apollo
4+
#endif
5+
import Foundation
6+
7+
/// An accumulator that converts data from a `Mock` to the correct values to create a `SelectionSet`.
8+
final class TestMockSelectionSetMapper<T: SelectionSet>: GraphQLResultAccumulator {
9+
10+
let underlyingMapper = GraphQLSelectionSetMapper<T>(handleMissingValues: .allowForAllFields)
11+
12+
func accept(scalar: AnyHashable, info: FieldExecutionInfo) throws -> AnyHashable? {
13+
return scalar
14+
}
15+
16+
func accept(customScalar: AnyHashable, info: FieldExecutionInfo) throws -> AnyHashable? {
17+
return customScalar
18+
}
19+
20+
func acceptNullValue(info: FieldExecutionInfo) -> AnyHashable? {
21+
return underlyingMapper.acceptNullValue(info: info)
22+
}
23+
24+
func acceptMissingValue(info: FieldExecutionInfo) throws -> AnyHashable? {
25+
return try underlyingMapper.acceptMissingValue(info: info)
26+
}
27+
28+
func accept(list: [AnyHashable?], info: FieldExecutionInfo) -> AnyHashable? {
29+
return underlyingMapper.accept(list: list, info: info)
30+
}
31+
32+
func accept(childObject: DataDict.SelectionSetData, info: FieldExecutionInfo) throws -> AnyHashable? {
33+
return try underlyingMapper.accept(childObject: childObject, info: info)
34+
}
35+
36+
func accept(fieldEntry: AnyHashable?, info: FieldExecutionInfo) -> (key: String, value: AnyHashable)? {
37+
return underlyingMapper.accept(fieldEntry: fieldEntry, info: info)
38+
}
39+
40+
func accept(
41+
fieldEntries: [(key: String, value: AnyHashable)],
42+
info: ObjectExecutionInfo
43+
) throws -> DataDict.SelectionSetData {
44+
return try underlyingMapper.accept(fieldEntries: fieldEntries, info: info)
45+
}
46+
47+
func finish(rootValue: DataDict.SelectionSetData, info: ObjectExecutionInfo) -> T {
48+
return underlyingMapper.finish(rootValue: rootValue, info: info)
49+
}
50+
}

Tests/ApolloTests/TestMockTests.swift

+63
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,59 @@ class TestMockTests: XCTestCase {
461461
// then
462462
expect(selectionSet.__data._data["species"]).to(beNil())
463463
}
464+
465+
func test__convertToSelectionSet__givenGraphQLEnumField__canAccessField() throws {
466+
// given
467+
class Animal: TestMockSchema.MockSelectionSet {
468+
override class var __parentType: ParentType { TestMockSchema.Interfaces.Animal }
469+
override class var __selections: [Selection] {[
470+
.field("speciesType", GraphQLEnum<Species>.self),
471+
]}
472+
473+
var speciesType: GraphQLEnum<Species> { __data["speciesType"] }
474+
}
475+
476+
let mock = Mock<Dog>()
477+
mock.speciesType = GraphQLEnum(Species.canine)
478+
479+
// when
480+
let selectionSet = Animal.from(mock)
481+
482+
// then
483+
expect(selectionSet.speciesType).to(equal(.case(.canine)))
484+
}
485+
486+
func test__convertToSelectionSet__setNestedListOfObjectsField__canAccessField() throws {
487+
// given
488+
class Animal: TestMockSchema.MockSelectionSet {
489+
override class var __parentType: ParentType { TestMockSchema.Interfaces.Animal }
490+
override class var __selections: [Selection] {[
491+
.field("nestedListOfObjects", [[CatData]].self),
492+
]}
493+
494+
var nestedListOfObjects: [[CatData]] { __data["nestedListOfObjects"] }
495+
496+
class CatData: TestMockSchema.MockSelectionSet {
497+
override class var __parentType: ParentType { TestMockSchema.Types.Cat }
498+
override class var __selections: [Selection] {[
499+
.field("species", String.self),
500+
]}
501+
}
502+
}
503+
504+
let mock = Mock<Dog>()
505+
let cat1 = Mock<Cat>()
506+
let cat2 = Mock<Cat>()
507+
let cat3 = Mock<Cat>()
508+
mock.nestedListOfObjects = [[cat1, cat2, cat3]]
509+
510+
// when
511+
let selectionSet = Animal.from(mock)
512+
513+
// then
514+
expect(selectionSet.nestedListOfObjects.count).to(equal(1))
515+
expect(selectionSet.nestedListOfObjects[0].count).to(equal(3))
516+
}
464517
}
465518

466519
// MARK: - Generated Example
@@ -537,6 +590,16 @@ class Dog: MockObject {
537590
}
538591
}
539592

593+
extension Mock where O == Dog {
594+
convenience init(
595+
speciesType: GraphQLEnum<Species>? = nil
596+
) {
597+
self.init()
598+
self.speciesType = speciesType
599+
}
600+
}
601+
602+
540603
class Cat: MockObject {
541604
static let objectType: Object = TestMockSchema.Types.Cat
542605
static let _mockFields = MockFields()

0 commit comments

Comments
 (0)