-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds a utility for finding field and enum deprecation usages. The function signature is very similar to validation which should make using it easy where validation is already being used in a reporting flow. Closes #389
- Loading branch information
Showing
4 changed files
with
152 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/** | ||
* Copyright (c) 2016, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
import { expect } from 'chai'; | ||
import { describe, it } from 'mocha'; | ||
import { findDeprecatedUsages } from '../findDeprecatedUsages'; | ||
import { parse } from '../../language'; | ||
import { | ||
GraphQLEnumType, | ||
GraphQLObjectType, | ||
GraphQLSchema, | ||
GraphQLString, | ||
} from '../../type'; | ||
|
||
describe('findDeprecatedUsages', () => { | ||
|
||
const enumType = new GraphQLEnumType({ | ||
name: 'EnumType', | ||
values: { | ||
ONE: {}, | ||
TWO: { deprecationReason: 'Some enum reason.' } | ||
} | ||
}); | ||
|
||
const schema = new GraphQLSchema({ | ||
query: new GraphQLObjectType({ | ||
name: 'Query', | ||
fields: { | ||
normalField: { | ||
args: { | ||
enumArg: { type: enumType }, | ||
}, | ||
type: GraphQLString, | ||
}, | ||
deprecatedField: { | ||
type: GraphQLString, | ||
deprecationReason: 'Some field reason.', | ||
} | ||
} | ||
}) | ||
}); | ||
|
||
it('should report empty set for no deprecated usages', () => { | ||
const errors = findDeprecatedUsages( | ||
schema, | ||
parse('{ normalField(enumArg: ONE) }') | ||
); | ||
|
||
expect(errors.length).to.equal(0); | ||
}); | ||
|
||
it('should report usage of deprecated fields', () => { | ||
const errors = findDeprecatedUsages( | ||
schema, | ||
parse('{ normalField, deprecatedField }') | ||
); | ||
|
||
const errorMessages = errors.map(err => err.message); | ||
|
||
expect(errorMessages).to.deep.equal([ | ||
'The field Query.deprecatedField is deprecated. Some field reason.' | ||
]); | ||
}); | ||
|
||
it('should report usage of deprecated enums', () => { | ||
const errors = findDeprecatedUsages( | ||
schema, | ||
parse('{ normalField(enumArg: TWO) }') | ||
); | ||
|
||
const errorMessages = errors.map(err => err.message); | ||
|
||
expect(errorMessages).to.deep.equal([ | ||
'The enum value EnumType.TWO is deprecated. Some enum reason.' | ||
]); | ||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* @flow */ | ||
/** | ||
* Copyright (c) Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
import { GraphQLError } from '../error/GraphQLError'; | ||
import { visit, visitWithTypeInfo } from '../language/visitor'; | ||
import type { DocumentNode } from '../language/ast'; | ||
import { getNamedType } from '../type/definition'; | ||
import { GraphQLSchema } from '../type/schema'; | ||
import { TypeInfo } from './TypeInfo'; | ||
|
||
/** | ||
* A validation rule which reports deprecated usages. | ||
* | ||
* Returns a list of GraphQLError instances describing every deprecated use. | ||
*/ | ||
export function findDeprecatedUsages( | ||
schema: GraphQLSchema, | ||
ast: DocumentNode, | ||
): Array<GraphQLError> { | ||
const errors = []; | ||
const typeInfo = new TypeInfo(schema); | ||
|
||
visit(ast, visitWithTypeInfo(typeInfo, { | ||
Field(node) { | ||
const fieldDef = typeInfo.getFieldDef(); | ||
if (fieldDef && fieldDef.isDeprecated) { | ||
const parentType = typeInfo.getParentType(); | ||
if (parentType) { | ||
const reason = fieldDef.deprecationReason; | ||
errors.push(new GraphQLError( | ||
`The field ${parentType.name}.${fieldDef.name} is deprecated.` + | ||
(reason ? ' ' + reason : ''), | ||
[ node ] | ||
)); | ||
} | ||
} | ||
}, | ||
EnumValue(node) { | ||
const enumVal = typeInfo.getEnumValue(); | ||
if (enumVal && enumVal.isDeprecated) { | ||
const type = getNamedType(typeInfo.getInputType()); | ||
if (type) { | ||
const reason = enumVal.deprecationReason; | ||
errors.push(new GraphQLError( | ||
`The enum value ${type.name}.${enumVal.name} is deprecated.` + | ||
(reason ? ' ' + reason : ''), | ||
[ node ] | ||
)); | ||
} | ||
} | ||
} | ||
})); | ||
|
||
return errors; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters