Skip to content

Commit

Permalink
Merge branch 'project-breakup' into feature/defer
Browse files Browse the repository at this point in the history
# Conflicts:
#	apollo-ios-codegen/Sources/GraphQLCompiler/ApolloCodegenFrontendBundle.swift
  • Loading branch information
calvincestari committed Sep 22, 2023
2 parents 0535ce5 + 35ad9d8 commit 443aca7
Show file tree
Hide file tree
Showing 13 changed files with 1,743 additions and 16 deletions.
4 changes: 2 additions & 2 deletions .github/actions/subtree-split-push/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ runs:
shell: bash
run: |
git fetch ${{ inputs.remote }} ${{ inputs.target-branch }}
splitResult=$(git subtree -P ${{ inputs.subtree }} split --squash --rejoin -m "split: ${{ inputs.subtree }} - PR #${{ inputs.pr-number }} - ${{ inputs.pr-title }}")
splitResult=$(sh git-subtree.sh -P ${{ inputs.subtree }} split --squash --rejoin -m "split: ${{ inputs.subtree }} - PR #${{ inputs.pr-number }} - ${{ inputs.pr-title }}")
if [ ! -z "$splitResult" ]
then
git subtree push -P ${{ inputs.subtree }} ${{ inputs.remote }} ${{ inputs.target-branch }}
sh git-subtree.sh push -P ${{ inputs.subtree }} ${{ inputs.remote }} ${{ inputs.target-branch }}
fi
Original file line number Diff line number Diff line change
Expand Up @@ -1040,4 +1040,54 @@ final class AnimalKingdomIRCreationTests: XCTestCase {
expect(selectionSet.parentType).to(equal(GraphQLObjectType.mock("Height")))
expect(actual).to(shallowlyMatch(self.expected))
}

// MARK: - Referenced Fragment Tests

func test__referencedFragments__AllAnimalsQuery_isCorrect() throws {
// given
let operation = compilationResult.operations.first { $0.name == "AllAnimalsQuery" }

// when
let expected: [CompilationResult.FragmentDefinition] = [
"HeightInMeters",
"WarmBloodedDetails",
"PetDetails"
].map { expectedName in
compilationResult.fragments.first(where:{ $0.name == expectedName })!
}

// then
expect(operation?.referencedFragments).to(equal(expected))
}

func test__referencedFragments__HeightInMeters_isCorrect() throws {
// given
let fragment = compilationResult.fragments.first { $0.name == "HeightInMeters" }

// then
expect(fragment?.referencedFragments).to(beEmpty())
}

func test__referencedFragments__WarmBloodedDetails_isCorrect() throws {
// given
let fragment = compilationResult.fragments.first { $0.name == "WarmBloodedDetails" }

// when
let expected: [CompilationResult.FragmentDefinition] = [
"HeightInMeters"
].map { expectedName in
compilationResult.fragments.first(where:{ $0.name == expectedName })!
}

// then
expect(fragment?.referencedFragments).to(equal(expected))
}

func test__referencedFragments__PetDetails_isCorrect() throws {
// given
let fragment = compilationResult.fragments.first { $0.name == "PetDetails" }

// then
expect(fragment?.referencedFragments).to(beEmpty())
}
}
2 changes: 1 addition & 1 deletion apollo-ios-codegen/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ SwiftScripts/.build-**
.netlify

# Generated js files we don't need committed
Sources/ApolloCodegenLib/Frontend/dist/
Sources/GraphQLCompiler/JavaScript/dist/

# Local generated packages we don't need in the main project
Sources/AnimalKingdomAPI/Generated/Package.swift
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ public class CompilationResult: JavaScriptObject {
public lazy var selectionSet: SelectionSet = self["selectionSet"]

public lazy var directives: [Directive]? = self["directives"]


public lazy var referencedFragments: [FragmentDefinition] = self["referencedFragments"]

public lazy var source: String = self["source"]

public lazy var filePath: String = self["filePath"]
Expand Down Expand Up @@ -103,6 +105,8 @@ public class CompilationResult: JavaScriptObject {

public lazy var directives: [Directive]? = self["directives"]

public lazy var referencedFragments: [FragmentDefinition] = self["referencedFragments"]

public lazy var isLocalCacheMutation: Bool = {
directives?.contains { $0.name == Constants.DirectiveNames.LocalCacheMutation } ?? false
}()
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import {
compileDocument,
parseOperationDocument,
loadSchemaFromSources,
mergeDocuments,
} from "../index"
import {
CompilationResult
} from "../compiler/index"
import {
FragmentDefinition,
OperationDefinition
} from "../compiler/ir"
import {
Source,
GraphQLSchema,
DocumentNode
} from "graphql";
import { emptyValidationOptions } from "../__testUtils__/validationHelpers";

describe("operation with referencedFragments", () => {
const operationADocument: DocumentNode = parseOperationDocument(
new Source( `
query OperationA {
...FragmentA
...FragmentC
}
`, "OperationA", { line: 1, column: 1 }),
false
);

const fragmentADocument: DocumentNode = parseOperationDocument(
new Source( `
fragment FragmentA on Query {
a
...FragmentB
}
`, "FragmentA", { line: 1, column: 1 }),
false
);

const fragmentBDocument: DocumentNode = parseOperationDocument(
new Source( `
fragment FragmentB on Query {
b
}
`, "FragmentB", { line: 1, column: 1 }),
false
);

const fragmentCDocument: DocumentNode = parseOperationDocument(
new Source( `
fragment FragmentC on Query {
c
}
`, "FragmentC", { line: 1, column: 1 }),
false
);

const schema: GraphQLSchema = loadSchemaFromSources([new Source(`
type Query {
a: String!
b: String!
c: String!
}
`,
"Test Schema", { line: 1, column: 1 })]);

const document: DocumentNode = mergeDocuments([
operationADocument,
fragmentADocument,
fragmentBDocument,
fragmentCDocument])

const compilationResult: CompilationResult = compileDocument(schema, document, false, emptyValidationOptions);

const operationA: OperationDefinition = compilationResult.operations.find(function(element) {
return element.name == 'OperationA'
}) as OperationDefinition

const fragmentA: FragmentDefinition = compilationResult.fragments.find(function(element) {
return element.name == 'FragmentA'
}) as FragmentDefinition

const fragmentB: FragmentDefinition = compilationResult.fragments.find(function(element) {
return element.name == 'FragmentB'
}) as FragmentDefinition

const fragmentC: FragmentDefinition = compilationResult.fragments.find(function(element) {
return element.name == 'FragmentC'
}) as FragmentDefinition

it("compilation result OperationA should have referencedFragments including only directly referenced fragments.", () => {
expect(operationA.referencedFragments).toEqual([fragmentA, fragmentC])
});

it("compilation result FragmentA should have referencedFragments including only directly referenced fragments.", () => {
expect(fragmentA.referencedFragments).toEqual([fragmentB])
});

});

describe("operation with referencedFragments on child entity selection sets", () => {
const operationADocument: DocumentNode = parseOperationDocument(
new Source( `
query OperationA {
a {
...FragmentA
}
...FragmentC
}
`, "OperationA", { line: 1, column: 1 }),
false
);

const fragmentADocument: DocumentNode = parseOperationDocument(
new Source( `
fragment FragmentA on A {
A
b {
...FragmentB
}
}
`, "FragmentA", { line: 1, column: 1 }),
false
);

const fragmentBDocument: DocumentNode = parseOperationDocument(
new Source( `
fragment FragmentB on B {
B
}
`, "FragmentB", { line: 1, column: 1 }),
false
);

const fragmentCDocument: DocumentNode = parseOperationDocument(
new Source( `
fragment FragmentC on Query {
c
}
`, "FragmentC", { line: 1, column: 1 }),
false
);

const schema: GraphQLSchema = loadSchemaFromSources([new Source(`
type Query {
a: A!
b: B!
c: String!
}
type A {
A: String!
b: B!
}
type B {
B: String!
}
`,
"Test Schema", { line: 1, column: 1 })]);

const document: DocumentNode = mergeDocuments([
operationADocument,
fragmentADocument,
fragmentBDocument,
fragmentCDocument])

const compilationResult: CompilationResult = compileDocument(schema, document, false, emptyValidationOptions);

const operationA: OperationDefinition = compilationResult.operations.find(function(element) {
return element.name == 'OperationA'
}) as OperationDefinition

const fragmentA: FragmentDefinition = compilationResult.fragments.find(function(element) {
return element.name == 'FragmentA'
}) as FragmentDefinition

const fragmentB: FragmentDefinition = compilationResult.fragments.find(function(element) {
return element.name == 'FragmentB'
}) as FragmentDefinition

const fragmentC: FragmentDefinition = compilationResult.fragments.find(function(element) {
return element.name == 'FragmentC'
}) as FragmentDefinition

it("compilation result OperationA should have referencedFragments including only directly referenced fragments.", () => {
expect(operationA.referencedFragments).toEqual([fragmentA, fragmentC])
});

it("compilation result FragmentA should have referencedFragments including only directly referenced fragments.", () => {
expect(fragmentA.referencedFragments).toEqual([fragmentB])
});

});
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export function compileToIR(
const filePath = filePathForNode(operationDefinition);
const name = operationDefinition.name.value;
const operationType = operationDefinition.operation;
const referencedFragments = new Set<ir.FragmentDefinition>();

const variables = (operationDefinition.variableDefinitions || []).map(
(node) => {
Expand Down Expand Up @@ -214,9 +215,11 @@ export function compileToIR(
rootType,
selectionSet: compileSelectionSet(
operationDefinition.selectionSet,
rootType
rootType,
referencedFragments
),
directives: directives,
referencedFragments: Array.from(referencedFragments.values()),
source,
filePath
};
Expand All @@ -232,6 +235,7 @@ export function compileToIR(
fragmentDefinition,
legacySafelistingCompatibleOperations
));
const referencedFragments = new Set<ir.FragmentDefinition>();

const typeCondition = typeFromAST(
schema,
Expand All @@ -249,29 +253,33 @@ export function compileToIR(
typeCondition,
selectionSet: compileSelectionSet(
fragmentDefinition.selectionSet,
typeCondition
typeCondition,
referencedFragments
),
directives: directives
directives: directives,
referencedFragments: Array.from(referencedFragments.values()),
};
}

function compileSelectionSet(
selectionSetNode: SelectionSetNode,
parentType: GraphQLCompositeType
parentType: GraphQLCompositeType,
operationReferencedFragments: Set<ir.FragmentDefinition>,
): ir.SelectionSet {
return {
parentType,
selections: selectionSetNode.selections
.map((selectionNode) =>
compileSelection(selectionNode, parentType)
compileSelection(selectionNode, parentType, operationReferencedFragments)
)
.filter(isNotNullOrUndefined),
};
}

function compileSelection(
selectionNode: SelectionNode,
parentType: GraphQLCompositeType
parentType: GraphQLCompositeType,
operationReferencedFragments: Set<ir.FragmentDefinition>,
): ir.Selection | undefined {
const [directives, inclusionConditions] = compileDirectives(selectionNode.directives) ?? [undefined, undefined];

Expand Down Expand Up @@ -343,7 +351,8 @@ export function compileToIR(

field.selectionSet = compileSelectionSet(
selectionSetNode,
unwrappedFieldType
unwrappedFieldType,
operationReferencedFragments
);
}
return field;
Expand All @@ -360,7 +369,8 @@ export function compileToIR(
kind: "InlineFragment",
selectionSet: compileSelectionSet(
selectionNode.selectionSet,
typeCondition
typeCondition,
operationReferencedFragments
),
inclusionConditions: inclusionConditions,
directives: directives
Expand All @@ -377,6 +387,8 @@ export function compileToIR(
);
}

operationReferencedFragments.add(fragment);

const fragmentSpread: ir.FragmentSpread = {
kind: "FragmentSpread",
fragment,
Expand Down
Loading

0 comments on commit 443aca7

Please sign in to comment.