| // 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 'package:flutter/rendering.dart'; |
| import 'package:flutter_test/flutter_test.dart'; |
| |
| import 'rendering_tester.dart'; |
| |
| void main() { |
| TestRenderingFlutterBinding.ensureInitialized(); |
| |
| // Create non-const instances, otherwise tests pass even if the |
| // operator override is incorrect. |
| ViewConfiguration createViewConfiguration({ |
| Size size = const Size(20, 20), |
| double devicePixelRatio = 2.0, |
| }) { |
| final BoxConstraints constraints = BoxConstraints.tight(size); |
| return ViewConfiguration( |
| logicalConstraints: constraints, |
| physicalConstraints: constraints * devicePixelRatio, |
| devicePixelRatio: devicePixelRatio, |
| ); |
| } |
| |
| group('RenderView', () { |
| test('accounts for device pixel ratio in paintBounds', () { |
| layout(RenderAspectRatio(aspectRatio: 1.0)); |
| pumpFrame(); |
| final Size logicalSize = TestRenderingFlutterBinding.instance.renderView.size; |
| final double devicePixelRatio = TestRenderingFlutterBinding.instance.renderView.configuration.devicePixelRatio; |
| final Size physicalSize = logicalSize * devicePixelRatio; |
| expect(TestRenderingFlutterBinding.instance.renderView.paintBounds, Offset.zero & physicalSize); |
| }); |
| |
| test('does not replace the root layer unnecessarily', () { |
| final RenderView view = RenderView( |
| configuration: createViewConfiguration(), |
| view: RendererBinding.instance.platformDispatcher.views.single, |
| ); |
| final PipelineOwner owner = PipelineOwner(); |
| view.attach(owner); |
| view.prepareInitialFrame(); |
| final ContainerLayer firstLayer = view.debugLayer!; |
| view.configuration = createViewConfiguration(); |
| expect(identical(view.debugLayer, firstLayer), true); |
| |
| view.configuration = createViewConfiguration(devicePixelRatio: 5.0); |
| expect(identical(view.debugLayer, firstLayer), false); |
| }); |
| |
| test('does not replace the root layer unnecessarily when view resizes', () { |
| final RenderView view = RenderView( |
| configuration: createViewConfiguration(size: const Size(100.0, 100.0)), |
| view: RendererBinding.instance.platformDispatcher.views.single, |
| ); |
| final PipelineOwner owner = PipelineOwner(); |
| view.attach(owner); |
| view.prepareInitialFrame(); |
| final ContainerLayer firstLayer = view.debugLayer!; |
| view.configuration = createViewConfiguration(size: const Size(100.0, 1117.0)); |
| expect(identical(view.debugLayer, firstLayer), true); |
| }); |
| }); |
| |
| test('ViewConfiguration == and hashCode', () { |
| final ViewConfiguration viewConfigurationA = createViewConfiguration(); |
| final ViewConfiguration viewConfigurationB = createViewConfiguration(); |
| final ViewConfiguration viewConfigurationC = createViewConfiguration(devicePixelRatio: 3.0); |
| |
| expect(viewConfigurationA == viewConfigurationB, true); |
| expect(viewConfigurationA != viewConfigurationC, true); |
| expect(viewConfigurationA.hashCode, viewConfigurationB.hashCode); |
| expect(viewConfigurationA.hashCode != viewConfigurationC.hashCode, true); |
| }); |
| |
| test('invokes DebugPaintCallback', () { |
| final PaintPattern paintsOrangeRect = paints..rect( |
| color: orange, |
| rect: orangeRect, |
| ); |
| final PaintPattern paintsGreenRect = paints..rect( |
| color: green, |
| rect: greenRect, |
| ); |
| final PaintPattern paintOrangeAndGreenRect = paints |
| ..rect( |
| color: orange, |
| rect: orangeRect, |
| ) |
| ..rect( |
| color: green, |
| rect: greenRect, |
| ); |
| void paintCallback(PaintingContext context, Offset offset, RenderView renderView) { |
| context.canvas.drawRect( |
| greenRect, |
| Paint()..color = green, |
| ); |
| } |
| |
| layout(TestRenderObject()); |
| expect( |
| TestRenderingFlutterBinding.instance.renderView, |
| paintsOrangeRect, |
| ); |
| expect( |
| TestRenderingFlutterBinding.instance.renderView, |
| isNot(paintsGreenRect), |
| ); |
| |
| RenderView.debugAddPaintCallback(paintCallback); |
| expect( |
| TestRenderingFlutterBinding.instance.renderView, |
| paintOrangeAndGreenRect, |
| ); |
| |
| RenderView.debugRemovePaintCallback(paintCallback); |
| expect( |
| TestRenderingFlutterBinding.instance.renderView, |
| paintsOrangeRect, |
| ); |
| expect( |
| TestRenderingFlutterBinding.instance.renderView, |
| isNot(paintsGreenRect), |
| ); |
| }); |
| |
| test('Config can be set and changed after instantiation without calling prepareInitialFrame first', () { |
| final RenderView view = RenderView( |
| view: RendererBinding.instance.platformDispatcher.views.single, |
| ); |
| view.configuration = ViewConfiguration(logicalConstraints: BoxConstraints.tight(const Size(100, 200)), devicePixelRatio: 3.0); |
| view.configuration = ViewConfiguration(logicalConstraints: BoxConstraints.tight(const Size(200, 300)), devicePixelRatio: 2.0); |
| PipelineOwner().rootNode = view; |
| view.prepareInitialFrame(); |
| }); |
| |
| test('Constraints are derived from configuration', () { |
| const BoxConstraints constraints = BoxConstraints(minWidth: 1, maxWidth: 2, minHeight: 3, maxHeight: 4); |
| const double devicePixelRatio = 3.0; |
| final ViewConfiguration config = ViewConfiguration( |
| logicalConstraints: constraints, |
| physicalConstraints: constraints * devicePixelRatio, |
| devicePixelRatio: devicePixelRatio, |
| ); |
| |
| // Configuration set via setter. |
| final RenderView view = RenderView( |
| view: RendererBinding.instance.platformDispatcher.views.single, |
| ); |
| expect(() => view.constraints, throwsA(isA<StateError>().having( |
| (StateError e) => e.message, |
| 'message', |
| contains('RenderView has not been given a configuration yet'), |
| ))); |
| view.configuration = config; |
| expect(view.constraints, constraints); |
| |
| // Configuration set in constructor. |
| final RenderView view2 = RenderView( |
| view: RendererBinding.instance.platformDispatcher.views.single, |
| configuration: config, |
| ); |
| expect(view2.constraints, constraints); |
| }); |
| } |
| |
| const Color orange = Color(0xFFFF9000); |
| const Color green = Color(0xFF0FF900); |
| const Rect orangeRect = Rect.fromLTWH(10, 10, 50, 75); |
| const Rect greenRect = Rect.fromLTWH(20, 20, 100, 150); |
| |
| class TestRenderObject extends RenderBox { |
| @override |
| void performLayout() { |
| size = constraints.biggest; |
| } |
| |
| @override |
| void paint(PaintingContext context, Offset offset) { |
| context.canvas.drawRect( |
| orangeRect, |
| Paint()..color = orange, |
| ); |
| } |
| } |