Skip to content

Commit c0b12a5

Browse files
author
Dimitri POSTOLOV
authored
4️⃣ fix false negative case in unique-fragment-name rule (#535)
1 parent 5e8ebd8 commit c0b12a5

File tree

6 files changed

+47
-6
lines changed

6 files changed

+47
-6
lines changed

.changeset/four-coats-vanish.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphql-eslint/eslint-plugin': patch
3+
---
4+
5+
fix(siblings): return virtual path for code files instead of real path

packages/plugin/src/rules/unique-fragment-name.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ export const checkNode = (
2222
const siblings = requireSiblingsOperations(ruleName, context);
2323
const siblingDocuments: (FragmentSource | OperationSource)[] =
2424
node.kind === Kind.FRAGMENT_DEFINITION ? siblings.getFragment(documentName) : siblings.getOperation(documentName);
25-
const realFilepath = getOnDiskFilepath(context.getFilename());
25+
const filepath = context.getFilename();
2626

2727
const conflictingDocuments = siblingDocuments.filter(f => {
2828
const isSameName = f.document.name?.value === documentName;
29-
const isSamePath = normalizePath(f.filePath) === normalizePath(realFilepath);
29+
const isSamePath = normalizePath(f.filePath) === normalizePath(filepath);
3030
return isSameName && !isSamePath;
3131
});
3232

@@ -36,7 +36,9 @@ export const checkNode = (
3636
messageId,
3737
data: {
3838
documentName,
39-
summary: conflictingDocuments.map(f => `\t${relative(process.cwd(), f.filePath)}`).join('\n'),
39+
summary: conflictingDocuments
40+
.map(f => `\t${relative(process.cwd(), getOnDiskFilepath(f.filePath))}`)
41+
.join('\n'),
4042
},
4143
loc: {
4244
start: {

packages/plugin/src/sibling-operations.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { resolve } from 'path';
12
import {
23
FragmentDefinitionNode,
34
FragmentSpreadNode,
@@ -29,6 +30,23 @@ export type SiblingOperations = {
2930
getOperationByType(operationType: OperationTypeNode): OperationSource[];
3031
};
3132

33+
const handleVirtualPath = (documents: Source[]): Source[] => {
34+
const filepathMap: Record<string, number> = {};
35+
36+
return documents.map(source => {
37+
const { location } = source;
38+
if (['.gql', '.graphql'].some(extension => location.endsWith(extension))) {
39+
return source;
40+
}
41+
filepathMap[location] = filepathMap[location] ?? -1;
42+
const index = filepathMap[location] += 1;
43+
return {
44+
...source,
45+
location: resolve(location, `${index}_document.graphql`)
46+
};
47+
});
48+
};
49+
3250
const operationsCache: Map<string, Source[]> = new Map();
3351
const siblingOperationsCache: Map<Source[], SiblingOperations> = new Map();
3452

@@ -56,7 +74,7 @@ const getSiblings = (filePath: string, gqlConfig: GraphQLConfig): Source[] => {
5674
};
5775

5876
export function getSiblingOperations(options: ParserOptions, gqlConfig: GraphQLConfig): SiblingOperations {
59-
const siblings = getSiblings(options.filePath, gqlConfig);
77+
const siblings = handleVirtualPath(getSiblings(options.filePath, gqlConfig));
6078

6179
if (siblings.length === 0) {
6280
let printed = false;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2+
const USER_FIELDS = /* GraphQL */ `
3+
fragment UserFields on User {
4+
id
5+
firstName
6+
}
7+
`;
8+
9+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
10+
const ALL_USER_FIELDS = /* GraphQL */ `
11+
fragment UserFields on User {
12+
id
13+
firstName
14+
lastName
15+
}
16+
`;

packages/plugin/tests/unique-fragment-name.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ ruleTester.runGraphQLTests('unique-fragment-name', rule, {
3131
{
3232
// Compare filepath of code as real instead of virtual with siblings
3333
...SIBLING_FRAGMENTS(join(__dirname, 'mocks/unique-fragment.js')),
34-
filename: join(__dirname, 'mocks/unique-fragment.js/0_document.graphql '),
34+
filename: join(__dirname, 'mocks/unique-fragment.js/0_document.graphql'),
3535
code: /* GraphQL */ `
3636
fragment UserFields on User {
3737
id

packages/plugin/tests/unique-operation-name.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ ruleTester.runGraphQLTests('unique-operation-name', rule, {
2121
{
2222
// Compare filepath of code as real instead of virtual with siblings
2323
...SIBLING_OPERATIONS(join(__dirname, 'mocks/unique-fragment.js')),
24-
filename: join(__dirname, 'mocks/unique-fragment.js/1_document.graphql '),
24+
filename: join(__dirname, 'mocks/unique-fragment.js/1_document.graphql'),
2525
code: /* GraphQL */ `
2626
query User {
2727
user {

0 commit comments

Comments
 (0)