material_test.dart 4.05 KB
Newer Older
1 2 3 4 5
// Copyright 2016 The Chromium 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/material.dart';
6
import 'package:flutter/rendering.dart';
7 8 9 10 11 12 13 14 15 16
import 'package:flutter_test/flutter_test.dart';

class NotifyMaterial extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    new LayoutChangedNotification().dispatch(context);
    return new Container();
  }
}

17
Widget buildMaterial(double elevation) {
18 19 20 21 22 23 24 25 26 27 28 29
  return new Center(
    child: new SizedBox(
      height: 100.0,
      width: 100.0,
      child: new Material(
        color: const Color(0xFF00FF00),
        elevation: elevation,
      ),
    ),
  );
}

30 31
RenderPhysicalModel getShadow(WidgetTester tester) {
  return tester.renderObject(find.byType(PhysicalModel));
32 33
}

34 35 36
class PaintRecorder extends CustomPainter {
  PaintRecorder(this.log);

37
  final List<Size> log;
38 39 40 41 42

  @override
  void paint(Canvas canvas, Size size) {
    log.add(size);
    final Paint paint = new Paint()..color = const Color(0xFF0000FF);
43
    canvas.drawRect(Offset.zero & size, paint);
44 45 46 47 48 49
  }

  @override
  bool shouldRepaint(PaintRecorder oldDelegate) => false;
}

50 51 52 53
void main() {
  testWidgets('LayoutChangedNotificaion test', (WidgetTester tester) async {
    await tester.pumpWidget(
      new Material(
54 55
        child: new NotifyMaterial(),
      ),
56 57
    );
  });
58 59

  testWidgets('ListView scroll does not repaint', (WidgetTester tester) async {
60
    final List<Size> log = <Size>[];
61 62

    await tester.pumpWidget(
63 64 65 66 67 68 69 70 71 72
      new Directionality(
        textDirection: TextDirection.ltr,
        child: new Column(
          children: <Widget>[
            new SizedBox(
              width: 150.0,
              height: 150.0,
              child: new CustomPaint(
                painter: new PaintRecorder(log),
              ),
73
            ),
74 75 76 77 78 79 80 81 82 83 84 85 86
            new Expanded(
              child: new Material(
                child: new Column(
                  children: <Widget>[
                    new Expanded(
                      child: new ListView(
                        children: <Widget>[
                          new Container(
                            height: 2000.0,
                            color: const Color(0xFF00FF00),
                          ),
                        ],
                      ),
87
                    ),
88 89 90 91 92 93
                    new SizedBox(
                      width: 100.0,
                      height: 100.0,
                      child: new CustomPaint(
                        painter: new PaintRecorder(log),
                      ),
94
                    ),
95 96
                  ],
                ),
97 98
              ),
            ),
99 100
          ],
        ),
101 102 103 104 105 106 107 108 109 110 111
      ),
    );

    // We paint twice because we have two CustomPaint widgets in the tree above
    // to test repainting both inside and outside the Material widget.
    expect(log, equals(<Size>[
      const Size(150.0, 150.0),
      const Size(100.0, 100.0),
    ]));
    log.clear();

112
    await tester.drag(find.byType(ListView), const Offset(0.0, -300.0));
113 114 115 116
    await tester.pump();

    expect(log, isEmpty);
  });
117 118

  testWidgets('Shadows animate smoothly', (WidgetTester tester) async {
119 120
    // This code verifies that the PhysicalModel's elevation animates over
    // a kThemeChangeDuration time interval.
121

122 123 124 125 126 127 128
    await tester.pumpWidget(buildMaterial(0.0));
    final RenderPhysicalModel modelA = getShadow(tester);
    expect(modelA.elevation, equals(0.0));

    await tester.pumpWidget(buildMaterial(9.0));
    final RenderPhysicalModel modelB = getShadow(tester);
    expect(modelB.elevation, equals(0.0));
129 130

    await tester.pump(const Duration(milliseconds: 1));
131 132
    final RenderPhysicalModel modelC = getShadow(tester);
    expect(modelC.elevation, closeTo(0.0, 0.001));
133 134

    await tester.pump(kThemeChangeDuration ~/ 2);
135 136
    final RenderPhysicalModel modelD = getShadow(tester);
    expect(modelD.elevation, isNot(closeTo(0.0, 0.001)));
137 138

    await tester.pump(kThemeChangeDuration);
139 140
    final RenderPhysicalModel modelE = getShadow(tester);
    expect(modelE.elevation, equals(9.0));
141
  });
142
}