Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,53 @@ type Mutation {
const result = parser.analyzeFile("schema.graphql", content);
expect(result.definitions!.some(d => d.name === "Role" && d.kind === "enum")).toBe(true);
});

it("does not let a scalar inherit a following type's fields or line range", () => {
// Arrange — a custom scalar declared above an object type (a ubiquitous
// pattern, e.g. `scalar DateTime`). scalar has no brace body of its own.
const content = `scalar DateTime

type User {
id: ID!
name: String!
}`;

// Act
const result = parser.analyzeFile("schema.graphql", content);

// Assert — the scalar is body-less: no stolen fields, single-line range.
const scalar = result.definitions!.find(d => d.name === "DateTime");
expect(scalar).toMatchObject({ kind: "scalar", lineRange: [1, 1] });
expect(scalar!.fields).toEqual([]);

// The following type keeps its own fields and range.
const user = result.definitions!.find(d => d.name === "User");
expect(user).toMatchObject({ kind: "type", lineRange: [3, 6] });
expect(user!.fields).toEqual(["id", "name"]);
});

it("does not let a union inherit a following type's fields or line range", () => {
// Arrange — a union declared above an object type. union has no brace body.
const content = `union SearchResult = User | Post

type Post {
id: ID!
title: String!
}`;

// Act
const result = parser.analyzeFile("schema.graphql", content);

// Assert — the union is body-less: no stolen fields, single-line range.
const union = result.definitions!.find(d => d.name === "SearchResult");
expect(union).toMatchObject({ kind: "union", lineRange: [1, 1] });
expect(union!.fields).toEqual([]);

// The following type is unaffected.
const post = result.definitions!.find(d => d.name === "Post");
expect(post).toMatchObject({ kind: "type", lineRange: [3, 6] });
expect(post!.fields).toEqual(["id", "title"]);
});
});

describe("ProtobufParser", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,18 @@ export class GraphQLParser implements AnalyzerPlugin {
if (name === "Query" || name === "Mutation" || name === "Subscription") continue;
const startLine = content.slice(0, match.index).split("\n").length;

// scalar and union have no brace-delimited body. Without this guard the
// logic below would scan forward and capture the fields and closing brace
// of a later braced definition — e.g. `scalar DateTime` declared above a
// `type` would inherit that type's fields and line range.
const hasBody = kind !== "scalar" && kind !== "union";

// Extract fields (for type/input/interface/enum)
const fields = this.extractFields(content, match.index);
const fields = hasBody ? this.extractFields(content, match.index) : [];

// Find closing brace
const afterMatch = content.slice(match.index);
const closeBrace = afterMatch.indexOf("}");
const closeBrace = hasBody ? afterMatch.indexOf("}") : -1;
const endLine = closeBrace !== -1
? content.slice(0, match.index + closeBrace + 1).split("\n").length
: startLine;
Expand Down