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)testSetChildren {
51 XCTAssertEqual(parent, child.
parent);
53 XCTAssertNil(child.
parent);
56- (void)testAccessibilityHitTestFocusAtLeaf {
66 object1.
children = @[ object2, object3 ];
71 node0.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
77 node1.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
83 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
89 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
93 CGPoint point = CGPointMake(10, 10);
97 XCTAssertEqual(hitTestResult, object2);
100- (void)testAccessibilityHitTestNoFocusableItem {
110 object1.
children = @[ object2, object3 ];
115 node0.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
120 node1.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
125 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
130 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
133 CGPoint point = CGPointMake(10, 10);
136 XCTAssertNil(hitTestResult);
139- (void)testAccessibilityScrollToVisible {
147 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
152 XCTAssertTrue(bridge->observations.size() == 1);
153 XCTAssertTrue(bridge->observations[0].id == 3);
157- (void)testAccessibilityScrollToVisibleWithChild {
165 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
170 XCTAssertTrue(bridge->observations.size() == 1);
171 XCTAssertTrue(bridge->observations[0].id == 3);
175- (void)testAccessibilityHitTestOutOfRect {
185 object1.
children = @[ object2, object3 ];
190 node0.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
196 node1.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
202 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
208 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
212 CGPoint point = CGPointMake(300, 300);
215 XCTAssertNil(hitTestResult);
218- (void)testReplaceChildAtIndex {
227 XCTAssertNil(child1.
parent);
228 XCTAssertEqual(parent, child2.
parent);
229 XCTAssertEqualObjects(parent.
children, @[ child2 ]);
232- (void)testPlainSemanticsObjectWithLabelHasStaticTextTrait {
240 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitStaticText);
243- (void)testNodeWithImplicitScrollIsAnAccessibilityElementWhenItisHidden {
253 XCTAssertEqual(
object.isAccessibilityElement, YES);
256- (void)testNodeWithImplicitScrollIsNotAnAccessibilityElementWhenItisNotHidden {
264 XCTAssertEqual(
object.isAccessibilityElement, NO);
267- (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait {
277 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);
280- (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait1 {
289 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);
292- (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait2 {
302 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitButton);
305- (void)testVerticalFlutterScrollableSemanticsObject {
310 float transformScale = 0.5f;
311 float screenScale = [[bridge->view() window] screen].scale;
312 float effectivelyScale = transformScale / screenScale;
317 float scrollExtentMax = 500.0;
318 float scrollPosition = 150.0;
323 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
327 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
336 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
338 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
341 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
343 XCTAssertEqualWithAccuracy(scrollView.contentSize.height,
346 XCTAssertEqual(scrollView.contentOffset.x, 0);
347 XCTAssertEqualWithAccuracy(scrollView.contentOffset.y, scrollPosition * effectivelyScale,
351- (void)testVerticalFlutterScrollableSemanticsObjectNoWindowDoesNotCrash {
356 float transformScale = 0.5f;
361 float scrollExtentMax = 500.0;
362 float scrollPosition = 150.0;
367 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
371 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
376 XCTAssertNoThrow([scrollable accessibilityBridgeDidFinishUpdate]);
379- (void)testHorizontalFlutterScrollableSemanticsObject {
384 float transformScale = 0.5f;
385 float screenScale = [[bridge->view() window] screen].scale;
386 float effectivelyScale = transformScale / screenScale;
391 float scrollExtentMax = 500.0;
392 float scrollPosition = 150.0;
397 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
401 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
410 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
412 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
415 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, (w + scrollExtentMax) * effectivelyScale,
417 XCTAssertEqualWithAccuracy(scrollView.contentSize.height, h * effectivelyScale,
420 XCTAssertEqualWithAccuracy(scrollView.contentOffset.x, scrollPosition * effectivelyScale,
422 XCTAssertEqual(scrollView.contentOffset.y, 0);
425- (void)testCanHandleInfiniteScrollExtent {
430 float transformScale = 0.5f;
431 float screenScale = [[bridge->view() window] screen].scale;
432 float effectivelyScale = transformScale / screenScale;
437 float scrollExtentMax = INFINITY;
438 float scrollPosition = 150.0;
443 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
447 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
455 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
457 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
460 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
462 XCTAssertEqualWithAccuracy(scrollView.contentSize.height,
466 XCTAssertEqual(scrollView.contentOffset.x, 0);
467 XCTAssertEqualWithAccuracy(scrollView.contentOffset.y, scrollPosition * effectivelyScale,
471- (void)testCanHandleNaNScrollExtentAndScrollPoisition {
476 float transformScale = 0.5f;
477 float screenScale = [[bridge->view() window] screen].scale;
478 float effectivelyScale = transformScale / screenScale;
483 float scrollExtentMax = std::nan(
"");
484 float scrollPosition = std::nan(
"");
489 node.
rect = SkRect::MakeXYWH(
x,
y, w, h);
493 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
502 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
504 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
508 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
510 XCTAssertEqualWithAccuracy(scrollView.contentSize.height, h * effectivelyScale,
513 XCTAssertEqual(scrollView.contentOffset.x, 0);
514 XCTAssertEqual(scrollView.contentOffset.y, 0);
517- (void)testFlutterScrollableSemanticsObjectIsNotHittestable {
525 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
534 XCTAssertEqual([scrollView hitTest:CGPointMake(10, 10) withEvent:nil], nil);
537- (void)testFlutterScrollableSemanticsObjectIsHiddenWhenVoiceOverIsRunning {
539 mock->isVoiceOverRunningValue =
false;
546 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
555 XCTAssertTrue(scrollView.isAccessibilityElement);
556 mock->isVoiceOverRunningValue =
true;
557 XCTAssertFalse(scrollView.isAccessibilityElement);
560- (void)testFlutterSemanticsObjectHasIdentifier {
562 mock->isVoiceOverRunningValue =
true;
571 XCTAssertTrue([
object.accessibilityIdentifier isEqualToString:
@"identifier"]);
574- (void)testFlutterSemanticsObjectHasLocale {
576 mock->isVoiceOverRunningValue =
true;
585 XCTAssertTrue([
object.accessibilityLanguage isEqualToString:
@"es-MX"]);
588- (void)testFlutterSemanticsObjectUseDefaultLocale {
590 mock->isVoiceOverRunningValue =
true;
595 mock->mockedLocale =
@"es-MX";
599 XCTAssertTrue([
object.accessibilityLanguage isEqualToString:
@"es-MX"]);
602- (void)testFlutterSemanticsObjectPrioritizedSectionLocale {
604 mock->isVoiceOverRunningValue =
true;
610 mock->mockedLocale =
@"es-MX";
616 XCTAssertTrue([
object.accessibilityLanguage isEqualToString:
@"zh-TW"]);
619- (void)testFlutterSemanticsObjectLocaleNil {
621 mock->isVoiceOverRunningValue =
true;
629 XCTAssertTrue(
object.accessibilityLanguage == nil);
632- (void)testFlutterScrollableSemanticsObjectWithLabelValueHintIsNotHiddenWhenVoiceOverIsRunning {
634 mock->isVoiceOverRunningValue =
true;
641 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
642 node.
label =
"label";
643 node.
value =
"value";
653 XCTAssertTrue(scrollView.isAccessibilityElement);
655 [scrollView.accessibilityLabel isEqualToString:NSLocalizedString(
@"label",
@"test")]);
657 [scrollView.accessibilityValue isEqualToString:NSLocalizedString(
@"value",
@"test")]);
658 XCTAssertTrue([scrollView.accessibilityHint isEqualToString:NSLocalizedString(
@"hint",
@"test")]);
661- (void)testFlutterSemanticsObjectMergeTooltipToLabel {
663 mock->isVoiceOverRunningValue =
true;
668 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
669 node.
label =
"label";
673 XCTAssertTrue(
object.isAccessibilityElement);
674 XCTAssertTrue([
object.accessibilityLabel isEqualToString:
@"label\ntooltip"]);
677- (void)testSemanticsObjectContainerAccessibilityFrameCoversEntireScreen {
679 mock->isVoiceOverRunningValue =
true;
690 child.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
701 parentObject.
children = @[ childObject ];
708 XCTAssertTrue(childObject.accessibilityRespondsToUserInteraction);
709 XCTAssertTrue(CGRectEqualToRect(container.accessibilityFrame, UIScreen.mainScreen.bounds));
712- (void)testFlutterSemanticsObjectAttributedStringsDoNotCrashWhenEmpty {
714 mock->isVoiceOverRunningValue =
true;
719 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
722 XCTAssertTrue(
object.accessibilityAttributedLabel == nil);
725- (void)testFlutterScrollableSemanticsObjectReturnsParentContainerIfNoChildren {
727 mock->isVoiceOverRunningValue =
true;
733 parent.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
734 parent.
label =
"label";
735 parent.
value =
"value";
736 parent.
hint =
"hint";
742 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
743 node.
label =
"label";
744 node.
value =
"value";
759 parentObject.
children = @[ scrollable ];
762 XCTAssertTrue(scrollView.isAccessibilityElement);
768- (void)testFlutterScrollableSemanticsObjectNoScrollBarOrContentInsets {
776 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
786 XCTAssertFalse(scrollView.showsHorizontalScrollIndicator);
787 XCTAssertFalse(scrollView.showsVerticalScrollIndicator);
788 XCTAssertEqual(scrollView.contentInsetAdjustmentBehavior,
789 UIScrollViewContentInsetAdjustmentNever);
790 XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(scrollView.contentInset, UIEdgeInsetsZero));
793- (void)testSemanticsObjectBuildsAttributedString {
798 node.
label =
"label";
799 std::shared_ptr<flutter::SpellOutStringAttribute> attribute =
800 std::make_shared<flutter::SpellOutStringAttribute>();
801 attribute->start = 1;
805 node.
value =
"value";
806 attribute = std::make_shared<flutter::SpellOutStringAttribute>();
807 attribute->start = 2;
812 std::shared_ptr<flutter::LocaleStringAttribute> local_attribute =
813 std::make_shared<flutter::LocaleStringAttribute>();
814 local_attribute->start = 3;
815 local_attribute->end = 4;
817 local_attribute->locale =
"en-MX";
821 NSMutableAttributedString* expectedAttributedLabel =
822 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"label", @"test")];
823 NSDictionary* attributeDict = @{
824 UIAccessibilitySpeechAttributeSpellOut : @YES,
826 [expectedAttributedLabel setAttributes:attributeDict range:NSMakeRange(1, 1)];
828 [
object.accessibilityAttributedLabel isEqualToAttributedString:expectedAttributedLabel]);
830 NSMutableAttributedString* expectedAttributedValue =
831 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"value", @"test")];
833 UIAccessibilitySpeechAttributeSpellOut : @YES,
835 [expectedAttributedValue setAttributes:attributeDict range:NSMakeRange(2, 1)];
837 [
object.accessibilityAttributedValue isEqualToAttributedString:expectedAttributedValue]);
839 NSMutableAttributedString* expectedAttributedHint =
840 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"hint", @"test")];
842 UIAccessibilitySpeechAttributeLanguage :
@"en-MX",
844 [expectedAttributedHint setAttributes:attributeDict range:NSMakeRange(3, 1)];
846 [
object.accessibilityAttributedHint isEqualToAttributedString:expectedAttributedHint]);
849- (void)testShouldTriggerAnnouncement {
856 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:nil]);
862 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&node]);
866 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:nil]);
869 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:&node]);
874 updatedNode.label =
"bar";
875 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&updatedNode]);
879 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:&updatedNode]);
882 updatedNode.label =
"foo";
884 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&node]);
887- (void)testShouldDispatchShowOnScreenActionForHeader {
901 [object accessibilityElementDidBecomeFocused];
903 XCTAssertTrue(bridge->observations.size() == 1);
904 XCTAssertTrue(bridge->observations[0].id == 1);
908- (void)testShouldDispatchShowOnScreenActionForHidden {
922 [object accessibilityElementDidBecomeFocused];
924 XCTAssertTrue(bridge->observations.size() == 1);
925 XCTAssertTrue(bridge->observations[0].id == 1);
929- (void)testFlutterSwitchSemanticsObjectMatchesUISwitch {
943 UISwitch* nativeSwitch = [[UISwitch alloc] init];
944 nativeSwitch.on = YES;
946 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
947 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
954 update.
label =
"foo";
957 nativeSwitch.on = NO;
959 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
960 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
963- (void)testFlutterSemanticsObjectOfRadioButton {
976 XCTAssertTrue((
object.accessibilityTraits & UIAccessibilityTraitButton) > 0);
977 XCTAssertNil(
object.accessibilityValue);
980- (void)testFlutterSwitchSemanticsObjectMatchesUISwitchDisabled {
993 UISwitch* nativeSwitch = [[UISwitch alloc] init];
994 nativeSwitch.on = YES;
995 nativeSwitch.enabled = NO;
997 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
998 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
1001- (void)testSemanticsObjectDeallocated {
1012 XCTAssertNil(weakObject);
1015- (void)testFlutterSemanticsObjectReturnsNilContainerWhenBridgeIsNotAlive {
1022 parent.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1023 parent.
label =
"label";
1024 parent.
value =
"value";
1025 parent.
hint =
"hint";
1031 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1032 node.
label =
"label";
1033 node.
value =
"value";
1041 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1042 node2.
label =
"label";
1043 node2.
value =
"value";
1044 node2.
hint =
"hint";
1052 mock->isVoiceOverRunningValue =
true;
1066 parentObject.
children = @[ scrollable, object2 ];
1081 XCTAssertNil(scrollable.accessibilityContainer);
1082 XCTAssertNil(object2.accessibilityContainer);
1085- (void)testAccessibilityHitTestSearchCanReturnPlatformView {
1097 platformView:platformView];
1101 object1.
children = @[ platformViewSemanticsContainer, object3 ];
1106 node0.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1112 node1.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1118 node2.
rect = SkRect::MakeXYWH(0, 0, 100, 100);
1124 node3.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1128 CGPoint point = CGPointMake(10, 10);
1131 XCTAssertEqual(hitTestResult, platformView);
1134- (void)testFlutterPlatformViewSemanticsContainer {
1142 weakPlatformView = platformView;
1148 platformView:platformView];
1149 weakContainer = container;
1151 XCTAssertNotNil(weakPlatformView);
1152 XCTAssertNotNil(weakContainer);
1156 XCTAssertNotNil(weakPlatformView);
1157 XCTAssertNotNil(weakContainer);
1161 XCTAssertNil(weakPlatformView);
1162 XCTAssertNil(weakContainer);
1165- (void)testTextInputSemanticsObject {
1177 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);
1180- (void)testTextInputSemanticsObject_canPerformAction {
1193 id textInputSurrogate = OCMClassMock([UIResponder
class]);
1194 id partialSemanticsObject = OCMPartialMock(
object);
1195 OCMStub([partialSemanticsObject textInputSurrogate]).andReturn(textInputSurrogate);
1197 OCMExpect([textInputSurrogate canPerformAction:[OCMArg anySelector] withSender:OCMOCK_ANY])
1199 XCTAssertTrue([partialSemanticsObject canPerformAction:
@selector(copy:) withSender:nil]);
1201 OCMExpect([textInputSurrogate canPerformAction:[OCMArg anySelector] withSender:OCMOCK_ANY])
1203 XCTAssertFalse([partialSemanticsObject canPerformAction:
@selector(copy:) withSender:nil]);
1206- (void)testTextInputSemanticsObject_editActions {
1220 id textInputSurrogate = OCMClassMock([UIResponder
class]);
1221 id partialSemanticsObject = OCMPartialMock(
object);
1222 OCMStub([partialSemanticsObject textInputSurrogate]).andReturn(textInputSurrogate);
1224 XCTestExpectation* copyExpectation =
1225 [
self expectationWithDescription:@"Surrogate's copy method is called."];
1226 XCTestExpectation* cutExpectation =
1227 [
self expectationWithDescription:@"Surrogate's cut method is called."];
1228 XCTestExpectation* pasteExpectation =
1229 [
self expectationWithDescription:@"Surrogate's paste method is called."];
1230 XCTestExpectation* selectAllExpectation =
1231 [
self expectationWithDescription:@"Surrogate's selectAll method is called."];
1232 XCTestExpectation* deleteExpectation =
1233 [
self expectationWithDescription:@"Surrogate's delete method is called."];
1235 OCMStub([textInputSurrogate copy:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1236 [copyExpectation fulfill];
1238 OCMStub([textInputSurrogate cut:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1239 [cutExpectation fulfill];
1241 OCMStub([textInputSurrogate paste:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1242 [pasteExpectation fulfill];
1244 OCMStub([textInputSurrogate selectAll:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1245 [selectAllExpectation fulfill];
1247 OCMStub([textInputSurrogate
delete:OCMOCK_ANY]).andDo(^(NSInvocation* invocation) {
1248 [deleteExpectation fulfill];
1251 [partialSemanticsObject copy:nil];
1252 [partialSemanticsObject cut:nil];
1253 [partialSemanticsObject paste:nil];
1254 [partialSemanticsObject selectAll:nil];
1255 [partialSemanticsObject delete:nil];
1257 [
self waitForExpectationsWithTimeout:1 handler:nil];
1260- (void)testSliderSemanticsObject {
1270 XCTAssertEqual([
object accessibilityActivate], YES);
1273- (void)testUIFocusItemConformance {
1282 XCTAssertTrue([parent.parentFocusEnvironment isKindOfClass:[UIView class]]);
1283 XCTAssertEqual(child.parentFocusEnvironment, child.
parent);
1290 XCTAssertFalse(child.canBecomeFocused);
1293 XCTAssertTrue(child.canBecomeFocused);
1296 XCTAssertFalse(child.canBecomeFocused);
1298 CGFloat scale = ((bridge->view().window.screen ?: UIScreen.mainScreen)).scale;
1300 childNode.
rect = SkRect::MakeXYWH(0, 0, 100 * scale, 100 * scale);
1303 parentNode.
rect = SkRect::MakeXYWH(0, 0, 200, 200);
1306 XCTAssertTrue(CGRectEqualToRect(child.frame, CGRectMake(0, 0, 100, 100)));
1309- (void)testUIFocusItemContainerConformance {
1319 NSArray<id<UIFocusItem>>* itemsInRect = [parent focusItemsInRect:CGRectMake(0, 0, 100, 100)];
1320 XCTAssertEqual(itemsInRect.count, (
unsigned long)2);
1321 XCTAssertTrue([itemsInRect containsObject:child1]);
1322 XCTAssertTrue([itemsInRect containsObject:child2]);
1325- (void)testUIFocusItemScrollableContainerConformance {
1333 CGPoint p = CGPointMake(123.0, 456.0);
1334 [scrollable.scrollView scrollViewWillEndDragging:scrollable.scrollView
1335 withVelocity:CGPointZero
1336 targetContentOffset:&p];
1338 [scrollable.scrollView scrollViewDidEndDecelerating:scrollable.scrollView];
1339 XCTAssertEqual(bridge->observations.size(), (
size_t)1);
1340 XCTAssertEqual(bridge->observations[0].id, 5);
1343 std::vector<uint8_t>
args = bridge->observations[0].args;
1344 XCTAssertEqual(
args.size(), 3 *
sizeof(CGFloat));
1346 NSData* encoded = [NSData dataWithBytes:args.data() length:args.size()];
1348 CGPoint point = CGPointZero;
1349 memcpy(&point, decoded.
data.bytes, decoded.
data.length);
1350 XCTAssertTrue(CGPointEqualToPoint(point, p));
1353- (void)testUIFocusItemScrollableContainerNoFeedbackLoops {
1361 const CGPoint p = CGPointMake(0.0, 456.0);
1363 bridge->observations.clear();
1365 const SkScalar scrollPosition = p.y + 0.0000000000000001;
1369 node.
rect = SkRect::MakeXYWH(0, 0, 100, 200);
1372 node.
transform = {1.0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0, 1.0, 0, 0, scrollPosition, 0, 1.0};
1376 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