5 #import <OCMock/OCMock.h>
6 #import <XCTest/XCTest.h>
25 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
27 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
29 XCTAssertNotNil(
object);
32 - (void)testSetChildren {
33 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
35 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
39 XCTAssertEqual(parent, child.
parent);
41 XCTAssertNil(child.
parent);
44 - (void)testAccessibilityHitTestFocusAtLeaf {
45 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
47 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
54 object1.
children = @[ object2, object3 ];
57 flutter::SemanticsNode node0;
59 node0.rect = SkRect::MakeXYWH(0, 0, 200, 200);
63 flutter::SemanticsNode node1;
65 node1.rect = SkRect::MakeXYWH(0, 0, 200, 200);
69 flutter::SemanticsNode node2;
71 node2.rect = SkRect::MakeXYWH(0, 0, 100, 100);
75 flutter::SemanticsNode node3;
77 node3.rect = SkRect::MakeXYWH(0, 0, 200, 200);
81 CGPoint point = CGPointMake(10, 10);
85 XCTAssertEqual(hitTestResult, object2);
88 - (void)testAccessibilityHitTestNoFocusableItem {
89 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
91 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
98 object1.
children = @[ object2, object3 ];
101 flutter::SemanticsNode node0;
103 node0.rect = SkRect::MakeXYWH(0, 0, 200, 200);
106 flutter::SemanticsNode node1;
108 node1.rect = SkRect::MakeXYWH(0, 0, 200, 200);
111 flutter::SemanticsNode node2;
113 node2.rect = SkRect::MakeXYWH(0, 0, 100, 100);
116 flutter::SemanticsNode node3;
118 node3.rect = SkRect::MakeXYWH(0, 0, 200, 200);
121 CGPoint point = CGPointMake(10, 10);
124 XCTAssertNil(hitTestResult);
127 - (void)testAccessibilityScrollToVisible {
128 fml::WeakPtrFactory<flutter::testing::MockAccessibilityBridge> factory(
130 fml::WeakPtr<flutter::testing::MockAccessibilityBridge> bridge = factory.GetWeakPtr();
133 flutter::SemanticsNode node3;
135 node3.rect = SkRect::MakeXYWH(0, 0, 200, 200);
140 XCTAssertTrue(bridge->observations.size() == 1);
141 XCTAssertTrue(bridge->observations[0].id == 3);
142 XCTAssertTrue(bridge->observations[0].action == flutter::SemanticsAction::kShowOnScreen);
145 - (void)testAccessibilityScrollToVisibleWithChild {
146 fml::WeakPtrFactory<flutter::testing::MockAccessibilityBridge> factory(
148 fml::WeakPtr<flutter::testing::MockAccessibilityBridge> bridge = factory.GetWeakPtr();
151 flutter::SemanticsNode node3;
153 node3.rect = SkRect::MakeXYWH(0, 0, 200, 200);
158 XCTAssertTrue(bridge->observations.size() == 1);
159 XCTAssertTrue(bridge->observations[0].id == 3);
160 XCTAssertTrue(bridge->observations[0].action == flutter::SemanticsAction::kShowOnScreen);
163 - (void)testAccessibilityHitTestOutOfRect {
164 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
166 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
173 object1.
children = @[ object2, object3 ];
176 flutter::SemanticsNode node0;
178 node0.rect = SkRect::MakeXYWH(0, 0, 200, 200);
182 flutter::SemanticsNode node1;
184 node1.rect = SkRect::MakeXYWH(0, 0, 200, 200);
188 flutter::SemanticsNode node2;
190 node2.rect = SkRect::MakeXYWH(0, 0, 100, 100);
194 flutter::SemanticsNode node3;
196 node3.rect = SkRect::MakeXYWH(0, 0, 200, 200);
200 CGPoint point = CGPointMake(300, 300);
203 XCTAssertNil(hitTestResult);
206 - (void)testReplaceChildAtIndex {
207 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
209 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
215 XCTAssertNil(child1.
parent);
216 XCTAssertEqual(parent, child2.
parent);
217 XCTAssertEqualObjects(parent.
children, @[ child2 ]);
220 - (void)testPlainSemanticsObjectWithLabelHasStaticTextTrait {
221 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
223 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
224 flutter::SemanticsNode node;
228 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitStaticText);
231 - (void)testNodeWithImplicitScrollIsAnAccessibilityElementWhenItisHidden {
232 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
234 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
235 flutter::SemanticsNode node;
236 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling) |
237 static_cast<int32_t
>(flutter::SemanticsFlags::kIsHidden);
240 XCTAssertEqual(
object.isAccessibilityElement, YES);
243 - (void)testNodeWithImplicitScrollIsNotAnAccessibilityElementWhenItisNotHidden {
244 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
246 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
247 flutter::SemanticsNode node;
248 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
251 XCTAssertEqual(
object.isAccessibilityElement, NO);
254 - (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait {
255 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
257 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
258 flutter::SemanticsNode node;
264 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);
267 - (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait1 {
268 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
270 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
271 flutter::SemanticsNode node;
273 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kIsTextField);
276 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);
279 - (void)testIntresetingSemanticsObjectWithLabelHasStaticTextTrait2 {
280 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
282 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
283 flutter::SemanticsNode node;
285 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kIsButton);
288 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitButton);
291 - (void)testVerticalFlutterScrollableSemanticsObject {
292 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
294 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
296 float transformScale = 0.5f;
297 float screenScale = [[bridge->view() window] screen].scale;
298 float effectivelyScale = transformScale / screenScale;
303 float scrollExtentMax = 500.0;
304 float scrollPosition = 150.0;
306 flutter::SemanticsNode node;
307 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
308 node.actions = flutter::kVerticalScrollSemanticsActions;
309 node.rect = SkRect::MakeXYWH(x, y, w, h);
310 node.scrollExtentMax = scrollExtentMax;
311 node.scrollPosition = scrollPosition;
313 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
320 XCTAssertEqualWithAccuracy(scrollView.frame.origin.x, x * effectivelyScale,
kFloatCompareEpsilon);
321 XCTAssertEqualWithAccuracy(scrollView.frame.origin.y, y * effectivelyScale,
kFloatCompareEpsilon);
322 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
324 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
327 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
329 XCTAssertEqualWithAccuracy(scrollView.contentSize.height,
332 XCTAssertEqual(scrollView.contentOffset.x, 0);
333 XCTAssertEqualWithAccuracy(scrollView.contentOffset.y, scrollPosition * effectivelyScale,
337 - (void)testVerticalFlutterScrollableSemanticsObjectNoWindowDoesNotCrash {
338 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
340 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
342 float transformScale = 0.5f;
347 float scrollExtentMax = 500.0;
348 float scrollPosition = 150.0;
350 flutter::SemanticsNode node;
351 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
352 node.actions = flutter::kVerticalScrollSemanticsActions;
353 node.rect = SkRect::MakeXYWH(x, y, w, h);
354 node.scrollExtentMax = scrollExtentMax;
355 node.scrollPosition = scrollPosition;
357 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
362 XCTAssertNoThrow([scrollable accessibilityBridgeDidFinishUpdate]);
365 - (void)testHorizontalFlutterScrollableSemanticsObject {
366 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
368 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
370 float transformScale = 0.5f;
371 float screenScale = [[bridge->view() window] screen].scale;
372 float effectivelyScale = transformScale / screenScale;
377 float scrollExtentMax = 500.0;
378 float scrollPosition = 150.0;
380 flutter::SemanticsNode node;
381 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
382 node.actions = flutter::kHorizontalScrollSemanticsActions;
383 node.rect = SkRect::MakeXYWH(x, y, w, h);
384 node.scrollExtentMax = scrollExtentMax;
385 node.scrollPosition = scrollPosition;
387 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
394 XCTAssertEqualWithAccuracy(scrollView.frame.origin.x, x * effectivelyScale,
kFloatCompareEpsilon);
395 XCTAssertEqualWithAccuracy(scrollView.frame.origin.y, y * effectivelyScale,
kFloatCompareEpsilon);
396 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
398 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
401 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, (w + scrollExtentMax) * effectivelyScale,
403 XCTAssertEqualWithAccuracy(scrollView.contentSize.height, h * effectivelyScale,
406 XCTAssertEqualWithAccuracy(scrollView.contentOffset.x, scrollPosition * effectivelyScale,
408 XCTAssertEqual(scrollView.contentOffset.y, 0);
411 - (void)testCanHandleInfiniteScrollExtent {
412 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
414 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
416 float transformScale = 0.5f;
417 float screenScale = [[bridge->view() window] screen].scale;
418 float effectivelyScale = transformScale / screenScale;
423 float scrollExtentMax = INFINITY;
424 float scrollPosition = 150.0;
426 flutter::SemanticsNode node;
427 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
428 node.actions = flutter::kVerticalScrollSemanticsActions;
429 node.rect = SkRect::MakeXYWH(x, y, w, h);
430 node.scrollExtentMax = scrollExtentMax;
431 node.scrollPosition = scrollPosition;
433 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
439 XCTAssertEqualWithAccuracy(scrollView.frame.origin.x, x * effectivelyScale,
kFloatCompareEpsilon);
440 XCTAssertEqualWithAccuracy(scrollView.frame.origin.y, y * effectivelyScale,
kFloatCompareEpsilon);
441 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
443 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
446 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
448 XCTAssertEqualWithAccuracy(scrollView.contentSize.height,
452 XCTAssertEqual(scrollView.contentOffset.x, 0);
453 XCTAssertEqualWithAccuracy(scrollView.contentOffset.y, scrollPosition * effectivelyScale,
457 - (void)testCanHandleNaNScrollExtentAndScrollPoisition {
458 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
460 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
462 float transformScale = 0.5f;
463 float screenScale = [[bridge->view() window] screen].scale;
464 float effectivelyScale = transformScale / screenScale;
469 float scrollExtentMax = std::nan(
"");
470 float scrollPosition = std::nan(
"");
472 flutter::SemanticsNode node;
473 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
474 node.actions = flutter::kVerticalScrollSemanticsActions;
475 node.rect = SkRect::MakeXYWH(x, y, w, h);
476 node.scrollExtentMax = scrollExtentMax;
477 node.scrollPosition = scrollPosition;
479 transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, transformScale, 0, 0, 0, 0, 1.0};
486 XCTAssertEqualWithAccuracy(scrollView.frame.origin.x, x * effectivelyScale,
kFloatCompareEpsilon);
487 XCTAssertEqualWithAccuracy(scrollView.frame.origin.y, y * effectivelyScale,
kFloatCompareEpsilon);
488 XCTAssertEqualWithAccuracy(scrollView.frame.size.width, w * effectivelyScale,
490 XCTAssertEqualWithAccuracy(scrollView.frame.size.height, h * effectivelyScale,
494 XCTAssertEqualWithAccuracy(scrollView.contentSize.width, w * effectivelyScale,
496 XCTAssertEqualWithAccuracy(scrollView.contentSize.height, h * effectivelyScale,
499 XCTAssertEqual(scrollView.contentOffset.x, 0);
500 XCTAssertEqual(scrollView.contentOffset.y, 0);
503 - (void)testFlutterScrollableSemanticsObjectIsNotHittestable {
504 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
506 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
508 flutter::SemanticsNode node;
509 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
510 node.actions = flutter::kHorizontalScrollSemanticsActions;
511 node.rect = SkRect::MakeXYWH(0, 0, 100, 200);
512 node.scrollExtentMax = 100.0;
513 node.scrollPosition = 0.0;
520 XCTAssertEqual([scrollView hitTest:CGPointMake(10, 10) withEvent:nil], nil);
523 - (void)testFlutterScrollableSemanticsObjectIsHiddenWhenVoiceOverIsRunning {
526 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(mock);
527 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
529 flutter::SemanticsNode node;
530 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
531 node.actions = flutter::kHorizontalScrollSemanticsActions;
532 node.rect = SkRect::MakeXYWH(0, 0, 100, 200);
533 node.scrollExtentMax = 100.0;
534 node.scrollPosition = 0.0;
541 XCTAssertTrue(scrollView.isAccessibilityElement);
543 XCTAssertFalse(scrollView.isAccessibilityElement);
546 - (void)testFlutterSemanticsObjectHasIdentifier {
549 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(mock);
550 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
552 flutter::SemanticsNode node;
553 node.identifier =
"identifier";
557 XCTAssertTrue([
object.accessibilityIdentifier isEqualToString:
@"identifier"]);
560 - (void)testFlutterScrollableSemanticsObjectWithLabelValueHintIsNotHiddenWhenVoiceOverIsRunning {
563 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(mock);
564 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
566 flutter::SemanticsNode node;
567 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
568 node.actions = flutter::kHorizontalScrollSemanticsActions;
569 node.rect = SkRect::MakeXYWH(0, 0, 100, 200);
570 node.label =
"label";
571 node.value =
"value";
573 node.scrollExtentMax = 100.0;
574 node.scrollPosition = 0.0;
581 XCTAssertTrue(scrollView.isAccessibilityElement);
583 [scrollView.accessibilityLabel isEqualToString:NSLocalizedString(
@"label",
@"test")]);
585 [scrollView.accessibilityValue isEqualToString:NSLocalizedString(
@"value",
@"test")]);
586 XCTAssertTrue([scrollView.accessibilityHint isEqualToString:NSLocalizedString(
@"hint",
@"test")]);
589 - (void)testFlutterSemanticsObjectMergeTooltipToLabel {
592 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(mock);
593 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
595 flutter::SemanticsNode node;
596 node.rect = SkRect::MakeXYWH(0, 0, 100, 200);
597 node.label =
"label";
598 node.tooltip =
"tooltip";
601 XCTAssertTrue(
object.isAccessibilityElement);
602 XCTAssertTrue([
object.accessibilityLabel isEqualToString:
@"label\ntooltip"]);
605 - (void)testFlutterSemanticsObjectAttributedStringsDoNotCrashWhenEmpty {
608 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(mock);
609 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
611 flutter::SemanticsNode node;
612 node.rect = SkRect::MakeXYWH(0, 0, 100, 200);
615 XCTAssertTrue(
object.accessibilityAttributedLabel == nil);
618 - (void)testFlutterScrollableSemanticsObjectReturnsParentContainerIfNoChildren {
621 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(mock);
622 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
624 flutter::SemanticsNode parent;
626 parent.rect = SkRect::MakeXYWH(0, 0, 100, 200);
627 parent.label =
"label";
628 parent.value =
"value";
629 parent.hint =
"hint";
631 flutter::SemanticsNode node;
633 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
634 node.actions = flutter::kHorizontalScrollSemanticsActions;
635 node.rect = SkRect::MakeXYWH(0, 0, 100, 200);
636 node.label =
"label";
637 node.value =
"value";
639 node.scrollExtentMax = 100.0;
640 node.scrollPosition = 0.0;
641 parent.childrenInTraversalOrder.push_back(1);
652 parentObject.
children = @[ scrollable ];
655 XCTAssertTrue(scrollView.isAccessibilityElement);
661 - (void)testFlutterScrollableSemanticsObjectHidesScrollBar {
662 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
664 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
666 flutter::SemanticsNode node;
667 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
668 node.actions = flutter::kHorizontalScrollSemanticsActions;
669 node.rect = SkRect::MakeXYWH(0, 0, 100, 200);
670 node.scrollExtentMax = 100.0;
671 node.scrollPosition = 0.0;
679 XCTAssertFalse(scrollView.showsHorizontalScrollIndicator);
680 XCTAssertFalse(scrollView.showsVerticalScrollIndicator);
683 - (void)testSemanticsObjectBuildsAttributedString {
684 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
686 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
687 flutter::SemanticsNode node;
688 node.label =
"label";
689 std::shared_ptr<flutter::SpellOutStringAttribute> attribute =
690 std::make_shared<flutter::SpellOutStringAttribute>();
691 attribute->start = 1;
693 attribute->type = flutter::StringAttributeType::kSpellOut;
694 node.labelAttributes.push_back(attribute);
695 node.value =
"value";
696 attribute = std::make_shared<flutter::SpellOutStringAttribute>();
697 attribute->start = 2;
699 attribute->type = flutter::StringAttributeType::kSpellOut;
700 node.valueAttributes.push_back(attribute);
702 std::shared_ptr<flutter::LocaleStringAttribute> local_attribute =
703 std::make_shared<flutter::LocaleStringAttribute>();
704 local_attribute->start = 3;
705 local_attribute->end = 4;
706 local_attribute->type = flutter::StringAttributeType::kLocale;
707 local_attribute->locale =
"en-MX";
708 node.hintAttributes.push_back(local_attribute);
711 NSMutableAttributedString* expectedAttributedLabel =
712 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"label", @"test")];
713 NSDictionary* attributeDict = @{
714 UIAccessibilitySpeechAttributeSpellOut : @YES,
716 [expectedAttributedLabel setAttributes:attributeDict range:NSMakeRange(1, 1)];
718 [
object.accessibilityAttributedLabel isEqualToAttributedString:expectedAttributedLabel]);
720 NSMutableAttributedString* expectedAttributedValue =
721 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"value", @"test")];
723 UIAccessibilitySpeechAttributeSpellOut : @YES,
725 [expectedAttributedValue setAttributes:attributeDict range:NSMakeRange(2, 1)];
727 [
object.accessibilityAttributedValue isEqualToAttributedString:expectedAttributedValue]);
729 NSMutableAttributedString* expectedAttributedHint =
730 [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"hint", @"test")];
732 UIAccessibilitySpeechAttributeLanguage :
@"en-MX",
734 [expectedAttributedHint setAttributes:attributeDict range:NSMakeRange(3, 1)];
736 [
object.accessibilityAttributedHint isEqualToAttributedString:expectedAttributedHint]);
739 - (void)testShouldTriggerAnnouncement {
740 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
742 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
746 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:nil]);
749 flutter::SemanticsNode node;
750 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kIsLiveRegion);
752 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&node]);
756 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:nil]);
759 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:&node]);
762 flutter::SemanticsNode updatedNode;
763 updatedNode.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kIsLiveRegion);
764 updatedNode.label =
"bar";
765 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&updatedNode]);
768 updatedNode.flags = 0;
769 XCTAssertFalse([
object nodeShouldTriggerAnnouncement:&updatedNode]);
772 updatedNode.label =
"foo";
774 XCTAssertTrue([
object nodeShouldTriggerAnnouncement:&node]);
777 - (void)testShouldDispatchShowOnScreenActionForHeader {
778 fml::WeakPtrFactory<flutter::testing::MockAccessibilityBridge> factory(
780 fml::WeakPtr<flutter::testing::MockAccessibilityBridge> bridge = factory.GetWeakPtr();
784 flutter::SemanticsNode node;
785 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kIsHeader);
791 [object accessibilityElementDidBecomeFocused];
793 XCTAssertTrue(bridge->observations.size() == 1);
794 XCTAssertTrue(bridge->observations[0].id == 1);
795 XCTAssertTrue(bridge->observations[0].action == flutter::SemanticsAction::kShowOnScreen);
798 - (void)testShouldDispatchShowOnScreenActionForHidden {
799 fml::WeakPtrFactory<flutter::testing::MockAccessibilityBridge> factory(
801 fml::WeakPtr<flutter::testing::MockAccessibilityBridge> bridge = factory.GetWeakPtr();
805 flutter::SemanticsNode node;
806 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kIsHidden);
812 [object accessibilityElementDidBecomeFocused];
814 XCTAssertTrue(bridge->observations.size() == 1);
815 XCTAssertTrue(bridge->observations[0].id == 1);
816 XCTAssertTrue(bridge->observations[0].action == flutter::SemanticsAction::kShowOnScreen);
819 - (void)testFlutterSwitchSemanticsObjectMatchesUISwitch {
820 fml::WeakPtrFactory<flutter::testing::MockAccessibilityBridge> factory(
822 fml::WeakPtr<flutter::testing::MockAccessibilityBridge> bridge = factory.GetWeakPtr();
827 flutter::SemanticsNode node;
828 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasToggledState) |
829 static_cast<int32_t
>(flutter::SemanticsFlags::kIsToggled) |
830 static_cast<int32_t
>(flutter::SemanticsFlags::kIsEnabled);
834 UISwitch* nativeSwitch = [[UISwitch alloc] init];
835 nativeSwitch.on = YES;
837 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
838 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
841 flutter::SemanticsNode update;
842 update.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasToggledState) |
843 static_cast<int32_t
>(flutter::SemanticsFlags::kIsEnabled);
844 update.label =
"foo";
847 nativeSwitch.on = NO;
849 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
850 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
853 - (void)testFlutterSemanticsObjectOfRadioButton {
854 fml::WeakPtrFactory<flutter::testing::MockAccessibilityBridge> factory(
856 fml::WeakPtr<flutter::testing::MockAccessibilityBridge> bridge = factory.GetWeakPtr();
860 flutter::SemanticsNode node;
861 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kIsInMutuallyExclusiveGroup) |
862 static_cast<int32_t
>(flutter::SemanticsFlags::kHasCheckedState) |
863 static_cast<int32_t
>(flutter::SemanticsFlags::kHasEnabledState) |
864 static_cast<int32_t
>(flutter::SemanticsFlags::kIsEnabled);
867 XCTAssertTrue((
object.accessibilityTraits & UIAccessibilityTraitButton) > 0);
868 XCTAssertNil(
object.accessibilityValue);
871 - (void)testFlutterSwitchSemanticsObjectMatchesUISwitchDisabled {
872 fml::WeakPtrFactory<flutter::testing::MockAccessibilityBridge> factory(
874 fml::WeakPtr<flutter::testing::MockAccessibilityBridge> bridge = factory.GetWeakPtr();
879 flutter::SemanticsNode node;
880 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasToggledState) |
881 static_cast<int32_t
>(flutter::SemanticsFlags::kIsToggled);
885 UISwitch* nativeSwitch = [[UISwitch alloc] init];
886 nativeSwitch.on = YES;
887 nativeSwitch.enabled = NO;
889 XCTAssertEqual(
object.accessibilityTraits, nativeSwitch.accessibilityTraits);
890 XCTAssertEqualObjects(
object.accessibilityValue, nativeSwitch.accessibilityValue);
893 - (void)testSemanticsObjectDeallocated {
894 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
896 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
904 XCTAssertNil(weakObject);
907 - (void)testFlutterSemanticsObjectReturnsNilContainerWhenBridgeIsNotAlive {
912 flutter::SemanticsNode parent;
914 parent.rect = SkRect::MakeXYWH(0, 0, 100, 200);
915 parent.label =
"label";
916 parent.value =
"value";
917 parent.hint =
"hint";
919 flutter::SemanticsNode node;
921 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kHasImplicitScrolling);
922 node.actions = flutter::kHorizontalScrollSemanticsActions;
923 node.rect = SkRect::MakeXYWH(0, 0, 100, 200);
924 node.label =
"label";
925 node.value =
"value";
927 node.scrollExtentMax = 100.0;
928 node.scrollPosition = 0.0;
929 parent.childrenInTraversalOrder.push_back(1);
931 flutter::SemanticsNode node2;
933 node2.rect = SkRect::MakeXYWH(0, 0, 100, 200);
934 node2.label =
"label";
935 node2.value =
"value";
937 node2.scrollExtentMax = 100.0;
938 node2.scrollPosition = 0.0;
939 parent.childrenInTraversalOrder.push_back(2);
945 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(mock);
946 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
958 parentObject.
children = @[ scrollable, object2 ];
973 XCTAssertNil(scrollable.accessibilityContainer);
974 XCTAssertNil(object2.accessibilityContainer);
977 - (void)testAccessibilityHitTestSearchCanReturnPlatformView {
978 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
980 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
989 platformView:platformView];
993 object1.
children = @[ platformViewSemanticsContainer, object3 ];
996 flutter::SemanticsNode node0;
998 node0.rect = SkRect::MakeXYWH(0, 0, 200, 200);
1002 flutter::SemanticsNode node1;
1004 node1.rect = SkRect::MakeXYWH(0, 0, 200, 200);
1008 flutter::SemanticsNode node2;
1010 node2.rect = SkRect::MakeXYWH(0, 0, 100, 100);
1014 flutter::SemanticsNode node3;
1016 node3.rect = SkRect::MakeXYWH(0, 0, 200, 200);
1020 CGPoint point = CGPointMake(10, 10);
1023 XCTAssertEqual(hitTestResult, platformView);
1026 - (void)testFlutterPlatformViewSemanticsContainer {
1027 fml::WeakPtrFactory<flutter::testing::MockAccessibilityBridge> factory(
1029 fml::WeakPtr<flutter::testing::MockAccessibilityBridge> bridge = factory.GetWeakPtr();
1034 weakPlatformView = platformView;
1040 platformView:platformView];
1041 weakContainer = container;
1043 XCTAssertNotNil(weakPlatformView);
1044 XCTAssertNotNil(weakContainer);
1048 XCTAssertNotNil(weakPlatformView);
1049 XCTAssertNotNil(weakContainer);
1053 XCTAssertNil(weakPlatformView);
1054 XCTAssertNil(weakContainer);
1057 - (void)testTextInputSemanticsObject {
1058 fml::WeakPtrFactory<flutter::AccessibilityBridgeIos> factory(
1060 fml::WeakPtr<flutter::AccessibilityBridgeIos> bridge = factory.GetWeakPtr();
1062 flutter::SemanticsNode node;
1064 node.flags =
static_cast<int32_t
>(flutter::SemanticsFlags::kIsTextField) |
1065 static_cast<int32_t
>(flutter::SemanticsFlags::kIsReadOnly);
1069 XCTAssertEqual([
object accessibilityTraits], UIAccessibilityTraitNone);