5#import <OCMock/OCMock.h>
6#import <XCTest/XCTest.h>
20@interface SemanticsObject (UIFocusSystem) <UIFocusItem, UIFocusItemContainer>
23@interface FlutterScrollableSemanticsObject (UIFocusItemScrollableContainer) <
24 UIFocusItemScrollableContainer>
27@interface TextInputSemanticsObject (Test)
28- (UIView<UITextInput>*)textInputSurrogate;
41 XCTAssertNotNil(
object);
44- (void)testUIFocusSystemMethodsDoNotCrashWhenBridgeIsDead {
48 auto mock_bridge = std::make_unique<flutter::testing::MockAccessibilityBridge>();
55 XCTAssertNil([
object parentFocusEnvironment]);
56 XCTAssertNil([
object coordinateSpace]);
57 XCTAssertTrue(CGRectEqualToRect([
object frame], CGRectZero));
60- (void)testSetChildren {
67 XCTAssertEqual(parent, child.
parent);
69 XCTAssertNil(child.
parent);
72- (void)testAccessibilityHitTestFocusAtLeaf {
82 object1.
children = @[ object2, object3 ];
87 node0.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
93 node1.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
99 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
105 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
109 CGPoint point = CGPointMake(10, 10);
113 XCTAssertEqual(hitTestResult, object2);
116- (void)testAccessibilityHitTestNoFocusableItem {
126 object1.
children = @[ object2, object3 ];
131 node0.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
136 node1.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
141 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
146 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
149 CGPoint point = CGPointMake(10, 10);
152 XCTAssertNil(hitTestResult);
155- (void)testAccessibilityScrollToVisible {
163 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
168 XCTAssertTrue(bridge->observations.size() == 1);
169 XCTAssertTrue(bridge->observations[0].id == 3);
173- (void)testFlutterScrollableSemanticsObjectIsNotAccessibilityElementWhenVoiceOverIsRunning {
175 mock->isVoiceOverRunningValue =
true;
185 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
196 XCTAssertFalse(scrollView.isAccessibilityElement);
199- (void)testAccessibilityScrollToVisibleWithChild {
207 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
212 XCTAssertTrue(bridge->observations.size() == 1);
213 XCTAssertTrue(bridge->observations[0].id == 3);
217- (void)testAccessibilityHitTestOutOfRect {
227 object1.
children = @[ object2, object3 ];
232 node0.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
238 node1.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
244 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
250 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
254 CGPoint point = CGPointMake(300, 300);
257 XCTAssertNil(hitTestResult);
260- (void)testReplaceChildAtIndex {
269 XCTAssertNil(child1.
parent);
270 XCTAssertEqual(parent, child2.
parent);
271 XCTAssertEqualObjects(parent.
children, @[ child2 ]);
274- (void)testPlainSemanticsObjectWithLabelHasStaticTextTrait {
282 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitStaticText);
285- (void)testNodeWithImplicitScrollIsAnAccessibilityElementWhenItisHidden {
295 XCTAssertEqual(
object.isAccessibilityElement, YES);
298- (void)testNodeWithImplicitScrollIsNotAnAccessibilityElementWhenItisNotHidden {
306 XCTAssertEqual(
object.isAccessibilityElement, NO);
309- (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait {
319 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);
322- (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait1 {
331 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);
334- (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait2 {
344 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitButton);
347- (void)testVerticalFlutterScrollableSemanticsObject {
352 float transformScale = 0.5f;
353 float screenScale = [[bridge->view() window] screen].scale;
354 float effectivelyScale = transformScale / screenScale;
359 float scrollExtentMax = 500.0;
360 float scrollPosition = 150.0;
365 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
369 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
378 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
380 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
383 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
385 XCTAssertEqualWithAccuracy(scrollView.contentSize.height,
388 XCTAssertEqual(scrollView.contentOffset.x, 0);
389 XCTAssertEqualWithAccuracy(scrollView.contentOffset.y, scrollPosition * effectivelyScale,
393- (void)testVerticalFlutterScrollableSemanticsObjectNoWindowDoesNotCrash {
398 float transformScale = 0.5f;
403 float scrollExtentMax = 500.0;
404 float scrollPosition = 150.0;
409 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
413 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
418 XCTAssertNoThrow([scrollable accessibilityBridgeDidFinishUpdate]);
421- (void)testHorizontalFlutterScrollableSemanticsObject {
426 float transformScale = 0.5f;
427 float screenScale = [[bridge->view() window] screen].scale;
428 float effectivelyScale = transformScale / screenScale;
433 float scrollExtentMax = 500.0;
434 float scrollPosition = 150.0;
439 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
443 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
452 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
454 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
457 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, (w + scrollExtentMax) * effectivelyScale,
459 XCTAssertEqualWithAccuracy(scrollView.contentSize.height, h * effectivelyScale,
462 XCTAssertEqualWithAccuracy(scrollView.contentOffset.x, scrollPosition * effectivelyScale,
464 XCTAssertEqual(scrollView.contentOffset.y, 0);
467- (void)testCanHandleInfiniteScrollExtent {
472 float transformScale = 0.5f;
473 float screenScale = [[bridge->view() window] screen].scale;
474 float effectivelyScale = transformScale / screenScale;
479 float scrollExtentMax = INFINITY;
480 float scrollPosition = 150.0;
485 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
489 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
497 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
499 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
502 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
504 XCTAssertEqualWithAccuracy(scrollView.contentSize.height,
508 XCTAssertEqual(scrollView.contentOffset.x, 0);
509 XCTAssertEqualWithAccuracy(scrollView.contentOffset.y, scrollPosition * effectivelyScale,
513- (void)testCanHandleNaNScrollExtentAndScrollPoisition {
518 float transformScale = 0.5f;
519 float screenScale = [[bridge->view() window] screen].scale;
520 float effectivelyScale = transformScale / screenScale;
525 float scrollExtentMax = std::nan(
"");
526 float scrollPosition = std::nan(
"");
531 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
535 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
544 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
546 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
550 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
552 XCTAssertEqualWithAccuracy(scrollView.contentSize.height, h * effectivelyScale,
555 XCTAssertEqual(scrollView.contentOffset.x, 0);
556 XCTAssertEqual(scrollView.contentOffset.y, 0);
559- (void)testFlutterScrollableSemanticsObjectIsNotHittestable {
567 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
576 XCTAssertEqual([scrollView hitTest:CGPointMake(10, 10) withEvent:nil], nil);
579- (void)testFlutterScrollableSemanticsObjectIsHiddenWhenVoiceOverIsRunning {
581 mock->isVoiceOverRunningValue =
false;
588 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
597 XCTAssertTrue(scrollView.isAccessibilityElement);
598 mock->isVoiceOverRunningValue =
true;
599 XCTAssertFalse(scrollView.isAccessibilityElement);
602- (void)testFlutterSemanticsObjectHasIdentifier {
604 mock->isVoiceOverRunningValue =
true;
613 XCTAssertTrue([
object.accessibilityIdentifier isEqualToString:
@"identifier"]);
616- (void)testFlutterSemanticsObjectHasLocale {
618 mock->isVoiceOverRunningValue =
true;
627 XCTAssertTrue([
object.accessibilityLanguage isEqualToString:
@"es-MX"]);
630- (void)testFlutterSemanticsObjectUseDefaultLocale {
632 mock->isVoiceOverRunningValue =
true;
637 mock->mockedLocale =
@"es-MX";
641 XCTAssertTrue([
object.accessibilityLanguage isEqualToString:
@"es-MX"]);
644- (void)testFlutterSemanticsObjectPrioritizedSectionLocale {
646 mock->isVoiceOverRunningValue =
true;
652 mock->mockedLocale =
@"es-MX";
658 XCTAssertTrue([
object.accessibilityLanguage isEqualToString:
@"zh-TW"]);
661- (void)testFlutterSemanticsObjectLocaleNil {
663 mock->isVoiceOverRunningValue =
true;
671 XCTAssertTrue(
object.accessibilityLanguage == nil);
674- (void)testFlutterScrollableSemanticsObjectWithLabelValueHintIsNotHiddenWhenVoiceOverIsRunning {
676 mock->isVoiceOverRunningValue =
true;
683 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
684 node.
label =
"label";
685 node.
value =
"value";
695 XCTAssertTrue(scrollView.isAccessibilityElement);
697 [scrollView.accessibilityLabel isEqualToString:NSLocalizedString(
@"label",
@"test")]);
699 [scrollView.accessibilityValue isEqualToString:NSLocalizedString(
@"value",
@"test")]);
700 XCTAssertTrue([scrollView.accessibilityHint isEqualToString:NSLocalizedString(
@"hint",
@"test")]);
703- (void)testFlutterSemanticsObjectMergeTooltipToLabel {
705 mock->isVoiceOverRunningValue =
true;
710 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
711 node.
label =
"label";
715 XCTAssertTrue(
object.isAccessibilityElement);
716 XCTAssertTrue([
object.accessibilityLabel isEqualToString:
@"label\ntooltip"]);
719- (void)testSemanticsObjectContainerAccessibilityFrameCoversEntireScreen {
721 mock->isVoiceOverRunningValue =
true;
732 child.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
743 parentObject.
children = @[ childObject ];
750 XCTAssertTrue(childObject.accessibilityRespondsToUserInteraction);
751 XCTAssertTrue(CGRectEqualToRect(container.accessibilityFrame, UIScreen.mainScreen.bounds));
754- (void)testFlutterSemanticsObjectAttributedStringsDoNotCrashWhenEmpty {
756 mock->isVoiceOverRunningValue =
true;
761 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
764 XCTAssertTrue(
object.accessibilityAttributedLabel == nil);
767- (void)testFlutterScrollableSemanticsObjectReturnsParentContainerIfNoChildren {
769 mock->isVoiceOverRunningValue =
true;
775 parent.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
776 parent.
label =
"label";
777 parent.
value =
"value";
778 parent.
hint =
"hint";
784 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
785 node.
label =
"label";
786 node.
value =
"value";
801 parentObject.
children = @[ scrollable ];
804 XCTAssertTrue(scrollView.isAccessibilityElement);
810- (void)testFlutterScrollableSemanticsObjectNoScrollBarOrContentInsets {
818 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
828 XCTAssertFalse(scrollView.showsHorizontalScrollIndicator);
829 XCTAssertFalse(scrollView.showsVerticalScrollIndicator);
830 XCTAssertEqual(scrollView.contentInsetAdjustmentBehavior,
831 UIScrollViewContentInsetAdjustmentNever);
832 XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(scrollView.contentInset, UIEdgeInsetsZero));
835- (void)testSemanticsObjectBuildsAttributedString {
840 node.
label =
"label";
841 std::shared_ptr<flutter::SpellOutStringAttribute> attribute =
842 std::make_shared<flutter::SpellOutStringAttribute>();
843 attribute->start = 1;
847 node.
value =
"value";
848 attribute = std::make_shared<flutter::SpellOutStringAttribute>();
849 attribute->start = 2;
854 std::shared_ptr<flutter::LocaleStringAttribute> local_attribute =
855 std::make_shared<flutter::LocaleStringAttribute>();
856 local_attribute->start = 3;
857 local_attribute->end = 4;
859 local_attribute->locale =
"en-MX";
863 NSMutableAttributedString* expectedAttributedLabel =
864 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"label", @"test")];
865 NSDictionary* attributeDict = @{
866 UIAccessibilitySpeechAttributeSpellOut : @YES,
868 [expectedAttributedLabel setAttributes:attributeDict range:NSMakeRange(1, 1)];
870 [
object.accessibilityAttributedLabel isEqualToAttributedString:expectedAttributedLabel]);
872 NSMutableAttributedString* expectedAttributedValue =
873 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"value", @"test")];
875 UIAccessibilitySpeechAttributeSpellOut : @YES,
877 [expectedAttributedValue setAttributes:attributeDict range:NSMakeRange(2, 1)];
879 [
object.accessibilityAttributedValue isEqualToAttributedString:expectedAttributedValue]);
881 NSMutableAttributedString* expectedAttributedHint =
882 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"hint", @"test")];
884 UIAccessibilitySpeechAttributeLanguage :
@"en-MX",
886 [expectedAttributedHint setAttributes:attributeDict range:NSMakeRange(3, 1)];
888 [
object.accessibilityAttributedHint isEqualToAttributedString:expectedAttributedHint]);
891- (void)testShouldTriggerAnnouncement {
898 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:nil]);
904 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&node]);
908 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:nil]);
911 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:&node]);
916 updatedNode.label =
"bar";
917 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&updatedNode]);
921 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:&updatedNode]);
924 updatedNode.label =
"foo";
926 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&node]);
929- (void)testShouldDispatchShowOnScreenActionForHeader {
943 [object accessibilityElementDidBecomeFocused];
945 XCTAssertTrue(bridge->observations.size() == 1);
946 XCTAssertTrue(bridge->observations[0].id == 1);
950- (void)testShouldDispatchShowOnScreenActionForHidden {
964 [object accessibilityElementDidBecomeFocused];
966 XCTAssertTrue(bridge->observations.size() == 1);
967 XCTAssertTrue(bridge->observations[0].id == 1);
971- (void)testFlutterSwitchSemanticsObjectMatchesUISwitch {
985 UISwitch* nativeSwitch = [[UISwitch alloc] init];
986 nativeSwitch.on = YES;
988 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
989 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
996 update.
label =
"foo";
999 nativeSwitch.on = NO;
1001 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
1002 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
1005- (void)testFlutterSemanticsObjectOfRadioButton {
1018 XCTAssertTrue((
object.accessibilityTraits & UIAccessibilityTraitButton) > 0);
1019 XCTAssertNil(
object.accessibilityValue);
1022- (void)testFlutterSwitchSemanticsObjectMatchesUISwitchDisabled {
1035 UISwitch* nativeSwitch = [[UISwitch alloc] init];
1036 nativeSwitch.on = YES;
1037 nativeSwitch.enabled = NO;
1039 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
1040 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
1043- (void)testSemanticsObjectDeallocated {
1054 XCTAssertNil(weakObject);
1057- (void)testFlutterSemanticsObjectReturnsNilContainerWhenBridgeIsNotAlive {
1064 parent.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1065 parent.
label =
"label";
1066 parent.
value =
"value";
1067 parent.
hint =
"hint";
1073 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1074 node.
label =
"label";
1075 node.
value =
"value";
1083 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1084 node2.
label =
"label";
1085 node2.
value =
"value";
1086 node2.
hint =
"hint";
1094 mock->isVoiceOverRunningValue =
true;
1108 parentObject.
children = @[ scrollable, object2 ];
1123 XCTAssertNil(scrollable.accessibilityContainer);
1124 XCTAssertNil(object2.accessibilityContainer);
1127- (void)testAccessibilityHitTestSearchCanReturnPlatformView {
1139 platformView:platformView];
1143 object1.
children = @[ platformViewSemanticsContainer, object3 ];
1148 node0.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1154 node1.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1160 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
1166 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1170 CGPoint point = CGPointMake(10, 10);
1173 XCTAssertEqual(hitTestResult, platformView);
1176- (void)testFlutterPlatformViewSemanticsContainer {
1184 weakPlatformView = platformView;
1190 platformView:platformView];
1191 weakContainer = container;
1193 XCTAssertNotNil(weakPlatformView);
1194 XCTAssertNotNil(weakContainer);
1198 XCTAssertNotNil(weakPlatformView);
1199 XCTAssertNotNil(weakContainer);
1203 XCTAssertNil(weakPlatformView);
1204 XCTAssertNil(weakContainer);
1207- (void)testTextInputSemanticsObject {
1219 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);
1222- (void)testTextInputSemanticsObject_canPerformAction {
1235 id textInputSurrogate = OCMClassMock([UIResponder
class]);
1236 id partialSemanticsObject = OCMPartialMock(
object);
1237 OCMStub([partialSemanticsObject textInputSurrogate]).andReturn(textInputSurrogate);
1239 OCMExpect([textInputSurrogate canPerformAction:[OCMArg anySelector] withSender:OCMOCK_ANY])
1241 XCTAssertTrue([partialSemanticsObject canPerformAction:
@selector(copy:) withSender:nil]);
1243 OCMExpect([textInputSurrogate canPerformAction:[OCMArg anySelector] withSender:OCMOCK_ANY])
1245 XCTAssertFalse([partialSemanticsObject canPerformAction:
@selector(copy:) withSender:nil]);
1248- (void)testTextInputSemanticsObject_editActions {
1262 id textInputSurrogate = OCMClassMock([UIResponder
class]);
1263 id partialSemanticsObject = OCMPartialMock(
object);
1264 OCMStub([partialSemanticsObject textInputSurrogate]).andReturn(textInputSurrogate);
1266 XCTestExpectation* copyExpectation =
1267 [
self expectationWithDescription:@"Surrogate's copy method is called."];
1268 XCTestExpectation* cutExpectation =
1269 [
self expectationWithDescription:@"Surrogate's cut method is called."];
1270 XCTestExpectation* pasteExpectation =
1271 [
self expectationWithDescription:@"Surrogate's paste method is called."];
1272 XCTestExpectation* selectAllExpectation =
1273 [
self expectationWithDescription:@"Surrogate's selectAll method is called."];
1274 XCTestExpectation* deleteExpectation =
1275 [
self expectationWithDescription:@"Surrogate's delete method is called."];
1277 OCMStub([textInputSurrogate copy:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1278 [copyExpectation fulfill];
1280 OCMStub([textInputSurrogate cut:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1281 [cutExpectation fulfill];
1283 OCMStub([textInputSurrogate paste:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1284 [pasteExpectation fulfill];
1286 OCMStub([textInputSurrogate selectAll:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1287 [selectAllExpectation fulfill];
1289 OCMStub([textInputSurrogate
delete:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1290 [deleteExpectation fulfill];
1293 [partialSemanticsObject copy:nil];
1294 [partialSemanticsObject cut:nil];
1295 [partialSemanticsObject paste:nil];
1296 [partialSemanticsObject selectAll:nil];
1297 [partialSemanticsObject delete:nil];
1299 [
self waitForExpectationsWithTimeout:1 handler:nil];
1302- (void)testSliderSemanticsObject {
1312 XCTAssertEqual([
object accessibilityActivate], YES);
1315- (void)testUIFocusItemConformance {
1324 XCTAssertTrue([parent.parentFocusEnvironment isKindOfClass:[UIView class]]);
1325 XCTAssertEqual(child.parentFocusEnvironment, child.
parent);
1332 XCTAssertFalse(child.canBecomeFocused);
1335 XCTAssertTrue(child.canBecomeFocused);
1338 XCTAssertFalse(child.canBecomeFocused);
1340 CGFloat scale = ((bridge->view().window.screen ?: UIScreen.mainScreen)).scale;
1342 childNode.
rect = SkRect::MakeXYWH(0, 0, 100 * scale, 100 * scale);
1345 parentNode.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1348 XCTAssertTrue(CGRectEqualToRect(child.frame, CGRectMake(0, 0, 100, 100)));
1351- (void)testUIFocusItemContainerConformance {
1361 NSArray<id<UIFocusItem>>* itemsInRect = [parent focusItemsInRect:CGRectMake(0, 0, 100, 100)];
1362 XCTAssertEqual(itemsInRect.count, (
unsigned long)2);
1363 XCTAssertTrue([itemsInRect containsObject:child1]);
1364 XCTAssertTrue([itemsInRect containsObject:child2]);
1367- (void)testUIFocusItemScrollableContainerConformance {
1375 CGPoint p = CGPointMake(123.0, 456.0);
1376 [scrollable.scrollView scrollViewWillEndDragging:scrollable.scrollView
1377 withVelocity:CGPointZero
1378 targetContentOffset:&p];
1380 [scrollable.scrollView scrollViewDidEndDecelerating:scrollable.scrollView];
1381 XCTAssertEqual(bridge->observations.size(), (
size_t)1);
1382 XCTAssertEqual(bridge->observations[0].id, 5);
1385 std::vector<uint8_t>
args = bridge->observations[0].args;
1386 XCTAssertEqual(
args.size(), 3 *
sizeof(CGFloat));
1388 NSData* encoded = [NSData dataWithBytes:args.data() length:args.size()];
1390 CGPoint point = CGPointZero;
1391 memcpy(&point, decoded.
data.bytes, decoded.
data.length);
1392 XCTAssertTrue(CGPointEqualToPoint(point, p));
1395- (void)testUIFocusItemScrollableContainerNoFeedbackLoops {
1403 const CGPoint p = CGPointMake(0.0, 456.0);
1405 bridge->observations.clear();
1407 const SkScalar scrollPosition = p.y + 0.0000000000000001;
1411 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1414 node.
transform = {1.0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0, 1.0, 0, 0, scrollPosition, 0, 1.0};
1418 XCTAssertEqual(bridge->observations.size(), (
size_t)0);
constexpr float kScrollExtentMaxForInf
FLUTTER_ASSERT_ARC const float kFloatCompareEpsilon
id accessibilityContainer()
WeakPtr< T > GetWeakPtr() const
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
SemanticsObject * semanticsObject
id _accessibilityHitTest:withEvent:(CGPoint point,[withEvent] UIEvent *event)
NSArray< SemanticsObject * > * childrenInHitTestOrder
BOOL accessibilityScrollToVisibleWithChild:(id child)
void accessibilityBridgeDidFinishUpdate()
BOOL accessibilityScrollToVisible()
NSArray< SemanticsObject * > * children
void replaceChildAtIndex:withChild:(NSInteger index,[withChild] SemanticsObject *child)
void setSemanticsNode:(const flutter::SemanticsNode *NS_REQUIRES_SUPER)
constexpr int kHorizontalScrollSemanticsActions
constexpr int kVerticalScrollSemanticsActions
instancetype sharedInstance()
SemanticsCheckState isChecked
SemanticsTristate isToggled
SemanticsTristate isEnabled
bool isInMutuallyExclusiveGroup
bool hasImplicitScrolling
StringAttributes hintAttributes
StringAttributes valueAttributes
StringAttributes labelAttributes
std::vector< int32_t > childrenInTraversalOrder