baseline_test.dart 4.43 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
import 'package:flutter/material.dart';
6
import 'package:flutter_test/flutter_test.dart';
7 8 9 10

void main() {
  testWidgets('Baseline - control test', (WidgetTester tester) async {
    await tester.pumpWidget(
11
      const Center(
12 13
        child: DefaultTextStyle(
          style: TextStyle(
14 15 16
            fontFamily: 'Ahem',
            fontSize: 100.0,
          ),
17
          child: Text('X', textDirection: TextDirection.ltr),
18 19 20 21
        ),
      ),
    );
    expect(tester.renderObject<RenderBox>(find.text('X')).size, const Size(100.0, 100.0));
22
  });
23 24 25

  testWidgets('Baseline - position test', (WidgetTester tester) async {
    await tester.pumpWidget(
26
      const Center(
27
        child: Baseline(
28 29
          baseline: 180.0,
          baselineType: TextBaseline.alphabetic,
30 31
          child: DefaultTextStyle(
            style: TextStyle(
32 33 34
              fontFamily: 'Ahem',
              fontSize: 100.0,
            ),
35
            child: Text('X', textDirection: TextDirection.ltr),
36 37 38 39 40
          ),
        ),
      ),
    );
    expect(tester.renderObject<RenderBox>(find.text('X')).size, const Size(100.0, 100.0));
41 42 43 44
    expect(
      tester.renderObject<RenderBox>(find.byType(Baseline)).size,
      within<Size>(from: const Size(100.0, 200.0), distance: 0.001),
    );
45
  });
46 47 48 49

  testWidgets('Chip caches baseline', (WidgetTester tester) async {
    int calls = 0;
    await tester.pumpWidget(
50 51 52
      MaterialApp(
        home: Material(
          child: Baseline(
53 54
            baseline: 100.0,
            baselineType: TextBaseline.alphabetic,
55 56
            child: Chip(
              label: BaselineDetector(() {
57 58 59 60 61 62 63 64 65 66 67 68 69
                calls += 1;
              }),
            ),
          ),
        ),
      ),
    );
    expect(calls, 1);
    await tester.pump();
    expect(calls, 1);
    tester.renderObject<RenderBaselineDetector>(find.byType(BaselineDetector)).dirty();
    await tester.pump();
    expect(calls, 2);
70
  });
71 72 73 74

  testWidgets('ListTile caches baseline', (WidgetTester tester) async {
    int calls = 0;
    await tester.pumpWidget(
75 76 77
      MaterialApp(
        home: Material(
          child: Baseline(
78 79
            baseline: 100.0,
            baselineType: TextBaseline.alphabetic,
80 81
            child: ListTile(
              title: BaselineDetector(() {
82 83 84 85 86 87 88 89 90 91 92 93 94 95
                calls += 1;
              }),
            ),
          ),
        ),
      ),
    );
    expect(calls, 1);
    await tester.pump();
    expect(calls, 1);
    tester.renderObject<RenderBaselineDetector>(find.byType(BaselineDetector)).dirty();
    await tester.pump();
    expect(calls, 2);
  });
96

97
  testWidgets("LayoutBuilder returns child's baseline", (WidgetTester tester) async {
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Baseline(
            baseline: 180.0,
            baselineType: TextBaseline.alphabetic,
            child: LayoutBuilder(
              builder: (BuildContext context, BoxConstraints constraints) {
                return BaselineDetector(() {});
              },
            ),
          ),
        ),
      ),
    );

    expect(tester.getRect(find.byType(BaselineDetector)).top, 160.0);
  });
116 117 118
}

class BaselineDetector extends LeafRenderObjectWidget {
119
  const BaselineDetector(this.callback, { Key? key }) : super(key: key);
120 121 122 123

  final VoidCallback callback;

  @override
124
  RenderBaselineDetector createRenderObject(BuildContext context) => RenderBaselineDetector(callback);
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155

  @override
  void updateRenderObject(BuildContext context, RenderBaselineDetector renderObject) {
    renderObject.callback = callback;
  }
}

class RenderBaselineDetector extends RenderBox {
  RenderBaselineDetector(this.callback);

  VoidCallback callback;

  @override
  bool get sizedByParent => true;

  @override
  double computeMinIntrinsicWidth(double height) => 0.0;

  @override
  double computeMaxIntrinsicWidth(double height) => 0.0;

  @override
  double computeMinIntrinsicHeight(double width) => 0.0;

  @override
  double computeMaxIntrinsicHeight(double width) => 0.0;

  @override
  double computeDistanceToActualBaseline(TextBaseline baseline) {
    if (callback != null)
      callback();
156
    return 20.0;
157 158 159 160 161 162 163
  }

  void dirty() {
    markNeedsLayout();
  }

  @override
164 165
  Size computeDryLayout(BoxConstraints constraints) {
    return constraints.smallest;
166 167 168 169
  }

  @override
  void paint(PaintingContext context, Offset offset) { }
170
}