// 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(); group('RenderAligningShiftedBox', () { test('RenderAligningShiftedBox has computeDryBaseline method implemented', () { final positionedBox = RenderPositionedBox(); // Verify the method exists and can be called expect( () => positionedBox.computeDryBaseline( const BoxConstraints(maxWidth: 100.0, maxHeight: 100.0), TextBaseline.alphabetic, ), returnsNormally, ); // Test with no child - should return null final double? baseline = positionedBox.computeDryBaseline( const BoxConstraints(maxWidth: 100.0, maxHeight: 100.0), TextBaseline.alphabetic, ); expect(baseline, isNull); }); test('computeDryBaseline returns null when child is null', () { final positioner = RenderPositionedBox(alignment: Alignment.topLeft); final double? baseline = positioner.computeDryBaseline( const BoxConstraints(maxWidth: 100.0, maxHeight: 100.0), TextBaseline.alphabetic, ); expect(baseline, isNull); }); test('computeDryBaseline returns null when child has no baseline', () { final child = MockRenderBoxNoBaseline(); final positioner = RenderPositionedBox(child: child); final double? baseline = positioner.computeDryBaseline( const BoxConstraints(maxWidth: 100.0, maxHeight: 100.0), TextBaseline.alphabetic, ); expect(baseline, isNull); }); test('computeDryBaseline works with center alignment', () { final child = MockRenderBox(); final positioner = RenderPositionedBox(child: child); final double? baseline = positioner.computeDryBaseline( const BoxConstraints(maxWidth: 200.0, maxHeight: 200.0), TextBaseline.alphabetic, ); // Should return child's baseline (40.0) plus the vertical offset from centering expect(baseline, isNotNull); expect(baseline! > 40.0, isTrue); // Should be greater than child's baseline due to centering }); test('computeDryBaseline works with top-left alignment', () { final child = MockRenderBox(); final positioner = RenderPositionedBox(alignment: Alignment.topLeft, child: child); final double? baseline = positioner.computeDryBaseline( const BoxConstraints(maxWidth: 200.0, maxHeight: 200.0), TextBaseline.alphabetic, ); // Should return exactly child's baseline (40.0) since no vertical offset with topLeft expect(baseline, equals(40.0)); }); test('computeDryBaseline works with bottom-right alignment', () { final child = MockRenderBox(); final positioner = RenderPositionedBox(alignment: Alignment.bottomRight, child: child); final double? baseline = positioner.computeDryBaseline( const BoxConstraints(maxWidth: 200.0, maxHeight: 200.0), TextBaseline.alphabetic, ); // Should return child's baseline plus significant vertical offset from bottom alignment expect(baseline, isNotNull); expect(baseline! > 100.0, isTrue); // Should be much greater due to bottom alignment }); test('computeDryBaseline with different TextBaseline types', () { final child = MockRenderBox(); final positioner = RenderPositionedBox(alignment: Alignment.topLeft, child: child); // Test alphabetic baseline final double? alphabeticBaseline = positioner.computeDryBaseline( const BoxConstraints(maxWidth: 100.0, maxHeight: 100.0), TextBaseline.alphabetic, ); // Test ideographic baseline final double? ideographicBaseline = positioner.computeDryBaseline( const BoxConstraints(maxWidth: 100.0, maxHeight: 100.0), TextBaseline.ideographic, ); expect(alphabeticBaseline, isNotNull); expect(ideographicBaseline, isNotNull); // Both should return the same value since our mock returns 40.0 for both expect(alphabeticBaseline, equals(ideographicBaseline)); }); test('computeDryBaseline works with width and height factors', () { final child = MockRenderBox(); final positioner = RenderPositionedBox( alignment: Alignment.topLeft, widthFactor: 2.0, heightFactor: 1.5, child: child, ); final double? baseline = positioner.computeDryBaseline( const BoxConstraints(maxWidth: 200.0, maxHeight: 200.0), TextBaseline.alphabetic, ); // Should return child's baseline since topLeft alignment expect(baseline, equals(40.0)); }); test('computeDryBaseline works with infinite constraints', () { final child = MockRenderBox(); final positioner = RenderPositionedBox(alignment: Alignment.topLeft, child: child); final double? baseline = positioner.computeDryBaseline( const BoxConstraints(), TextBaseline.alphabetic, ); expect(baseline, equals(40.0)); }); }); group('Other RenderShiftedBox classes', () { test('RenderConstrainedOverflowBox computeDryBaseline', () { final child = MockRenderBox(); final constrainedBox = RenderConstrainedOverflowBox( alignment: Alignment.topLeft, child: child, ); final double? baseline = constrainedBox.computeDryBaseline( const BoxConstraints(maxWidth: 100.0, maxHeight: 100.0), TextBaseline.alphabetic, ); expect(baseline, isNotNull); }); test('RenderSizedOverflowBox computeDryBaseline', () { final child = MockRenderBox(); final sizedBox = RenderSizedOverflowBox( requestedSize: const Size(100.0, 100.0), alignment: Alignment.topLeft, child: child, ); final double? baseline = sizedBox.computeDryBaseline( const BoxConstraints(maxWidth: 200.0, maxHeight: 200.0), TextBaseline.alphabetic, ); expect(baseline, isNotNull); }); test('RenderFractionallySizedOverflowBox computeDryBaseline', () { final child = MockRenderBox(); final fractionalBox = RenderFractionallySizedOverflowBox( alignment: Alignment.topLeft, widthFactor: 0.5, heightFactor: 0.5, child: child, ); final double? baseline = fractionalBox.computeDryBaseline( const BoxConstraints(maxWidth: 200.0, maxHeight: 200.0), TextBaseline.alphabetic, ); expect(baseline, isNotNull); }); test('RenderPadding computeDryBaseline', () { final child = MockRenderBox(); final padding = RenderPadding(padding: const EdgeInsets.all(10.0), child: child); final double? baseline = padding.computeDryBaseline( const BoxConstraints(maxWidth: 100.0, maxHeight: 100.0), TextBaseline.alphabetic, ); expect(baseline, isNotNull); }); test('RenderBaseline computeDryBaseline', () { final child = MockRenderBox(); final baselineBox = RenderBaseline( baseline: 30.0, baselineType: TextBaseline.alphabetic, child: child, ); final double? baseline = baselineBox.computeDryBaseline( const BoxConstraints(maxWidth: 100.0, maxHeight: 100.0), TextBaseline.alphabetic, ); expect(baseline, isNotNull); }); test('computeDryBaseline handles edge cases consistently', () { // Test with very small constraints final child = MockRenderBox(); final positioner = RenderPositionedBox(child: child); final double? smallBaseline = positioner.computeDryBaseline( const BoxConstraints(maxWidth: 1.0, maxHeight: 1.0), TextBaseline.alphabetic, ); expect(smallBaseline, isNotNull); // Test with zero constraints final double? zeroBaseline = positioner.computeDryBaseline( const BoxConstraints.tightFor(width: 0.0, height: 0.0), TextBaseline.alphabetic, ); expect(zeroBaseline, isNotNull); }); }); } // Mock render box for testing class MockRenderBox extends RenderBox { @override Size computeDryLayout(BoxConstraints constraints) { return constraints.constrain(const Size(50.0, 50.0)); } @override double? computeDryBaseline(BoxConstraints constraints, TextBaseline baseline) { return 40.0; // Mock baseline at 40 pixels from top } @override void performLayout() { size = constraints.constrain(const Size(50.0, 50.0)); } } // Mock render box that has no baseline for testing class MockRenderBoxNoBaseline extends RenderBox { @override Size computeDryLayout(BoxConstraints constraints) { return constraints.constrain(const Size(50.0, 50.0)); } @override double? computeDryBaseline(BoxConstraints constraints, TextBaseline baseline) { return null; // No baseline } @override void performLayout() { size = constraints.constrain(const Size(50.0, 50.0)); } }