mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
make FakeView not send Scene and semantics to the engine (#138849)
`FakeView` wraps the same underlying `FlutterView`. Sending semantics updates and Scene objects from multiple fake views into the same engine `FlutterView` violates contracts with the engine. This PR stubs out `render` and `updateSemantics` methods in `FakeView` classes to prevent that. This unblocks https://github.com/flutter/engine/pull/48251, which implements multi-view semantics for web.
This commit is contained in:
parent
c7d4b32fdd
commit
14549b3889
33
packages/flutter/test/widgets/multi_view_testing.dart
Normal file
33
packages/flutter/test/widgets/multi_view_testing.dart
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
class FakeView extends TestFlutterView {
|
||||
FakeView(FlutterView view, { this.viewId = 100 }) : super(
|
||||
view: view,
|
||||
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
|
||||
display: view.display as TestDisplay,
|
||||
);
|
||||
|
||||
@override
|
||||
final int viewId;
|
||||
|
||||
@override
|
||||
void render(Scene scene) {
|
||||
// Do not render the scene in the engine. The engine only observes one
|
||||
// instance of FlutterView (the _view), and it is generally expected that
|
||||
// the framework will render no more than one `Scene` per frame.
|
||||
}
|
||||
|
||||
@override
|
||||
void updateSemantics(SemanticsUpdate update) {
|
||||
// Do not send the update to the engine. The engine only observes one
|
||||
// instance of FlutterView (the _view). Sending semantic updates meant for
|
||||
// different views to the same engine view does not work as the updates do
|
||||
// not produce consistent semantics trees.
|
||||
}
|
||||
}
|
@ -2,13 +2,13 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import 'multi_view_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('Widgets in view update as expected', (WidgetTester tester) async {
|
||||
final Widget widget = View(
|
||||
@ -209,14 +209,3 @@ Future<void> pumpWidgetWithoutViewWrapper({required WidgetTester tester, require
|
||||
tester.binding.scheduleFrame();
|
||||
return tester.binding.pump();
|
||||
}
|
||||
|
||||
class FakeView extends TestFlutterView{
|
||||
FakeView(FlutterView view, { this.viewId = 100 }) : super(
|
||||
view: view,
|
||||
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
|
||||
display: view.display as TestDisplay,
|
||||
);
|
||||
|
||||
@override
|
||||
final int viewId;
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import 'multi_view_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('Providing a RenderObjectWidget directly to the RootWidget fails', (WidgetTester tester) async {
|
||||
// No render tree exists to attach the RenderObjectWidget to.
|
||||
@ -1149,14 +1151,3 @@ Future<void> pumpWidgetWithoutViewWrapper({required WidgetTester tester, require
|
||||
tester.binding.scheduleFrame();
|
||||
return tester.binding.pump();
|
||||
}
|
||||
|
||||
class FakeView extends TestFlutterView{
|
||||
FakeView(FlutterView view, { this.viewId = 100 }) : super(
|
||||
view: view,
|
||||
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
|
||||
display: view.display as TestDisplay,
|
||||
);
|
||||
|
||||
@override
|
||||
final int viewId;
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import 'multi_view_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgetsWithLeakTracking('Widgets running with runApp can find View', (WidgetTester tester) async {
|
||||
FlutterView? viewOf;
|
||||
@ -456,17 +458,6 @@ Future<void> pumpWidgetWithoutViewWrapper({required WidgetTester tester, require
|
||||
return tester.binding.pump();
|
||||
}
|
||||
|
||||
class FakeView extends TestFlutterView{
|
||||
FakeView(FlutterView view, { this.viewId = 100 }) : super(
|
||||
view: view,
|
||||
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
|
||||
display: view.display as TestDisplay,
|
||||
);
|
||||
|
||||
@override
|
||||
final int viewId;
|
||||
}
|
||||
|
||||
class SpyRenderWidget extends SizedBox {
|
||||
const SpyRenderWidget({super.key, required this.label, required this.log, super.child});
|
||||
|
||||
|
@ -3,11 +3,12 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'multi_view_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Detects tap targets in all views', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
@ -122,14 +123,3 @@ Future<void> pumpViews({required WidgetTester tester, required List<Widget> vie
|
||||
tester.binding.scheduleFrame();
|
||||
return tester.binding.pump();
|
||||
}
|
||||
|
||||
class FakeView extends TestFlutterView{
|
||||
FakeView(FlutterView view, { this.viewId = 100 }) : super(
|
||||
view: view,
|
||||
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
|
||||
display: view.display as TestDisplay,
|
||||
);
|
||||
|
||||
@override
|
||||
final int viewId;
|
||||
}
|
||||
|
@ -2,12 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'multi_view_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('simulatedAccessibilityTraversal - start and end in same view', (WidgetTester tester) async {
|
||||
await pumpViews(tester: tester);
|
||||
@ -219,14 +219,3 @@ Future<void> pumpViews({required WidgetTester tester}) {
|
||||
tester.binding.scheduleFrame();
|
||||
return tester.binding.pump();
|
||||
}
|
||||
|
||||
class FakeView extends TestFlutterView{
|
||||
FakeView(FlutterView view, { this.viewId = 100 }) : super(
|
||||
view: view,
|
||||
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
|
||||
display: view.display as TestDisplay,
|
||||
);
|
||||
|
||||
@override
|
||||
final int viewId;
|
||||
}
|
||||
|
33
packages/flutter_test/test/multi_view_testing.dart
Normal file
33
packages/flutter_test/test/multi_view_testing.dart
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
class FakeView extends TestFlutterView {
|
||||
FakeView(FlutterView view, { this.viewId = 100 }) : super(
|
||||
view: view,
|
||||
platformDispatcher: view.platformDispatcher as TestPlatformDispatcher,
|
||||
display: view.display as TestDisplay,
|
||||
);
|
||||
|
||||
@override
|
||||
final int viewId;
|
||||
|
||||
@override
|
||||
void render(Scene scene) {
|
||||
// Do not render the scene in the engine. The engine only observes one
|
||||
// instance of FlutterView (the _view), and it is generally expected that
|
||||
// the framework will render no more than one `Scene` per frame.
|
||||
}
|
||||
|
||||
@override
|
||||
void updateSemantics(SemanticsUpdate update) {
|
||||
// Do not send the update to the engine. The engine only observes one
|
||||
// instance of FlutterView (the _view). Sending semantic updates meant for
|
||||
// different views to the same engine view does not work as the updates do
|
||||
// not produce consistent semantics trees.
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user