@@ -333,6 +333,178 @@ - (void)testAnnouncesRouteChanges {
333333 UIAccessibilityScreenChangedNotification);
334334}
335335
336+ - (void )testAnnouncesRouteChangesWhenAddAdditionalRoute {
337+ flutter::MockDelegate mock_delegate;
338+ auto thread_task_runner = CreateNewThread (" AccessibilityBridgeTest" );
339+ flutter::TaskRunners runners (/* label=*/ self.name .UTF8String ,
340+ /* platform=*/ thread_task_runner,
341+ /* raster=*/ thread_task_runner,
342+ /* ui=*/ thread_task_runner,
343+ /* io=*/ thread_task_runner);
344+ auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
345+ /* delegate=*/ mock_delegate,
346+ /* rendering_api=*/ flutter::IOSRenderingAPI::kSoftware ,
347+ /* task_runners=*/ runners);
348+ id mockFlutterView = OCMClassMock ([FlutterView class ]);
349+ id mockFlutterViewController = OCMClassMock ([FlutterViewController class ]);
350+ OCMStub ([mockFlutterViewController view ]).andReturn (mockFlutterView);
351+
352+ NSMutableArray <NSDictionary <NSString *, id >*>* accessibility_notifications =
353+ [[[NSMutableArray alloc ] init ] autorelease ];
354+ auto ios_delegate = std::make_unique<flutter::MockIosDelegate>();
355+ ios_delegate->on_PostAccessibilityNotification_ =
356+ [accessibility_notifications](UIAccessibilityNotifications notification, id argument) {
357+ [accessibility_notifications addObject: @{
358+ @" notification" : @(notification),
359+ @" argument" : argument ? argument : [NSNull null ],
360+ }];
361+ };
362+ __block auto bridge =
363+ std::make_unique<flutter::AccessibilityBridge>(/* view_controller=*/ mockFlutterViewController,
364+ /* platform_view=*/ platform_view.get (),
365+ /* platform_views_controller=*/ nil ,
366+ /* ios_delegate=*/ std::move (ios_delegate));
367+
368+ flutter::CustomAccessibilityActionUpdates actions;
369+ flutter::SemanticsNodeUpdates nodes;
370+
371+ flutter::SemanticsNode node1;
372+ node1.id = 1 ;
373+ node1.label = " node1" ;
374+ node1.flags = static_cast <int32_t >(flutter::SemanticsFlags::kScopesRoute ) |
375+ static_cast <int32_t >(flutter::SemanticsFlags::kNamesRoute );
376+ nodes[node1.id ] = node1;
377+ flutter::SemanticsNode root_node;
378+ root_node.id = kRootNodeId ;
379+ root_node.flags = static_cast <int32_t >(flutter::SemanticsFlags::kScopesRoute );
380+ root_node.childrenInTraversalOrder = {1 };
381+ root_node.childrenInHitTestOrder = {1 };
382+ nodes[root_node.id ] = root_node;
383+ bridge->UpdateSemantics (/* nodes=*/ nodes, /* actions=*/ actions);
384+
385+ XCTAssertEqual ([accessibility_notifications count ], 1ul );
386+ XCTAssertEqualObjects (accessibility_notifications[0 ][@" argument" ], @" node1" );
387+ XCTAssertEqual ([accessibility_notifications[0 ][@" notification" ] unsignedIntValue ],
388+ UIAccessibilityScreenChangedNotification);
389+
390+ flutter::SemanticsNodeUpdates new_nodes;
391+
392+ flutter::SemanticsNode new_node1;
393+ new_node1.id = 1 ;
394+ new_node1.label = " new_node1" ;
395+ new_node1.flags = static_cast <int32_t >(flutter::SemanticsFlags::kScopesRoute ) |
396+ static_cast <int32_t >(flutter::SemanticsFlags::kNamesRoute );
397+ new_node1.childrenInTraversalOrder = {2 };
398+ new_node1.childrenInHitTestOrder = {2 };
399+ new_nodes[new_node1.id ] = new_node1;
400+ flutter::SemanticsNode new_node2;
401+ new_node2.id = 2 ;
402+ new_node2.label = " new_node2" ;
403+ new_node2.flags = static_cast <int32_t >(flutter::SemanticsFlags::kScopesRoute ) |
404+ static_cast <int32_t >(flutter::SemanticsFlags::kNamesRoute );
405+ new_nodes[new_node2.id ] = new_node2;
406+ flutter::SemanticsNode new_root_node;
407+ new_root_node.id = kRootNodeId ;
408+ new_root_node.flags = static_cast <int32_t >(flutter::SemanticsFlags::kScopesRoute );
409+ new_root_node.childrenInTraversalOrder = {1 };
410+ new_root_node.childrenInHitTestOrder = {1 };
411+ new_nodes[new_root_node.id ] = new_root_node;
412+ bridge->UpdateSemantics (/* nodes=*/ new_nodes, /* actions=*/ actions);
413+ XCTAssertEqual ([accessibility_notifications count ], 2ul );
414+ XCTAssertEqualObjects (accessibility_notifications[1 ][@" argument" ], @" new_node2" );
415+ XCTAssertEqual ([accessibility_notifications[1 ][@" notification" ] unsignedIntValue ],
416+ UIAccessibilityScreenChangedNotification);
417+ }
418+
419+ - (void )testAnnouncesRouteChangesRemoveRouteInMiddle {
420+ flutter::MockDelegate mock_delegate;
421+ auto thread_task_runner = CreateNewThread (" AccessibilityBridgeTest" );
422+ flutter::TaskRunners runners (/* label=*/ self.name .UTF8String ,
423+ /* platform=*/ thread_task_runner,
424+ /* raster=*/ thread_task_runner,
425+ /* ui=*/ thread_task_runner,
426+ /* io=*/ thread_task_runner);
427+ auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
428+ /* delegate=*/ mock_delegate,
429+ /* rendering_api=*/ flutter::IOSRenderingAPI::kSoftware ,
430+ /* task_runners=*/ runners);
431+ id mockFlutterView = OCMClassMock ([FlutterView class ]);
432+ id mockFlutterViewController = OCMClassMock ([FlutterViewController class ]);
433+ OCMStub ([mockFlutterViewController view ]).andReturn (mockFlutterView);
434+
435+ NSMutableArray <NSDictionary <NSString *, id >*>* accessibility_notifications =
436+ [[[NSMutableArray alloc ] init ] autorelease ];
437+ auto ios_delegate = std::make_unique<flutter::MockIosDelegate>();
438+ ios_delegate->on_PostAccessibilityNotification_ =
439+ [accessibility_notifications](UIAccessibilityNotifications notification, id argument) {
440+ [accessibility_notifications addObject: @{
441+ @" notification" : @(notification),
442+ @" argument" : argument ? argument : [NSNull null ],
443+ }];
444+ };
445+ __block auto bridge =
446+ std::make_unique<flutter::AccessibilityBridge>(/* view_controller=*/ mockFlutterViewController,
447+ /* platform_view=*/ platform_view.get (),
448+ /* platform_views_controller=*/ nil ,
449+ /* ios_delegate=*/ std::move (ios_delegate));
450+
451+ flutter::CustomAccessibilityActionUpdates actions;
452+ flutter::SemanticsNodeUpdates nodes;
453+
454+ flutter::SemanticsNode node1;
455+ node1.id = 1 ;
456+ node1.label = " node1" ;
457+ node1.flags = static_cast <int32_t >(flutter::SemanticsFlags::kScopesRoute ) |
458+ static_cast <int32_t >(flutter::SemanticsFlags::kNamesRoute );
459+ node1.childrenInTraversalOrder = {2 };
460+ node1.childrenInHitTestOrder = {2 };
461+ nodes[node1.id ] = node1;
462+ flutter::SemanticsNode node2;
463+ node2.id = 2 ;
464+ node2.label = " node2" ;
465+ node2.flags = static_cast <int32_t >(flutter::SemanticsFlags::kScopesRoute ) |
466+ static_cast <int32_t >(flutter::SemanticsFlags::kNamesRoute );
467+ nodes[node2.id ] = node2;
468+ flutter::SemanticsNode root_node;
469+ root_node.id = kRootNodeId ;
470+ root_node.flags = static_cast <int32_t >(flutter::SemanticsFlags::kScopesRoute );
471+ root_node.childrenInTraversalOrder = {1 };
472+ root_node.childrenInHitTestOrder = {1 };
473+ nodes[root_node.id ] = root_node;
474+ bridge->UpdateSemantics (/* nodes=*/ nodes, /* actions=*/ actions);
475+
476+ XCTAssertEqual ([accessibility_notifications count ], 1ul );
477+ XCTAssertEqualObjects (accessibility_notifications[0 ][@" argument" ], @" node2" );
478+ XCTAssertEqual ([accessibility_notifications[0 ][@" notification" ] unsignedIntValue ],
479+ UIAccessibilityScreenChangedNotification);
480+
481+ flutter::SemanticsNodeUpdates new_nodes;
482+
483+ flutter::SemanticsNode new_node1;
484+ new_node1.id = 1 ;
485+ new_node1.label = " new_node1" ;
486+ new_node1.childrenInTraversalOrder = {2 };
487+ new_node1.childrenInHitTestOrder = {2 };
488+ new_nodes[new_node1.id ] = new_node1;
489+ flutter::SemanticsNode new_node2;
490+ new_node2.id = 2 ;
491+ new_node2.label = " new_node2" ;
492+ new_node2.flags = static_cast <int32_t >(flutter::SemanticsFlags::kScopesRoute ) |
493+ static_cast <int32_t >(flutter::SemanticsFlags::kNamesRoute );
494+ new_nodes[new_node2.id ] = new_node2;
495+ flutter::SemanticsNode new_root_node;
496+ new_root_node.id = kRootNodeId ;
497+ new_root_node.flags = static_cast <int32_t >(flutter::SemanticsFlags::kScopesRoute );
498+ new_root_node.childrenInTraversalOrder = {1 };
499+ new_root_node.childrenInHitTestOrder = {1 };
500+ new_nodes[new_root_node.id ] = new_root_node;
501+ bridge->UpdateSemantics (/* nodes=*/ new_nodes, /* actions=*/ actions);
502+ XCTAssertEqual ([accessibility_notifications count ], 2ul );
503+ XCTAssertEqualObjects (accessibility_notifications[1 ][@" argument" ], @" new_node2" );
504+ XCTAssertEqual ([accessibility_notifications[1 ][@" notification" ] unsignedIntValue ],
505+ UIAccessibilityScreenChangedNotification);
506+ }
507+
336508- (void )testAnnouncesRouteChangesWhenNoNamesRoute {
337509 flutter::MockDelegate mock_delegate;
338510 auto thread_task_runner = CreateNewThread (" AccessibilityBridgeTest" );
0 commit comments