Unverified Commit 5054b6e5 authored by Bernardo Ferrari's avatar Bernardo Ferrari Committed by GitHub

Add Non-Uniform Border to Border. (#121921)

Add Non-Uniform Border to Border.
parent 59c9d4e8
...@@ -212,7 +212,9 @@ abstract class BoxBorder extends ShapeBorder { ...@@ -212,7 +212,9 @@ abstract class BoxBorder extends ShapeBorder {
/// ///
/// See also: /// See also:
/// ///
/// * [paintBorder], which is used if the border is not uniform. /// * [paintBorder], which is used if the border has non-uniform colors or styles and no borderRadius.
/// * [Border.paint], similar to this method, includes additional comments
/// and provides more details on each parameter than described here.
@override @override
void paint( void paint(
Canvas canvas, Canvas canvas,
...@@ -240,6 +242,62 @@ abstract class BoxBorder extends ShapeBorder { ...@@ -240,6 +242,62 @@ abstract class BoxBorder extends ShapeBorder {
} }
} }
static void _paintNonUniformBorder(
Canvas canvas,
Rect rect, {
required BorderRadius? borderRadius,
required BoxShape shape,
required TextDirection? textDirection,
required BorderSide left,
required BorderSide top,
required BorderSide right,
required BorderSide bottom,
}) {
final RRect borderRect;
switch(shape) {
case BoxShape.rectangle:
borderRect = (borderRadius ?? BorderRadius.zero)
.resolve(textDirection)
.toRRect(rect);
case BoxShape.circle:
assert(borderRadius == null, 'A borderRadius cannot be given when shape is a BoxShape.circle.');
borderRect = RRect.fromRectAndRadius(
Rect.fromCircle(center: rect.center, radius: rect.shortestSide / 2.0),
Radius.circular(rect.width),
);
}
final Paint paint = Paint()..color = top.color;
final RRect inner = _deflateRRect(borderRect, EdgeInsets.fromLTRB(left.strokeInset, top.strokeInset, right.strokeInset, bottom.strokeInset));
final RRect outer = _inflateRRect(borderRect, EdgeInsets.fromLTRB(left.strokeOutset, top.strokeOutset, right.strokeOutset, bottom.strokeOutset));
canvas.drawDRRect(outer, inner, paint);
}
static RRect _inflateRRect(RRect rect, EdgeInsets insets) {
return RRect.fromLTRBAndCorners(
rect.left - insets.left,
rect.top - insets.top,
rect.right + insets.right,
rect.bottom + insets.bottom,
topLeft: (rect.tlRadius + Radius.elliptical(insets.left, insets.top)).clamp(minimum: Radius.zero), // ignore_clamp_double_lint
topRight: (rect.trRadius + Radius.elliptical(insets.right, insets.top)).clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomRight: (rect.brRadius + Radius.elliptical(insets.right, insets.bottom)).clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomLeft: (rect.blRadius + Radius.elliptical(insets.left, insets.bottom)).clamp(minimum: Radius.zero), // ignore_clamp_double_lint
);
}
static RRect _deflateRRect(RRect rect, EdgeInsets insets) {
return RRect.fromLTRBAndCorners(
rect.left + insets.left,
rect.top + insets.top,
rect.right - insets.right,
rect.bottom - insets.bottom,
topLeft: (rect.tlRadius - Radius.elliptical(insets.left, insets.top)).clamp(minimum: Radius.zero), // ignore_clamp_double_lint
topRight: (rect.trRadius - Radius.elliptical(insets.right, insets.top)).clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomRight: (rect.brRadius - Radius.elliptical(insets.right, insets.bottom)).clamp(minimum: Radius.zero), // ignore_clamp_double_lint
bottomLeft:(rect.blRadius - Radius.elliptical(insets.left, insets.bottom)).clamp(minimum: Radius.zero), // ignore_clamp_double_lint
);
}
static void _paintUniformBorderWithCircle(Canvas canvas, Rect rect, BorderSide side) { static void _paintUniformBorderWithCircle(Canvas canvas, Rect rect, BorderSide side) {
assert(side.style != BorderStyle.none); assert(side.style != BorderStyle.none);
final double radius = (rect.shortestSide + side.strokeOffset) / 2; final double radius = (rect.shortestSide + side.strokeOffset) / 2;
...@@ -313,6 +371,10 @@ abstract class BoxBorder extends ShapeBorder { ...@@ -313,6 +371,10 @@ abstract class BoxBorder extends ShapeBorder {
/// * [BorderSide], which is used to describe each side of the box. /// * [BorderSide], which is used to describe each side of the box.
/// * [Theme], from the material layer, which can be queried to obtain appropriate colors /// * [Theme], from the material layer, which can be queried to obtain appropriate colors
/// to use for borders in a [MaterialApp], as shown in the "divider" sample above. /// to use for borders in a [MaterialApp], as shown in the "divider" sample above.
/// * [paint], which explains the behavior of [BoxDecoration] parameters.
/// * <https://pub.dev/packages/non_uniform_border>, a package that implements
/// a Non-Uniform Border on ShapeBorder, which is used by Material Design
/// buttons and other widgets, under the "shape" field.
class Border extends BoxBorder { class Border extends BoxBorder {
/// Creates a border. /// Creates a border.
/// ///
...@@ -407,24 +469,24 @@ class Border extends BoxBorder { ...@@ -407,24 +469,24 @@ class Border extends BoxBorder {
bool get _colorIsUniform { bool get _colorIsUniform {
final Color topColor = top.color; final Color topColor = top.color;
return right.color == topColor && bottom.color == topColor && left.color == topColor; return left.color == topColor && bottom.color == topColor && right.color == topColor;
} }
bool get _widthIsUniform { bool get _widthIsUniform {
final double topWidth = top.width; final double topWidth = top.width;
return right.width == topWidth && bottom.width == topWidth && left.width == topWidth; return left.width == topWidth && bottom.width == topWidth && right.width == topWidth;
} }
bool get _styleIsUniform { bool get _styleIsUniform {
final BorderStyle topStyle = top.style; final BorderStyle topStyle = top.style;
return right.style == topStyle && bottom.style == topStyle && left.style == topStyle; return left.style == topStyle && bottom.style == topStyle && right.style == topStyle;
} }
bool get _strokeAlignIsUniform { bool get _strokeAlignIsUniform {
final double topStrokeAlign = top.strokeAlign; final double topStrokeAlign = top.strokeAlign;
return right.strokeAlign == topStrokeAlign return left.strokeAlign == topStrokeAlign
&& bottom.strokeAlign == topStrokeAlign && bottom.strokeAlign == topStrokeAlign
&& left.strokeAlign == topStrokeAlign; && right.strokeAlign == topStrokeAlign;
} }
@override @override
...@@ -491,14 +553,16 @@ class Border extends BoxBorder { ...@@ -491,14 +553,16 @@ class Border extends BoxBorder {
/// Paints the border within the given [Rect] on the given [Canvas]. /// Paints the border within the given [Rect] on the given [Canvas].
/// ///
/// Uniform borders are more efficient to paint than more complex borders. /// Uniform borders and non-uniform borders with similar colors and styles
/// are more efficient to paint than more complex borders.
/// ///
/// You can provide a [BoxShape] to draw the border on. If the `shape` in /// You can provide a [BoxShape] to draw the border on. If the `shape` in
/// [BoxShape.circle], there is the requirement that the border [isUniform]. /// [BoxShape.circle], there is the requirement that the border has uniform
/// color and style.
/// ///
/// If you specify a rectangular box shape ([BoxShape.rectangle]), then you /// If you specify a rectangular box shape ([BoxShape.rectangle]), then you
/// may specify a [BorderRadius]. If a `borderRadius` is specified, there is /// may specify a [BorderRadius]. If a `borderRadius` is specified, there is
/// the requirement that the border [isUniform]. /// the requirement that the border has uniform color and style.
/// ///
/// The [getInnerPath] and [getOuterPath] methods do not know about the /// The [getInnerPath] and [getOuterPath] methods do not know about the
/// `shape` and `borderRadius` arguments. /// `shape` and `borderRadius` arguments.
...@@ -507,7 +571,10 @@ class Border extends BoxBorder { ...@@ -507,7 +571,10 @@ class Border extends BoxBorder {
/// ///
/// See also: /// See also:
/// ///
/// * [paintBorder], which is used if the border is not uniform. /// * [paintBorder], which is used if the border has non-uniform colors or styles and no borderRadius.
/// * <https://pub.dev/packages/non_uniform_border>, a package that implements
/// a Non-Uniform Border on ShapeBorder, which is used by Material Design
/// buttons and other widgets, under the "shape" field.
@override @override
void paint( void paint(
Canvas canvas, Canvas canvas,
...@@ -523,7 +590,7 @@ class Border extends BoxBorder { ...@@ -523,7 +590,7 @@ class Border extends BoxBorder {
case BorderStyle.solid: case BorderStyle.solid:
switch (shape) { switch (shape) {
case BoxShape.circle: case BoxShape.circle:
assert(borderRadius == null, 'A borderRadius can only be given for rectangular boxes.'); assert(borderRadius == null, 'A borderRadius cannot be given when shape is a BoxShape.circle.');
BoxBorder._paintUniformBorderWithCircle(canvas, rect, top); BoxBorder._paintUniformBorderWithCircle(canvas, rect, top);
case BoxShape.rectangle: case BoxShape.rectangle:
if (borderRadius != null && borderRadius != BorderRadius.zero) { if (borderRadius != null && borderRadius != BorderRadius.zero) {
...@@ -536,15 +603,31 @@ class Border extends BoxBorder { ...@@ -536,15 +603,31 @@ class Border extends BoxBorder {
} }
} }
// Allow painting non-uniform borders if the color and style are uniform.
if (_colorIsUniform && _styleIsUniform) {
switch(top.style) {
case BorderStyle.none:
return;
case BorderStyle.solid:
BoxBorder._paintNonUniformBorder(canvas, rect,
shape: shape,
borderRadius: borderRadius,
textDirection: textDirection,
left: left,
top: top,
right: right,
bottom: bottom);
return;
}
}
assert(() { assert(() {
if (borderRadius != null) { if (borderRadius != null) {
throw FlutterError.fromParts(<DiagnosticsNode>[ throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('A borderRadius can only be given for a uniform Border.'), ErrorSummary('A borderRadius can only be given on borders with uniform colors and styles.'),
ErrorDescription('The following is not uniform:'), ErrorDescription('The following is not uniform:'),
if (!_colorIsUniform) ErrorDescription('BorderSide.color'), if (!_colorIsUniform) ErrorDescription('BorderSide.color'),
if (!_widthIsUniform) ErrorDescription('BorderSide.width'),
if (!_styleIsUniform) ErrorDescription('BorderSide.style'), if (!_styleIsUniform) ErrorDescription('BorderSide.style'),
if (!_strokeAlignIsUniform) ErrorDescription('BorderSide.strokeAlign'),
]); ]);
} }
return true; return true;
...@@ -552,12 +635,10 @@ class Border extends BoxBorder { ...@@ -552,12 +635,10 @@ class Border extends BoxBorder {
assert(() { assert(() {
if (shape != BoxShape.rectangle) { if (shape != BoxShape.rectangle) {
throw FlutterError.fromParts(<DiagnosticsNode>[ throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('A Border can only be drawn as a circle if it is uniform.'), ErrorSummary('A Border can only be drawn as a circle on borders with uniform colors and styles.'),
ErrorDescription('The following is not uniform:'), ErrorDescription('The following is not uniform:'),
if (!_colorIsUniform) ErrorDescription('BorderSide.color'), if (!_colorIsUniform) ErrorDescription('BorderSide.color'),
if (!_widthIsUniform) ErrorDescription('BorderSide.width'),
if (!_styleIsUniform) ErrorDescription('BorderSide.style'), if (!_styleIsUniform) ErrorDescription('BorderSide.style'),
if (!_strokeAlignIsUniform) ErrorDescription('BorderSide.strokeAlign'),
]); ]);
} }
return true; return true;
...@@ -565,7 +646,7 @@ class Border extends BoxBorder { ...@@ -565,7 +646,7 @@ class Border extends BoxBorder {
assert(() { assert(() {
if (!_strokeAlignIsUniform || top.strokeAlign != BorderSide.strokeAlignInside) { if (!_strokeAlignIsUniform || top.strokeAlign != BorderSide.strokeAlignInside) {
throw FlutterError.fromParts(<DiagnosticsNode>[ throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('A Border can only draw strokeAlign different than BorderSide.strokeAlignInside on uniform borders.'), ErrorSummary('A Border can only draw strokeAlign different than BorderSide.strokeAlignInside on borders with uniform colors and styles.'),
]); ]);
} }
return true; return true;
...@@ -626,6 +707,9 @@ class Border extends BoxBorder { ...@@ -626,6 +707,9 @@ class Border extends BoxBorder {
/// * [BorderSide], which is used to describe each side of the box. /// * [BorderSide], which is used to describe each side of the box.
/// * [Theme], from the material layer, which can be queried to obtain appropriate colors /// * [Theme], from the material layer, which can be queried to obtain appropriate colors
/// to use for borders in a [MaterialApp], as shown in the "divider" sample above. /// to use for borders in a [MaterialApp], as shown in the "divider" sample above.
/// * <https://pub.dev/packages/non_uniform_border>, a package that implements
/// a Non-Uniform Border on ShapeBorder, which is used by Material Design
/// buttons and other widgets, under the "shape" field.
class BorderDirectional extends BoxBorder { class BorderDirectional extends BoxBorder {
/// Creates a border. /// Creates a border.
/// ///
...@@ -698,33 +782,21 @@ class BorderDirectional extends BoxBorder { ...@@ -698,33 +782,21 @@ class BorderDirectional extends BoxBorder {
} }
@override @override
bool get isUniform { bool get isUniform => _colorIsUniform && _widthIsUniform && _styleIsUniform && _strokeAlignIsUniform;
bool get _colorIsUniform {
final Color topColor = top.color; final Color topColor = top.color;
if (start.color != topColor || return start.color == topColor && bottom.color == topColor && end.color == topColor;
end.color != topColor || }
bottom.color != topColor) {
return false;
}
bool get _widthIsUniform {
final double topWidth = top.width; final double topWidth = top.width;
if (start.width != topWidth || return start.width == topWidth && bottom.width == topWidth && end.width == topWidth;
end.width != topWidth || }
bottom.width != topWidth) {
return false;
}
bool get _styleIsUniform {
final BorderStyle topStyle = top.style; final BorderStyle topStyle = top.style;
if (start.style != topStyle || return start.style == topStyle && bottom.style == topStyle && end.style == topStyle;
end.style != topStyle ||
bottom.style != topStyle) {
return false;
}
if (_strokeAlignIsUniform == false) {
return false;
}
return true;
} }
bool get _strokeAlignIsUniform { bool get _strokeAlignIsUniform {
...@@ -850,7 +922,7 @@ class BorderDirectional extends BoxBorder { ...@@ -850,7 +922,7 @@ class BorderDirectional extends BoxBorder {
/// ///
/// See also: /// See also:
/// ///
/// * [paintBorder], which is used if the border is not uniform. /// * [paintBorder], which is used if the border has non-uniform colors or styles and no borderRadius.
@override @override
void paint( void paint(
Canvas canvas, Canvas canvas,
...@@ -866,7 +938,7 @@ class BorderDirectional extends BoxBorder { ...@@ -866,7 +938,7 @@ class BorderDirectional extends BoxBorder {
case BorderStyle.solid: case BorderStyle.solid:
switch (shape) { switch (shape) {
case BoxShape.circle: case BoxShape.circle:
assert(borderRadius == null, 'A borderRadius can only be given for rectangular boxes.'); assert(borderRadius == null, 'A borderRadius cannot be given when shape is a BoxShape.circle.');
BoxBorder._paintUniformBorderWithCircle(canvas, rect, top); BoxBorder._paintUniformBorderWithCircle(canvas, rect, top);
case BoxShape.rectangle: case BoxShape.rectangle:
if (borderRadius != null && borderRadius != BorderRadius.zero) { if (borderRadius != null && borderRadius != BorderRadius.zero) {
...@@ -879,10 +951,6 @@ class BorderDirectional extends BoxBorder { ...@@ -879,10 +951,6 @@ class BorderDirectional extends BoxBorder {
} }
} }
assert(borderRadius == null, 'A borderRadius can only be given for uniform borders.');
assert(shape == BoxShape.rectangle, 'A border can only be drawn as a circle if it is uniform.');
assert(_strokeAlignIsUniform && top.strokeAlign == BorderSide.strokeAlignInside, 'A Border can only draw strokeAlign different than strokeAlignInside on uniform borders.');
final BorderSide left, right; final BorderSide left, right;
assert(textDirection != null, 'Non-uniform BorderDirectional objects require a TextDirection when painting.'); assert(textDirection != null, 'Non-uniform BorderDirectional objects require a TextDirection when painting.');
switch (textDirection!) { switch (textDirection!) {
...@@ -893,6 +961,29 @@ class BorderDirectional extends BoxBorder { ...@@ -893,6 +961,29 @@ class BorderDirectional extends BoxBorder {
left = start; left = start;
right = end; right = end;
} }
// Allow painting non-uniform borders if the color and style are uniform.
if (_colorIsUniform && _styleIsUniform) {
switch(top.style) {
case BorderStyle.none:
return;
case BorderStyle.solid:
BoxBorder._paintNonUniformBorder(canvas, rect,
shape: shape,
borderRadius: borderRadius,
textDirection: textDirection,
left: left,
top: top,
right: right,
bottom: bottom);
return;
}
}
assert(borderRadius == null, 'A borderRadius can only be given for borders with uniform colors and styles.');
assert(shape == BoxShape.rectangle, 'A Border can only be drawn as a circle on borders with uniform colors and styles.');
assert(_strokeAlignIsUniform && top.strokeAlign == BorderSide.strokeAlignInside, 'A Border can only draw strokeAlign different than strokeAlignInside on borders with uniform colors and styles.');
paintBorder(canvas, rect, top: top, left: left, bottom: bottom, right: right); paintBorder(canvas, rect, top: top, left: left, bottom: bottom, right: right);
} }
......
...@@ -1749,11 +1749,7 @@ void main() { ...@@ -1749,11 +1749,7 @@ void main() {
); );
expect( expect(
find.ancestor(of: find.byType(Table), matching: find.byType(Container)), find.ancestor(of: find.byType(Table), matching: find.byType(Container)),
paints paints..drrect(color: borderColor),
..path(color: borderColor)
..path(color: borderColor)
..path(color: borderColor)
..path(color: borderColor),
); );
expect( expect(
tester.getTopLeft(find.byType(Table)), tester.getTopLeft(find.byType(Table)),
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/foundation.dart' show FlutterError; import 'package:flutter/widgets.dart';
import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
class TestCanvas implements Canvas { class TestCanvas implements Canvas {
...@@ -264,8 +263,8 @@ void main() { ...@@ -264,8 +263,8 @@ void main() {
// Border.all supports all StrokeAlign values. // Border.all supports all StrokeAlign values.
// Border() supports [BorderSide.strokeAlignInside] only. // Border() supports [BorderSide.strokeAlignInside] only.
const Border( const Border(
left: BorderSide(strokeAlign: BorderSide.strokeAlignCenter), left: BorderSide(strokeAlign: BorderSide.strokeAlignCenter, color: Color(0xff000001)),
right: BorderSide(strokeAlign: BorderSide.strokeAlignOutside), right: BorderSide(strokeAlign: BorderSide.strokeAlignOutside, color: Color(0xff000002)),
).paint(canvas, const Rect.fromLTWH(10.0, 20.0, 30.0, 40.0)); ).paint(canvas, const Rect.fromLTWH(10.0, 20.0, 30.0, 40.0));
} on FlutterError catch (e) { } on FlutterError catch (e) {
error = e; error = e;
...@@ -274,7 +273,7 @@ void main() { ...@@ -274,7 +273,7 @@ void main() {
expect(error.diagnostics.length, 1); expect(error.diagnostics.length, 1);
expect( expect(
error.diagnostics[0].toStringDeep(), error.diagnostics[0].toStringDeep(),
'A Border can only draw strokeAlign different than\nBorderSide.strokeAlignInside on uniform borders.\n', 'A Border can only draw strokeAlign different than\nBorderSide.strokeAlignInside on borders with uniform colors and\nstyles.\n',
); );
}); });
...@@ -299,5 +298,108 @@ void main() { ...@@ -299,5 +298,108 @@ void main() {
const BorderSide outsideSide = BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignOutside); const BorderSide outsideSide = BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignOutside);
const BorderDirectional outsideBorderDirectional = BorderDirectional(top: outsideSide, bottom: outsideSide, start: outsideSide, end: outsideSide); const BorderDirectional outsideBorderDirectional = BorderDirectional(top: outsideSide, bottom: outsideSide, start: outsideSide, end: outsideSide);
expect(outsideBorderDirectional.dimensions, EdgeInsetsDirectional.zero); expect(outsideBorderDirectional.dimensions, EdgeInsetsDirectional.zero);
const Border nonUniformBorder = Border(
left: BorderSide(width: 5),
top: BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignCenter),
right: BorderSide(width: 15, strokeAlign: BorderSide.strokeAlignOutside),
bottom: BorderSide(width: 20),
);
expect(nonUniformBorder.dimensions, const EdgeInsets.fromLTRB(5, 5, 0, 20));
const BorderDirectional nonUniformBorderDirectional = BorderDirectional(
start: BorderSide(width: 5),
top: BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignCenter),
end: BorderSide(width: 15, strokeAlign: BorderSide.strokeAlignOutside),
bottom: BorderSide(width: 20),
);
expect(nonUniformBorderDirectional.dimensions, const EdgeInsetsDirectional.fromSTEB(5, 5, 0, 20));
});
testWidgets('Non-Uniform Border variations', (WidgetTester tester) async {
Widget buildWidget({ required BoxBorder border, BorderRadius? borderRadius, BoxShape boxShape = BoxShape.rectangle}) {
return Directionality(
textDirection: TextDirection.ltr,
child: DecoratedBox(
decoration: BoxDecoration(
shape: boxShape,
border: border,
borderRadius: borderRadius,
),
),
);
}
// This is used to test every allowed non-uniform border combination.
const Border allowedBorderVariations = Border(
left: BorderSide(width: 5),
top: BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignCenter),
right: BorderSide(width: 15, strokeAlign: BorderSide.strokeAlignOutside),
bottom: BorderSide(width: 20),
);
// This falls into non-uniform border because of strokeAlign.
await tester.pumpWidget(buildWidget(border: allowedBorderVariations));
expect(tester.takeException(), isNull,
reason: 'Border with non-uniform strokeAlign should not fail.');
await tester.pumpWidget(buildWidget(
border: allowedBorderVariations,
borderRadius: BorderRadius.circular(25),
));
expect(tester.takeException(), isNull);
await tester.pumpWidget(buildWidget(border: allowedBorderVariations, boxShape: BoxShape.circle));
expect(tester.takeException(), isNull);
await tester.pumpWidget(
buildWidget(
border: const Border(
left: BorderSide(width: 5, style: BorderStyle.none),
top: BorderSide(width: 10),
right: BorderSide(width: 15),
bottom: BorderSide(width: 20),
),
borderRadius: BorderRadius.circular(25),
),
);
expect(tester.takeException(), isAssertionError,
reason: 'Border with non-uniform styles should fail with borderRadius.');
await tester.pumpWidget(
buildWidget(
border: const Border(
left: BorderSide(width: 5, color: Color(0xff123456)),
top: BorderSide(width: 10),
right: BorderSide(width: 15),
bottom: BorderSide(width: 20),
),
borderRadius: BorderRadius.circular(20),
),
);
expect(tester.takeException(), isAssertionError,
reason: 'Border with non-uniform colors should fail with borderRadius.');
// Tests for BorderDirectional.
const BorderDirectional allowedBorderDirectionalVariations = BorderDirectional(
start: BorderSide(width: 5),
top: BorderSide(width: 10, strokeAlign: BorderSide.strokeAlignCenter),
end: BorderSide(width: 15, strokeAlign: BorderSide.strokeAlignOutside),
bottom: BorderSide(width: 20),
);
await tester.pumpWidget(buildWidget(border: allowedBorderDirectionalVariations));
expect(tester.takeException(), isNull);
await tester.pumpWidget(buildWidget(
border: allowedBorderDirectionalVariations,
borderRadius: BorderRadius.circular(25),
));
expect(tester.takeException(), isNull,
reason:'BorderDirectional should not fail with uniform styles and colors.');
await tester.pumpWidget(buildWidget(border: allowedBorderDirectionalVariations, boxShape: BoxShape.circle));
expect(tester.takeException(), isNull);
}); });
} }
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