mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-08-23 23:55:50 +00:00
* refactor(core): remove root barrel self-imports * fix(core): activate root barrel boundary rule * test(core): cover root barrel export visitors * fix(core): remove unused boundary constant * fix(core): correct misplaced imports flagged by root barrel rule coreToolScheduler: ToolExecutionStatus is exported from core/turn.ts, not tools/tools.ts; was also duplicated in the tools import block. nonInteractiveToolExecutor: RuntimeContentGeneratorView is exported from agents/runtime/agent-context.ts, not core/contentGenerator.ts. Both were surfaced by the new no-core-root-barrel-import rule in #9152. * fix(core): complete telemetry mock and harden barrel rule edge cases extensionManager.test: the ../telemetry/loggers.js mock was missing logExtensionInstallEvent, logExtensionUninstall, and logExtensionDisable, which the source now imports from that path after the barrel cleanup. This caused 53 test failures. no-core-root-barrel-import.js: added package-specifier detection (@qwen-code/qwen-code-core), template-literal dynamic import support, depth-0 ./index.js handling, and __tests__ exemption parity with the test-file check. Added trailing newline. Tests: added coverage for all new edge cases in both rule test files. Refs #9152 * fix(core): close package-level barrel gap and coverage holes The barrel rule blocked only specifiers resolving to the src-level index.{js,ts}; the package-level barrel (packages/core/index.ts, which re-exports the src barrel) remained reachable via one extra ../ hop. Match ../index.{js,ts} so core production files cannot re-import the root barrel through that path. Also: hoist the duplicated src-root marker to a single constant, reword the rule message so it no longer hardcodes ../index.js, pin the .ts spelling branch, fix the vacuous fixtures-exemption case, and add a cross-directory flat-config fixture so a narrowed files glob fails the integration test. Refs #9152 * fix(core): flag barrel subpaths and inline type imports in the root barrel rule * fix(core): harden no-core-root-barrel-import rule Anchor the source-root marker on its last occurrence so nested checkouts resolve correctly, reject relative imports of the compiled dist barrel, and treat .spec files as tests. Adds regression coverage for each.
138 lines
4.2 KiB
JavaScript
138 lines
4.2 KiB
JavaScript
import { describe, expect, it } from 'vitest';
|
|
import { Linter } from 'eslint';
|
|
import rule from '../../eslint-rules/no-core-root-barrel-import.js';
|
|
|
|
function runRule(code, filename) {
|
|
const linter = new Linter({ configType: 'eslintrc' });
|
|
linter.defineRule('architecture/no-core-root-barrel-import', rule);
|
|
return linter.verify(
|
|
code,
|
|
{
|
|
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
|
|
rules: { 'architecture/no-core-root-barrel-import': 'error' },
|
|
},
|
|
{ filename },
|
|
);
|
|
}
|
|
|
|
describe('no-core-root-barrel-import', () => {
|
|
it.each([
|
|
['packages/core/src/core/client.ts', '../index.js'],
|
|
['packages/core/src/a/b/c/module.ts', '../../../index.js'],
|
|
// depth-0: src-root module importing the barrel from the same directory
|
|
['packages/core/src/index.ts', './index.js'],
|
|
// package-level barrel (packages/core/index.js) via an extra directory hop
|
|
['packages/core/src/core/client.ts', '../../index.js'],
|
|
// .ts spelling of the src barrel
|
|
['packages/core/src/core/client.ts', '../index.ts'],
|
|
// nested checkout: a parent directory also contains the marker, so the
|
|
// rule must anchor on the LAST occurrence to derive the correct source root
|
|
[
|
|
'/tmp/packages/core/src/checkout/repo/packages/core/src/core/client.ts',
|
|
'../index.js',
|
|
],
|
|
// exports-map subpaths that reach the same root barrel
|
|
[
|
|
'packages/core/src/core/client.ts',
|
|
'@qwen-code/qwen-code-core/src/index.js',
|
|
],
|
|
[
|
|
'packages/core/src/core/client.ts',
|
|
'@qwen-code/qwen-code-core/dist/index.js',
|
|
],
|
|
// .ts spelling of the exports-map src subpath
|
|
[
|
|
'packages/core/src/core/client.ts',
|
|
'@qwen-code/qwen-code-core/src/index.ts',
|
|
],
|
|
// relative import of the compiled barrel
|
|
['packages/core/src/core/client.ts', '../../dist/index.js'],
|
|
])('rejects root barrel imports from %s', (filename, importedPath) => {
|
|
expect(
|
|
runRule(`import value from '${importedPath}';`, filename),
|
|
).toHaveLength(1);
|
|
});
|
|
|
|
it('rejects export and dynamic root barrel sources', () => {
|
|
expect(
|
|
runRule(
|
|
"export { value } from '../index.js';",
|
|
'packages/core/src/core/client.ts',
|
|
),
|
|
).toHaveLength(1);
|
|
expect(
|
|
runRule(
|
|
"export * from '../index.js';",
|
|
'packages/core/src/core/client.ts',
|
|
),
|
|
).toHaveLength(1);
|
|
expect(
|
|
runRule("import('../index.js');", 'packages/core/src/core/client.ts'),
|
|
).toHaveLength(1);
|
|
});
|
|
|
|
it('rejects package-specifier barrel imports from core production', () => {
|
|
expect(
|
|
runRule(
|
|
"import value from '@qwen-code/qwen-code-core';",
|
|
'packages/core/src/core/client.ts',
|
|
),
|
|
).toHaveLength(1);
|
|
});
|
|
|
|
it('rejects static template-literal dynamic barrel imports', () => {
|
|
expect(
|
|
runRule('import(`../index.js`);', 'packages/core/src/core/client.ts'),
|
|
).toHaveLength(1);
|
|
});
|
|
|
|
it('allows tests, fixtures, __tests__, and non-core consumers', () => {
|
|
expect(
|
|
runRule(
|
|
"import value from '../index.js';",
|
|
'packages/core/src/core/client.test.ts',
|
|
),
|
|
).toHaveLength(0);
|
|
expect(
|
|
runRule(
|
|
"import value from '../index.js';",
|
|
'packages/core/src/core/client.spec.ts',
|
|
),
|
|
).toHaveLength(0);
|
|
expect(
|
|
runRule(
|
|
"import value from '../index.js';",
|
|
'packages/core/src/fixtures/client.ts',
|
|
),
|
|
).toHaveLength(0);
|
|
expect(
|
|
runRule(
|
|
"import value from '../index.js';",
|
|
'packages/core/src/__tests__/helper.ts',
|
|
),
|
|
).toHaveLength(0);
|
|
// non-core consumers can import the package specifier freely
|
|
expect(
|
|
runRule(
|
|
"import value from '@qwen-code/qwen-code-core';",
|
|
'packages/cli/src/index.ts',
|
|
),
|
|
).toHaveLength(0);
|
|
// non-barrel package subpaths stay allowed even inside core production
|
|
expect(
|
|
runRule(
|
|
"import { memoryScopes } from '@qwen-code/qwen-code-core/memoryScopes';",
|
|
'packages/core/src/core/client.ts',
|
|
),
|
|
).toHaveLength(0);
|
|
});
|
|
|
|
it('allows direct owner imports', () => {
|
|
expect(
|
|
runRule(
|
|
"import value from '../tools/tools.js';",
|
|
'packages/core/src/core/client.ts',
|
|
),
|
|
).toHaveLength(0);
|
|
});
|
|
});
|