blob: 69afd74f7943fbc36abb3d4e6c4a2b02c09b7e21 [file] [log] [blame]
// 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));
}
}