mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-14 04:08:05 +00:00
fix(r): flag an unreadable DESCRIPTION as truncated and tighten three R test assertions
An unreadable DESCRIPTION left RPackageConfig.truncated false, so a qualifier naming the package it declares was classed external and its call site dropped. The sibling hidesUndiscoveredPackage case already treats an unreadable DESCRIPTION as unknown; do the same here and cover it with a test. Tighten three weak test assertions: the escaped-bracket export pattern now asserts its exact match results, the S4 anchors test proves each generic is defined exactly once, and the worker owner-absence test fails on any defined ownerId, including an empty string.
This commit is contained in:
parent
3b478e4c46
commit
37efc888fc
5 changed files with 36 additions and 5 deletions
|
|
@ -383,7 +383,8 @@ export async function loadRPackageConfig(repoRoot: string): Promise<RPackageConf
|
|||
}
|
||||
}
|
||||
} catch {
|
||||
// Can't read DESCRIPTION
|
||||
// Can't read DESCRIPTION: the package it declares was not discovered.
|
||||
truncated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ describe.skipIf(!hasDistWorker)('R worker never emits an owner id (before post-p
|
|||
let hintedMembers = 0;
|
||||
graph.forEachNode((n) => {
|
||||
if (n.properties.language !== 'r') return;
|
||||
if (typeof n.properties.ownerId === 'string') ownedNodes++;
|
||||
if (n.properties.ownerId !== undefined) ownedNodes++;
|
||||
if (
|
||||
(n.label === 'Method' || n.label === 'Property') &&
|
||||
typeof n.properties.ownerNameHint === 'string'
|
||||
|
|
@ -88,7 +88,7 @@ describe.skipIf(!hasDistWorker)('R worker never emits an owner id (before post-p
|
|||
for (const result of raw) {
|
||||
for (const symbol of result.symbols) {
|
||||
symbols++;
|
||||
if (symbol.ownerId) ownedSymbols++;
|
||||
if (symbol.ownerId !== undefined) ownedSymbols++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ describe('R S4/RefClass definitions are named by their first argument only', ()
|
|||
|
||||
it('defines the generics once, with no Function from valueClass = "numeric"', () => {
|
||||
const functions = getNodesByLabel(result, 'Function');
|
||||
expect(functions).toContain('describe');
|
||||
expect(functions).toContain('summarise');
|
||||
expect(functions.filter((n) => n === 'describe')).toHaveLength(1);
|
||||
expect(functions.filter((n) => n === 'summarise')).toHaveLength(1);
|
||||
expect(functions).not.toContain('numeric');
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,12 @@ describe('compileRExportPattern', () => {
|
|||
});
|
||||
|
||||
it('does not treat an escaped bracket as a bracket expression', () => {
|
||||
// `\[` is a literal bracket; the rest is an ordinary one-character class of `:alph`,
|
||||
// so the pattern compiles (to itself) and matches `[` plus exactly one of those characters.
|
||||
expect(compileRExportPattern('^\\[[:alpha:]$')?.source).toBe('^\\[[:alpha:]$');
|
||||
expect(matches('^\\[[:alpha:]$', '[a')).toBe(true);
|
||||
expect(matches('^\\[[:alpha:]$', '[:')).toBe(true);
|
||||
expect(matches('^\\[[:alpha:]$', '[b')).toBe(false);
|
||||
expect(matches('^\\[[:alpha:]$', '[:alpha:')).toBe(false);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -369,6 +369,30 @@ describe('loadRPackageConfig: truncation only when a skipped subtree hides an un
|
|||
if (locked) await fs.chmod(locked, 0o755).catch(() => undefined);
|
||||
}
|
||||
});
|
||||
|
||||
it('an unreadable DESCRIPTION is truncated, so its qualifier stays unknown', async () => {
|
||||
if (typeof process.getuid === 'function' && process.getuid() === 0) return; // root reads anything
|
||||
let locked = '';
|
||||
try {
|
||||
const cfg = await withRepo(async (root) => {
|
||||
locked = path.join(root, 'sub', 'DESCRIPTION');
|
||||
await writePkg(path.join(root, 'sub'), 'hiddenpkg');
|
||||
await fs.chmod(locked, 0o000);
|
||||
// Guard: a platform that still reads a mode-000 file cannot exercise the catch.
|
||||
await fs.readFile(locked).then(
|
||||
() => {
|
||||
throw new Error('DESCRIPTION is still readable; cannot simulate an I/O error');
|
||||
},
|
||||
() => undefined,
|
||||
);
|
||||
});
|
||||
expect(cfg?.packages.has('hiddenpkg')).toBe(false);
|
||||
expect(cfg?.truncated).toBe(true);
|
||||
expect(rQualifierLocality('hiddenpkg', cfg as RPackageConfig, new Set())).toBe('unknown');
|
||||
} finally {
|
||||
if (locked) await fs.chmod(locked, 0o644).catch(() => undefined);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('hidesUndiscoveredPackage', () => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue