Skip to content

Commit

Permalink
chore: Refactor build node connections (#9803)
Browse files Browse the repository at this point in the history
Another refactoring! The plus side of all these is more readable code (hopefully), but they're mostly to ease the loki integration. This one renames a lot of the vars/functions in `build-node-connections` so they're consistent with the actual graphql types and field class names as per https://graphql.org/graphql-js/type/#graphqlobjecttype

Another benefit of this refactor is the ability to create types (connections in this case) one by one instead of having to do them as a whole batch. This will be eventually needed for incremental builds

Update: I slipped a refactor to `build-node-types` in as well.
  • Loading branch information
Moocar authored and pieh committed Nov 12, 2018
1 parent f78c610 commit 66fa756
Show file tree
Hide file tree
Showing 7 changed files with 422 additions and 286 deletions.
4 changes: 2 additions & 2 deletions packages/gatsby/src/bootstrap/index.js
Expand Up @@ -351,7 +351,7 @@ module.exports = async (args: BootstrapArgs) => {
parentSpan: bootstrapSpan,
})
activity.start()
await require(`../schema`)({ parentSpan: activity.span })
await require(`../schema`).build({ parentSpan: activity.span })
activity.end()

// Collect resolvable extensions and attach to program.
Expand Down Expand Up @@ -414,7 +414,7 @@ module.exports = async (args: BootstrapArgs) => {
parentSpan: bootstrapSpan,
})
activity.start()
await require(`../schema`)({ parentSpan: activity.span })
await require(`../schema`).build({ parentSpan: activity.span })
activity.end()

require(`../schema/type-conflict-reporter`).printConflicts()
Expand Down
@@ -1,11 +1,9 @@
const { graphql, GraphQLObjectType, GraphQLSchema } = require(`graphql`)
const _ = require(`lodash`)

const createPageDependency = require(`../../redux/actions/add-page-dependency`)
jest.mock(`../../redux/actions/add-page-dependency`)

const buildNodeTypes = require(`../build-node-types`)
const buildNodeConnections = require(`../build-node-connections`)
const nodeConnections = require(`../build-node-connections`)

describe(`build-node-connections`, () => {
let schema, store, types, connections
Expand Down Expand Up @@ -51,7 +49,7 @@ describe(`build-node-connections`, () => {
].forEach(n => store.dispatch({ type: `CREATE_NODE`, payload: n }))

types = await buildNodeTypes({})
connections = await buildNodeConnections(_.values(types))
connections = await nodeConnections.buildAll(_.values(types))

schema = new GraphQLSchema({
query: new GraphQLObjectType({
Expand Down
112 changes: 108 additions & 4 deletions packages/gatsby/src/schema/__tests__/build-node-types-test.js
@@ -1,5 +1,14 @@
const { graphql, GraphQLObjectType, GraphQLSchema } = require(`graphql`)
const {
graphql,
GraphQLObjectType,
GraphQLSchema,
GraphQLString,
} = require(`graphql`)
const _ = require(`lodash`)

jest.mock(`../../utils/api-runner-node`)
const apiRunnerNode = require(`../../utils/api-runner-node`)

const createPageDependency = require(`../../redux/actions/add-page-dependency`)
jest.mock(`../../redux/actions/add-page-dependency`)
const buildNodeTypes = require(`../build-node-types`)
Expand All @@ -15,6 +24,20 @@ describe(`build-node-types`, () => {
}

beforeEach(async () => {
createPageDependency.mockClear()
const apiRunnerResponse = [
{
pluginField: {
type: GraphQLString,
description: `test description`,
resolve: parent => {
console.log(`in resolver: ${parent}`)
return `pluginFieldValue`
},
},
},
]
apiRunnerNode.mockImplementation(() => apiRunnerResponse)
;({ store } = require(`../../redux`))
store.dispatch({ type: `DELETE_CACHE` })
;[
Expand Down Expand Up @@ -130,7 +153,69 @@ describe(`build-node-types`, () => {
expect(parent.childRelative.id).toEqual(`r1`)
})

it(`should create page dependency`, async () => {
it(`should handle plugin fields`, async () => {
const result = await runQuery(
`
{
parent(id: { eq: "p1" }) {
pluginField
}
}
`
)
expect(result.parent.pluginField).toEqual(`pluginFieldValue`)
})

it(`should create root query type page dependency`, async () => {
await runQuery(` { parent(id: { eq: "p1" }) { id } } `)

expect(createPageDependency).toHaveBeenCalledWith({
path: `foo`,
nodeId: `p1`,
})
})

it(`should create children page dependency`, async () => {
await runQuery(
`
{
parent {
children { id }
}
}
`
)
expect(createPageDependency).toHaveBeenCalledWith({
path: `foo`,
nodeId: `c1`,
})
expect(createPageDependency).toHaveBeenCalledWith({
path: `foo`,
nodeId: `c2`,
})
expect(createPageDependency).toHaveBeenCalledWith({
path: `foo`,
nodeId: `r1`,
})
})

it(`should create parent page dependency`, async () => {
await runQuery(
`
{
child(id: { eq: "c1" }) {
parent { id }
}
}
`
)
expect(createPageDependency).toHaveBeenCalledWith({
path: `foo`,
nodeId: `p1`,
})
})

it(`should create childX page dependency`, async () => {
await runQuery(
`
{
Expand All @@ -145,11 +230,30 @@ describe(`build-node-types`, () => {

expect(createPageDependency).toHaveBeenCalledWith({
path: `foo`,
nodeId: `p1`,
nodeId: `r1`,
})
})

it(`should create childrenX page dependency`, async () => {
await runQuery(
`
{
parent(id: { eq: "p1" }) {
childrenChild { # lol
id
}
}
}
`
)

expect(createPageDependency).toHaveBeenCalledWith({
path: `foo`,
nodeId: `r1`,
nodeId: `c1`,
})
expect(createPageDependency).toHaveBeenCalledWith({
path: `foo`,
nodeId: `c2`,
})
})
})
@@ -1,25 +1,16 @@
const _ = require(`lodash`)
const {
graphql,
GraphQLString,
GraphQLObjectType,
GraphQLSchema,
GraphQLInputObjectType,
} = require(`graphql`)
const { connectionArgs, connectionDefinitions } = require(`graphql-skip-limit`)

const { runQuery } = require(`../../db/nodes`)
const { graphql, GraphQLString, GraphQLObjectType } = require(`graphql`)

const { inferObjectStructureFromNodes } = require(`../infer-graphql-type`)
const buildConnectionFields = require(`../build-connection-fields`)
const nodeConnections = require(`../build-node-connections`)
const { buildNodesSchema } = require(`../index`)
const {
inferInputObjectStructureFromNodes,
} = require(`../infer-graphql-input-fields`)
const createSortField = require(`../create-sort-field`)
const {
getExampleValues,
clearTypeExampleValues,
} = require(`../data-tree-utils`)
const { connectionFromArray } = require(`graphql-skip-limit`)

let mockNodes
jest.unmock(`../../db/nodes`)
Expand All @@ -28,67 +19,21 @@ nodesDb.getNodesByType = () => mockNodes

function queryResult(nodes, query, { types = [] } = {}) {
mockNodes = nodes
const nodeType = new GraphQLObjectType({
name: `Test`,
const nodeObjectType = new GraphQLObjectType({
name: `Node`,
fields: inferObjectStructureFromNodes({
nodes,
types: [{ name: `Test` }, ...types],
types: [{ name: `Node` }, ...types],
}),
})

const { connectionType: nodeConnection } = connectionDefinitions({
nodeType,
connectionFields: () =>
buildConnectionFields({
name,
nodes,
nodeObjectType: nodeType,
}),
})

const { sort, inferredFields } = inferInputObjectStructureFromNodes({
const processedType = {
nodes,
typeName: `test`,
})
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: `RootQueryType`,
fields: () => {
return {
allNode: {
name: `nodeConnection`,
type: nodeConnection,
args: {
...connectionArgs,
sort: createSortField(`RootQueryType`, sort),
filter: {
type: new GraphQLInputObjectType({
name: _.camelCase(`filter test`),
description: `Filter connection on its fields`,
fields: () => inferredFields,
}),
},
},
async resolve(nvi, queryArgs) {
const results = await runQuery({
queryArgs,
firstOnly: false,
gqlType: nodeType,
})
if (results.length > 0) {
const connection = connectionFromArray(results, queryArgs)
connection.totalCount = results.length
return connection
} else {
return null
}
},
},
}
},
}),
})

name: `Node`,
nodeObjectType,
fieldsFromPlugins: [],
}
const fields = nodeConnections.buildFieldConfigMap(processedType)
const schema = buildNodesSchema(fields)
return graphql(schema, query)
}

Expand Down

0 comments on commit 66fa756

Please sign in to comment.