@anysphere/scip-typescript
Version:
SCIP indexer for TypeScript and JavaScript
114 lines (107 loc) • 3.9 kB
text/typescript
import * as fs from 'fs'
import { join } from 'path'
import * as path from 'path'
import * as process from 'process'
import * as Diff from 'diff'
import { test } from 'uvu'
import { Input } from './Input'
import { indexCommand } from './main'
import * as scip from './scip'
import { formatSnapshot } from './SnapshotTesting'
function isUpdateSnapshot(): boolean {
return process.argv.includes('--update-snapshots')
}
const snapshotNodeModules = join(process.cwd(), 'snapshots', 'node_modules')
if (!fs.existsSync(snapshotNodeModules)) {
throw new Error(
`no such file: ${snapshotNodeModules} (to fix this problem, run 'yarn install' in the snapshots/ directory)`
)
}
const inputDirectory = join(process.cwd(), 'snapshots', 'input')
const outputDirectory = join(process.cwd(), 'snapshots', 'output')
const snapshotDirectories = fs.readdirSync(inputDirectory)
const isUpdate = isUpdateSnapshot()
if (isUpdate && fs.existsSync(outputDirectory)) {
fs.rmSync(outputDirectory, { recursive: true })
}
interface PackageJson {
workspaces: string[]
packageManager?: string
}
for (const snapshotDirectory of snapshotDirectories) {
// Uncomment below if you want to skip certain tests for local development.
// if (!snapshotDirectory.includes('syntax')) {
// continue
// }
const inputRoot = join(inputDirectory, snapshotDirectory)
const outputRoot = join(outputDirectory, snapshotDirectory)
if (!fs.statSync(inputRoot).isDirectory()) {
continue
}
test(snapshotDirectory, () => {
const packageJsonPath = path.join(inputRoot, 'package.json')
const packageJson = JSON.parse(
fs.readFileSync(packageJsonPath).toString()
) as PackageJson
const tsconfigJsonPath = path.join(inputRoot, 'tsconfig.json')
const inferTsconfig = !fs.existsSync(tsconfigJsonPath)
const output = path.join(inputRoot, 'index.scip')
indexCommand([], {
cwd: inputRoot,
inferTsconfig,
output,
yarnWorkspaces: Boolean(packageJson.workspaces),
yarnBerryWorkspaces: false,
pnpmWorkspaces: Boolean(packageJson.packageManager?.includes('pnpm')),
progressBar: false,
indexedProjects: new Set(),
globalCaches: true,
gitignore: false,
})
if (inferTsconfig) {
fs.rmSync(tsconfigJsonPath)
}
const index = scip.scip.Index.deserializeBinary(
fs.readFileSync(path.join(inputRoot, 'index.scip'))
)
fs.mkdirSync(outputRoot, { recursive: true })
fs.renameSync(output, path.join(outputRoot, 'index.scip'))
if (index.documents.length === 0) {
throw new Error('empty LSIF index')
}
for (const document of index.documents) {
const inputPath = path.join(inputRoot, document.relative_path)
const relativeToInputDirectory = path.relative(inputDirectory, inputPath)
const outputPath = path.resolve(outputDirectory, relativeToInputDirectory)
const expected: string = fs.existsSync(outputPath)
? fs.readFileSync(outputPath).toString()
: ''
const input = Input.fromFile(inputPath)
const obtained = formatSnapshot(input, document)
if (obtained === expected) {
// Test passed
continue
}
if (isUpdate) {
// Update the snapshot test to reflect the new behavior
fs.mkdirSync(path.dirname(outputPath), {
recursive: true,
})
fs.writeFileSync(outputPath, obtained)
console.log(`updated snapshot: ${outputPath}`)
} else {
// Fail the test with a diff error message
const patch = Diff.createTwoFilesPatch(
outputPath,
outputPath,
expected,
obtained,
'(what the snapshot tests expect)',
"(what the current code produces). Run the command 'npm run update-snapshots' to accept the new behavior."
)
throw new Error(patch)
}
}
})
}
test.run()