131 lines
3.5 KiB
TypeScript
131 lines
3.5 KiB
TypeScript
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);
|
|
});
|
|
});
|