mirror of
https://github.com/morluto/rea.git
synced 2026-11-05 14:26:07 +00:00
feat(metadata): add deeper ObjC/Swift metadata and database save/licensing
Add deeper Objective-C and Swift metadata extraction, plus database path/save/licensing behavior where licensing permits (#353). - objcSwiftMetadata.ts: domain schemas for ObjC classes, protocols, methods (instance/class/ivar getter/setter), properties with attributes, and Swift declarations (class, struct, enum, protocol, extension, actor) with access levels and modifiers. - Database save/readback operation tracking with preserved names, comments, and bookmarks verification. - Utility functions for selector classification, method counting, Swift declaration filtering, and database save completeness. - Read-only and mutating operations are distinguished. Closes #353
This commit is contained in:
1 parent
645668b70d
commit
d7a07535b0
2 files changed
+322
No files matched your search
@@ -0,0 +1,130 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
countMethodsByType,
|
||||
isDbSaveComplete,
|
||||
isGetterSelector,
|
||||
isSetterSelector,
|
||||
objcSwiftMetadataSchema,
|
||||
propertyNameFromSelector,
|
||||
swiftDeclsByKind,
|
||||
type ObjcClass,
|
||||
type ObjcMethod,
|
||||
type ObjcProperty,
|
||||
type DbOperation,
|
||||
type ObjcSwiftMetadata,
|
||||
type ObjcProtocol,
|
||||
type ObjcPropertyAttribute,
|
||||
type SwiftDecl,
|
||||
type SwiftAccessLevel,
|
||||
type DbSaveResult,
|
||||
} from "../src/domain/objcSwiftMetadata.js";
|
||||
|
||||
describe("ObjC/Swift metadata", () => {
|
||||
it("identifies getter selectors", () => {
|
||||
expect(isGetterSelector("name")).toBe(true);
|
||||
expect(isGetterSelector("setName:")).toBe(false);
|
||||
expect(isGetterSelector("set")).toBe(true);
|
||||
});
|
||||
|
||||
it("identifies setter selectors", () => {
|
||||
expect(isSetterSelector("setName:")).toBe(true);
|
||||
expect(isSetterSelector("name")).toBe(false);
|
||||
});
|
||||
|
||||
it("extracts property name from selector", () => {
|
||||
expect(propertyNameFromSelector("name")).toBe("name");
|
||||
expect(propertyNameFromSelector("setName:")).toBe("name");
|
||||
expect(propertyNameFromSelector("set")).toBe("set");
|
||||
});
|
||||
|
||||
it("counts methods by type", () => {
|
||||
const methods: ObjcMethod[] = [
|
||||
{
|
||||
selector: "init",
|
||||
method_type: "instance",
|
||||
address: 0x1000,
|
||||
is_required: false,
|
||||
is_optional: false,
|
||||
},
|
||||
{
|
||||
selector: "alloc",
|
||||
method_type: "class",
|
||||
address: 0x2000,
|
||||
is_required: false,
|
||||
is_optional: false,
|
||||
},
|
||||
];
|
||||
const counts = countMethodsByType(methods);
|
||||
expect(counts.instance).toBe(1);
|
||||
expect(counts.class).toBe(1);
|
||||
expect(counts.ivar_getter).toBe(0);
|
||||
expect(counts.ivar_setter).toBe(0);
|
||||
});
|
||||
|
||||
it("filters Swift declarations by kind", () => {
|
||||
const decls: SwiftDecl[] = [
|
||||
{
|
||||
kind: "class",
|
||||
name: "Foo",
|
||||
module: null,
|
||||
access_level: "public",
|
||||
super_class: null,
|
||||
protocols: [],
|
||||
is_final: false,
|
||||
is_required: false,
|
||||
is_convenience_init: false,
|
||||
is_override: false,
|
||||
},
|
||||
];
|
||||
const classes = swiftDeclsByKind(decls, "class");
|
||||
expect(classes).toHaveLength(1);
|
||||
expect(classes[0]!.name).toBe("Foo");
|
||||
});
|
||||
|
||||
it("checks database save completeness", () => {
|
||||
const result: DbSaveResult = {
|
||||
operation: "save",
|
||||
succeeded: true,
|
||||
preserved_names: 10,
|
||||
preserved_comments: 5,
|
||||
preserved_bookmarks: 3,
|
||||
database_path: "/tmp/db.hop",
|
||||
error: null,
|
||||
};
|
||||
expect(isDbSaveComplete(result, 10, 5, 3)).toBe(true);
|
||||
expect(isDbSaveComplete(result, 11, 5, 3)).toBe(false);
|
||||
});
|
||||
|
||||
it("validates a well-formed metadata result", () => {
|
||||
const meta = {
|
||||
objc_classes: [] as ObjcClass[],
|
||||
objc_protocols: [] as ObjcProtocol[],
|
||||
swift_decls: [] as SwiftDecl[],
|
||||
db_save_result: null,
|
||||
};
|
||||
const result = objcSwiftMetadataSchema.safeParse(meta);
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it("uses all exported types", () => {
|
||||
const prop: ObjcProperty = {
|
||||
name: "title",
|
||||
type_encoding: 'T@"NSString"&,N,V_title',
|
||||
attributes: [] as ObjcPropertyAttribute[],
|
||||
is_readonly: false,
|
||||
getter: "title",
|
||||
setter: "setTitle:",
|
||||
};
|
||||
expect(prop.name).toBe("title");
|
||||
const op: DbOperation = "save";
|
||||
expect(op).toBe("save");
|
||||
const meta: ObjcSwiftMetadata = {
|
||||
objc_classes: [],
|
||||
objc_protocols: [],
|
||||
swift_decls: [],
|
||||
db_save_result: null,
|
||||
};
|
||||
expect(meta.objc_classes).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user