Skip to content

Commit 0f99aee

Browse files
calvincestarigh-action-runner
authored andcommitted
fix: Deferred fragment accessor with nested fragment (#709)
1 parent 0b6001b commit 0f99aee

File tree

2 files changed

+108
-12
lines changed

2 files changed

+108
-12
lines changed

Tests/ApolloCodegenTests/CodeGeneration/Templates/SelectionSet/SelectionSetTemplateTests.swift

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3822,7 +3822,93 @@ class SelectionSetTemplateTests: XCTestCase {
38223822
ignoringExtraLines: true
38233823
))
38243824
}
3825-
3825+
3826+
func test__render_selections__givenDeferredNamedFragment_insideNamedFragment_rendersInitializerForBothMergedAndDirectFragmentAccessors() async throws {
3827+
// given
3828+
schemaSDL = """
3829+
type Query {
3830+
allAnimals: [Animal!]
3831+
}
3832+
3833+
type Animal {
3834+
id: String!
3835+
name: String!
3836+
species: String!
3837+
}
3838+
""".appendingDeferDirective()
3839+
3840+
document = """
3841+
query TestOperation {
3842+
allAnimals {
3843+
...BasicFragment
3844+
}
3845+
}
3846+
3847+
fragment BasicFragment on Animal {
3848+
id
3849+
...DetailsFragment @defer(label: "slowDetails")
3850+
}
3851+
3852+
fragment DetailsFragment on Animal {
3853+
name
3854+
species
3855+
}
3856+
"""
3857+
3858+
// when
3859+
try await buildSubjectAndOperation()
3860+
3861+
// then
3862+
let allAnimals = try XCTUnwrap(operation[field: "query"]?[field: "allAnimals"]?.selectionSet)
3863+
let allAnimals_basicFragment = try XCTUnwrap(allAnimals[fragment: "BasicFragment"])
3864+
3865+
let rendered_allAnimals = subject.test_render(childEntity: allAnimals.computed)
3866+
3867+
let basicFragmentSubject = SelectionSetTemplate(
3868+
definition: allAnimals_basicFragment.fragment,
3869+
generateInitializers: false,
3870+
config: self.subject.config,
3871+
nonFatalErrorRecorder: .init(),
3872+
renderAccessControl: self.subject.renderAccessControl()
3873+
)
3874+
let rendered_allAnimals_basicFragment = basicFragmentSubject.test_render(
3875+
childEntity: try XCTUnwrap(allAnimals_basicFragment.rootField.selectionSet?.computed)
3876+
)
3877+
3878+
expect(rendered_allAnimals).to(equalLineByLine(
3879+
"""
3880+
public struct Fragments: FragmentContainer {
3881+
public let __data: DataDict
3882+
public init(_dataDict: DataDict) {
3883+
__data = _dataDict
3884+
_detailsFragment = Deferred(_dataDict: _dataDict)
3885+
}
3886+
3887+
public var basicFragment: BasicFragment { _toFragment() }
3888+
@Deferred public var detailsFragment: DetailsFragment?
3889+
}
3890+
""",
3891+
atLine: 14,
3892+
ignoringExtraLines: true
3893+
))
3894+
3895+
expect(rendered_allAnimals_basicFragment).to(equalLineByLine(
3896+
"""
3897+
public struct Fragments: FragmentContainer {
3898+
public let __data: DataDict
3899+
public init(_dataDict: DataDict) {
3900+
__data = _dataDict
3901+
_detailsFragment = Deferred(_dataDict: _dataDict)
3902+
}
3903+
3904+
@Deferred public var detailsFragment: DetailsFragment?
3905+
}
3906+
""",
3907+
atLine: 15,
3908+
ignoringExtraLines: true
3909+
))
3910+
}
3911+
38263912
func test__render_selections__givenDeferredInlineFragmentOnDifferentTypeCase_insideNamedFragment_rendersDeferredFragmentSelection() async throws {
38273913
// given
38283914
schemaSDL = """

apollo-ios-codegen/Sources/ApolloCodegenLib/Templates/SelectionSetTemplate.swift

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -526,12 +526,18 @@ struct SelectionSetTemplate {
526526
private func FragmentInitializerTemplate(
527527
_ selectionSet: ComputedSelectionSet
528528
) -> String {
529-
if let directSelections = selectionSet.direct,
530-
(directSelections.inlineFragments.containsDeferredFragment
531-
|| directSelections.namedFragments.containsDeferredFragment)
532-
{
533-
return DesignatedInitializerTemplate(
534-
"""
529+
guard
530+
selectionSet.direct?.inlineFragments.containsDeferredFragment ?? false ||
531+
selectionSet.direct?.namedFragments.containsDeferredFragment ?? false ||
532+
selectionSet.merged.inlineFragments.containsDeferredFragment ||
533+
selectionSet.merged.namedFragments.containsDeferredFragment
534+
else {
535+
return DesignatedInitializerTemplate()
536+
}
537+
538+
return DesignatedInitializerTemplate(
539+
"""
540+
\(ifLet: selectionSet.direct, { directSelections in """
535541
\(forEachIn: directSelections.inlineFragments.values, separator: "\n", {
536542
if let deferCondition = $0.typeInfo.deferCondition {
537543
return DeferredPropertyInitializationStatement(deferCondition.label)
@@ -546,12 +552,16 @@ struct SelectionSetTemplate {
546552

547553
return ""
548554
})
549-
"""
550-
)
555+
"""})
556+
\(forEachIn: selectionSet.merged.namedFragments.values, separator: "\n", {
557+
if let _ = $0.typeInfo.deferCondition {
558+
return DeferredPropertyInitializationStatement($0.definition.name.firstLowercased)
559+
}
551560

552-
} else {
553-
return DesignatedInitializerTemplate()
554-
}
561+
return ""
562+
})
563+
"""
564+
)
555565
}
556566

557567
private func DeferredPropertyInitializationStatement(_ propertyName: String) -> TemplateString {

0 commit comments

Comments
 (0)