Skip to content

Commit

Permalink
don't provide custom class names (#114)
Browse files Browse the repository at this point in the history
* i knew better

* add test case

* remove half comment
  • Loading branch information
stevenbrix authored Oct 27, 2023
1 parent cf78185 commit 108f24a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 10 deletions.
14 changes: 5 additions & 9 deletions swiftwinrt/Resources/Support/WinRTProtocols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,10 @@ extension WinRTClass {
}

public func GetRuntimeClassName() -> HString {
if type(of: self) != Self.self {
// Aggregated, get a string describing the type of the Swift class instead.
// Use String(reflecting:) instead of NSStringFromClass because that doesn't
// crash on nested classes
let string = String(reflecting: type(of: self))
return try! HString(string)
} else {
return try! _inner.GetRuntimeClassName()
}
// always use the runtime class name of the inner WinRT object. the winui runtime will query for
// class names and if it isn't recognized, it will call out to IXamlMetadataProvider (IXMP)
// to get the associated XamlType. We aren't using Xaml for swift, so we don't actually
// need or want the framework to think it's dealing with custom types.
return try! _inner.GetRuntimeClassName()
}
}
20 changes: 19 additions & 1 deletion tests/test_app/AggregationTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import WinSDK
import XCTest
import test_component
@_spi(WinRTInternal) import test_component
import Ctest_component
import Foundation

Expand Down Expand Up @@ -91,11 +91,29 @@ class AggregationTests : XCTestCase {
let derived = UnsealedDerived(32)
XCTAssertEqual(derived.prop, 32)
}

public func runtimeClassName(_ base: Base) -> String {
return String(hString: base.GetRuntimeClassName())
}

public func testGetRuntimeClassNameReturnsBase() throws {
// WinUI calls GetRuntimeClassName when types are being constructed,
// so we need to return something that the runtime understands. Without an
// IXamlMetadataProvider implementation, returning custom type names will
// break the app.
let appDerived = AppDerived()

// In order to validate the test, we have to call GetRuntimeClassName on the base
// type. This will make the type check we had think we're being aggregated, where
// calling it directly on the AppDerived type won't
XCTAssertEqual(runtimeClassName(appDerived), "test_component.Base")
}
}

var aggregationTests: [XCTestCaseEntry] = [
testCase([
("testAggregation", AggregationTests.testAggregation),
("testCustomConstructorOnUnsealedType", AggregationTests.testCustomConstructorOnUnsealedType),
("testGetRuntimeClassNameReturnsBase", AggregationTests.testGetRuntimeClassNameReturnsBase)
])
]

0 comments on commit 108f24a

Please sign in to comment.