Commit 99822088 authored by Adam Barth's avatar Adam Barth Committed by GitHub

Add operator== and hashCode to TextTheme (#7586)

Teach `paints` matches about `drawRect` and how to `paintChild`.

Also, improve test coverage.
parent cbda208b
...@@ -277,6 +277,43 @@ class TextTheme { ...@@ -277,6 +277,43 @@ class TextTheme {
button: TextStyle.lerp(begin.button, end.button, t) button: TextStyle.lerp(begin.button, end.button, t)
); );
} }
@override
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
if (other is! TextTheme)
return false;
final TextTheme typedOther = other;
return display4 == typedOther.display4 &&
display3 == typedOther.display3 &&
display2 == typedOther.display2 &&
display1 == typedOther.display1 &&
headline == typedOther.headline &&
title == typedOther.title &&
subhead == typedOther.subhead &&
body2 == typedOther.body2 &&
body1 == typedOther.body1 &&
caption == typedOther.caption &&
button == typedOther.button;
}
@override
int get hashCode {
return hashValues(
display4,
display3,
display2,
display1,
headline,
title,
subhead,
body2,
body1,
caption,
button,
);
}
} }
/// The two material design text themes. /// The two material design text themes.
......
...@@ -6,6 +6,13 @@ import 'package:flutter/material.dart'; ...@@ -6,6 +6,13 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
test('ThemeDataTween control test', () {
ThemeData light = new ThemeData.light();
ThemeData dark = new ThemeData.light();
ThemeDataTween tween = new ThemeDataTween(begin: light, end: dark);
expect(tween.lerp(0.25), equals(ThemeData.lerp(light, dark, 0.25)));
});
testWidgets('PopupMenu inherits app theme', (WidgetTester tester) async { testWidgets('PopupMenu inherits app theme', (WidgetTester tester) async {
final Key popupMenuButtonKey = new UniqueKey(); final Key popupMenuButtonKey = new UniqueKey();
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -6,6 +6,14 @@ import 'package:flutter/material.dart'; ...@@ -6,6 +6,14 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
test('TextTheme control test', () {
Typography typography = new Typography(platform: TargetPlatform.android);
expect(typography.black, equals(typography.black.copyWith()));
expect(typography.black, equals(typography.black.apply()));
expect(typography.black.hashCode, equals(typography.black.copyWith().hashCode));
expect(typography.black, isNot(equals(typography.white)));
});
test('Typography is defined for all target platforms', () { test('Typography is defined for all target platforms', () {
for (TargetPlatform platform in TargetPlatform.values) { for (TargetPlatform platform in TargetPlatform.values) {
Typography typography = new Typography(platform: platform); Typography typography = new Typography(platform: platform);
......
...@@ -89,17 +89,17 @@ abstract class PaintPattern { ...@@ -89,17 +89,17 @@ abstract class PaintPattern {
/// See also: [save], [restore]. /// See also: [save], [restore].
void saveRestore(); void saveRestore();
/// Indicates that a circle is expected next. /// Indicates that a rectangle is expected next.
/// ///
/// The next circle is examined. Any arguments that are passed to this method /// The next rectangle is examined. Any arguments that are passed to this
/// are compared to the actual [Canvas.drawCircle] call's arguments and any /// method are compared to the actual [Canvas.drawRect] call's arguments
/// mismatches result in failure. /// and any mismatches result in failure.
/// ///
/// If no call to [Canvas.drawCircle] was made, then this results in failure. /// If no call to [Canvas.drawRect] was made, then this results in failure.
/// ///
/// Any calls made between the last matched call (if any) and the /// Any calls made between the last matched call (if any) and the
/// [Canvas.drawCircle] call are ignored. /// [Canvas.drawRect] call are ignored.
void circle({ double x, double y, double radius, Color color, bool hasMaskFilter, PaintingStyle style }); void rect({ Rect rect, Color color });
/// Indicates that a rounded rectangle is expected next. /// Indicates that a rounded rectangle is expected next.
/// ///
...@@ -113,6 +113,18 @@ abstract class PaintPattern { ...@@ -113,6 +113,18 @@ abstract class PaintPattern {
/// [Canvas.drawRRect] call are ignored. /// [Canvas.drawRRect] call are ignored.
void rrect({ RRect rrect, Color color, bool hasMaskFilter, PaintingStyle style }); void rrect({ RRect rrect, Color color, bool hasMaskFilter, PaintingStyle style });
/// Indicates that a circle is expected next.
///
/// The next circle is examined. Any arguments that are passed to this method
/// are compared to the actual [Canvas.drawCircle] call's arguments and any
/// mismatches result in failure.
///
/// If no call to [Canvas.drawCircle] was made, then this results in failure.
///
/// Any calls made between the last matched call (if any) and the
/// [Canvas.drawCircle] call are ignored.
void circle({ double x, double y, double radius, Color color, bool hasMaskFilter, PaintingStyle style });
/// Provides a custom matcher. /// Provides a custom matcher.
/// ///
/// Each method call after the last matched call (if any) will be passed to /// Each method call after the last matched call (if any) will be passed to
...@@ -171,8 +183,8 @@ class _TestRecordingCanvasPatternMatcher extends Matcher implements PaintPattern ...@@ -171,8 +183,8 @@ class _TestRecordingCanvasPatternMatcher extends Matcher implements PaintPattern
} }
@override @override
void circle({ double x, double y, double radius, Color color, bool hasMaskFilter, PaintingStyle style }) { void rect({ Rect rect, Color color, bool hasMaskFilter, PaintingStyle style }) {
_predicates.add(new _CirclePaintPredicate(x: x, y: y, radius: radius, color: color, hasMaskFilter: hasMaskFilter, style: style)); _predicates.add(new _RectPaintPredicate(rect: rect, color: color, hasMaskFilter: hasMaskFilter, style: style));
} }
@override @override
...@@ -180,6 +192,12 @@ class _TestRecordingCanvasPatternMatcher extends Matcher implements PaintPattern ...@@ -180,6 +192,12 @@ class _TestRecordingCanvasPatternMatcher extends Matcher implements PaintPattern
_predicates.add(new _RRectPaintPredicate(rrect: rrect, color: color, hasMaskFilter: hasMaskFilter, style: style)); _predicates.add(new _RRectPaintPredicate(rrect: rrect, color: color, hasMaskFilter: hasMaskFilter, style: style));
} }
@override
void circle({ double x, double y, double radius, Color color, bool hasMaskFilter, PaintingStyle style }) {
_predicates.add(new _CirclePaintPredicate(x: x, y: y, radius: radius, color: color, hasMaskFilter: hasMaskFilter, style: style));
}
@override @override
void something(PaintPatternPredicate predicate) { void something(PaintPatternPredicate predicate) {
_predicates.add(new _SomethingPaintPredicate(predicate)); _predicates.add(new _SomethingPaintPredicate(predicate));
...@@ -306,6 +324,11 @@ class _TestRecordingPaintingContext implements PaintingContext { ...@@ -306,6 +324,11 @@ class _TestRecordingPaintingContext implements PaintingContext {
@override @override
final Canvas canvas; final Canvas canvas;
@override
void paintChild(RenderObject child, Offset offset) {
child.paint(this, offset);
}
@override @override
void noSuchMethod(Invocation invocation) { void noSuchMethod(Invocation invocation) {
} }
...@@ -392,6 +415,56 @@ abstract class _DrawCommandPaintPredicate extends _PaintPredicate { ...@@ -392,6 +415,56 @@ abstract class _DrawCommandPaintPredicate extends _PaintPredicate {
} }
} }
class _OneParameterPaintPredicate<T> extends _DrawCommandPaintPredicate {
_OneParameterPaintPredicate(Symbol symbol, String name, {
@required this.expected,
@required Color color,
@required bool hasMaskFilter,
@required PaintingStyle style
}) : super(
symbol, name, 2, 1, color: color, hasMaskFilter: hasMaskFilter, style: style);
final T expected;
@override
void verifyArguments(List<dynamic> arguments) {
super.verifyArguments(arguments);
final T actual = arguments[0];
if (expected != null && actual != expected)
throw 'called $methodName with ${T.runtimeType}, $actual, which was not exactly the expected ${T.runtimeType} ($expected).';
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
if (expected != null)
description.add('${T.runtimeType}: $expected');
}
}
class _RectPaintPredicate extends _OneParameterPaintPredicate<Rect> {
_RectPaintPredicate({ Rect rect, Color color, bool hasMaskFilter, PaintingStyle style }) : super(
#drawRect,
'a rectangle',
expected: rect,
color: color,
hasMaskFilter: hasMaskFilter,
style: style,
);
}
class _RRectPaintPredicate extends _OneParameterPaintPredicate<RRect> {
_RRectPaintPredicate({ RRect rrect, Color color, bool hasMaskFilter, PaintingStyle style }) : super(
#drawRRect,
'a rounded rectangle',
expected: rrect,
color: color,
hasMaskFilter: hasMaskFilter,
style: style,
);
}
class _CirclePaintPredicate extends _DrawCommandPaintPredicate { class _CirclePaintPredicate extends _DrawCommandPaintPredicate {
_CirclePaintPredicate({ this.x, this.y, this.radius, Color color, bool hasMaskFilter, PaintingStyle style }) : super( _CirclePaintPredicate({ this.x, this.y, this.radius, Color color, bool hasMaskFilter, PaintingStyle style }) : super(
#drawCircle, 'a circle', 3, 2, color: color, hasMaskFilter: hasMaskFilter, style: style #drawCircle, 'a circle', 3, 2, color: color, hasMaskFilter: hasMaskFilter, style: style
...@@ -436,29 +509,6 @@ class _CirclePaintPredicate extends _DrawCommandPaintPredicate { ...@@ -436,29 +509,6 @@ class _CirclePaintPredicate extends _DrawCommandPaintPredicate {
} }
} }
class _RRectPaintPredicate extends _DrawCommandPaintPredicate {
_RRectPaintPredicate({ this.rrect, Color color, bool hasMaskFilter, PaintingStyle style }) : super(
#drawRRect, 'a rounded rectangle', 2, 1, color: color, hasMaskFilter: hasMaskFilter, style: style
);
final RRect rrect;
@override
void verifyArguments(List<dynamic> arguments) {
super.verifyArguments(arguments);
final RRect rrectArgument = arguments[0];
if (rrect != null && rrectArgument != rrect)
throw 'called $methodName with an rrect, $rrectArgument, which was not exactly the expected rrect ($rrect).';
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
if (rrect != null)
description.add('$rrect');
}
}
class _SomethingPaintPredicate extends _PaintPredicate { class _SomethingPaintPredicate extends _PaintPredicate {
_SomethingPaintPredicate(this.predicate); _SomethingPaintPredicate(this.predicate);
...@@ -593,4 +643,4 @@ String _describeInvocation(Invocation call) { ...@@ -593,4 +643,4 @@ String _describeInvocation(Invocation call) {
buffer.write(')'); buffer.write(')');
} }
return buffer.toString(); return buffer.toString();
} }
\ No newline at end of file
...@@ -7,6 +7,23 @@ import 'package:flutter/rendering.dart'; ...@@ -7,6 +7,23 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
void main() { void main() {
testWidgets('AnimatedContainer.debugFillDescription', (WidgetTester tester) async {
AnimatedContainer container = new AnimatedContainer(
constraints: const BoxConstraints.tightFor(width: 17.0, height: 23.0),
decoration: const BoxDecoration(backgroundColor: const Color(0xFF00FF00)),
foregroundDecoration: const BoxDecoration(backgroundColor: const Color(0x7F0000FF)),
margin: const EdgeInsets.all(10.0),
padding: const EdgeInsets.all(7.0),
transform: new Matrix4.translationValues(4.0, 3.0, 0.0),
width: 50.0,
height: 75.0,
curve: Curves.ease,
duration: const Duration(milliseconds: 200),
);
expect(container, hasOneLineDescription);
});
testWidgets('AnimatedContainer control test', (WidgetTester tester) async { testWidgets('AnimatedContainer control test', (WidgetTester tester) async {
GlobalKey key = new GlobalKey(); GlobalKey key = new GlobalKey();
......
...@@ -7,6 +7,19 @@ import 'package:flutter/rendering.dart'; ...@@ -7,6 +7,19 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
void main() { void main() {
testWidgets('AnimatedPositioned.fromRect control test', (WidgetTester tester) async {
AnimatedPositioned positioned = new AnimatedPositioned.fromRect(
rect: new Rect.fromLTWH(7.0, 5.0, 12.0, 16.0),
duration: const Duration(milliseconds: 200),
);
expect(positioned.left, equals(7.0));
expect(positioned.top, equals(5.0));
expect(positioned.width, equals(12.0));
expect(positioned.height, equals(16.0));
expect(positioned, hasOneLineDescription);
});
testWidgets('AnimatedPositioned - basics', (WidgetTester tester) async { testWidgets('AnimatedPositioned - basics', (WidgetTester tester) async {
GlobalKey key = new GlobalKey(); GlobalKey key = new GlobalKey();
......
...@@ -5,7 +5,50 @@ ...@@ -5,7 +5,50 @@
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import '../rendering/mock_canvas.dart';
void main() { void main() {
testWidgets('Container control test', (WidgetTester tester) async {
Container container = new Container(
alignment: FractionalOffset.bottomRight,
padding: const EdgeInsets.all(7.0),
decoration: const BoxDecoration(backgroundColor: const Color(0xFF00FF00)),
foregroundDecoration: const BoxDecoration(backgroundColor: const Color(0x7F0000FF)),
width: 53.0,
height: 76.0,
constraints: const BoxConstraints(
minWidth: 50.0,
maxWidth: 55.0,
minHeight: 78.0,
maxHeight: 82.0,
),
margin: const EdgeInsets.all(5.0),
child: new SizedBox(
width: 25.0,
height: 33.0,
child: new DecoratedBox(
decoration: const BoxDecoration(backgroundColor: const Color(0xFFFFFF00)),
),
),
);
expect(container, hasOneLineDescription);
await tester.pumpWidget(new Align(
alignment: FractionalOffset.topLeft,
child: container
));
RenderBox box = tester.renderObject(find.byType(Container));
expect(box, isNotNull);
expect(box, paints
..rect(rect: new Rect.fromLTWH(5.0, 5.0, 53.0, 78.0), color: const Color(0xFF00FF00))
..rect(rect: new Rect.fromLTWH(26.0, 43.0, 25.0, 33.0), color: const Color(0xFFFFFF00))
..rect(rect: new Rect.fromLTWH(5.0, 5.0, 53.0, 78.0), color: const Color(0x7F0000FF))
);
});
testWidgets('Can be placed in an infinite box', (WidgetTester tester) async { testWidgets('Can be placed in an infinite box', (WidgetTester tester) async {
await tester.pumpWidget(new Block(children: <Widget>[new Container()])); await tester.pumpWidget(new Block(children: <Widget>[new Container()]));
}); });
......
// Copyright 2017 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_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
class TestLocaleQueryData extends LocaleQueryData {
@override
String toString() => 'Test data';
}
void main() {
testWidgets('LocaleQuery control test', (WidgetTester tester) async {
await tester.pumpWidget(new Container());
expect(LocaleQuery.of(tester.element(find.byType(Container))), isNull);
LocaleQueryData data = new TestLocaleQueryData();
Widget widget = new LocaleQuery(
data: data,
child: new Container(),
);
expect(widget, hasOneLineDescription);
expect(widget.toString(), contains('Test data'));
await tester.pumpWidget(widget);
expect(LocaleQuery.of(tester.element(find.byType(Container))), equals(data));
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment