test: add assertion bodies to known limitation skip tests

Convert empty skip test stubs to proper tests with parse/buildTypeEnv/expect
assertions following the codebase convention (e.g., call-processor.test.ts:319).
Each skip test now documents the exact expected behavior, so removing .skip
will cause a meaningful failure when the limitation is eventually fixed.

Also clarify Python integration skip tests as call-extraction issues (not
type-env) and Swift integration skips as build-dep issues (self/super
resolution code already exists in type-env.ts).
This commit is contained in:
Gergo Magyar 2026-03-16 23:13:05 +00:00
parent f1df9a12c1
commit 5f12ffccf2
3 changed files with 70 additions and 11 deletions

View file

@ -986,9 +986,10 @@ describe('Python match/case as-pattern type binding', () => {
expect(true).toBe(true);
});
// Skip: tree-sitter-python match_statement call extraction needs query updates
// Type-env binding works (unit test passes), but calls inside case_clause blocks
// are not captured by the current call extraction queries.
// Skip: call extraction issue, NOT a type-env limitation.
// Type-env binding works correctly (unit test passes). The root cause is likely
// in call-processor's findEnclosingFunction scope resolution within match_statement
// blocks, not the tree-sitter query patterns (which descend recursively by default).
it.skip('resolves u.save() to User#save via match/case as-pattern binding', () => {
const calls = getRelationships(result, 'CALLS');
const userSave = calls.find(c =>

View file

@ -57,7 +57,8 @@ describe.skipIf(!swiftAvailable)('Swift constructor-inferred type resolution', (
// ---------------------------------------------------------------------------
// self.save() resolves to enclosing class's own save method
// Known issue: tree-sitter-swift has build issues on Node 22
// Build-dep issue (NOT a feature gap): tree-sitter-swift has build issues on Node 22.
// The self/super resolution code already exists in type-env.ts lookupInEnv (lines 56-66).
// ---------------------------------------------------------------------------
describe.skip('Swift self resolution', () => {
@ -86,7 +87,8 @@ describe.skip('Swift self resolution', () => {
// ---------------------------------------------------------------------------
// Parent class resolution: EXTENDS + protocol conformance
// Known issue: tree-sitter-swift has build issues on Node 22
// Build-dep issue (NOT a feature gap): tree-sitter-swift has build issues on Node 22.
// findEnclosingParentClassName in type-env.ts already has Swift inheritance_specifier handler.
// ---------------------------------------------------------------------------
describe.skip('Swift parent resolution', () => {

View file

@ -2928,25 +2928,81 @@ class Foo {
});
});
// These tests document capabilities we intentionally do not support yet.
// Each skip test has assertions that should pass once the feature is implemented.
// When a skip test starts passing, remove .skip and update the corresponding issue.
describe('known limitations (documented skip tests)', () => {
it.skip('TS destructured for-of: for (const [k, v] of entries) — requires tuple destructuring', () => {
// extractVarName returns undefined for array_pattern
// extractVarName returns undefined for array_pattern; also needs
// resolveIterableElementType to return tuple types and ForLoopExtractor
// type signature to support multi-variable binding
const tree = parse(`
function process(entries: Map<string, User>) {
for (const [key, user] of entries) {
user.save();
}
}
`, TypeScript);
const { env } = buildTypeEnv(tree, 'typescript');
expect(flatGet(env, 'user')).toBe('User');
});
it.skip('Python tuple unpacking: for key, value in dict.items() — requires pattern_list', () => {
// left is pattern_list, not identifier
it.skip('Python tuple unpacking: for key, value in dict.items() — requires pattern_list + method call iterable', () => {
// Left side is pattern_list, not identifier (needs Group A: tuple destructuring).
// Right side is call_expression .items() (needs Group C: method call iterable resolution).
const tree = parse(`
def process(data: dict[str, User]):
for key, user in data.items():
user.save()
`, Python);
const { env } = buildTypeEnv(tree, 'python');
expect(flatGet(env, 'user')).toBe('User');
});
it.skip('TS instanceof narrowing: if (x instanceof User) { x.save() } — needs block-level scoping', () => {
// Narrows existing variable, does not introduce new one
// Narrows existing variable within a block, does not introduce a new one.
// Requires scope stack infrastructure (push/pop on block entry/exit) and
// type guard recognition. TS parses instanceof as binary_expression, not
// a dedicated node type.
const tree = parse(`
function process(x: unknown) {
if (x instanceof User) {
x.save();
}
}
`, TypeScript);
const { env } = buildTypeEnv(tree, 'typescript');
// x should be narrowed to User inside the if-block
expect(flatGet(env, 'x')).toBe('User');
});
it.skip('Rust for with .iter(): for user in users.iter() — needs method call iterable resolution', () => {
// Iterable is a call_expression, not an identifier
// Iterable is a call_expression, not an identifier. In idiomatic Rust,
// .iter()/.into_iter()/.iter_mut() is the dominant iteration pattern —
// the plain identifier form (which IS supported) is less common.
const tree = parse(`
fn process(users: Vec<User>) {
for user in users.iter() {
user.save();
}
}
`, Rust);
const { env } = buildTypeEnv(tree, 'rust');
expect(flatGet(env, 'user')).toBe('User');
});
it.skip('Ruby block parameter: users.each { |user| } — closure param inference, different feature', () => {
// Not a for-loop; requires block/closure parameter inference
// Not a for-loop; .each { |user| } is a method call with a block.
// Requires closure parameter inference — a different feature category
// applicable to Ruby, Swift closures, Kotlin lambdas, and Java lambdas.
// Depends on method call resolution (Group C) as prerequisite.
const tree = parse(`
def process(users)
users.each { |user| user.save }
end
`, Ruby);
const { env } = buildTypeEnv(tree, 'ruby');
expect(flatGet(env, 'user')).toBe('User');
});
});