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)testPlainSemanticsObjectWithHeadingLevelHasHeaderTrait {
293 XCTAssertTrue(([
object accessibilityTraits] & UIAccessibilityTraitHeader) > 0);
296- (void)testNodeWithImplicitScrollIsAnAccessibilityElementWhenItisHidden {
306 XCTAssertEqual(
object.isAccessibilityElement, YES);
309- (void)testNodeWithImplicitScrollIsNotAnAccessibilityElementWhenItisNotHidden {
317 XCTAssertEqual(
object.isAccessibilityElement, NO);
320- (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait {
330 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);
333- (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait1 {
342 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);
345- (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait2 {
355 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitButton);
358- (void)testVerticalFlutterScrollableSemanticsObject {
363 float transformScale = 0.5f;
364 float screenScale = [[bridge->view() window] screen].scale;
365 float effectivelyScale = transformScale / screenScale;
370 float scrollExtentMax = 500.0;
371 float scrollPosition = 150.0;
376 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
380 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
389 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
391 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
394 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
396 XCTAssertEqualWithAccuracy(scrollView.contentSize.height,
399 XCTAssertEqual(scrollView.contentOffset.x, 0);
400 XCTAssertEqualWithAccuracy(scrollView.contentOffset.y, scrollPosition * effectivelyScale,
404- (void)testVerticalFlutterScrollableSemanticsObjectNoWindowDoesNotCrash {
409 float transformScale = 0.5f;
414 float scrollExtentMax = 500.0;
415 float scrollPosition = 150.0;
420 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
424 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
429 XCTAssertNoThrow([scrollable accessibilityBridgeDidFinishUpdate]);
432- (void)testHorizontalFlutterScrollableSemanticsObject {
437 float transformScale = 0.5f;
438 float screenScale = [[bridge->view() window] screen].scale;
439 float effectivelyScale = transformScale / screenScale;
444 float scrollExtentMax = 500.0;
445 float scrollPosition = 150.0;
450 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
454 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
463 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
465 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
468 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, (w + scrollExtentMax) * effectivelyScale,
470 XCTAssertEqualWithAccuracy(scrollView.contentSize.height, h * effectivelyScale,
473 XCTAssertEqualWithAccuracy(scrollView.contentOffset.x, scrollPosition * effectivelyScale,
475 XCTAssertEqual(scrollView.contentOffset.y, 0);
478- (void)testCanHandleInfiniteScrollExtent {
483 float transformScale = 0.5f;
484 float screenScale = [[bridge->view() window] screen].scale;
485 float effectivelyScale = transformScale / screenScale;
490 float scrollExtentMax = INFINITY;
491 float scrollPosition = 150.0;
496 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
500 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
508 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
510 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
513 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
515 XCTAssertEqualWithAccuracy(scrollView.contentSize.height,
519 XCTAssertEqual(scrollView.contentOffset.x, 0);
520 XCTAssertEqualWithAccuracy(scrollView.contentOffset.y, scrollPosition * effectivelyScale,
524- (void)testCanHandleNaNScrollExtentAndScrollPoisition {
529 float transformScale = 0.5f;
530 float screenScale = [[bridge->view() window] screen].scale;
531 float effectivelyScale = transformScale / screenScale;
536 float scrollExtentMax = std::nan(
"");
537 float scrollPosition = std::nan(
"");
542 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
546 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
555 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
557 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
561 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
563 XCTAssertEqualWithAccuracy(scrollView.contentSize.height, h * effectivelyScale,
566 XCTAssertEqual(scrollView.contentOffset.x, 0);
567 XCTAssertEqual(scrollView.contentOffset.y, 0);
570- (void)testFlutterScrollableSemanticsObjectIsNotHittestable {
578 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
587 XCTAssertEqual([scrollView hitTest:CGPointMake(10, 10) withEvent:nil], nil);
590- (void)testFlutterScrollableSemanticsObjectIsHiddenWhenVoiceOverIsRunning {
592 mock->isVoiceOverRunningValue =
false;
599 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
608 XCTAssertTrue(scrollView.isAccessibilityElement);
609 mock->isVoiceOverRunningValue =
true;
610 XCTAssertFalse(scrollView.isAccessibilityElement);
613- (void)testFlutterSemanticsObjectHasIdentifier {
615 mock->isVoiceOverRunningValue =
true;
624 XCTAssertTrue([
object.accessibilityIdentifier isEqualToString:
@"identifier"]);
627- (void)testFlutterSemanticsObjectHasLocale {
629 mock->isVoiceOverRunningValue =
true;
638 XCTAssertTrue([
object.accessibilityLanguage isEqualToString:
@"es-MX"]);
641- (void)testFlutterSemanticsObjectUseDefaultLocale {
643 mock->isVoiceOverRunningValue =
true;
648 mock->mockedLocale =
@"es-MX";
652 XCTAssertTrue([
object.accessibilityLanguage isEqualToString:
@"es-MX"]);
655- (void)testFlutterSemanticsObjectPrioritizedSectionLocale {
657 mock->isVoiceOverRunningValue =
true;
663 mock->mockedLocale =
@"es-MX";
669 XCTAssertTrue([
object.accessibilityLanguage isEqualToString:
@"zh-TW"]);
672- (void)testFlutterSemanticsObjectLocaleNil {
674 mock->isVoiceOverRunningValue =
true;
682 XCTAssertTrue(
object.accessibilityLanguage == nil);
685- (void)testFlutterScrollableSemanticsObjectWithLabelValueHintIsNotHiddenWhenVoiceOverIsRunning {
687 mock->isVoiceOverRunningValue =
true;
694 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
695 node.
label =
"label";
696 node.
value =
"value";
706 XCTAssertTrue(scrollView.isAccessibilityElement);
708 [scrollView.accessibilityLabel isEqualToString:NSLocalizedString(
@"label",
@"test")]);
710 [scrollView.accessibilityValue isEqualToString:NSLocalizedString(
@"value",
@"test")]);
711 XCTAssertTrue([scrollView.accessibilityHint isEqualToString:NSLocalizedString(
@"hint",
@"test")]);
714- (void)testFlutterSemanticsObjectMergeTooltipToLabel {
716 mock->isVoiceOverRunningValue =
true;
721 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
722 node.
label =
"label";
726 XCTAssertTrue(
object.isAccessibilityElement);
727 XCTAssertTrue([
object.accessibilityLabel isEqualToString:
@"label\ntooltip"]);
730- (void)testSemanticsObjectContainerAccessibilityFrameCoversEntireScreen {
732 mock->isVoiceOverRunningValue =
true;
743 child.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
754 parentObject.
children = @[ childObject ];
761 XCTAssertTrue(childObject.accessibilityRespondsToUserInteraction);
762 XCTAssertTrue(CGRectEqualToRect(container.accessibilityFrame, UIScreen.mainScreen.bounds));
765- (void)testFlutterSemanticsObjectAttributedStringsDoNotCrashWhenEmpty {
767 mock->isVoiceOverRunningValue =
true;
772 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
775 XCTAssertTrue(
object.accessibilityAttributedLabel == nil);
778- (void)testFlutterScrollableSemanticsObjectReturnsParentContainerIfNoChildren {
780 mock->isVoiceOverRunningValue =
true;
786 parent.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
787 parent.
label =
"label";
788 parent.
value =
"value";
789 parent.
hint =
"hint";
795 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
796 node.
label =
"label";
797 node.
value =
"value";
812 parentObject.
children = @[ scrollable ];
815 XCTAssertTrue(scrollView.isAccessibilityElement);
821- (void)testFlutterScrollableSemanticsObjectNoScrollBarOrContentInsets {
829 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
839 XCTAssertFalse(scrollView.showsHorizontalScrollIndicator);
840 XCTAssertFalse(scrollView.showsVerticalScrollIndicator);
841 XCTAssertEqual(scrollView.contentInsetAdjustmentBehavior,
842 UIScrollViewContentInsetAdjustmentNever);
843 XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(scrollView.contentInset, UIEdgeInsetsZero));
846- (void)testSemanticsObjectBuildsAttributedString {
851 node.
label =
"label";
852 std::shared_ptr<flutter::SpellOutStringAttribute> attribute =
853 std::make_shared<flutter::SpellOutStringAttribute>();
854 attribute->start = 1;
858 node.
value =
"value";
859 attribute = std::make_shared<flutter::SpellOutStringAttribute>();
860 attribute->start = 2;
865 std::shared_ptr<flutter::LocaleStringAttribute> local_attribute =
866 std::make_shared<flutter::LocaleStringAttribute>();
867 local_attribute->start = 3;
868 local_attribute->end = 4;
870 local_attribute->locale =
"en-MX";
874 NSMutableAttributedString* expectedAttributedLabel =
875 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"label", @"test")];
876 NSDictionary* attributeDict = @{
877 UIAccessibilitySpeechAttributeSpellOut : @YES,
879 [expectedAttributedLabel setAttributes:attributeDict range:NSMakeRange(1, 1)];
881 [
object.accessibilityAttributedLabel isEqualToAttributedString:expectedAttributedLabel]);
883 NSMutableAttributedString* expectedAttributedValue =
884 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"value", @"test")];
886 UIAccessibilitySpeechAttributeSpellOut : @YES,
888 [expectedAttributedValue setAttributes:attributeDict range:NSMakeRange(2, 1)];
890 [
object.accessibilityAttributedValue isEqualToAttributedString:expectedAttributedValue]);
892 NSMutableAttributedString* expectedAttributedHint =
893 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"hint", @"test")];
895 UIAccessibilitySpeechAttributeLanguage :
@"en-MX",
897 [expectedAttributedHint setAttributes:attributeDict range:NSMakeRange(3, 1)];
899 [
object.accessibilityAttributedHint isEqualToAttributedString:expectedAttributedHint]);
902- (void)testShouldTriggerAnnouncement {
909 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:nil]);
915 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&node]);
919 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:nil]);
922 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:&node]);
927 updatedNode.label =
"bar";
928 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&updatedNode]);
932 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:&updatedNode]);
935 updatedNode.label =
"foo";
937 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&node]);
940- (void)testShouldDispatchShowOnScreenActionForHeader {
954 [object accessibilityElementDidBecomeFocused];
956 XCTAssertTrue(bridge->observations.size() == 1);
957 XCTAssertTrue(bridge->observations[0].id == 1);
961- (void)testShouldDispatchShowOnScreenActionForHidden {
975 [object accessibilityElementDidBecomeFocused];
977 XCTAssertTrue(bridge->observations.size() == 1);
978 XCTAssertTrue(bridge->observations[0].id == 1);
982- (void)testFlutterSwitchSemanticsObjectMatchesUISwitch {
996 UISwitch* nativeSwitch = [[UISwitch alloc] init];
997 nativeSwitch.on = YES;
999 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
1000 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
1007 update.
label =
"foo";
1010 nativeSwitch.on = NO;
1012 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
1013 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
1016- (void)testFlutterSemanticsObjectOfRadioButton {
1029 XCTAssertTrue((
object.accessibilityTraits & UIAccessibilityTraitButton) > 0);
1030 XCTAssertNil(
object.accessibilityValue);
1033- (void)testFlutterSwitchSemanticsObjectMatchesUISwitchDisabled {
1046 UISwitch* nativeSwitch = [[UISwitch alloc] init];
1047 nativeSwitch.on = YES;
1048 nativeSwitch.enabled = NO;
1050 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
1051 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
1054- (void)testSemanticsObjectDeallocated {
1065 XCTAssertNil(weakObject);
1068- (void)testFlutterSemanticsObjectReturnsNilContainerWhenBridgeIsNotAlive {
1075 parent.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1076 parent.
label =
"label";
1077 parent.
value =
"value";
1078 parent.
hint =
"hint";
1084 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1085 node.
label =
"label";
1086 node.
value =
"value";
1094 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1095 node2.
label =
"label";
1096 node2.
value =
"value";
1097 node2.
hint =
"hint";
1105 mock->isVoiceOverRunningValue =
true;
1119 parentObject.
children = @[ scrollable, object2 ];
1134 XCTAssertNil(scrollable.accessibilityContainer);
1135 XCTAssertNil(object2.accessibilityContainer);
1138- (void)testAccessibilityHitTestSearchCanReturnPlatformView {
1150 platformView:platformView];
1154 object1.
children = @[ platformViewSemanticsContainer, object3 ];
1159 node0.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1165 node1.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1171 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
1177 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1181 CGPoint point = CGPointMake(10, 10);
1184 XCTAssertEqual(hitTestResult, platformView);
1187- (void)testFlutterPlatformViewSemanticsContainer {
1195 weakPlatformView = platformView;
1201 platformView:platformView];
1202 weakContainer = container;
1204 XCTAssertNotNil(weakPlatformView);
1205 XCTAssertNotNil(weakContainer);
1209 XCTAssertNotNil(weakPlatformView);
1210 XCTAssertNotNil(weakContainer);
1214 XCTAssertNil(weakPlatformView);
1215 XCTAssertNil(weakContainer);
1218- (void)testTextInputSemanticsObject {
1230 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);
1233- (void)testTextInputSemanticsObject_canPerformAction {
1246 id textInputSurrogate = OCMClassMock([UIResponder
class]);
1247 id partialSemanticsObject = OCMPartialMock(
object);
1248 OCMStub([partialSemanticsObject textInputSurrogate]).andReturn(textInputSurrogate);
1250 OCMExpect([textInputSurrogate canPerformAction:[OCMArg anySelector] withSender:OCMOCK_ANY])
1252 XCTAssertTrue([partialSemanticsObject canPerformAction:
@selector(copy:) withSender:nil]);
1254 OCMExpect([textInputSurrogate canPerformAction:[OCMArg anySelector] withSender:OCMOCK_ANY])
1256 XCTAssertFalse([partialSemanticsObject canPerformAction:
@selector(copy:) withSender:nil]);
1259- (void)testTextInputSemanticsObject_editActions {
1273 id textInputSurrogate = OCMClassMock([UIResponder
class]);
1274 id partialSemanticsObject = OCMPartialMock(
object);
1275 OCMStub([partialSemanticsObject textInputSurrogate]).andReturn(textInputSurrogate);
1277 XCTestExpectation* copyExpectation =
1278 [
self expectationWithDescription:@"Surrogate's copy method is called."];
1279 XCTestExpectation* cutExpectation =
1280 [
self expectationWithDescription:@"Surrogate's cut method is called."];
1281 XCTestExpectation* pasteExpectation =
1282 [
self expectationWithDescription:@"Surrogate's paste method is called."];
1283 XCTestExpectation* selectAllExpectation =
1284 [
self expectationWithDescription:@"Surrogate's selectAll method is called."];
1285 XCTestExpectation* deleteExpectation =
1286 [
self expectationWithDescription:@"Surrogate's delete method is called."];
1288 OCMStub([textInputSurrogate copy:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1289 [copyExpectation fulfill];
1291 OCMStub([textInputSurrogate cut:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1292 [cutExpectation fulfill];
1294 OCMStub([textInputSurrogate paste:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1295 [pasteExpectation fulfill];
1297 OCMStub([textInputSurrogate selectAll:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1298 [selectAllExpectation fulfill];
1300 OCMStub([textInputSurrogate
delete:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1301 [deleteExpectation fulfill];
1304 [partialSemanticsObject copy:nil];
1305 [partialSemanticsObject cut:nil];
1306 [partialSemanticsObject paste:nil];
1307 [partialSemanticsObject selectAll:nil];
1308 [partialSemanticsObject delete:nil];
1310 [
self waitForExpectationsWithTimeout:1 handler:nil];
1313- (void)testSliderSemanticsObject {
1323 XCTAssertEqual([
object accessibilityActivate], YES);
1326- (void)testUIFocusItemConformance {
1335 XCTAssertTrue([parent.parentFocusEnvironment isKindOfClass:[UIView class]]);
1336 XCTAssertEqual(child.parentFocusEnvironment, child.
parent);
1343 XCTAssertFalse(child.canBecomeFocused);
1346 XCTAssertTrue(child.canBecomeFocused);
1349 XCTAssertFalse(child.canBecomeFocused);
1351 CGFloat scale = ((bridge->view().window.screen ?: UIScreen.mainScreen)).scale;
1353 childNode.
rect = SkRect::MakeXYWH(0, 0, 100 * scale, 100 * scale);
1356 parentNode.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1359 XCTAssertTrue(CGRectEqualToRect(child.frame, CGRectMake(0, 0, 100, 100)));
1362- (void)testUIFocusItemContainerConformance {
1372 NSArray<id<UIFocusItem>>* itemsInRect = [parent focusItemsInRect:CGRectMake(0, 0, 100, 100)];
1373 XCTAssertEqual(itemsInRect.count, (
unsigned long)2);
1374 XCTAssertTrue([itemsInRect containsObject:child1]);
1375 XCTAssertTrue([itemsInRect containsObject:child2]);
1378- (void)testUIFocusItemScrollableContainerConformance {
1386 CGPoint p = CGPointMake(123.0, 456.0);
1387 [scrollable.scrollView scrollViewWillEndDragging:scrollable.scrollView
1388 withVelocity:CGPointZero
1389 targetContentOffset:&p];
1391 [scrollable.scrollView scrollViewDidEndDecelerating:scrollable.scrollView];
1392 XCTAssertEqual(bridge->observations.size(), (
size_t)1);
1393 XCTAssertEqual(bridge->observations[0].id, 5);
1396 std::vector<uint8_t>
args = bridge->observations[0].args;
1397 XCTAssertEqual(
args.size(), 3 *
sizeof(CGFloat));
1399 NSData* encoded = [NSData dataWithBytes:args.data() length:args.size()];
1401 CGPoint point = CGPointZero;
1402 memcpy(&point, decoded.
data.bytes, decoded.
data.length);
1403 XCTAssertTrue(CGPointEqualToPoint(point, p));
1406- (void)testUIFocusItemScrollableContainerNoFeedbackLoops {
1414 const CGPoint p = CGPointMake(0.0, 456.0);
1416 bridge->observations.clear();
1418 const SkScalar scrollPosition = p.y + 0.0000000000000001;
1422 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1425 node.
transform = {1.0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0, 1.0, 0, 0, scrollPosition, 0, 1.0};
1429 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