openpencil/tools/checks/lint/tests/deep-paths.test.ts
Danila Poyarkov cff091bc6a
test: resolve repository files without climbing directories (#946)
* test: resolve repository files without climbing directories

Twelve tests and helpers reached shared fixtures, package assets, and workers with ../.. paths from import.meta, which the import rule does not see. They now go through repoPath and testPath, a workspaceRoot() that finds the root by its lockfile, the core package's own root, or the #core alias through import.meta.resolve. The root finder derives its folder from import.meta.url, so Playwright specs running under Node can use the helpers too. open-pencil/no-deep-parent-relative-paths rejects climbing two levels in new URL(…, import.meta.url) and in path calls that start from import.meta.

* fix(lint): catch Windows separators and wrapped import.meta paths, and stop at template expressions

The path rule missed '..\..' and a base such as dirname(fileURLToPath(import.meta.url)), and read `../${folder}` followed by '..' as climbing two levels.
2026-10-07 12:35:39 +00:00

35 lines
1.4 KiB
TypeScript

import { describe, expect, test } from 'bun:test'
import { lint, ruleDiagnostics } from './helpers/lint.ts'
const rule = 'no-deep-parent-relative-paths'
const rules = { [`open-pencil/${rule}`]: 'error' }
// A template that climbs one level and then names a folder, assembled so it stays source text.
const oneLevelTemplate = ['join(import.meta.dir, `../', '$', "{folder}`, '..', 'assets')"].join('')
describe('no-deep-parent-relative-paths', () => {
test.each([
"new URL('../../fixtures/a.fig', import.meta.url)",
'new URL(`../../fixtures/a.fig`, import.meta.url)',
"resolve(import.meta.dir, '../../../tests/fixtures')",
"join(import.meta.dirname, '..', '..', 'assets')",
"path.resolve(import.meta.dir, '../..')",
"join(import.meta.dir, '..\\\\..\\\\assets')",
"join(dirname(fileURLToPath(import.meta.url)), '../../fixtures')"
])('rejects %s', async (source) => {
expect(ruleDiagnostics(await lint(source, rules), rule)).toHaveLength(1)
})
test.each([
"new URL('../fixtures/a.fig', import.meta.url)",
"new URL('./worker.ts', import.meta.url)",
"join(import.meta.dir, '..', 'fixtures')",
"credentialRef('../../other-app', 'api-key')",
"resolve(root, '../../somewhere')",
"join(dirname(fileURLToPath(import.meta.url)), '..', 'fixtures')",
oneLevelTemplate
])('accepts %s', async (source) => {
expect(ruleDiagnostics(await lint(source, rules), rule)).toHaveLength(0)
})
})