Skip to content

Commit

Permalink
Test infer-graphql-input-type-from-fields
Browse files Browse the repository at this point in the history
* Add tests
* Strengthen error recovery for objects
  • Loading branch information
Zalastax committed Sep 14, 2017
1 parent 0f8bffa commit 5127fa1
Show file tree
Hide file tree
Showing 2 changed files with 265 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
const _ = require(`lodash`)
const {
graphql,
GraphQLBoolean,
GraphQLFloat,
GraphQLInt,
GraphQLNonNull,
GraphQLString,
GraphQLObjectType,
GraphQLScalarType,
GraphQLList,
GraphQLSchema,
GraphQLInputObjectType,
} = require(`graphql`)
const { connectionArgs, connectionDefinitions } = require(`graphql-skip-limit`)

const {
createSortField,
inferInputObjectStructureFromFields,
} = require(`../infer-graphql-input-fields-from-fields.js`)

function isIntInput(type) {
expect(type instanceof GraphQLInputObjectType).toBeTruthy()
expect(type.getFields()).toEqual({
eq: { name: `eq`, type: GraphQLInt },
ne: { name: `ne`, type: GraphQLInt },
})
}

function isStringInput(type) {
expect(type instanceof GraphQLInputObjectType).toBeTruthy()
expect(type.getFields()).toEqual({
eq: { name: `eq`, type: GraphQLString },
ne: { name: `ne`, type: GraphQLString },
regex: { name: `regex`, type: GraphQLString },
glob: { name: `glob`, type: GraphQLString },
})
}

function typeField(type) {
return {
type,
}
}

describe(`GraphQL Input args from fields, test-only`, () => {
function oddValue(value) {
return value % 2 === 1 ? value : null
}

const OddType = new GraphQLScalarType({
name: `Odd`,
serialize: oddValue,
parseValue: oddValue,
parseLiteral(ast) {
if (ast.kind === Kind.INT) {
return oddValue(parseInt(ast.value, 10))
}
return null
},
})

it(`handles all known scalars`, async () => {
const fields = {
scal_int: typeField(GraphQLInt),
scal_float: typeField(GraphQLFloat),
scal_string: typeField(GraphQLString),
scal_bool: typeField(GraphQLBoolean),
scal_odd_unknown: typeField(OddType),
}

const { inferredFields } = inferInputObjectStructureFromFields({
fields,
typeName: `AType`,
})

const int = inferredFields.scal_int.type
expect(int.name).toBe(`scalIntQueryInt`)
isIntInput(int)

const float = inferredFields.scal_float.type
expect(float.name).toBe(`scalFloatQueryFloat`)
expect(float instanceof GraphQLInputObjectType).toBeTruthy()
expect(float.getFields()).toEqual({
eq: { name: `eq`, type: GraphQLFloat },
ne: { name: `ne`, type: GraphQLFloat },
})

const string = inferredFields.scal_string.type
expect(string.name).toBe(`scalStringQueryString`)
isStringInput(string)

const bool = inferredFields.scal_bool.type
expect(bool.name).toBe(`scalBoolQueryBoolean`)
expect(bool instanceof GraphQLInputObjectType).toBeTruthy()
expect(bool.getFields()).toEqual({
eq: { name: `eq`, type: GraphQLBoolean },
ne: { name: `ne`, type: GraphQLBoolean },
})

expect(inferredFields).not.toHaveProperty(`scal_odd_unknown`)
})

it(`recursively converts object types`, async () => {
const fields = {
obj: typeField(
new GraphQLObjectType({
name: `Obj`,
fields: {
foo: typeField(GraphQLInt),
bar: typeField(
new GraphQLObjectType({
name: `Jbo`,
fields: {
foo: typeField(GraphQLString),
},
})
),
},
})
),
}

const { inferredFields } = inferInputObjectStructureFromFields({
fields,
typeName: `AType`,
})

const obj = inferredFields.obj.type
const objFields = obj.getFields()

expect(obj instanceof GraphQLInputObjectType).toBeTruthy()
isIntInput(objFields.foo.type)

const innerObj = objFields.bar.type
const innerObjFields = innerObj.getFields()
isStringInput(innerObjFields.foo.type)
})

it(`recovers from unknown output types`, async () => {
const fields = {
obj: {
type: new GraphQLObjectType({
name: `Obj`,
fields: {
aa: typeField(OddType),
foo: typeField(GraphQLInt),
bar: typeField(
new GraphQLObjectType({
name: `Jbo`,
fields: {
aa: typeField(OddType),
foo: typeField(GraphQLString),
ba: typeField(OddType),
bar: typeField(GraphQLInt),
},
})
),
},
}),
},
odd: typeField(OddType),
}

const { inferredFields } = inferInputObjectStructureFromFields({
fields,
typeName: `AType`,
})

expect(inferredFields.odd).toBeUndefined()

const obj = inferredFields.obj.type
const objFields = obj.getFields()

expect(obj instanceof GraphQLInputObjectType).toBeTruthy()
isIntInput(objFields.foo.type)
expect(objFields.aa).toBeUndefined()

const innerObj = objFields.bar.type
const innerObjFields = innerObj.getFields()
expect(innerObjFields.aa).toBeUndefined()
isStringInput(innerObjFields.foo.type)
expect(innerObjFields.ba).toBeUndefined()
isIntInput(innerObjFields.bar.type)
})

it(`includes the filters of list elements`, async () => {
const fields = {
list: typeField(new GraphQLList(GraphQLFloat)),
}

const { inferredFields } = inferInputObjectStructureFromFields({
fields,
typeName: `AType`,
})

const list = inferredFields.list.type

expect(list instanceof GraphQLInputObjectType).toBeTruthy()
expect(list.getFields()).toEqual({
eq: { name: `eq`, type: GraphQLFloat },
ne: { name: `ne`, type: GraphQLFloat },
in: { name: `in`, type: new GraphQLList(GraphQLFloat) },
})
})

it(`strips away NonNull`, async () => {
const fields = {
nonNull: typeField(new GraphQLNonNull(GraphQLInt)),
}

const { inferredFields } = inferInputObjectStructureFromFields({
fields,
typeName: `AType`,
})

isIntInput(inferredFields.nonNull.type)
})

it(`extracts the fields you can sort on`, async () => {
const fields = {
foo: typeField(GraphQLString),
bar: typeField(GraphQLFloat),
baz: typeField(
new GraphQLObjectType({
name: `Baz`,
fields: {
ka: typeField(GraphQLFloat),
ma: typeField(
new GraphQLList(
new GraphQLObjectType({
name: `Hol`,
fields: {
go: typeField(GraphQLFloat),
},
})
)
),
},
})
),
}

const { sort } = inferInputObjectStructureFromFields({
fields,
typeName: `AType`,
})

expect(sort.sort()).toEqual([`bar`, `baz___ka`, `baz___ma`, `foo`])
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,14 @@ function convertToInputType(type: GraphQLType): GraphQLInputType {
} else if (type instanceof GraphQLObjectType) {
return new GraphQLInputObjectType({
name: createTypeName(`${type.name}InputObject`),
fields: _.mapValues(type.getFields(), fieldConfig => {return {
type: convertToInputType(fieldConfig.type),
}}),
fields: _.transform(type.getFields(), (out, fieldConfig, key) => {
try {
const type = convertToInputType(fieldConfig.type)
out[key] = { type }
} catch (e) {
console.log(e)
}
}),
})
} else if (type instanceof GraphQLList) {
return new GraphQLList(makeNullable(convertToInputType(type.ofType)))
Expand Down Expand Up @@ -112,17 +117,15 @@ function convertToInputFilter(
} else if (type instanceof GraphQLInputObjectType) {
return new GraphQLInputObjectType({
name: createTypeName(`${prefix}{type.name}`),
fields: _.mapValues(type.getFields(), (fieldConfig, key) => {
fields: _.transform(type.getFields(), (out, fieldConfig, key) => {
try {
return {
type: convertToInputFilter(
`${prefix}${_.upperFirst(key)}`,
fieldConfig.type
),
}
const type = convertToInputFilter(
`${prefix}${_.upperFirst(key)}`,
fieldConfig.type
)
out[key] = { type }
} catch (e) {
console.log(e)
return undefined
}
}),
})
Expand Down

0 comments on commit 5127fa1

Please sign in to comment.