Extracted from gtk-swift monorepo. Previous history contains 38 commits across the full Phase 1 development including GIR XML parsing, IR model, analysis engine, code generation, CLI, plugins, and documentation.
99 lines
5.1 KiB
Swift
99 lines
5.1 KiB
Swift
import Testing
|
|
@testable import SwiftGtkGenCore
|
|
|
|
@Test("Generates a simple class wrapper")
|
|
func testGenerateClass() throws {
|
|
let repo = Repository(namespaces: [
|
|
Namespace(name: "GLib", version: "2.0", classes: [
|
|
Class(name: "String", cType: "GString", parent: nil,
|
|
constructors: [
|
|
Constructor(name: "new", cIdentifier: "g_string_new",
|
|
parameters: [
|
|
Parameter(name: "init", type: .string, transferOwnership: .none)
|
|
], returnType: .typeRef("String"))
|
|
],
|
|
methods: [
|
|
Method(name: "assign", cIdentifier: "g_string_assign",
|
|
parameters: [
|
|
Parameter(name: "string", type: .string, isNullable: false,
|
|
transferOwnership: .none, isInstanceParameter: true),
|
|
Parameter(name: "value", type: .string)
|
|
], returnType: .typeRef("String"))
|
|
], properties: [
|
|
Property(name: "length", type: .int32, isReadable: true, isWritable: false)
|
|
], signals: [
|
|
Signal(name: "changed", parameters: [], returnType: .void)
|
|
])
|
|
])
|
|
])
|
|
let config = GenerationConfig(library: "GLib", version: "2.0", girsDirectories: [],
|
|
targetDirectory: "", externalLibraries: [],
|
|
generate: ["GLib.String"], manual: [], ignore: [], objects: [])
|
|
let generator = CodeGenerator(config: config)
|
|
let files = try generator.generateFiles(repository: repo, analysis: Analyzer(config: config).analyze(repository: repo))
|
|
|
|
let output = files["String.swift"] ?? ""
|
|
#expect(output.contains("public final class String"))
|
|
#expect(output.contains("convenience init"))
|
|
#expect(output.contains("g_string_new(`init`)"))
|
|
#expect(output.contains("func assign"))
|
|
#expect(output.contains("g_value_get_int"))
|
|
#expect(output.contains("connectChanged"))
|
|
#expect(output.contains("g_signal_connect_data"))
|
|
// Verify real C function call instead of fatalError
|
|
#expect(output.contains("g_string_assign(pointer, value)"))
|
|
#expect(!output.contains("fatalError(\"g_object_get_property"))
|
|
#expect(!output.contains("fatalError(\"g_object_set_property"))
|
|
#expect(!output.contains("fatalError(\"C function call not yet implemented"))
|
|
}
|
|
|
|
@Test("Kebab-case property names are converted to camelCase")
|
|
func testKebabCaseToCamelCase() throws {
|
|
let repo = Repository(namespaces: [
|
|
Namespace(name: "Gtk", version: "4.0", classes: [
|
|
Class(name: "Box", cType: "GtkBox", parent: "Widget",
|
|
properties: [
|
|
Property(name: "baseline-child", type: .int32, isReadable: true, isWritable: true),
|
|
Property(name: "baseline-position", type: .int32, isReadable: true, isWritable: false),
|
|
Property(name: "homogeneous", type: .boolean, isReadable: true, isWritable: true),
|
|
Property(name: "spacing", type: .int32, isReadable: true, isWritable: true),
|
|
])
|
|
])
|
|
])
|
|
let config = GenerationConfig(library: "Gtk", version: "4.0", girsDirectories: [],
|
|
targetDirectory: "", externalLibraries: [],
|
|
generate: ["Gtk.Box"], manual: [], ignore: [], objects: [])
|
|
let generator = CodeGenerator(config: config)
|
|
let files = try generator.generateFiles(repository: repo, analysis: Analyzer(config: config).analyze(repository: repo))
|
|
|
|
let output = files["Box.swift"] ?? ""
|
|
#expect(output.contains("var baselineChild"), "baseline-child should become baselineChild")
|
|
#expect(output.contains("var baselinePosition"), "baseline-position should become baselinePosition")
|
|
#expect(output.contains("var homogeneous"), "homogeneous should stay as-is (no hyphens)")
|
|
#expect(output.contains("var spacing"), "spacing should stay as-is")
|
|
// Verify no kebab-case names remain in var declarations
|
|
#expect(!output.contains("var baseline-"), "No kebab-case var names should remain")
|
|
}
|
|
|
|
@Test("Generates enumeration")
|
|
func testGenerateEnum() throws {
|
|
let repo = Repository(namespaces: [
|
|
Namespace(name: "Gtk", version: "4.0", enumerations: [
|
|
Enumeration(name: "Align", cType: "GtkAlign",
|
|
members: [
|
|
EnumMember(name: "fill", value: "0", cIdentifier: "GTK_ALIGN_FILL"),
|
|
EnumMember(name: "start", value: "1", cIdentifier: "GTK_ALIGN_START"),
|
|
])
|
|
])
|
|
])
|
|
let config = GenerationConfig(library: "Gtk", version: "4.0", girsDirectories: [],
|
|
targetDirectory: "", externalLibraries: [],
|
|
generate: ["Gtk.Align"], manual: [], ignore: [], objects: [])
|
|
let generator = CodeGenerator(config: config)
|
|
let files = try generator.generateFiles(repository: repo, analysis: Analyzer(config: config).analyze(repository: repo))
|
|
|
|
let output = files["Align.swift"] ?? ""
|
|
#expect(output.contains("public enum Align"))
|
|
#expect(output.contains("case fill"))
|
|
#expect(output.contains("case start"))
|
|
}
|