GitNexus/gitnexus/test/unit/objective-c-parser-loader.test.ts
mengkaka 4154b63131
feat(indexing): add Objective-C semantic indexing support (#3179)
* docs: add Objective-C fork provider notes

* feat(objective-c): add deterministic provider and grammar

* feat(objective-c): finalize provider MVP

* fix(objective-c): harden provider integration

* fix(objective-c): normalize bare macro markers

* docs(objective-c): integrate provider documentation

* fix(objective-c): harden resolution and header classification

* fix(objective-c): complete provider follow-ups

* fix: address Objective-C review follow-ups

* chore: format Objective-C grammar sources

* fix(objective-c): harden review follow-ups

* Address PR review feedback (#3179)

Keep Objective-C chunking and macro recovery aligned with the grammar, and stop Community MEMBER_OF edges from leaking into symbol context.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Address follow-up review on ObjC chunking and language fallback.

Keep preprocessor directive text from changing file-scope brace depth, group real ivar nodes, skip header modifiers, and restore Rakefile/Gemfile detection through getLanguageFromFilename.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Parse Objective-C headers with the objc grammar in embeddings.

ensureAndParse and structural extraction now use the same content classifier as ingest, including method snippets from .h files, so Protocol/Category/Class chunks are not re-parsed as C++.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Address PR review feedback (#3179)

Keep file-scope macro elision off C line splices and @interface/@protocol/@implementation bodies, and attach ivar attributes to the following instance variable when chunking.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(bench): rebaseline Objective-C CSV emit

* feat(objective-c): add workspace resolution and linear emit benches

Plain .h files are classified as C++, so the ObjC pass could not
resolve #import of those headers. Load a C/C#-style workspace once
per pass, and keep protocol-candidate USES linear.

Refs #3179

Co-authored-by: Cursor <cursoragent@cursor.com>

* Address PR review feedback (#3179)

- Compare LadybugDB labels() as a scalar when excluding Community MEMBER_OF edges.
- Walk superclass members, skip file-static C sibling defs, and ignore comments in ObjC header/macro scans.

Note: pre-existing failure in objective-c-provider integration (worker-pool ready timeout) not addressed by this PR.
Co-authored-by: Cursor <cursoragent@cursor.com>

* Address PR review feedback (#3179)

Emit Objective-C declaration captures so compilation-unit siblings can share
header/implementation bindings, and keep class vs protocol visibility groups
distinct.

Note: pre-existing failure in worker-pool startup (GITNEXUS_WORKER_READY_TIMEOUT_MS) not addressed by this PR.
Co-authored-by: Cursor <cursoragent@cursor.com>

* Address PR review feedback (#3179)

Emit every comma-separated property/ivar declarator, and count @interface
after a multiline block comment closes so in-declaration macros stay intact.

Note: pre-existing failure in worker-pool startup (GITNEXUS_WORKER_READY_TIMEOUT_MS) not addressed by this PR.
Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: ximengkai <ximengkai@soyoung.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-09 09:40:21 +00:00

65 lines
2.4 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from 'vitest';
import { SupportedLanguages } from '../../src/config/supported-languages.js';
describe('Objective-C parser-loader failure path', () => {
afterEach(() => {
vi.resetModules();
vi.doUnmock('../../src/core/logger.js');
vi.doUnmock('../../src/core/tree-sitter/vendored-grammars.js');
});
it('reports a clean unavailable Objective-C grammar with an actionable diagnostic', async () => {
const errorLog = vi.fn();
const warnLog = vi.fn();
vi.doMock('../../src/core/logger.js', () => ({
logger: {
error: errorLog,
warn: warnLog,
},
}));
vi.doMock('../../src/core/tree-sitter/vendored-grammars.js', () => ({
requireVendoredGrammar: (name: string) => {
if (name === 'tree-sitter-objc') throw new Error('synthetic missing objc grammar');
return {};
},
}));
const { getLanguageGrammar, isGrammarRuntimeSkipped, isLanguageAvailable } =
await import('../../src/core/tree-sitter/parser-loader.js');
expect(isLanguageAvailable(SupportedLanguages.ObjectiveC)).toBe(false);
expect(isGrammarRuntimeSkipped(SupportedLanguages.ObjectiveC)).toBe(false);
expect(() => getLanguageGrammar(SupportedLanguages.ObjectiveC)).toThrow(
/Unsupported language: objective-c/,
);
expect(warnLog).not.toHaveBeenCalled();
expect(String(errorLog.mock.calls[0]?.[0] ?? '')).toMatch(
/Objective-C parsing disabled[\s\S]*tree-sitter-objc[\s\S]*synthetic missing objc grammar/,
);
});
it('keeps explicit Objective-C headers out of the C++ fallback when the grammar is unavailable', async () => {
vi.doMock('../../src/core/tree-sitter/vendored-grammars.js', () => ({
requireVendoredGrammar: (name: string) => {
if (name === 'tree-sitter-objc') throw new Error('synthetic missing objc grammar');
return {};
},
}));
const { classifyObjectiveCFileContent } =
await import('../../src/core/ingestion/languages/objective-c.js');
expect(
classifyObjectiveCFileContent('ObjectiveC.h', '@interface ObjectiveC : NSObject\n@end\n'),
).toBe(true);
expect(classifyObjectiveCFileContent('PlainCpp.h', 'class Widget { int value; };\n')).toBe(
false,
);
expect(
classifyObjectiveCFileContent(
'Comment.h',
'// @interface Comment : NSObject\nconst char *x = "@protocol";\n',
),
).toBe(false);
});
});