-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic tests for multifile schemas (#1731)
* Basic tests for multifile schemas * Fix windows test * fix: Newline characters should be a part of untrimmed lines * Fix characterAfter, add failing test for empty completion * Fix `@map` spacing * Revert windows hack * Windows, please
- Loading branch information
Serhii Tatarintsev
authored
May 16, 2024
1 parent
281e45a
commit fe081ac
Showing
27 changed files
with
601 additions
and
37 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
83 changes: 83 additions & 0 deletions
83
packages/language-server/src/__test__/multifile/MultifileHelper.ts
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,83 @@ | ||
import { URI } from 'vscode-uri' | ||
import { PrismaSchema, SchemaDocument } from '../../lib/Schema' | ||
import path from 'path' | ||
import { getMultifileSchema } from '../helper' | ||
import { Position, TextEdit } from 'vscode-languageserver' | ||
import { TextDocument } from 'vscode-languageserver-textdocument' | ||
|
||
export async function getMultifileHelper(fixturePath: string) { | ||
const schema = await getMultifileSchema(fixturePath) | ||
const helper = new MultfileHelper(`/multifile/${fixturePath}`, schema) | ||
return helper | ||
} | ||
|
||
class MultfileHelper { | ||
constructor( | ||
private baseDir: string, | ||
readonly schema: PrismaSchema, | ||
) {} | ||
|
||
file(filePath: string) { | ||
const doc = this.schema.findDocByUri(URI.file(path.join(this.baseDir, filePath)).toString()) | ||
if (!doc) { | ||
throw new Error(`${filePath} is not found fixture`) | ||
} | ||
|
||
return new File(doc) | ||
} | ||
|
||
applyChanges(edits: Record<string, TextEdit[]> | undefined): Record<string, string> { | ||
if (!edits) { | ||
return {} | ||
} | ||
const results = {} as Record<string, string> | ||
for (const [uri, fileEdits] of Object.entries(edits)) { | ||
let doc = this.schema.findDocByUri(uri)?.textDocument | ||
if (!doc) { | ||
doc = TextDocument.create(uri, 'prisma', 1, '') | ||
} | ||
const updatedDoc = TextDocument.applyEdits(doc, fileEdits) | ||
results[uri] = updatedDoc | ||
} | ||
return results | ||
} | ||
} | ||
|
||
class File { | ||
constructor(readonly schemaDocument: SchemaDocument) {} | ||
|
||
get textDocument() { | ||
return this.schemaDocument.textDocument | ||
} | ||
|
||
get uri() { | ||
return this.schemaDocument.uri | ||
} | ||
|
||
lineContaining(match: string) { | ||
for (const line of this.schemaDocument.lines) { | ||
if (line.text.includes(match)) { | ||
return new Line(line.lineIndex, line.untrimmedText) | ||
} | ||
} | ||
throw new Error(`Can not find line with "${match}"`) | ||
} | ||
} | ||
|
||
class Line { | ||
constructor( | ||
readonly lineNumber: number, | ||
readonly text: string, | ||
) {} | ||
|
||
characterAfter(substring: string): Position { | ||
const index = this.text.indexOf(substring) | ||
if (index === -1) { | ||
throw new Error(`Can not find ${substring} in ${this.text}`) | ||
} | ||
return { | ||
line: this.lineNumber, | ||
character: index + substring.length + 1, | ||
} | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
packages/language-server/src/__test__/multifile/completion.test.ts
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,33 @@ | ||
import { test, expect } from 'vitest' | ||
import { handleCompletionRequest } from '../../lib/MessageHandler' | ||
import { getMultifileHelper } from './MultifileHelper' | ||
|
||
test('type name completion', async () => { | ||
const helper = await getMultifileHelper('complete-field') | ||
const post = helper.file('Post.prisma') | ||
|
||
const response = handleCompletionRequest(helper.schema, post.textDocument, { | ||
textDocument: { | ||
uri: post.uri, | ||
}, | ||
position: post.lineContaining('author Us').characterAfter('U'), | ||
}) | ||
|
||
const userItem = response?.items.find((item) => item.label === 'User') | ||
expect(userItem).not.toBeUndefined() | ||
}) | ||
|
||
test('type name completion with no name typed', async () => { | ||
const helper = await getMultifileHelper('complete-field') | ||
const post = helper.file('Post.prisma') | ||
|
||
const response = handleCompletionRequest(helper.schema, post.textDocument, { | ||
textDocument: { | ||
uri: post.uri, | ||
}, | ||
position: post.lineContaining('author ').characterAfter('r '), | ||
}) | ||
|
||
const userItem = response?.items.find((item) => item.label === 'User') | ||
expect(userItem).not.toBeUndefined() | ||
}) |
21 changes: 21 additions & 0 deletions
21
packages/language-server/src/__test__/multifile/hover.test.ts
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,21 @@ | ||
import { test, expect } from 'vitest' | ||
import { handleHoverRequest } from '../../lib/MessageHandler' | ||
import { getMultifileHelper } from './MultifileHelper' | ||
|
||
test('basic doc', async () => { | ||
const helper = await getMultifileHelper('user-posts') | ||
const user = helper.file('User.prisma') | ||
|
||
const response = handleHoverRequest(helper.schema, user.textDocument, { | ||
textDocument: { | ||
uri: user.uri, | ||
}, | ||
position: user.lineContaining('posts Post[]').characterAfter('Po'), | ||
}) | ||
|
||
expect(response).toMatchInlineSnapshot(` | ||
{ | ||
"contents": "This is a blog post", | ||
} | ||
`) | ||
}) |
43 changes: 43 additions & 0 deletions
43
packages/language-server/src/__test__/multifile/jumpToDefinition.test.ts
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,43 @@ | ||
import { test, expect } from 'vitest' | ||
import { handleDefinitionRequest } from '../../lib/MessageHandler' | ||
import { getMultifileHelper } from './MultifileHelper' | ||
|
||
test('basic doc', async () => { | ||
const helper = await getMultifileHelper('user-posts') | ||
const post = helper.file('Post.prisma') | ||
|
||
const response = handleDefinitionRequest(helper.schema, post.textDocument, { | ||
textDocument: { | ||
uri: post.uri, | ||
}, | ||
position: post.lineContaining('author User').characterAfter('Us'), | ||
}) | ||
|
||
expect(response).toMatchInlineSnapshot(` | ||
[ | ||
{ | ||
"targetRange": { | ||
"end": { | ||
"character": 1, | ||
"line": 6, | ||
}, | ||
"start": { | ||
"character": 0, | ||
"line": 1, | ||
}, | ||
}, | ||
"targetSelectionRange": { | ||
"end": { | ||
"character": 10, | ||
"line": 1, | ||
}, | ||
"start": { | ||
"character": 6, | ||
"line": 1, | ||
}, | ||
}, | ||
"targetUri": "file:///multifile/user-posts/User.prisma", | ||
}, | ||
] | ||
`) | ||
}) |
35 changes: 35 additions & 0 deletions
35
packages/language-server/src/__test__/multifile/linting.test.ts
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,35 @@ | ||
import { test, expect } from 'vitest' | ||
import { handleDiagnosticsRequest } from '../../lib/MessageHandler' | ||
import { getMultifileHelper } from './MultifileHelper' | ||
|
||
test('invalid doc', async () => { | ||
const helper = await getMultifileHelper('linting') | ||
|
||
const response = handleDiagnosticsRequest(helper.schema) | ||
|
||
expect(response).toMatchInlineSnapshot(` | ||
DiagnosticMap { | ||
"_map": Map { | ||
"file:///multifile/linting/Post.prisma" => [ | ||
{ | ||
"message": "Type "Like" is neither a built-in type, nor refers to another model, composite type, or enum.", | ||
"range": { | ||
"end": { | ||
"character": 17, | ||
"line": 7, | ||
}, | ||
"start": { | ||
"character": 13, | ||
"line": 7, | ||
}, | ||
}, | ||
"severity": 1, | ||
"source": "Prisma", | ||
}, | ||
], | ||
"file:///multifile/linting/User.prisma" => [], | ||
"file:///multifile/linting/config.prisma" => [], | ||
}, | ||
} | ||
`) | ||
}) |
35 changes: 35 additions & 0 deletions
35
packages/language-server/src/__test__/multifile/quickFix.test.ts
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,35 @@ | ||
import { test, expect } from 'vitest' | ||
import { handleCodeActions, handleDiagnosticsRequest } from '../../lib/MessageHandler' | ||
import { getMultifileHelper } from './MultifileHelper' | ||
|
||
test('basic doc', async () => { | ||
const helper = await getMultifileHelper('quick-fix') | ||
const profile = helper.file('Profile.prisma') | ||
const diagnostics = handleDiagnosticsRequest(helper.schema).get(profile.uri) | ||
|
||
const response = handleCodeActions(helper.schema, profile.textDocument, { | ||
textDocument: { | ||
uri: profile.uri, | ||
}, | ||
range: { | ||
start: profile.lineContaining('user User').characterAfter('us'), | ||
end: profile.lineContaining('user User').characterAfter('user'), | ||
}, | ||
context: { | ||
diagnostics, | ||
}, | ||
}) | ||
|
||
const changes = response[0]?.edit?.changes | ||
const updated = helper.applyChanges(changes) | ||
expect(updated).toMatchInlineSnapshot(` | ||
{ | ||
"file:///multifile/quick-fix/Profile.prisma": "model Profile { | ||
id String @id @default(uuid()) | ||
userId String @unique | ||
user User @relation(fields: [userId], references: [id]) | ||
} | ||
", | ||
} | ||
`) | ||
}) |
Oops, something went wrong.