tailwind-ctp-intellisense/packages/tailwindcss-language-server/tests/common.js

215 lines
6.4 KiB
JavaScript

import * as path from 'node:path'
import * as cp from 'node:child_process'
import * as rpc from 'vscode-jsonrpc'
import { beforeAll } from 'vitest'
async function init(fixture) {
let settings = {}
let docSettings = new Map()
let childProcess = cp.fork('./bin/tailwindcss-language-server', { silent: true })
const capabilities = {
textDocument: {
codeAction: { dynamicRegistration: true },
codeLens: { dynamicRegistration: true },
colorProvider: { dynamicRegistration: true },
completion: {
completionItem: {
commitCharactersSupport: true,
documentationFormat: ['markdown', 'plaintext'],
snippetSupport: true,
},
completionItemKind: {
valueSet: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25,
],
},
contextSupport: true,
dynamicRegistration: true,
},
definition: { dynamicRegistration: true },
documentHighlight: { dynamicRegistration: true },
documentLink: { dynamicRegistration: true },
documentSymbol: {
dynamicRegistration: true,
symbolKind: {
valueSet: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26,
],
},
},
formatting: { dynamicRegistration: true },
hover: {
contentFormat: ['markdown', 'plaintext'],
dynamicRegistration: true,
},
implementation: { dynamicRegistration: true },
onTypeFormatting: { dynamicRegistration: true },
publishDiagnostics: { relatedInformation: true },
rangeFormatting: { dynamicRegistration: true },
references: { dynamicRegistration: true },
rename: { dynamicRegistration: true },
signatureHelp: {
dynamicRegistration: true,
signatureInformation: { documentationFormat: ['markdown', 'plaintext'] },
},
synchronization: {
didSave: true,
dynamicRegistration: true,
willSave: true,
willSaveWaitUntil: true,
},
typeDefinition: { dynamicRegistration: true },
},
workspace: {
applyEdit: true,
configuration: true,
didChangeConfiguration: { dynamicRegistration: true },
didChangeWatchedFiles: { dynamicRegistration: true },
executeCommand: { dynamicRegistration: true },
symbol: {
dynamicRegistration: true,
symbolKind: {
valueSet: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26,
],
},
},
workspaceEdit: { documentChanges: true },
workspaceFolders: true,
},
}
let connection = rpc.createMessageConnection(
new rpc.StreamMessageReader(childProcess.stdout),
new rpc.StreamMessageWriter(childProcess.stdin)
)
connection.listen()
await connection.sendRequest(new rpc.RequestType('initialize'), {
processId: -1,
// rootPath: '.',
rootUri: `file://${path.resolve('./tests/fixtures/', fixture)}`,
capabilities,
trace: 'off',
workspaceFolders: [],
initializationOptions: {
testMode: true,
},
})
await connection.sendNotification(new rpc.NotificationType('initialized'))
connection.onRequest(new rpc.RequestType('workspace/configuration'), (params) => {
return params.items.map((item) => {
if (docSettings.has(item.scopeUri)) {
return docSettings.get(item.scopeUri)[item.section] ?? {}
}
return settings[item.section] ?? {}
})
})
let initPromise = new Promise((resolve) => {
connection.onRequest(new rpc.RequestType('client/registerCapability'), ({ registrations }) => {
if (registrations.findIndex((r) => r.method === 'textDocument/completion') > -1) {
resolve()
}
return null
})
})
let counter = 0
return {
connection,
sendRequest(type, params) {
return connection.sendRequest(new rpc.RequestType(type), params)
},
onNotification(type, callback) {
return connection.onNotification(new rpc.RequestType(type), callback)
},
async openDocument({ text, lang = 'html', dir = '', settings = {} }) {
let uri = `file://${path.resolve('./tests/fixtures', fixture, dir, `file-${counter++}`)}`
docSettings.set(uri, settings)
await connection.sendNotification(new rpc.NotificationType('textDocument/didOpen'), {
textDocument: {
uri,
languageId: lang,
version: 1,
text,
},
})
await initPromise
return {
uri,
async updateSettings(settings) {
docSettings.set(uri, settings)
await connection.sendNotification(
new rpc.NotificationType('workspace/didChangeConfiguration')
)
},
}
},
async updateSettings(newSettings) {
settings = newSettings
await connection.sendNotification(
new rpc.NotificationType('workspace/didChangeConfiguration')
)
},
async updateFile(file, text) {
let uri = `file://${path.resolve('./tests/fixtures', fixture, file)}`
await connection.sendNotification(new rpc.NotificationType('textDocument/didChange'), {
textDocument: { uri, version: counter++ },
contentChanges: [{ text }],
})
},
}
}
export function withFixture(fixture, callback) {
let c = {}
beforeAll(async () => {
// Using the connection object as the prototype lets us access the connection
// without defining getters for all the methods and also lets us add helpers
// to the connection object without having to resort to using a Proxy
Object.setPrototypeOf(c, await init(fixture))
return () => c.connection.end()
})
callback(c)
}
// let counter = 0
// export async function openDocument(connection, fixture, languageId, text) {
// let uri = `file://${path.resolve('./tests/fixtures', fixture, `file-${counter++}`)}`
// await connection.sendNotification(new rpc.NotificationType('textDocument/didOpen'), {
// textDocument: {
// uri,
// languageId,
// version: 1,
// text,
// },
// })
// await initPromise
// return uri
// }
// export async function updateSettings(connection, newSettings) {
// settings = newSettings
// await connection.sendNotification(new rpc.NotificationType('workspace/didChangeConfiguration'))
// }