Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.keyboardcontroller.KeyboardControllerNativeTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) KEYBOARD_CONTROLLER_NEW_ARCH_ENABLED";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
Expand All @@ -613,6 +614,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.keyboardcontroller.KeyboardControllerNativeTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) KEYBOARD_CONTROLLER_NEW_ARCH_ENABLED";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@
@testable import KeyboardControllerNative
import XCTest

#if KEYBOARD_CONTROLLER_NEW_ARCH_ENABLED
extension NSObject {
func safeValue(forKey key: String) -> Any? {
return value(forKey: key)
}
}

@objcMembers
private final class ReactSuperview: UIView {
dynamic var nativeId: String?
}
#endif

extension XCTestCase {
func waitForFocusChange(
to textField: TestableInput,
Expand Down Expand Up @@ -94,6 +107,29 @@ final class KeyboardControllerNativeTests: XCTestCase {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

#if KEYBOARD_CONTROLLER_NEW_ARCH_ENABLED
func testNativeIDReturnsNilForUIKitSuperviewWithoutNativeID() {
let superview = UIView()
let textField = UITextField()
superview.addSubview(textField)

let responder: UIResponder? = textField

XCTAssertNil(responder.nativeID)
}

func testNativeIDReadsReactSuperviewNativeID() {
let superview = ReactSuperview()
let textField = UITextField()
superview.nativeId = "react-view"
superview.addSubview(textField)

let responder: UIResponder? = textField

XCTAssertEqual(responder.nativeID, "react-view")
}
#endif
Comment on lines +110 to +131

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are testing mock implementation?

I don't think it makes a lot of sense to do that?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They exercise the actual Optional<UIResponder>.nativeID implementation from UIResponder.swift, which is compiled directly into the native test target. ReactSuperview is only a fixture that exposes the selector.

You're right that the test target supplies a safeValue stub because this standalone project does not currently link the production Objective-C SafeKVC helper. So these tests specifically cover the new guard:

  • a plain UIKit UIView returns nil before safeValue is called;
  • a view exposing nativeId passes the guard and is still read.

They do not cover the production NSObject+SafeKVC bridge itself. I can instead wire NSObject.swift and the Objective-C category into the native test target if you would prefer full production-path coverage over this isolated guard coverage.


func testSetFocusToNextShouldSetFocusToNextField() {
let textInput1 = textFields[0]
FocusedInputHolder.shared.set(textInput1)
Expand Down
1 change: 1 addition & 0 deletions ios/extensions/UIResponder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public extension Optional where Wrapped == UIResponder {
guard let superview = (self as? UIView)?.superview else { return nil }

#if KEYBOARD_CONTROLLER_NEW_ARCH_ENABLED
guard superview.responds(to: NSSelectorFromString("nativeId")) else { return nil }
return superview.safeValue(forKey: "nativeId") as? String
#else
return superview.nativeID
Expand Down