1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This file is run as part of a reduced test set in CI on Mac and Windows
6// machines.
7@Tags(<String>['reduced-test-set'])
8library;
9
10import 'dart:math' as math;
11
12import 'package:flutter/widgets.dart';
13import 'package:flutter_test/flutter_test.dart';
14
15bool _listDoubleMatches(List<double>? x, List<double>? y) {
16 if (x == null && y == null) {
17 return true;
18 }
19 if (x == null || y == null) {
20 return false;
21 }
22 if (x.length != y.length) {
23 return false;
24 }
25 for (int i = 0; i < x.length; i++) {
26 if ((x[i] - y[i]).abs() >= 0.0001) {
27 return false;
28 }
29 }
30 return true;
31}
32
33bool _listColorMatches(List<Color> x, List<Color> y) {
34 if (x.length != y.length) {
35 return false;
36 }
37 const double limit = 1/255;
38 for (int i = 0; i < x.length; i++) {
39 if ((x[i].a - y[i].a).abs() >= limit ||
40 (x[i].r - y[i].r).abs() >= limit ||
41 (x[i].g - y[i].g).abs() >= limit ||
42 (x[i].b - y[i].b).abs() >= limit) {
43 return false;
44 }
45 }
46 return true;
47}
48
49class _LinearGradientMatcher extends Matcher {
50 _LinearGradientMatcher(this._target);
51 final LinearGradient _target;
52
53 @override
54 Description describe(Description description) {
55 description.add('expected $_target');
56 return description;
57 }
58
59 @override
60 bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
61 return item is LinearGradient &&
62 item.begin == _target.begin &&
63 item.end == _target.end &&
64 item.tileMode == _target.tileMode &&
65 item.transform == _target.transform &&
66 _listColorMatches(item.colors, _target.colors) &&
67 _listDoubleMatches(item.stops, _target.stops);
68 }
69}
70
71Matcher _matchesLinearGradient(LinearGradient target) =>
72 _LinearGradientMatcher(target);
73
74class _RadialGradientMatcher extends Matcher {
75 _RadialGradientMatcher(this._target);
76 final RadialGradient _target;
77
78 @override
79 Description describe(Description description) {
80 description.add('expected $_target');
81 return description;
82 }
83
84 @override
85 bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
86 if (item is RadialGradient) {
87 return item.center == _target.center &&
88 item.radius == _target.radius &&
89 item.tileMode == _target.tileMode &&
90 item.transform == _target.transform &&
91 item.focal == _target.focal &&
92 item.focalRadius == _target.focalRadius &&
93 _listColorMatches(item.colors, _target.colors) &&
94 _listDoubleMatches(item.stops, _target.stops);
95 } else {
96 return false;
97 }
98 }
99}
100
101Matcher _matchesRadialGradient(RadialGradient target) =>
102 _RadialGradientMatcher(target);
103
104
105class _SweepGradientMatcher extends Matcher {
106 _SweepGradientMatcher(this._target);
107 final SweepGradient _target;
108
109 @override
110 Description describe(Description description) {
111 description.add('expected $_target');
112 return description;
113 }
114
115 @override
116 bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
117 if (item is SweepGradient) {
118 return item.center == _target.center &&
119 item.startAngle == _target.startAngle &&
120 item.endAngle == _target.endAngle &&
121 item.tileMode == _target.tileMode &&
122 item.transform == _target.transform &&
123 _listColorMatches(item.colors, _target.colors) &&
124 _listDoubleMatches(item.stops, _target.stops);
125 } else {
126 return false;
127 }
128 }
129}
130
131Matcher _matchesSweepGradient(SweepGradient target) =>
132 _SweepGradientMatcher(target);
133
134void main() {
135 test('LinearGradient scale test', () {
136 const LinearGradient testGradient = LinearGradient(
137 begin: Alignment.bottomRight,
138 end: Alignment(0.7, 1.0),
139 colors: <Color>[
140 Color(0x00FFFFFF),
141 Color(0x11777777),
142 Color(0x44444444),
143 ],
144 );
145 final LinearGradient? actual = LinearGradient.lerp(null, testGradient, 0.25);
146
147 expect(actual, _matchesLinearGradient(const LinearGradient(
148 begin: Alignment.bottomRight,
149 end: Alignment(0.7, 1.0),
150 colors: <Color>[
151 Color(0x00FFFFFF),
152 Color(0x04777777),
153 Color(0x11444444),
154 ],
155 )));
156 });
157
158 test('LinearGradient lerp test', () {
159 const LinearGradient testGradient1 = LinearGradient(
160 begin: Alignment.topLeft,
161 end: Alignment.bottomLeft,
162 colors: <Color>[
163 Color(0x33333333),
164 Color(0x66666666),
165 ],
166 );
167 const LinearGradient testGradient2 = LinearGradient(
168 begin: Alignment.topRight,
169 end: Alignment.topLeft,
170 colors: <Color>[
171 Color(0x44444444),
172 Color(0x88888888),
173 ],
174 );
175
176 final LinearGradient? actual = LinearGradient.lerp(testGradient1, testGradient2, 0.5);
177 expect(actual, _matchesLinearGradient(const LinearGradient(
178 begin: Alignment.topCenter,
179 end: Alignment.centerLeft,
180 colors: <Color>[
181 Color(0x3B3B3B3B),
182 Color(0x77777777),
183 ],
184 stops: <double>[0, 1],
185 )));
186 });
187
188 test('LinearGradient.lerp identical a,b', () {
189 expect(LinearGradient.lerp(null, null, 0), null);
190 const LinearGradient gradient = LinearGradient(
191 colors: <Color>[
192 Color(0x33333333),
193 Color(0x66666666),
194 ],
195 );
196 expect(identical(LinearGradient.lerp(gradient, gradient, 0.5), gradient), true);
197 });
198
199 test('LinearGradient lerp test with stops', () {
200 const LinearGradient testGradient1 = LinearGradient(
201 begin: Alignment.topLeft,
202 end: Alignment.bottomLeft,
203 colors: <Color>[
204 Color(0x33333333),
205 Color(0x66666666),
206 ],
207 stops: <double>[
208 0.0,
209 0.5,
210 ],
211 );
212 const LinearGradient testGradient2 = LinearGradient(
213 begin: Alignment.topRight,
214 end: Alignment.topLeft,
215 colors: <Color>[
216 Color(0x44444444),
217 Color(0x88888888),
218 ],
219 stops: <double>[
220 0.5,
221 1.0,
222 ],
223 );
224
225 final LinearGradient? actual = LinearGradient.lerp(testGradient1, testGradient2, 0.5);
226 expect(actual, _matchesLinearGradient(const LinearGradient(
227 begin: Alignment.topCenter,
228 end: Alignment.centerLeft,
229 colors: <Color>[
230 Color(0x3B3B3B3B),
231 Color(0x55555555),
232 Color(0x77777777),
233 ],
234 stops: <double>[
235 0.0,
236 0.5,
237 1.0,
238 ],
239 )));
240 });
241
242 test('LinearGradient lerp test with unequal number of colors', () {
243 const LinearGradient testGradient1 = LinearGradient(
244 colors: <Color>[
245 Color(0x22222222),
246 Color(0x66666666),
247 ],
248 );
249 const LinearGradient testGradient2 = LinearGradient(
250 colors: <Color>[
251 Color(0x44444444),
252 Color(0x66666666),
253 Color(0x88888888),
254 ],
255 );
256
257 final LinearGradient? actual = LinearGradient.lerp(testGradient1, testGradient2, 0.5);
258 expect(actual, _matchesLinearGradient(const LinearGradient(
259 colors: <Color>[
260 Color(0x33333333),
261 Color(0x55555555),
262 Color(0x77777777),
263 ],
264 stops: <double>[
265 0.0,
266 0.5,
267 1.0,
268 ],
269 )));
270 });
271
272 test('LinearGradient lerp test with stops and unequal number of colors', () {
273 const LinearGradient testGradient1 = LinearGradient(
274 colors: <Color>[
275 Color(0x33333333),
276 Color(0x66666666),
277 ],
278 stops: <double>[
279 0.0,
280 0.5,
281 ],
282 );
283 const LinearGradient testGradient2 = LinearGradient(
284 colors: <Color>[
285 Color(0x44444444),
286 Color(0x48484848),
287 Color(0x88888888),
288 ],
289 stops: <double>[
290 0.5,
291 0.7,
292 1.0,
293 ],
294 );
295
296 final LinearGradient? actual = LinearGradient.lerp(testGradient1, testGradient2, 0.5);
297 expect(actual, _matchesLinearGradient(const LinearGradient(
298 colors: <Color>[
299 Color(0x3B3B3B3B),
300 Color(0x55555555),
301 Color(0x57575757),
302 Color(0x77777777),
303 ],
304 stops: <double>[
305 0.0,
306 0.5,
307 0.7,
308 1.0,
309 ],
310 )));
311 });
312
313 test('LinearGradient lerp test with transforms', () {
314 const LinearGradient testGradient1 = LinearGradient(
315 transform: GradientRotation(math.pi/4),
316 colors: <Color>[
317 Color(0x33333333),
318 Color(0x66666666),
319 ],
320 stops: <double>[0, 1],
321 );
322 const LinearGradient testGradient2 = LinearGradient(
323 transform: GradientRotation(math.pi/2),
324 colors: <Color>[
325 Color(0x33333333),
326 Color(0x66666666),
327 ],
328 stops: <double>[0, 1],
329 );
330
331 final LinearGradient? actual0 = LinearGradient.lerp(testGradient1, testGradient2, 0.0);
332 final LinearGradient? actual1 = LinearGradient.lerp(testGradient1, testGradient2, 1.0);
333 final LinearGradient? actual2 = LinearGradient.lerp(testGradient1, testGradient2, 0.5);
334 expect(testGradient1, equals(actual0));
335 expect(testGradient2, equals(actual1));
336 expect(testGradient2, equals(actual2));
337 });
338
339 test('LinearGradient toString', () {
340 expect(
341 const LinearGradient(
342 begin: Alignment.topLeft,
343 end: Alignment.bottomLeft,
344 transform: GradientRotation(1.6),
345 colors: <Color>[
346 Color(0x33333333),
347 Color(0x66666666),
348 ],
349 ).toString(),
350 equals(
351 'LinearGradient(begin: Alignment.topLeft, end: Alignment.bottomLeft, colors: [${const Color(0x33333333)}, ${const Color(0x66666666)}], tileMode: TileMode.clamp, transform: GradientRotation(radians: 1.6))',
352 ),
353 );
354 });
355
356 test('LinearGradient with different transforms', () {
357 const LinearGradient testGradient1 = LinearGradient(
358 transform: GradientRotation(math.pi/4),
359 colors: <Color>[
360 Color(0x33333333),
361 Color(0x66666666),
362 ],
363 );
364 const LinearGradient testGradient1Copy = LinearGradient(
365 transform: GradientRotation(math.pi/4),
366 colors: <Color>[
367 Color(0x33333333),
368 Color(0x66666666),
369 ],
370 );
371 const LinearGradient testGradient2 = LinearGradient(
372 transform: GradientRotation(math.pi/2),
373 colors: <Color>[
374 Color(0x33333333),
375 Color(0x66666666),
376 ],
377 );
378
379 expect(
380 testGradient1,
381 equals(testGradient1Copy),
382 );
383 expect(
384 testGradient1,
385 isNot(equals(testGradient2)),
386 );
387 });
388
389 test('LinearGradient with AlignmentDirectional', () {
390 expect(
391 () {
392 return const LinearGradient(
393 begin: AlignmentDirectional.topStart,
394 colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
395 ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
396 },
397 throwsAssertionError,
398 );
399 expect(
400 () {
401 return const LinearGradient(
402 begin: AlignmentDirectional.topStart,
403 colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
404 ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0), textDirection: TextDirection.rtl);
405 },
406 returnsNormally,
407 );
408 expect(
409 () {
410 return const LinearGradient(
411 begin: AlignmentDirectional.topStart,
412 colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
413 ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0), textDirection: TextDirection.ltr);
414 },
415 returnsNormally,
416 );
417 expect(
418 () {
419 return const LinearGradient(
420 begin: Alignment.topLeft,
421 colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
422 ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
423 },
424 returnsNormally,
425 );
426 });
427
428 test('LinearGradient withOpacity test', () {
429 const LinearGradient testGradient = LinearGradient(
430 begin: Alignment.bottomRight,
431 end: Alignment.topCenter,
432 colors: <Color>[
433 Color(0xFFFFFFFF),
434 Color(0xAF777777),
435 Color(0x44444444),
436 ],
437 );
438 final LinearGradient actual = testGradient.withOpacity(0.5);
439
440 expect(actual, const LinearGradient(
441 begin: Alignment.bottomRight,
442 end: Alignment.topCenter,
443 colors: <Color>[
444 Color(0x80FFFFFF),
445 Color(0x80777777),
446 Color(0x80444444),
447 ],
448 ));
449 });
450
451 test('LinearGradient withOpacity() preserves transform', () {
452 const LinearGradient testGradient = LinearGradient(
453 begin: Alignment.bottomRight,
454 end: Alignment.topCenter,
455 colors: <Color>[
456 Color(0xFFFFFFFF),
457 Color(0xAF777777),
458 Color(0x44444444),
459 ],
460 transform: GradientRotation(1),
461 );
462 final LinearGradient actual = testGradient.withOpacity(0.5);
463
464 expect(actual, const LinearGradient(
465 begin: Alignment.bottomRight,
466 end: Alignment.topCenter,
467 colors: <Color>[
468 Color(0x80FFFFFF),
469 Color(0x80777777),
470 Color(0x80444444),
471 ],
472 transform: GradientRotation(1),
473 ));
474 });
475
476 test('RadialGradient with AlignmentDirectional', () {
477 expect(
478 () {
479 return const RadialGradient(
480 center: AlignmentDirectional.topStart,
481 colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
482 ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
483 },
484 throwsAssertionError,
485 );
486
487 expect(
488 () {
489 return const RadialGradient(
490 center: AlignmentDirectional.topStart,
491 colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
492 ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0), textDirection: TextDirection.rtl);
493 },
494 returnsNormally,
495 );
496 expect(
497 () {
498 return const RadialGradient(
499 center: AlignmentDirectional.topStart,
500 colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
501 ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0), textDirection: TextDirection.ltr);
502 },
503 returnsNormally,
504 );
505 expect(
506 () {
507 return const RadialGradient(
508 center: Alignment.topLeft,
509 colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
510 ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
511 },
512 returnsNormally,
513 );
514 });
515
516 test('RadialGradient lerp test', () {
517 const RadialGradient testGradient1 = RadialGradient(
518 center: Alignment.topLeft,
519 radius: 20.0,
520 colors: <Color>[
521 Color(0x33333333),
522 Color(0x66666666),
523 ],
524 );
525 const RadialGradient testGradient2 = RadialGradient(
526 center: Alignment.topRight,
527 radius: 10.0,
528 colors: <Color>[
529 Color(0x44444444),
530 Color(0x88888888),
531 ],
532 );
533
534 final RadialGradient? actual = RadialGradient.lerp(testGradient1, testGradient2, 0.5);
535 expect(actual, _matchesRadialGradient(const RadialGradient(
536 center: Alignment.topCenter,
537 radius: 15.0,
538 colors: <Color>[
539 Color(0x3B3B3B3B),
540 Color(0x77777777),
541 ],
542 stops: <double>[
543 0.0,
544 1.0,
545 ],
546 )));
547 });
548
549 test('RadialGradient.lerp identical a,b', () {
550 expect(RadialGradient.lerp(null, null, 0), null);
551 const RadialGradient gradient = RadialGradient(
552 colors: <Color>[
553 Color(0x33333333),
554 Color(0x66666666),
555 ],
556 );
557 expect(identical(RadialGradient.lerp(gradient, gradient, 0.5), gradient), true);
558 });
559
560 test('RadialGradient lerp test with stops', () {
561 const RadialGradient testGradient1 = RadialGradient(
562 center: Alignment.topLeft,
563 radius: 20.0,
564 colors: <Color>[
565 Color(0x33333333),
566 Color(0x66666666),
567 ],
568 stops: <double>[
569 0.0,
570 0.5,
571 ],
572 );
573 const RadialGradient testGradient2 = RadialGradient(
574 center: Alignment.topRight,
575 radius: 10.0,
576 colors: <Color>[
577 Color(0x44444444),
578 Color(0x88888888),
579 ],
580 stops: <double>[
581 0.5,
582 1.0,
583 ],
584 );
585
586 final RadialGradient? actual = RadialGradient.lerp(testGradient1, testGradient2, 0.5);
587
588 expect(actual, _matchesRadialGradient(const RadialGradient(
589 center: Alignment.topCenter,
590 radius: 15.0,
591 colors: <Color>[
592 Color(0x3B3B3B3B),
593 Color(0x55555555),
594 Color(0x77777777),
595 ],
596 stops: <double>[
597 0.0,
598 0.5,
599 1.0,
600 ],
601 )));
602
603 expect(actual!.focal, isNull);
604 });
605
606 test('RadialGradient lerp test with unequal number of colors', () {
607 const RadialGradient testGradient1 = RadialGradient(
608 colors: <Color>[
609 Color(0x22222222),
610 Color(0x66666666),
611 ],
612 );
613 const RadialGradient testGradient2 = RadialGradient(
614 colors: <Color>[
615 Color(0x44444444),
616 Color(0x66666666),
617 Color(0x88888888),
618 ],
619 );
620
621 final RadialGradient? actual = RadialGradient.lerp(testGradient1, testGradient2, 0.5);
622 expect(actual, _matchesRadialGradient(const RadialGradient(
623 colors: <Color>[
624 Color(0x33333333),
625 Color(0x55555555),
626 Color(0x77777777),
627 ],
628 stops: <double>[
629 0.0,
630 0.5,
631 1.0,
632 ],
633 )));
634 });
635
636 test('RadialGradient lerp test with stops and unequal number of colors', () {
637 const RadialGradient testGradient1 = RadialGradient(
638 colors: <Color>[
639 Color(0x33333333),
640 Color(0x66666666),
641 ],
642 stops: <double>[
643 0.0,
644 0.5,
645 ],
646 );
647 const RadialGradient testGradient2 = RadialGradient(
648 colors: <Color>[
649 Color(0x44444444),
650 Color(0x48484848),
651 Color(0x88888888),
652 ],
653 stops: <double>[
654 0.5,
655 0.7,
656 1.0,
657 ],
658 );
659
660 final RadialGradient? actual = RadialGradient.lerp(testGradient1, testGradient2, 0.5);
661 expect(actual, _matchesRadialGradient(const RadialGradient(
662 colors: <Color>[
663 Color(0x3B3B3B3B),
664 Color(0x55555555),
665 Color(0x57575757),
666 Color(0x77777777),
667 ],
668 stops: <double>[
669 0.0,
670 0.5,
671 0.7,
672 1.0,
673 ],
674 )));
675 });
676
677 test('RadialGradient lerp test with transforms', () {
678 const RadialGradient testGradient1 = RadialGradient(
679 transform: GradientRotation(math.pi/4),
680 colors: <Color>[
681 Color(0x33333333),
682 Color(0x66666666),
683 ],
684 stops: <double>[0, 1],
685 );
686 const RadialGradient testGradient2 = RadialGradient(
687 transform: GradientRotation(math.pi/2),
688 colors: <Color>[
689 Color(0x33333333),
690 Color(0x66666666),
691 ],
692 stops: <double>[0, 1],
693 );
694
695 final RadialGradient? actual0 = RadialGradient.lerp(testGradient1, testGradient2, 0.0);
696 final RadialGradient? actual1 = RadialGradient.lerp(testGradient1, testGradient2, 1.0);
697 final RadialGradient? actual2 = RadialGradient.lerp(testGradient1, testGradient2, 0.5);
698 expect(testGradient1, equals(actual0));
699 expect(testGradient2, equals(actual1));
700 expect(testGradient2, equals(actual2));
701 });
702
703 test('RadialGradient lerp test with focal', () {
704 const RadialGradient testGradient1 = RadialGradient(
705 center: Alignment.topLeft,
706 focal: Alignment.centerLeft,
707 radius: 20.0,
708 focalRadius: 10.0,
709 colors: <Color>[
710 Color(0x33333333),
711 Color(0x66666666),
712 ],
713 );
714 const RadialGradient testGradient2 = RadialGradient(
715 center: Alignment.topRight,
716 focal: Alignment.centerRight,
717 radius: 10.0,
718 focalRadius: 5.0,
719 colors: <Color>[
720 Color(0x44444444),
721 Color(0x88888888),
722 ],
723 );
724 const RadialGradient testGradient3 = RadialGradient(
725 center: Alignment.topRight,
726 radius: 10.0,
727 colors: <Color>[
728 Color(0x44444444),
729 Color(0x88888888),
730 ],
731 );
732
733 final RadialGradient? actual = RadialGradient.lerp(testGradient1, testGradient2, 0.5);
734 expect(actual, _matchesRadialGradient(const RadialGradient(
735 center: Alignment.topCenter,
736 focal: Alignment.center,
737 radius: 15.0,
738 focalRadius: 7.5,
739 colors: <Color>[
740 Color(0x3B3B3B3B),
741 Color(0x77777777),
742 ],
743 stops: <double>[
744 0.0,
745 1.0,
746 ],
747 )));
748
749 final RadialGradient? actual2 = RadialGradient.lerp(testGradient1, testGradient3, 0.5);
750 expect(actual2, _matchesRadialGradient(const RadialGradient(
751 center: Alignment.topCenter,
752 focal: Alignment(-0.5, 0.0),
753 radius: 15.0,
754 focalRadius: 5.0,
755 colors: <Color>[
756 Color(0x3B3B3B3B),
757 Color(0x77777777),
758 ],
759 stops: <double>[
760 0.0,
761 1.0,
762 ],
763 )));
764 });
765
766
767 test('RadialGradient withOpacity test', () {
768 const RadialGradient testGradient = RadialGradient(
769 center: Alignment.topLeft,
770 focal: Alignment.centerLeft,
771 radius: 20.0,
772 focalRadius: 10.0,
773 colors: <Color>[
774 Color(0xFFFFFFFF),
775 Color(0xAF777777),
776 Color(0x44444444),
777 ],
778 );
779 final RadialGradient actual = testGradient.withOpacity(0.5);
780
781 expect(actual, const RadialGradient(
782 center: Alignment.topLeft,
783 focal: Alignment.centerLeft,
784 radius: 20.0,
785 focalRadius: 10.0,
786 colors: <Color>[
787 Color(0x80FFFFFF),
788 Color(0x80777777),
789 Color(0x80444444),
790 ],
791 ));
792 });
793
794 test('RadialGradient withOpacity() preserves transform', () {
795 const RadialGradient testGradient = RadialGradient(
796 center: Alignment.topLeft,
797 focal: Alignment.centerLeft,
798 radius: 20.0,
799 focalRadius: 10.0,
800 colors: <Color>[
801 Color(0xFFFFFFFF),
802 Color(0xAF777777),
803 Color(0x44444444),
804 ],
805 transform: GradientRotation(1),
806 );
807 final RadialGradient actual = testGradient.withOpacity(0.5);
808
809 expect(actual, const RadialGradient(
810 center: Alignment.topLeft,
811 focal: Alignment.centerLeft,
812 radius: 20.0,
813 focalRadius: 10.0,
814 colors: <Color>[
815 Color(0x80FFFFFF),
816 Color(0x80777777),
817 Color(0x80444444),
818 ],
819 transform: GradientRotation(1),
820 ));
821 });
822
823 test('SweepGradient lerp test', () {
824 const SweepGradient testGradient1 = SweepGradient(
825 center: Alignment.topLeft,
826 endAngle: math.pi / 2,
827 colors: <Color>[
828 Color(0x33333333),
829 Color(0x66666666),
830 ],
831 );
832 const SweepGradient testGradient2 = SweepGradient(
833 center: Alignment.topRight,
834 startAngle: math.pi / 2,
835 endAngle: math.pi,
836 colors: <Color>[
837 Color(0x44444444),
838 Color(0x88888888),
839 ],
840 );
841
842 final SweepGradient? actual = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
843 expect(actual, _matchesSweepGradient(const SweepGradient(
844 center: Alignment.topCenter,
845 startAngle: math.pi / 4,
846 endAngle: math.pi * 3/4,
847 colors: <Color>[
848 Color(0x3B3B3B3B),
849 Color(0x77777777),
850 ],
851 stops: <double>[
852 0.0,
853 1.0,
854 ],
855 )));
856 });
857
858 test('SweepGradient.lerp identical a,b', () {
859 expect(SweepGradient.lerp(null, null, 0), null);
860 const SweepGradient gradient = SweepGradient(
861 colors: <Color>[
862 Color(0x33333333),
863 Color(0x66666666),
864 ],
865 );
866 expect(identical(SweepGradient.lerp(gradient, gradient, 0.5), gradient), true);
867 });
868
869 test('SweepGradient lerp test with stops', () {
870 const SweepGradient testGradient1 = SweepGradient(
871 center: Alignment.topLeft,
872 endAngle: math.pi / 2,
873 colors: <Color>[
874 Color(0x33333333),
875 Color(0x66666666),
876 ],
877 stops: <double>[
878 0.0,
879 0.5,
880 ],
881 );
882 const SweepGradient testGradient2 = SweepGradient(
883 center: Alignment.topRight,
884 startAngle: math.pi / 2,
885 endAngle: math.pi,
886 colors: <Color>[
887 Color(0x44444444),
888 Color(0x88888888),
889 ],
890 stops: <double>[
891 0.5,
892 1.0,
893 ],
894 );
895
896 final SweepGradient? actual = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
897 expect(actual, _matchesSweepGradient(const SweepGradient(
898 center: Alignment.topCenter,
899 startAngle: math.pi / 4,
900 endAngle: math.pi * 3/4,
901 colors: <Color>[
902 Color(0x3B3B3B3B),
903 Color(0x55555555),
904 Color(0x77777777),
905 ],
906 stops: <double>[
907 0.0,
908 0.5,
909 1.0,
910 ],
911 )));
912 });
913
914 test('SweepGradient lerp test with unequal number of colors', () {
915 const SweepGradient testGradient1 = SweepGradient(
916 colors: <Color>[
917 Color(0x22222222),
918 Color(0x66666666),
919 ],
920 );
921 const SweepGradient testGradient2 = SweepGradient(
922 colors: <Color>[
923 Color(0x44444444),
924 Color(0x66666666),
925 Color(0x88888888),
926 ],
927 );
928
929 final SweepGradient? actual = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
930 expect(actual, _matchesSweepGradient(const SweepGradient(
931 colors: <Color>[
932 Color(0x33333333),
933 Color(0x55555555),
934 Color(0x77777777),
935 ],
936 stops: <double>[
937 0.0,
938 0.5,
939 1.0,
940 ],
941 )));
942 });
943
944 test('SweepGradient lerp test with stops and unequal number of colors', () {
945 const SweepGradient testGradient1 = SweepGradient(
946 colors: <Color>[
947 Color(0x33333333),
948 Color(0x66666666),
949 ],
950 stops: <double>[
951 0.0,
952 0.5,
953 ],
954 );
955 const SweepGradient testGradient2 = SweepGradient(
956 colors: <Color>[
957 Color(0x44444444),
958 Color(0x48484848),
959 Color(0x88888888),
960 ],
961 stops: <double>[
962 0.5,
963 0.7,
964 1.0,
965 ],
966 );
967
968 final SweepGradient? actual = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
969 expect(actual, _matchesSweepGradient(const SweepGradient(
970 colors: <Color>[
971 Color(0x3B3B3B3B),
972 Color(0x55555555),
973 Color(0x57575757),
974 Color(0x77777777),
975 ],
976 stops: <double>[
977 0.0,
978 0.5,
979 0.7,
980 1.0,
981 ],
982 )));
983 });
984
985 test('SweepGradient lerp test with transforms', () {
986 const SweepGradient testGradient1 = SweepGradient(
987 transform: GradientRotation(math.pi/4),
988 colors: <Color>[
989 Color(0x33333333),
990 Color(0x66666666),
991 ],
992 stops: <double>[0, 1],
993 );
994 const SweepGradient testGradient2 = SweepGradient(
995 transform: GradientRotation(math.pi/2),
996 colors: <Color>[
997 Color(0x33333333),
998 Color(0x66666666),
999 ],
1000 stops: <double>[0, 1],
1001 );
1002
1003 final SweepGradient? actual0 = SweepGradient.lerp(testGradient1, testGradient2, 0.0);
1004 final SweepGradient? actual1 = SweepGradient.lerp(testGradient1, testGradient2, 1.0);
1005 final SweepGradient? actual2 = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
1006 expect(testGradient1, equals(actual0));
1007 expect(testGradient2, equals(actual1));
1008 expect(testGradient2, equals(actual2));
1009 });
1010
1011 test('SweepGradient scale test)', () {
1012 const SweepGradient testGradient = SweepGradient(
1013 center: Alignment.topLeft,
1014 endAngle: math.pi / 2,
1015 colors: <Color>[
1016 Color(0xff333333),
1017 Color(0xff666666),
1018 ],
1019 );
1020
1021 final SweepGradient actual = testGradient.scale(0.5);
1022
1023 expect(actual, _matchesSweepGradient(const SweepGradient(
1024 center: Alignment.topLeft,
1025 endAngle: math.pi / 2,
1026 colors: <Color>[
1027 Color(0x80333333),
1028 Color(0x80666666),
1029 ],
1030 )));
1031 });
1032
1033 test('SweepGradient withOpacity test', () {
1034 const SweepGradient testGradient = SweepGradient(
1035 center: Alignment.topLeft,
1036 endAngle: math.pi / 2,
1037 colors: <Color>[
1038 Color(0xFFFFFFFF),
1039 Color(0xAF777777),
1040 Color(0x44444444),
1041 ],
1042 );
1043 final SweepGradient actual = testGradient.withOpacity(0.5);
1044
1045 expect(actual, const SweepGradient(
1046 center: Alignment.topLeft,
1047 endAngle: math.pi / 2,
1048 colors: <Color>[
1049 Color(0x80FFFFFF),
1050 Color(0x80777777),
1051 Color(0x80444444),
1052 ],
1053 ));
1054 });
1055
1056 test('SweepGradient withOpacity() preserves transform', () {
1057 const SweepGradient testGradient = SweepGradient(
1058 center: Alignment.topLeft,
1059 endAngle: math.pi / 2,
1060 colors: <Color>[
1061 Color(0xFFFFFFFF),
1062 Color(0xAF777777),
1063 Color(0x44444444),
1064 ],
1065 transform: GradientRotation(1),
1066 );
1067 final SweepGradient actual = testGradient.withOpacity(0.5);
1068
1069 expect(actual, const SweepGradient(
1070 center: Alignment.topLeft,
1071 endAngle: math.pi / 2,
1072 colors: <Color>[
1073 Color(0x80FFFFFF),
1074 Color(0x80777777),
1075 Color(0x80444444),
1076 ],
1077 transform: GradientRotation(1),
1078 ));
1079 });
1080
1081 test('Gradient lerp test (with RadialGradient)', () {
1082 const RadialGradient testGradient1 = RadialGradient(
1083 center: Alignment.topLeft,
1084 radius: 20.0,
1085 colors: <Color>[
1086 Color(0x33333333),
1087 Color(0x66666666),
1088 ],
1089 stops: <double>[
1090 0.0,
1091 1.0,
1092 ],
1093 );
1094 const RadialGradient testGradient2 = RadialGradient(
1095 center: Alignment.topCenter,
1096 radius: 15.0,
1097 colors: <Color>[
1098 Color(0x3B3B3B3B),
1099 Color(0x77777777),
1100 ],
1101 stops: <double>[
1102 0.0,
1103 1.0,
1104 ],
1105 );
1106 const RadialGradient testGradient3 = RadialGradient(
1107 center: Alignment.topRight,
1108 radius: 10.0,
1109 colors: <Color>[
1110 Color(0x44444444),
1111 Color(0x88888888),
1112 ],
1113 stops: <double>[
1114 0.0,
1115 1.0,
1116 ],
1117 );
1118
1119 expect(Gradient.lerp(testGradient1, testGradient3, 0.0), _matchesRadialGradient(testGradient1));
1120 expect(Gradient.lerp(testGradient1, testGradient3, 0.5), _matchesRadialGradient(testGradient2));
1121 expect(Gradient.lerp(testGradient1, testGradient3, 1.0), _matchesRadialGradient(testGradient3));
1122 expect(Gradient.lerp(testGradient3, testGradient1, 0.0), _matchesRadialGradient(testGradient3));
1123 expect(Gradient.lerp(testGradient3, testGradient1, 0.5), _matchesRadialGradient(testGradient2));
1124 expect(Gradient.lerp(testGradient3, testGradient1, 1.0), _matchesRadialGradient(testGradient1));
1125 });
1126
1127 test('Gradient lerp test (LinearGradient to RadialGradient)', () {
1128 const LinearGradient testGradient1 = LinearGradient(
1129 begin: Alignment.topLeft,
1130 end: Alignment.bottomRight,
1131 colors: <Color>[
1132 Color(0x33333333),
1133 Color(0x66666666),
1134 ],
1135 );
1136 const RadialGradient testGradient2 = RadialGradient(
1137 radius: 20.0,
1138 colors: <Color>[
1139 Color(0x44444444),
1140 Color(0x88888888),
1141 ],
1142 );
1143
1144 expect(Gradient.lerp(testGradient1, testGradient2, 0.0), testGradient1);
1145 expect(Gradient.lerp(testGradient1, testGradient2, 1.0), testGradient2);
1146 expect(Gradient.lerp(testGradient1, testGradient2, 0.5), testGradient2.scale(0.0));
1147 });
1148
1149 test('Gradients can handle missing stops and report mismatched stops', () {
1150 const LinearGradient test1a = LinearGradient(
1151 colors: <Color>[
1152 Color(0x11111111),
1153 Color(0x22222222),
1154 Color(0x33333333),
1155 ],
1156 );
1157 const RadialGradient test1b = RadialGradient(
1158 colors: <Color>[
1159 Color(0x11111111),
1160 Color(0x22222222),
1161 Color(0x33333333),
1162 ],
1163 );
1164 const LinearGradient test2a = LinearGradient(
1165 colors: <Color>[
1166 Color(0x11111111),
1167 Color(0x22222222),
1168 Color(0x33333333),
1169 ],
1170 stops: <double>[0.0, 1.0],
1171 );
1172 const RadialGradient test2b = RadialGradient(
1173 colors: <Color>[
1174 Color(0x11111111),
1175 Color(0x22222222),
1176 Color(0x33333333),
1177 ],
1178 stops: <double>[0.0, 1.0],
1179 );
1180 const Rect rect = Rect.fromLTWH(1.0, 2.0, 3.0, 4.0);
1181 expect(test1a.createShader(rect), isNotNull);
1182 expect(test1b.createShader(rect), isNotNull);
1183 expect(() { test2a.createShader(rect); }, throwsArgumentError);
1184 expect(() { test2b.createShader(rect); }, throwsArgumentError);
1185 });
1186
1187 group('Transforms', () {
1188 const List<Color> colors = <Color>[Color(0xFFFFFFFF), Color(0xFF000088)];
1189 const Rect rect = Rect.fromLTWH(0.0, 0.0, 300.0, 400.0);
1190 const List<Gradient> gradients45 = <Gradient>[
1191 LinearGradient(colors: colors, transform: GradientRotation(math.pi/4)),
1192 // A radial gradient won't be interesting to rotate unless the center is changed.
1193 RadialGradient(colors: colors, center: Alignment.topCenter, transform: GradientRotation(math.pi/4)),
1194 SweepGradient(colors: colors, transform: GradientRotation(math.pi/4)),
1195 ];
1196 const List<Gradient> gradients90 = <Gradient>[
1197 LinearGradient(colors: colors, transform: GradientRotation(math.pi/2)),
1198 // A radial gradient won't be interesting to rotate unless the center is changed.
1199 RadialGradient(colors: colors, center: Alignment.topCenter, transform: GradientRotation(math.pi/2)),
1200 SweepGradient(colors: colors, transform: GradientRotation(math.pi/2)),
1201 ];
1202
1203 const Map<Type, String> gradientSnakeCase = <Type, String> {
1204 LinearGradient: 'linear_gradient',
1205 RadialGradient: 'radial_gradient',
1206 SweepGradient: 'sweep_gradient',
1207 };
1208
1209 Future<void> runTest(WidgetTester tester, Gradient gradient, double degrees) async {
1210 final String goldenName = '${gradientSnakeCase[gradient.runtimeType]}_$degrees.png';
1211 final Shader shader = gradient.createShader(
1212 rect,
1213 );
1214 final Key painterKey = UniqueKey();
1215 await tester.pumpWidget(Center(
1216 child: SizedBox.fromSize(
1217 size: rect.size,
1218 child: RepaintBoundary(
1219 key: painterKey,
1220 child: CustomPaint(
1221 painter: GradientPainter(shader, rect),
1222 ),
1223 ),
1224 ),
1225 ));
1226 await expectLater(
1227 find.byKey(painterKey),
1228 matchesGoldenFile(goldenName),
1229 );
1230 }
1231
1232 group('Gradients - 45 degrees', () {
1233 for (final Gradient gradient in gradients45) {
1234 testWidgets('$gradient', (WidgetTester tester) async {
1235 await runTest(tester, gradient, 45);
1236 });
1237 }
1238 });
1239
1240 group('Gradients - 90 degrees', () {
1241 for (final Gradient gradient in gradients90) {
1242 testWidgets('$gradient', (WidgetTester tester) async {
1243 await runTest(tester, gradient, 90);
1244 });
1245 }
1246 });
1247 });
1248}
1249
1250class GradientPainter extends CustomPainter {
1251 const GradientPainter(this.shader, this.rect);
1252
1253 final Shader shader;
1254 final Rect rect;
1255
1256 @override
1257 void paint(Canvas canvas, Size size) {
1258 canvas.drawRect(rect, Paint()..shader = shader);
1259 }
1260
1261 @override
1262 bool shouldRepaint(CustomPainter oldDelegate) => true;
1263
1264}
1265

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com