Skip to content

Commit

Permalink
Field Merging[2/x] Compute MergedSelections w/MergingStrategy
Browse files Browse the repository at this point in the history
  • Loading branch information
AnthonyMDev committed Mar 21, 2024
1 parent eec8762 commit 73b01cd
Show file tree
Hide file tree
Showing 11 changed files with 329 additions and 109 deletions.
21 changes: 16 additions & 5 deletions Tests/ApolloCodegenInternalTestHelpers/IRBuilderTestWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,30 @@ public class IRBuilderTestWrapper {
}

public func build(
operation operationDefinition: CompilationResult.OperationDefinition
operation operationDefinition: CompilationResult.OperationDefinition,
mergingStrategy: IR.MergedSelections.MergingStrategy = .all
) async -> IRTestWrapper<IR.Operation> {
let operation = await irBuilder.build(operation: operationDefinition)
return IRTestWrapper(
irObject: operation,
computedSelectionSetCache: .init(entityStorage: operation.entityStorage)
computedSelectionSetCache: .init(
mergingStrategy: mergingStrategy,
entityStorage: operation.entityStorage
)
)
}

public func build(
fragment fragmentDefinition: CompilationResult.FragmentDefinition
fragment fragmentDefinition: CompilationResult.FragmentDefinition,
mergingStrategy: IR.MergedSelections.MergingStrategy = .all
) async -> IRTestWrapper<IR.NamedFragment> {
let fragment = await irBuilder.build(fragment: fragmentDefinition)
return IRTestWrapper(
irObject: fragment,
computedSelectionSetCache: .init(entityStorage: fragment.entityStorage)
computedSelectionSetCache: .init(
mergingStrategy: mergingStrategy,
entityStorage: fragment.entityStorage
)
)
}

Expand All @@ -58,7 +66,10 @@ public class IRBuilderTestWrapper {

return IRTestWrapper(
irObject: fragment,
computedSelectionSetCache: .init(entityStorage: fragment.entityStorage)
computedSelectionSetCache: .init(
mergingStrategy: .all,
entityStorage: fragment.entityStorage
)
)
}
}
Expand Down
27 changes: 20 additions & 7 deletions Tests/ApolloCodegenInternalTestHelpers/IRTestWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ import GraphQLCompiler
///
/// This wrapper provides the subscripts for accessing child selections by automatically computing and storing the `ComputedSelectionSet` results as they are accessed in unit tests.
///
/// `IRTestWrapper` types should never be initialized directly. They should be created using an
/// - Warning: `IRTestWrapper` types should never be initialized directly. They should be created using an
/// `IRBuilderTestWrapper`.
@dynamicMemberLookup
public class IRTestWrapper<T: CustomDebugStringConvertible>: CustomDebugStringConvertible {
public let irObject: T
let computedSelectionSetCache: ComputedSelectionSetCache

public var mergingStrategy: MergedSelections.MergingStrategy {
computedSelectionSetCache.mergingStrategy
}

init(
irObject: T,
computedSelectionSetCache: ComputedSelectionSetCache
Expand Down Expand Up @@ -198,7 +202,10 @@ extension IRTestWrapper<IR.NamedFragmentSpread> {
public var rootField: IRTestWrapper<IR.Field> {
return IRTestWrapper<IR.Field>(
irObject: irObject.fragment.rootField,
computedSelectionSetCache: .init(entityStorage: irObject.fragment.entityStorage)
computedSelectionSetCache: .init(
mergingStrategy: self.mergingStrategy,
entityStorage: irObject.fragment.entityStorage
)
)
}

Expand Down Expand Up @@ -246,15 +253,15 @@ extension SelectionSetTestWrapper {
public subscript(field field: String) -> IRTestWrapper<IR.Field>? {
IRTestWrapper<IR.Field>(
irObject:
computed.direct?.fields[field] ?? computed.merged.fields[field],
computed.direct?.fields[field] ?? computed.merged[mergingStrategy]!.fields[field],
computedSelectionSetCache: computedSelectionSetCache
)
}

public subscript(fragment fragment: String) -> IRTestWrapper<IR.NamedFragmentSpread>? {
IRTestWrapper<IR.NamedFragmentSpread>(
irObject:
computed.direct?.namedFragments[fragment] ?? computed.merged.namedFragments[fragment],
computed.direct?.namedFragments[fragment] ?? computed.merged[mergingStrategy]!.namedFragments[fragment],
computedSelectionSetCache: computedSelectionSetCache
)
}
Expand All @@ -264,20 +271,26 @@ extension SelectionSetTestWrapper {

class ComputedSelectionSetCache {
private var selectionSets: [SelectionSet.TypeInfo: ComputedSelectionSet] = [:]
public let mergingStrategy: MergedSelections.MergingStrategy
public let entityStorage: DefinitionEntityStorage

init(entityStorage: DefinitionEntityStorage) {
init(
mergingStrategy: MergedSelections.MergingStrategy,
entityStorage: DefinitionEntityStorage
) {
self.mergingStrategy = mergingStrategy
self.entityStorage = entityStorage
}

func computed(for selectionSet: SelectionSet) -> ComputedSelectionSet{
func computed(for selectionSet: SelectionSet) -> ComputedSelectionSet {
if let selectionSet = selectionSets[selectionSet.typeInfo] {
return selectionSet
}

let selectionSet = ComputedSelectionSet.Builder(
directSelections: selectionSet.selections?.readOnlyView,
typeInfo: selectionSet.typeInfo,
typeInfo: selectionSet.typeInfo,
mergingStrategies: [mergingStrategy],
entityStorage: entityStorage
).build()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,13 @@ extension ComputedSelectionSet: ScopedChildSelectionSetAccessible {
with conditions: IR.ScopeCondition,
computedSelectionSetCache: ComputedSelectionSetCache
) -> SelectionSetTestWrapper? {
let selectionSet = direct?.inlineFragments[conditions]?.selectionSet ??
merged.inlineFragments[conditions]?.selectionSet
let selectionSet =
direct?
.inlineFragments[conditions]?
.selectionSet ??
merged[computedSelectionSetCache.mergingStrategy]!
.inlineFragments[conditions]?
.selectionSet

return SelectionSetTestWrapper(
irObject: selectionSet,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLObjectType.mock("Height")))
Expand Down Expand Up @@ -328,7 +328,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLInterfaceType.mock("WarmBlooded")))
Expand Down Expand Up @@ -387,7 +387,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLInterfaceType.mock("WarmBlooded")))
Expand Down Expand Up @@ -432,7 +432,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLObjectType.mock("Height")))
Expand Down Expand Up @@ -499,7 +499,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLInterfaceType.mock("Pet")))
Expand Down Expand Up @@ -555,7 +555,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLObjectType.mock("Height")))
Expand Down Expand Up @@ -621,7 +621,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLInterfaceType.mock("WarmBlooded")))
Expand Down Expand Up @@ -670,7 +670,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLObjectType.mock("Height")))
Expand Down Expand Up @@ -738,7 +738,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLObjectType.mock("Cat")))
Expand Down Expand Up @@ -787,7 +787,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLObjectType.mock("Height")))
Expand Down Expand Up @@ -845,7 +845,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLUnionType.mock("ClassroomPet")))
Expand Down Expand Up @@ -913,7 +913,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLObjectType.mock("Bird")))
Expand Down Expand Up @@ -962,7 +962,7 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
)

// when
let actual = selectionSet.computed.merged
let actual = selectionSet.computed.merged[.all]

// then
expect(selectionSet.parentType).to(equal(GraphQLObjectType.mock("Height")))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import XCTest
import Nimble
import OrderedCollections
import GraphQLCompiler
@testable import IR
@testable import ApolloCodegenLib
import ApolloInternalTestHelpers
import ApolloCodegenInternalTestHelpers
import ApolloAPI

class IRMergedSelections_FieldMergingStrategy_Tests: XCTestCase {

var schemaSDL: String!
var document: String!
var ir: IRBuilderTestWrapper!
var operation: CompilationResult.OperationDefinition!
var rootField: IRTestWrapper<IR.Field>!

var schema: IR.Schema { ir.schema }

override func setUp() {
super.setUp()
}

override func tearDown() {
schemaSDL = nil
document = nil
operation = nil
rootField = nil
super.tearDown()
}

// MARK: - Helpers

func buildRootField(
mergingStrategy: IR.MergedSelections.MergingStrategy
) async throws {
ir = try await IRBuilderTestWrapper(.mock(schema: schemaSDL, document: document))
operation = try XCTUnwrap(ir.compilationResult.operations.first)

rootField = await ir.build(
operation: operation,
mergingStrategy: mergingStrategy
).rootField
}

// MARK: - Test MergingStrategy: Ancestors

func test__mergingStrategy_ancestors__givenFieldInAncestor_includesField() async throws {
// given
schemaSDL = """
type Query {
allAnimals: [Animal!]
}
interface Animal {
species: String
}
interface Pet implements Animal {
species: String
petName: String
}
"""

document = """
query Test {
allAnimals {
species
... on Pet {
petName
}
}
}
"""
let mergingStrategy: MergedSelections.MergingStrategy = .ancestors

try await buildRootField(mergingStrategy: mergingStrategy)

let Scalar_String = try unwrap(self.schema[scalar: "String"])

// when
let subject = rootField[field: "allAnimals"]?[as: "Pet"]

let expected = SelectionSetMatcher(
parentType: try unwrap(self.schema[interface: "Pet"]),
directSelections: [
.field("petName", type: .scalar(Scalar_String))
],
mergedSelections: [
.field("species", type: .scalar(Scalar_String))
],
mergedSources: [
try .mock(rootField[field:"allAnimals"])
],
mergingStrategy: mergingStrategy
)

// then
expect(subject).to(shallowlyMatch(expected))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1590,8 +1590,10 @@ class IRRootFieldBuilderTests: XCTestCase {
let aField = subject[field: "aField"]

// then
expect(aField?.selectionSet?.computed.direct).to(shallowlyMatch(expected_direct))
expect(aField?.selectionSet?.computed.merged).to(shallowlyMatch(expected_merged))
expect(aField?.selectionSet?.computed.direct)
.to(shallowlyMatch(expected_direct))
expect(aField?.selectionSet?.computed.merged[.all])
.to(shallowlyMatch(expected_merged))
}

func test__mergedSelections__givenSelectionSetWithSelectionsAndParentFields_returnsSelfAndParentFields() async throws {
Expand Down Expand Up @@ -4144,7 +4146,8 @@ class IRRootFieldBuilderTests: XCTestCase {
]

// then
expect(allAnimals_predator.selectionSet?.computed.merged.mergedSources).to(equal(expected))
expect(allAnimals_predator.selectionSet?.computed.merged[.all]?.mergedSources)
.to(equal(expected))
}

// MARK: - Referenced Fragments
Expand Down

0 comments on commit 73b01cd

Please sign in to comment.