Skip to content

Commit 9995e37

Browse files
authored
Fix StarBorder operator== (flutter#113588)
1 parent 021f8a5 commit 9995e37

File tree

4 files changed

+103
-61
lines changed

4 files changed

+103
-61
lines changed

dev/manual_tests/lib/star_border.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ class _MyHomePageState extends State<MyHomePage> {
7272
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
7373
children: <Widget>[
7474
Container(
75-
key: UniqueKey(),
7675
alignment: Alignment.center,
7776
width: 300,
7877
height: 200,
@@ -94,7 +93,6 @@ class _MyHomePageState extends State<MyHomePage> {
9493
child: const Text('Polygon'),
9594
),
9695
Container(
97-
key: UniqueKey(),
9896
alignment: Alignment.center,
9997
width: 300,
10098
height: 200,

examples/api/lib/painting/star_border/star_border.0.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ class ExampleBorder extends StatelessWidget {
144144
@override
145145
Widget build(BuildContext context) {
146146
return Container(
147-
key: UniqueKey(),
148147
alignment: Alignment.center,
149148
padding: const EdgeInsets.all(20),
150149
width: 150,

packages/flutter/lib/src/painting/star_border.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,14 @@ class StarBorder extends OutlinedBorder {
422422
if (other.runtimeType != runtimeType) {
423423
return false;
424424
}
425-
return other is StarBorder && other.side == side;
425+
return other is StarBorder
426+
&& other.side == side
427+
&& other.points == points
428+
&& other._innerRadiusRatio == _innerRadiusRatio
429+
&& other.pointRounding == pointRounding
430+
&& other.valleyRounding == valleyRounding
431+
&& other._rotationRadians == _rotationRadians
432+
&& other.squash == squash;
426433
}
427434

428435
@override

packages/flutter/test/painting/star_border_test.dart

Lines changed: 95 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,41 @@ void main() {
7676
expect(const StarBorder(), equals(const StarBorder().copyWith()));
7777
expect(copy, equals(expected));
7878
expect(copy.hashCode, equals(expected.hashCode));
79+
80+
// Test that all properties are checked in operator==
81+
expect(const StarBorder(), isNot(equals(const StarBorderSubclass())));
82+
expect(copy, isNot(equals('Not a StarBorder')));
83+
84+
// Test that two StarBorders where the only difference is polygon vs star
85+
// constructor compare as different (which they are, because
86+
// _innerRadiusRatio is null on the polygon).
87+
expect(
88+
const StarBorder(
89+
points: 3,
90+
innerRadiusRatio: 1,
91+
pointRounding: 0.2,
92+
rotation: 180,
93+
squash: 0.4,
94+
),
95+
isNot(equals(
96+
const StarBorder.polygon(
97+
sides: 3,
98+
pointRounding: 0.2,
99+
rotation: 180,
100+
squash: 0.4,
101+
),
102+
)),
103+
);
104+
105+
// Test that copies are unequal whenever any one of the properties changes.
106+
expect(copy, equals(copy));
107+
expect(copy, isNot(equals(copy.copyWith(side: const BorderSide()))));
108+
expect(copy, isNot(equals(copy.copyWith(points: 10))));
109+
expect(copy, isNot(equals(copy.copyWith(innerRadiusRatio: 0.5))));
110+
expect(copy, isNot(equals(copy.copyWith(pointRounding: 0.5))));
111+
expect(copy, isNot(equals(copy.copyWith(valleyRounding: 0.5))));
112+
expect(copy, isNot(equals(copy.copyWith(rotation: 10))));
113+
expect(copy, isNot(equals(copy.copyWith(squash: 0.0))));
79114
});
80115

81116
testWidgets('StarBorder basic geometry', (WidgetTester tester) async {
@@ -87,14 +122,14 @@ void main() {
87122
await testBorder(tester, 'points_6', const StarBorder(points: 6));
88123
await testBorder(tester, 'points_2', const StarBorder(points: 2));
89124
await testBorder(tester, 'inner_radius_0', const StarBorder(innerRadiusRatio: 0.0));
90-
await testBorder(tester, 'inner_radius_2', const StarBorder(innerRadiusRatio: 0.2));
91-
await testBorder(tester, 'inner_radius_7', const StarBorder(innerRadiusRatio: 0.7));
92-
await testBorder(tester, 'point_rounding_2', const StarBorder(pointRounding: 0.2));
93-
await testBorder(tester, 'point_rounding_7', const StarBorder(pointRounding: 0.7));
94-
await testBorder(tester, 'point_rounding_10', const StarBorder(pointRounding: 1.0));
95-
await testBorder(tester, 'valley_rounding_2', const StarBorder(valleyRounding: 0.2));
96-
await testBorder(tester, 'valley_rounding_7', const StarBorder(valleyRounding: 0.7));
97-
await testBorder(tester, 'valley_rounding_10', const StarBorder(valleyRounding: 1.0));
125+
await testBorder(tester, 'inner_radius_20', const StarBorder(innerRadiusRatio: 0.2));
126+
await testBorder(tester, 'inner_radius_70', const StarBorder(innerRadiusRatio: 0.7));
127+
await testBorder(tester, 'point_rounding_20', const StarBorder(pointRounding: 0.2));
128+
await testBorder(tester, 'point_rounding_70', const StarBorder(pointRounding: 0.7));
129+
await testBorder(tester, 'point_rounding_100', const StarBorder(pointRounding: 1.0));
130+
await testBorder(tester, 'valley_rounding_20', const StarBorder(valleyRounding: 0.2));
131+
await testBorder(tester, 'valley_rounding_70', const StarBorder(valleyRounding: 0.7));
132+
await testBorder(tester, 'valley_rounding_100', const StarBorder(valleyRounding: 1.0));
98133
await testBorder(tester, 'squash_2', const StarBorder(squash: 0.2));
99134
await testBorder(tester, 'squash_7', const StarBorder(squash: 0.7));
100135
await testBorder(tester, 'squash_10', const StarBorder(squash: 1.0));
@@ -104,32 +139,27 @@ void main() {
104139
await testBorder(tester, 'side_none', const StarBorder(side: BorderSide(style: BorderStyle.none)));
105140
await testBorder(tester, 'side_1', const StarBorder(side: BorderSide(color: Color(0xffff0000))));
106141
await testBorder(tester, 'side_10', const StarBorder(side: BorderSide(color: Color(0xffff0000), width: 10)));
107-
await testBorder(tester, 'side_align_center',
108-
const StarBorder(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignCenter)));
109-
await testBorder(tester, 'side_align_outside',
110-
const StarBorder(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignOutside)));
142+
await testBorder(tester, 'side_align_center', const StarBorder(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignCenter)));
143+
await testBorder(tester, 'side_align_outside', const StarBorder(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignOutside)));
111144
});
112145

113146
testWidgets('StarBorder.polygon parameters', (WidgetTester tester) async {
114147
await testBorder(tester, 'poly_sides_6', const StarBorder.polygon(sides: 6));
115148
await testBorder(tester, 'poly_sides_2', const StarBorder.polygon(sides: 2));
116-
await testBorder(tester, 'poly_point_rounding_2', const StarBorder.polygon(pointRounding: 0.2));
117-
await testBorder(tester, 'poly_point_rounding_7', const StarBorder.polygon(pointRounding: 0.7));
118-
await testBorder(tester, 'poly_point_rounding_10', const StarBorder.polygon(pointRounding: 1.0));
119-
await testBorder(tester, 'poly_squash_2', const StarBorder.polygon(squash: 0.2));
120-
await testBorder(tester, 'poly_squash_7', const StarBorder.polygon(squash: 0.7));
121-
await testBorder(tester, 'poly_squash_10', const StarBorder.polygon(squash: 1.0));
149+
await testBorder(tester, 'poly_point_rounding_20', const StarBorder.polygon(pointRounding: 0.2));
150+
await testBorder(tester, 'poly_point_rounding_70', const StarBorder.polygon(pointRounding: 0.7));
151+
await testBorder(tester, 'poly_point_rounding_100', const StarBorder.polygon(pointRounding: 1.0));
152+
await testBorder(tester, 'poly_squash_20', const StarBorder.polygon(squash: 0.2));
153+
await testBorder(tester, 'poly_squash_70', const StarBorder.polygon(squash: 0.7));
154+
await testBorder(tester, 'poly_squash_100', const StarBorder.polygon(squash: 1.0));
122155
await testBorder(tester, 'poly_rotate_27', const StarBorder.polygon(rotation: 27));
123156
await testBorder(tester, 'poly_rotate_270', const StarBorder.polygon(rotation: 270));
124157
await testBorder(tester, 'poly_rotate_360', const StarBorder.polygon(rotation: 360));
125158
await testBorder(tester, 'poly_side_none', const StarBorder.polygon(side: BorderSide(style: BorderStyle.none)));
126159
await testBorder(tester, 'poly_side_1', const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000))));
127-
await testBorder(
128-
tester, 'poly_side_10', const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000), width: 10)));
129-
await testBorder(tester, 'poly_side_align_center',
130-
const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignCenter)));
131-
await testBorder(tester, 'poly_side_align_outside',
132-
const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignOutside)));
160+
await testBorder(tester, 'poly_side_10', const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000), width: 10)));
161+
await testBorder(tester, 'poly_side_align_center', const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignCenter)));
162+
await testBorder(tester, 'poly_side_align_outside', const StarBorder.polygon(side: BorderSide(color: Color(0xffff0000), strokeAlign: BorderSide.strokeAlignOutside)));
133163
});
134164

135165
testWidgets("StarBorder doesn't try to scale an infinite scale matrix", (WidgetTester tester) async {
@@ -141,7 +171,7 @@ void main() {
141171
width: 100,
142172
height: 100,
143173
child: Stack(
144-
children: <Widget> [
174+
children: <Widget>[
145175
Positioned.fromRelativeRect(
146176
rect: const RelativeRect.fromLTRB(100, 100, 100, 100),
147177
child: Container(
@@ -169,61 +199,69 @@ void main() {
169199
innerRadiusRatio: 0.5,
170200
rotation: 90,
171201
);
172-
await testBorder(tester, 'to_star_border_2', from, lerpTo: otherBorder, lerpAmount: 0.2);
173-
await testBorder(tester, 'to_star_border_7', from, lerpTo: otherBorder, lerpAmount: 0.7);
174-
await testBorder(tester, 'to_star_border_10', from, lerpTo: otherBorder, lerpAmount: 1.0);
175-
await testBorder(tester, 'from_star_border_2', from, lerpFrom: otherBorder, lerpAmount: 0.2);
176-
await testBorder(tester, 'from_star_border_7', from, lerpFrom: otherBorder, lerpAmount: 0.7);
177-
await testBorder(tester, 'from_star_border_10', from, lerpFrom: otherBorder, lerpAmount: 1.0);
202+
await testBorder(tester, 'to_star_border_20', from, lerpTo: otherBorder, lerpAmount: 0.2);
203+
await testBorder(tester, 'to_star_border_70', from, lerpTo: otherBorder, lerpAmount: 0.7);
204+
await testBorder(tester, 'to_star_border_100', from, lerpTo: otherBorder, lerpAmount: 1.0);
205+
await testBorder(tester, 'from_star_border_20', from, lerpFrom: otherBorder, lerpAmount: 0.2);
206+
await testBorder(tester, 'from_star_border_70', from, lerpFrom: otherBorder, lerpAmount: 0.7);
207+
await testBorder(tester, 'from_star_border_100', from, lerpFrom: otherBorder, lerpAmount: 1.0);
178208
});
179209

180210
testWidgets('StarBorder lerped with CircleBorder', (WidgetTester tester) async {
181211
const StarBorder from = StarBorder();
182212
const ShapeBorder otherBorder = CircleBorder();
183213
const ShapeBorder eccentricCircle = CircleBorder(eccentricity: 0.6);
184-
await testBorder(tester, 'to_circle_border_2', from, lerpTo: otherBorder, lerpAmount: 0.2);
185-
await testBorder(tester, 'to_circle_border_7', from, lerpTo: otherBorder, lerpAmount: 0.7);
186-
await testBorder(tester, 'to_circle_border_10', from, lerpTo: otherBorder, lerpAmount: 1.0);
187-
await testBorder(tester, 'from_circle_border_2', from, lerpFrom: otherBorder, lerpAmount: 0.2);
188-
await testBorder(tester, 'from_circle_border_7', from, lerpFrom: otherBorder, lerpAmount: 0.7);
189-
await testBorder(tester, 'from_circle_border_10', from, lerpFrom: otherBorder, lerpAmount: 1.0);
190-
await testBorder(tester, 'to_eccentric_circle_border', from, lerpTo: eccentricCircle, lerpAmount: 0.4);
191-
await testBorder(tester, 'from_eccentric_circle_border', from, lerpFrom: eccentricCircle, lerpAmount: 0.4);
214+
await testBorder(tester, 'to_circle_border_20', from, lerpTo: otherBorder, lerpAmount: 0.2);
215+
await testBorder(tester, 'to_circle_border_70', from, lerpTo: otherBorder, lerpAmount: 0.7);
216+
await testBorder(tester, 'to_circle_border_100', from, lerpTo: otherBorder, lerpAmount: 1.0);
217+
await testBorder(tester, 'from_circle_border_20', from, lerpFrom: otherBorder, lerpAmount: 0.2);
218+
await testBorder(tester, 'from_circle_border_70', from, lerpFrom: otherBorder, lerpAmount: 0.7);
219+
await testBorder(tester, 'from_circle_border_100', from, lerpFrom: otherBorder, lerpAmount: 1.0);
220+
await testBorder(tester, 'to_eccentric_circle_border_20', from, lerpTo: eccentricCircle, lerpAmount: 0.2);
221+
await testBorder(tester, 'to_eccentric_circle_border_70', from, lerpTo: eccentricCircle, lerpAmount: 0.7);
222+
await testBorder(tester, 'to_eccentric_circle_border_100', from, lerpTo: eccentricCircle, lerpAmount: 1.0);
223+
await testBorder(tester, 'from_eccentric_circle_border_20', from, lerpFrom: eccentricCircle, lerpAmount: 0.2);
224+
await testBorder(tester, 'from_eccentric_circle_border_70', from, lerpFrom: eccentricCircle, lerpAmount: 0.7);
225+
await testBorder(tester, 'from_eccentric_circle_border_100', from, lerpFrom: eccentricCircle, lerpAmount: 1.0);
192226
});
193227

194228
testWidgets('StarBorder lerped with RoundedRectangleBorder', (WidgetTester tester) async {
195229
const StarBorder from = StarBorder();
196230
const RoundedRectangleBorder rectangleBorder = RoundedRectangleBorder();
197-
await testBorder(tester, 'to_rect_border_2', from, lerpTo: rectangleBorder, lerpAmount: 0.2);
198-
await testBorder(tester, 'to_rect_border_7', from, lerpTo: rectangleBorder, lerpAmount: 0.7);
199-
await testBorder(tester, 'to_rect_border_10', from, lerpTo: rectangleBorder, lerpAmount: 1.0);
200-
await testBorder(tester, 'from_rect_border_2', from, lerpFrom: rectangleBorder, lerpAmount: 0.2);
201-
await testBorder(tester, 'from_rect_border_7', from, lerpFrom: rectangleBorder, lerpAmount: 0.7);
202-
await testBorder(tester, 'from_rect_border_10', from, lerpFrom: rectangleBorder, lerpAmount: 1.0);
231+
await testBorder(tester, 'to_rect_border_20', from, lerpTo: rectangleBorder, lerpAmount: 0.2);
232+
await testBorder(tester, 'to_rect_border_70', from, lerpTo: rectangleBorder, lerpAmount: 0.7);
233+
await testBorder(tester, 'to_rect_border_100', from, lerpTo: rectangleBorder, lerpAmount: 1.0);
234+
await testBorder(tester, 'from_rect_border_20', from, lerpFrom: rectangleBorder, lerpAmount: 0.2);
235+
await testBorder(tester, 'from_rect_border_70', from, lerpFrom: rectangleBorder, lerpAmount: 0.7);
236+
await testBorder(tester, 'from_rect_border_100', from, lerpFrom: rectangleBorder, lerpAmount: 1.0);
203237

204238
const RoundedRectangleBorder roundedRectBorder = RoundedRectangleBorder(
205239
borderRadius: BorderRadius.only(
206240
bottomLeft: Radius.circular(10.0),
207241
bottomRight: Radius.circular(10.0),
208242
),
209243
);
210-
await testBorder(tester, 'to_rrect_border_2', from, lerpTo: roundedRectBorder, lerpAmount: 0.2);
211-
await testBorder(tester, 'to_rrect_border_7', from, lerpTo: roundedRectBorder, lerpAmount: 0.7);
212-
await testBorder(tester, 'to_rrect_border_10', from, lerpTo: roundedRectBorder, lerpAmount: 1.0);
213-
await testBorder(tester, 'from_rrect_border_2', from, lerpFrom: roundedRectBorder, lerpAmount: 0.2);
214-
await testBorder(tester, 'from_rrect_border_7', from, lerpFrom: roundedRectBorder, lerpAmount: 0.7);
215-
await testBorder(tester, 'from_rrect_border_10', from, lerpFrom: roundedRectBorder, lerpAmount: 1.0);
244+
await testBorder(tester, 'to_rrect_border_20', from, lerpTo: roundedRectBorder, lerpAmount: 0.2);
245+
await testBorder(tester, 'to_rrect_border_70', from, lerpTo: roundedRectBorder, lerpAmount: 0.7);
246+
await testBorder(tester, 'to_rrect_border_100', from, lerpTo: roundedRectBorder, lerpAmount: 1.0);
247+
await testBorder(tester, 'from_rrect_border_20', from, lerpFrom: roundedRectBorder, lerpAmount: 0.2);
248+
await testBorder(tester, 'from_rrect_border_70', from, lerpFrom: roundedRectBorder, lerpAmount: 0.7);
249+
await testBorder(tester, 'from_rrect_border_100', from, lerpFrom: roundedRectBorder, lerpAmount: 1.0);
216250
});
217251

218252
testWidgets('StarBorder lerped with StadiumBorder', (WidgetTester tester) async {
219253
const StarBorder from = StarBorder();
220254
const StadiumBorder stadiumBorder = StadiumBorder();
221255

222-
await testBorder(tester, 'to_stadium_border_2', from, lerpTo: stadiumBorder, lerpAmount: 0.2);
223-
await testBorder(tester, 'to_stadium_border_7', from, lerpTo: stadiumBorder, lerpAmount: 0.7);
224-
await testBorder(tester, 'to_stadium_border_10', from, lerpTo: stadiumBorder, lerpAmount: 1.0);
225-
await testBorder(tester, 'from_stadium_border_2', from, lerpFrom: stadiumBorder, lerpAmount: 0.2);
226-
await testBorder(tester, 'from_stadium_border_7', from, lerpFrom: stadiumBorder, lerpAmount: 0.7);
227-
await testBorder(tester, 'from_stadium_border_10', from, lerpFrom: stadiumBorder, lerpAmount: 1.0);
256+
await testBorder(tester, 'to_stadium_border_20', from, lerpTo: stadiumBorder, lerpAmount: 0.2);
257+
await testBorder(tester, 'to_stadium_border_70', from, lerpTo: stadiumBorder, lerpAmount: 0.7);
258+
await testBorder(tester, 'to_stadium_border_100', from, lerpTo: stadiumBorder, lerpAmount: 1.0);
259+
await testBorder(tester, 'from_stadium_border_20', from, lerpFrom: stadiumBorder, lerpAmount: 0.2);
260+
await testBorder(tester, 'from_stadium_border_70', from, lerpFrom: stadiumBorder, lerpAmount: 0.7);
261+
await testBorder(tester, 'from_stadium_border_100', from, lerpFrom: stadiumBorder, lerpAmount: 1.0);
228262
});
229263
}
264+
265+
class StarBorderSubclass extends StarBorder {
266+
const StarBorderSubclass();
267+
}

0 commit comments

Comments
 (0)