Compare commits
4 Commits
main
...
fix-ci-checks
| Author | SHA1 | Date | |
|---|---|---|---|
| ca68016f8b | |||
| 1298dbcc52 | |||
| 41fba155b5 | |||
| 8cf2304c99 |
@@ -51,9 +51,9 @@ describe('linux-do topic-content', () => {
|
||||
expect(command?.columns).toEqual(['content']);
|
||||
});
|
||||
it('keeps topic adapter as a summarized first-page reader after the split', () => {
|
||||
const topicTs = fs.readFileSync(new URL('./topic.ts', import.meta.url), 'utf8');
|
||||
expect(topicTs).not.toContain('main_only');
|
||||
expect(topicTs).toContain('slice(0, 200)');
|
||||
expect(topicTs).toContain('帖子首页摘要和回复');
|
||||
const topicSource = fs.readFileSync(new URL('./topic.js', import.meta.url), 'utf8');
|
||||
expect(topicSource).not.toContain('main_only');
|
||||
expect(topicSource).toContain('slice(0, 200)');
|
||||
expect(topicSource).toContain('帖子首页摘要和回复');
|
||||
});
|
||||
});
|
||||
|
||||
+6
-5
@@ -45,6 +45,7 @@
|
||||
"build-manifest": "node dist/src/build-manifest.js",
|
||||
"clean-dist": "node scripts/clean-dist.cjs",
|
||||
"clean-yaml": "node scripts/clean-yaml.cjs",
|
||||
"prepare-test-self-exports": "node scripts/prepare-test-self-exports.mjs",
|
||||
"copy-yaml": "node scripts/copy-yaml.cjs",
|
||||
"start": "node dist/src/main.js",
|
||||
"start:bun": "bun dist/src/main.js",
|
||||
@@ -54,11 +55,11 @@
|
||||
"lint": "tsc --noEmit",
|
||||
"prepare": "[ -d src ] && npm run build || true",
|
||||
"prepublishOnly": "npm run build",
|
||||
"test": "vitest run --project unit --project extension",
|
||||
"test:bun": "bun vitest run --project unit --project extension",
|
||||
"test:adapter": "vitest run --project adapter",
|
||||
"test:all": "vitest run",
|
||||
"test:e2e": "vitest run --project e2e",
|
||||
"test": "npm run prepare-test-self-exports && vitest run --project unit --project extension",
|
||||
"test:bun": "node scripts/prepare-test-self-exports.mjs && bun vitest run --project unit --project extension",
|
||||
"test:adapter": "npm run prepare-test-self-exports && vitest run --project adapter",
|
||||
"test:all": "npm run prepare-test-self-exports && vitest run",
|
||||
"test:e2e": "npm run prepare-test-self-exports && vitest run --project e2e",
|
||||
"docs:dev": "vitepress dev docs",
|
||||
"docs:build": "vitepress build docs",
|
||||
"docs:preview": "vitepress preview docs"
|
||||
|
||||
@@ -30,6 +30,11 @@ for adapter_dir in "$SRC_DIR"/*/; do
|
||||
adapter_name="$(basename "$adapter_dir")"
|
||||
# Skip internal directories (e.g., _shared)
|
||||
[[ "$adapter_name" == _* ]] && continue
|
||||
# Skip helper-only directories that do not expose any top-level adapter commands.
|
||||
top_level_files="$(find "$adapter_dir" -maxdepth 1 -type f | awk -F/ '{print $NF}')"
|
||||
if [[ -n "$top_level_files" ]] && ! printf '%s\n' "$top_level_files" | grep -qv '^_'; then
|
||||
continue
|
||||
fi
|
||||
total=$((total + 1))
|
||||
|
||||
# Check if doc exists in browser/ or desktop/ subdirectories
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const pkgJson = JSON.parse(await fs.readFile(path.join(rootDir, 'package.json'), 'utf8'));
|
||||
|
||||
function toSourcePath(target) {
|
||||
return target.replace(/^\.\/dist\//, './').replace(/\.js$/, '.ts');
|
||||
}
|
||||
|
||||
async function writeShim(defaultTarget, sourceTarget) {
|
||||
const absTarget = path.join(rootDir, defaultTarget);
|
||||
const absSource = path.join(rootDir, sourceTarget);
|
||||
const relSource = path.relative(path.dirname(absTarget), absSource).split(path.sep).join('/');
|
||||
const sourceRef = relSource.startsWith('.') ? relSource : `./${relSource}`;
|
||||
const contents = `export * from ${JSON.stringify(sourceRef)};\n`;
|
||||
|
||||
await fs.mkdir(path.dirname(absTarget), { recursive: true });
|
||||
await fs.writeFile(absTarget, contents, 'utf8');
|
||||
}
|
||||
|
||||
for (const target of Object.values(pkgJson.exports)) {
|
||||
if (typeof target !== 'string') continue;
|
||||
await writeShim(target, toSourcePath(target));
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import * as fs from 'node:fs';
|
||||
import * as os from 'node:os';
|
||||
import * as path from 'node:path';
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
|
||||
const tempDirs: string[] = [];
|
||||
|
||||
afterEach(() => {
|
||||
for (const dir of tempDirs.splice(0)) {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
describe('CI regression coverage', () => {
|
||||
it('ignores helper-only adapter directories when checking docs coverage', () => {
|
||||
const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'opencli-doc-coverage-'));
|
||||
tempDirs.push(fixtureRoot);
|
||||
|
||||
const scriptsDir = path.join(fixtureRoot, 'scripts');
|
||||
const clisDir = path.join(fixtureRoot, 'clis', 'slock');
|
||||
const docsBrowserDir = path.join(fixtureRoot, 'docs', 'adapters', 'browser');
|
||||
const docsDesktopDir = path.join(fixtureRoot, 'docs', 'adapters', 'desktop');
|
||||
|
||||
fs.mkdirSync(scriptsDir, { recursive: true });
|
||||
fs.mkdirSync(clisDir, { recursive: true });
|
||||
fs.mkdirSync(docsBrowserDir, { recursive: true });
|
||||
fs.mkdirSync(docsDesktopDir, { recursive: true });
|
||||
|
||||
fs.copyFileSync(
|
||||
path.join(process.cwd(), 'scripts', 'check-doc-coverage.sh'),
|
||||
path.join(scriptsDir, 'check-doc-coverage.sh'),
|
||||
);
|
||||
fs.writeFileSync(
|
||||
path.join(clisDir, '_utils.js'),
|
||||
'export const helper = () => "noop";\n',
|
||||
);
|
||||
|
||||
const output = execFileSync(
|
||||
'bash',
|
||||
[path.join(scriptsDir, 'check-doc-coverage.sh'), '--strict'],
|
||||
{
|
||||
cwd: fixtureRoot,
|
||||
encoding: 'utf8',
|
||||
},
|
||||
);
|
||||
|
||||
expect(output).toContain('Doc Coverage: 0/0 adapters documented');
|
||||
expect(output).toContain('All adapters have documentation');
|
||||
});
|
||||
});
|
||||
@@ -102,6 +102,12 @@ describe('adapter imports use package exports', () => {
|
||||
});
|
||||
});
|
||||
|
||||
function expectRealFile(target: string) {
|
||||
const sourcePath = target.replace(/^\.\/dist\//, './').replace(/\.js$/, '.ts');
|
||||
const fullPath = path.join(ROOT, sourcePath);
|
||||
expect(fs.existsSync(fullPath), `Missing source: ${sourcePath}`).toBe(true);
|
||||
}
|
||||
|
||||
describe('package.json exports resolve to real files', () => {
|
||||
const pkgJson = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf-8'));
|
||||
const exports = pkgJson.exports as Record<string, string>;
|
||||
@@ -114,11 +120,7 @@ describe('package.json exports resolve to real files', () => {
|
||||
it(`export "${exportPath}" → ${target} has a source file`, () => {
|
||||
// Export targets point to dist/ (compiled). Verify the source .ts exists.
|
||||
// dist/src/foo.js → src/foo.ts
|
||||
const sourcePath = target
|
||||
.replace(/^\.\/dist\//, './')
|
||||
.replace(/\.js$/, '.ts');
|
||||
const fullPath = path.join(ROOT, sourcePath);
|
||||
expect(fs.existsSync(fullPath), `Missing source: ${sourcePath}`).toBe(true);
|
||||
expectRealFile(target);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ export default defineConfig({
|
||||
test: {
|
||||
name: 'unit',
|
||||
include: ['src/**/*.test.ts'],
|
||||
exclude: ['clis/**/*.test.ts'],
|
||||
exclude: ['src/clis/**/*.test.ts'],
|
||||
sequence: { groupOrder: 0 },
|
||||
},
|
||||
},
|
||||
@@ -23,7 +23,7 @@ export default defineConfig({
|
||||
{
|
||||
test: {
|
||||
name: 'adapter',
|
||||
include: ['clis/**/*.test.ts'],
|
||||
include: ['clis/**/*.test.js', 'src/clis/**/*.test.ts'],
|
||||
sequence: { groupOrder: 1 },
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user