From 4b41f738da8d9c45783159a0b8e36299f9cf6df3 Mon Sep 17 00:00:00 2001
From: Prashant Sawant <75819349+ps9310@users.noreply.github.com>
Date: Fri, 14 Jun 2024 17:09:17 -0400
Subject: [PATCH] test: 100% test coverage for theme, utils, Zeta and
ZetaProvider
test: Added ZetaTooltip test
docs: Added guides for golden and unit testing
ci: Updted github action to run tests
---
.github/workflows/on-main.yml | 1 +
.github/workflows/pull-request.yml | 1 +
CONTRIBUTING.md | 121 ++
coverage.sh | 31 +
example/ios/Flutter/AppFrameworkInfo.plist | 2 +-
example/ios/Podfile | 2 +-
example/ios/Podfile.lock | 23 +-
example/ios/Runner.xcodeproj/project.pbxproj | 8 +-
.../xcshareddata/xcschemes/Runner.xcscheme | 2 +-
example/lib/utils/theme_color_switch.dart | 6 +-
example/lib/utils/theme_constrast_switch.dart | 12 +-
example/lib/utils/theme_mode_switch.dart | 6 +-
golden/arrow_down.png | Bin 0 -> 3651 bytes
golden/arrow_left.png | Bin 0 -> 3651 bytes
golden/arrow_right.png | Bin 0 -> 3647 bytes
golden/arrow_up.png | Bin 0 -> 3658 bytes
lib/src/theme/color_swatch.dart | 31 +-
lib/src/theme/colors.dart | 90 +-
lib/src/theme/colors_base.dart | 4 +-
lib/src/theme/theme_data.dart | 20 +-
lib/src/utils/{utils.dart => debounce.dart} | 0
lib/src/utils/extensions.dart | 7 +-
lib/src/zeta.dart | 248 ---
lib/src/zeta_provider.dart | 257 +++
lib/zeta_flutter.dart | 3 +-
pubspec.yaml | 7 +
.../components/tooltip/golden/arrow_down.png | Bin 0 -> 3651 bytes
.../components/tooltip/golden/arrow_left.png | Bin 0 -> 3651 bytes
.../components/tooltip/golden/arrow_right.png | Bin 0 -> 3647 bytes
.../components/tooltip/golden/arrow_up.png | Bin 0 -> 3658 bytes
test/src/components/tooltip/tooltip_test.dart | 247 +++
test/src/theme/breakpoints_test.dart | 137 ++
test/src/theme/color_extensions_test.dart | 131 ++
test/src/theme/color_scheme_test.dart | 108 ++
test/src/theme/color_swatch_test.dart | 163 ++
test/src/theme/colors_test.dart | 291 +++
test/src/theme/contrast_test.dart | 32 +
test/src/theme/theme_data_test.dart | 62 +
test/src/utils/debounce_test.dart | 73 +
test/src/utils/extensions_test.dart | 244 +++
test/src/utils/extensions_test.mocks.dart | 1724 +++++++++++++++++
test/src/zeta_provider_test.dart | 327 ++++
test/src/zeta_provider_test.mocks.dart | 61 +
test/src/zeta_test.dart | 174 ++
test/test_utils/test_app.dart | 22 +
test/test_utils/tolerant_comparator.dart | 67 +
46 files changed, 4383 insertions(+), 362 deletions(-)
create mode 100644 coverage.sh
create mode 100644 golden/arrow_down.png
create mode 100644 golden/arrow_left.png
create mode 100644 golden/arrow_right.png
create mode 100644 golden/arrow_up.png
rename lib/src/utils/{utils.dart => debounce.dart} (100%)
create mode 100644 lib/src/zeta_provider.dart
create mode 100644 test/src/components/tooltip/golden/arrow_down.png
create mode 100644 test/src/components/tooltip/golden/arrow_left.png
create mode 100644 test/src/components/tooltip/golden/arrow_right.png
create mode 100644 test/src/components/tooltip/golden/arrow_up.png
create mode 100644 test/src/components/tooltip/tooltip_test.dart
create mode 100644 test/src/theme/breakpoints_test.dart
create mode 100644 test/src/theme/color_extensions_test.dart
create mode 100644 test/src/theme/color_scheme_test.dart
create mode 100644 test/src/theme/color_swatch_test.dart
create mode 100644 test/src/theme/colors_test.dart
create mode 100644 test/src/theme/contrast_test.dart
create mode 100644 test/src/theme/theme_data_test.dart
create mode 100644 test/src/utils/debounce_test.dart
create mode 100644 test/src/utils/extensions_test.dart
create mode 100644 test/src/utils/extensions_test.mocks.dart
create mode 100644 test/src/zeta_provider_test.dart
create mode 100644 test/src/zeta_provider_test.mocks.dart
create mode 100644 test/src/zeta_test.dart
create mode 100644 test/test_utils/test_app.dart
create mode 100644 test/test_utils/tolerant_comparator.dart
diff --git a/.github/workflows/on-main.yml b/.github/workflows/on-main.yml
index bb3b9aa4..15fb2e0e 100644
--- a/.github/workflows/on-main.yml
+++ b/.github/workflows/on-main.yml
@@ -33,6 +33,7 @@ jobs:
dart format . -l 120
dart fix --apply
flutter analyze
+ flutter test
cd example && flutter test
- name: Check for modified files
id: git-check
diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml
index dab856c5..72c1158a 100644
--- a/.github/workflows/pull-request.yml
+++ b/.github/workflows/pull-request.yml
@@ -66,6 +66,7 @@ jobs:
dart format . -l 120
dart fix --apply
flutter analyze
+ flutter test
cd example && flutter test
- name: Check for modified files
id: git-check
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4b53985d..24c127c2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -34,6 +34,127 @@ For more information on widgetbook, [read the docs](https://docs.widgetbook.io/)
We should also create a test for each widget created.
+### Contributing Guide for Writing Tests
+
+#### Folder Structure
+
+To maintain consistency and ease of navigation, follow the same folder structure in the `test` directory as in the `lib` directory. For example, if you have a file located at `lib/src/components/tooltip/tooltip.dart`, your test file should be located at `test/src/components/tooltip/tooltip_test.dart`.
+
+##### Example Folder Structure
+
+```
+lib/
+└── src/
+ └── components/
+ └── tooltip/
+ └── tooltip.dart
+
+test/
+└── src/
+ └── components/
+ └── tooltip/
+ └── tooltip_test.dart
+```
+
+#### Writing Tests
+
+1. **Unit Tests**: Test individual functions and classes.
+2. **Widget Tests**: Test individual widgets and their interactions.
+3. **Integration Tests**: Test the complete app or large parts of it.
+
+##### Guidelines
+
+- Use descriptive test names.
+- Test one thing per test.
+- Mock dependencies using `mockito`.
+- Write tests for edge cases.
+
+#### Measuring Code Coverage
+
+To ensure high code coverage (at least > 96%), use the following steps:
+
+##### With 'lcov'
+1. **Run the script coverage.sh from the project root, which make use of `lcov` to generate the coverage report**:
+ ```sh
+ sh coverage.sh
+ ```
+##### Alternatively, with 'genhtml'
+1. **Install dependencies**:
+ ```sh
+ flutter pub add --dev test coverage
+ ```
+
+2. **Run tests with coverage**:
+ ```sh
+ flutter test --coverage
+ ```
+
+3. **Generate coverage report**:
+ ```sh
+ genhtml coverage/lcov.info -o coverage/html
+ ```
+
+4. **View coverage report**:
+ Open `coverage/html/index.html` in a web browser.
+
+
+##### Maximizing Coverage
+
+- Write tests for all public methods and classes.
+- Include tests for edge cases and error handling.
+- Avoid excluding files from coverage unless necessary.
+
+#### Golden Tests
+
+Golden tests are used to ensure that the visual output of your widgets remains consistent over time. They are particularly useful for complex UI components.
+
+##### Why Golden Tests?
+
+In the `tooltip` example, the direction of the arrows in the tooltip is crucial. Golden tests help to ensure that any changes to the tooltip do not unintentionally alter the direction of the arrows or other visual aspects.
+
+##### Adding Golden Tests
+
+1. **Set up golden tests**:
+ ```dart
+ import 'package:flutter_test/flutter_test.dart';
+ import 'package:zeta_flutter/zeta_flutter.dart';
+
+ import '../../../test_utils/test_app.dart';
+
+ void main() {
+ testWidgets('renders with arrow correctly in up direction', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ const TestApp(
+ home: Scaffold(
+ body: ZetaTooltip(
+ arrowDirection: ZetaTooltipArrowDirection.up,
+ child: Text('Tooltip up'),
+ ),
+ ),
+ ),
+ );
+
+ expect(find.text('Tooltip up'), findsOneWidget);
+
+ // Verifying the CustomPaint with different arrow directions.
+ await expectLater(
+ find.byType(ZetaTooltip),
+ matchesGoldenFile(p.join('golden', 'arrow_up.png')),
+ );
+ });
+ }
+ ```
+
+2. **Run golden tests**:
+ ```sh
+ flutter test --update-goldens
+ ```
+
+3. **Verify golden tests**:
+ Ensure that the generated golden files are correct and commit them to the repository.
+
+
+
## Code reviews
All submissions, including submissions by project members, require review. We use GitHub pull requests (PRs) for this purpose. Consult [GitHub Help](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) for more information on using pull requests.
diff --git a/coverage.sh b/coverage.sh
new file mode 100644
index 00000000..a20e51f0
--- /dev/null
+++ b/coverage.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# Check if lcov is installed
+if ! command -v lcov &> /dev/null
+then
+ echo "lcov could not be found, please install it first."
+ exit
+fi
+
+# Run the tests with coverage
+flutter test --coverage
+
+# Generate the LCOV report
+lcov --capture --directory coverage --output-file coverage/lcov.info
+
+# Remove unnecessary files from the report
+lcov --remove coverage/lcov.info 'lib/*/*.g.dart' 'lib/*/*.freezed.dart' -o coverage/lcov.info
+
+# Generate the HTML report
+genhtml coverage/lcov.info --output-directory coverage/html
+
+# Open the coverage report in the default browser
+if [ "$(uname)" == "Darwin" ]; then
+ open coverage/html/index.html
+elif [ "$(uname)" == "Linux" ]; then
+ xdg-open coverage/html/index.html
+elif [ "$(uname)" == "CYGWIN" ] || [ "$(uname)" == "MINGW32" ] || [ "$(uname)" == "MINGW64" ]; then
+ start coverage/html/index.html
+fi
+
+echo "Coverage report generated and opened in the default browser."
diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist
index 9625e105..7c569640 100644
--- a/example/ios/Flutter/AppFrameworkInfo.plist
+++ b/example/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 11.0
+ 12.0
diff --git a/example/ios/Podfile b/example/ios/Podfile
index 88359b22..279576f3 100644
--- a/example/ios/Podfile
+++ b/example/ios/Podfile
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
-# platform :ios, '11.0'
+# platform :ios, '12.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock
index f6342e74..15073017 100644
--- a/example/ios/Podfile.lock
+++ b/example/ios/Podfile.lock
@@ -6,11 +6,18 @@ PODS:
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
+ - sqflite (0.0.3):
+ - Flutter
+ - FlutterMacOS
+ - url_launcher_ios (0.0.1):
+ - Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
+ - sqflite (from `.symlinks/plugins/sqflite/darwin`)
+ - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
EXTERNAL SOURCES:
Flutter:
@@ -19,12 +26,18 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
+ sqflite:
+ :path: ".symlinks/plugins/sqflite/darwin"
+ url_launcher_ios:
+ :path: ".symlinks/plugins/url_launcher_ios/ios"
SPEC CHECKSUMS:
- Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
- path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
- shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
+ Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
+ path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
+ shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
+ sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
+ url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
-PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
+PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011
-COCOAPODS: 1.14.3
+COCOAPODS: 1.15.2
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index 83853dd6..62e10fdd 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -156,7 +156,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1430;
+ LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@@ -343,7 +343,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -421,7 +421,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -470,7 +470,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index a6b826db..5e31d3d3 100644
--- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,6 +1,6 @@
(
value: e.value.identifier,
alignment: Alignment.center,
- child: CircleAvatar(
+ child: ZetaAvatar(
+ size: ZetaAvatarSize.xxs,
backgroundColor: color.surface,
- foregroundColor: color,
- child: Icon(Icons.color_lens, color: color),
+ image: Icon(Icons.color_lens, color: color),
),
);
}).toList(),
diff --git a/example/lib/utils/theme_constrast_switch.dart b/example/lib/utils/theme_constrast_switch.dart
index 780acd01..7e7c060d 100644
--- a/example/lib/utils/theme_constrast_switch.dart
+++ b/example/lib/utils/theme_constrast_switch.dart
@@ -34,12 +34,14 @@ class ZetaThemeContrastSwitch extends StatelessWidget {
return DropdownMenuItem(
value: e,
alignment: Alignment.center,
- child: CircleAvatar(
+ child: ZetaAvatar(
+ size: ZetaAvatarSize.xxs,
backgroundColor: colors.primary.surface,
- foregroundColor: colors.primary,
- child: Text(
- e == ZetaContrast.aa ? 'AA' : 'AAA',
- style: ZetaTextStyles.bodyMedium.copyWith(color: colors.primary, fontWeight: FontWeight.w700),
+ image: Center(
+ child: Text(
+ e == ZetaContrast.aa ? 'AA' : 'AAA',
+ style: ZetaTextStyles.bodyMedium.copyWith(color: colors.primary, fontWeight: FontWeight.w700),
+ ),
),
),
);
diff --git a/example/lib/utils/theme_mode_switch.dart b/example/lib/utils/theme_mode_switch.dart
index fb9a22e1..200ceeba 100644
--- a/example/lib/utils/theme_mode_switch.dart
+++ b/example/lib/utils/theme_mode_switch.dart
@@ -36,10 +36,10 @@ class ZetaThemeModeSwitch extends StatelessWidget {
return DropdownMenuItem(
value: e,
alignment: Alignment.center,
- child: CircleAvatar(
+ child: ZetaAvatar(
+ size: ZetaAvatarSize.xxs,
backgroundColor: colors.primary.surface,
- foregroundColor: colors.primary,
- child: Icon(
+ image: Icon(
e == ThemeMode.system
? Icons.system_security_update_good
: e == ThemeMode.light
diff --git a/golden/arrow_down.png b/golden/arrow_down.png
new file mode 100644
index 0000000000000000000000000000000000000000..aa99574828a6aa4e8b76f44e1cb35ae22cefdb9e
GIT binary patch
literal 3651
zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI
zLpXq-h9ji|sOhbzi(^Q|oVRxk^Fvb^jz9cvwx(qAgC`CL8(YpNI6hY2$jiZE*U84c
zWXJ0GgBl-XZ?qWgICzUMXYK01wrMT*y{qS??^QSdKWEQr{qJ|?Tz$BE@nXge0siyt
zrTgc->6>1?{@A~N|K3>6NqqhK_2W~=o)%_jSKqm@$F7?1fQdFElg`!m_5TdF?b~lz
z&Bp!Z$-~DV-(J6eW*(!#(OYjA88+Met1SP$!sWW9WyUt7o
zMzPlq9wZ=S85m|3Z)Rtx>AH69+Oe(K*ZXS!W^I*9-YVtZ-rl{VuE#KLPlX|$f5BhR
zIp2QUA3MI+o?$uAl#2fIdNC6F|9pG>Msog^v+K={-!{*;J5@fv_4j|n_xuMkp9$(P
zFeoTHFfcUqFfcMO7%{OhFr45JKoz{l%yfW#XVuqNKmI&AnjHWBXbnS;q65PZ2W$Rv
zzmmP;pBW9>+&2Ktm;g3o_2F`N_s#AMXFeRAF1=ZOLqh%kt>)EC2Sn-^f&TjQ^D|H^
z;GEos6egC4HND=`)BF<_&aq86$-=QA!hHYjdA5zMMc*1!Kg$awT%2cDZzgAZQ_b
zT<_n%e{U9B9KLq_`thl~rypOt_HD<;%Gz%-4Vf$)497nm_UAv=Z_R)2_szYx%a8xH
zE`RLGFvm^qAk%}0clUQ%zq|XdKBa@7!Oy9Ip&;jfufRvf1DU
z=6^;|5CC=H3J9#BGb)IdTt)+AG(hkdD5EK4G=+?&kkMKOv#Bv!GK`iCqb0*=$v|?+
b@R|Qt$y{yAc=>n0jv#}ltDnm{r-UW|7LTE=
literal 0
HcmV?d00001
diff --git a/golden/arrow_left.png b/golden/arrow_left.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f66b33e576aa16865bf29dd67ae890685f00760
GIT binary patch
literal 3651
zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI
zLpXq-h9ji|sOhbzi(^Q|oVR!P_l2a&G(5~#+qQcyi#E5Ij>ir*ag(@CZ-?n8rY8KD
z9b5fXtcU5lgSt+u>^5)5?b(S=DaV_5&s9(OZ1Z%c{^WSSeb3IGvAqB2#nq1=Egn96
z?Ed)Qzk3x`A97^mH5c2d^mhhq_|-(JA(nUHe=C;KR*$?PoJKi)_lfL
z&Cig)7RJQFz>pAYXLa_`(;`c~*j-<)y%z62D$#w^!p>^e(O-tgDn30qX<>Er*X1Ak
z@BcTvR$b4)Q1O4RmV=#LaoV3BpZ#CYdfL3<@6T^PJ|FGgTJycV;Q#eXu$sLe#n(ia
z=lPqmGXNd2p83hOxwjwx-VL%aV*XQ!N6ZWi89GOSk^vv3;ushdHt*S4om}(%ZSTtG
zzyME6uskNA1XQcB$BzBUvv>CyA5~5$FaG%G=*N>cH|OuYcd&+m;mk>CcENjh_9{Bu
zyLh*{+?0O&Dg2L_mHK%O5J91Rd~(i}|;
zqq$?WWB``YqZwf|BaCK*(Tp(KG#YIyLR#&Eszx{yUtKUabN{b~3}C;6!PC{xWt~$(
F699fgpi}?=
literal 0
HcmV?d00001
diff --git a/golden/arrow_right.png b/golden/arrow_right.png
new file mode 100644
index 0000000000000000000000000000000000000000..30d99000c0bec9ab95a4b899e8d2f3732b6d8e53
GIT binary patch
literal 3647
zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI
zLpXq-h9ji|sOhDri(^Q|oVRy3_JyP}v^}hMi{3UlVc}V(vuf46dKr6|dd(H213K?D
zmM?HTaDa8i-qude0{+{a-j0jdZr|0o+c#JBOxmGpo14!wpQn6!`Xv9}lQVOUp6tH*
z>fqw`$M61DKmPb|a$!k{$%Fq%+1c4K`zkW;?AT_%?p^H6Dn14V>8L-SKCfS$JwJAS
z75kn`f35HL^WXoU@Jf<_A?HEw8GFGxO+GD_i3^2qY~Xm
zBj(PT)A{(%y*3^VR|Ge24T`T22v`@a#nGnelD{_R-&
z`j_s1(m(#&f9^LY!+|e0O-I+%e7?JOr8)z{21dq1Yig>0PvZb;HDo;WrbB?C;ir(o
znMoi4bw(xzh7=Z#&0n5AH$NU8e`ih=Fg}*6ILwg!$jD$2uV2g0v3}d;&Bpik6(qiW
zy*DG@_z^Qh!abG~ZF%>1)~-T`*fg<%O=4h}5V_~`yKh;q1UIZp-!JQD%gE5ct8;#?
zwfR@Ji0;i?3=vgcG>^{
literal 0
HcmV?d00001
diff --git a/golden/arrow_up.png b/golden/arrow_up.png
new file mode 100644
index 0000000000000000000000000000000000000000..da590cb580efa4b72348a2bd02f04952cae12241
GIT binary patch
literal 3658
zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI
zLpXq-h9ji|sOgKRi(^Q|oVRy3=1omyIR5av$-1{{2TwLOF?+5**mO*LBMXmO9On`d
zkJsz&H3dG9yU}8_PkcY0Ke_u)(Z0#~h2P%&sbM%E
zBxiF=KDp=P<-hXjaZCqx{mgmC$gpNQd;hoNhnxR?ukRLMn6}aII|IYD>wU#;pMuB}jrF
zgv;B
z()$@1BMxmAKYx7k;=> {
+class ZetaColorSwatch extends ColorSwatch with EquatableMixin {
/// Constructs a [ZetaColorSwatch].
///
/// See also:
@@ -142,7 +143,8 @@ class ZetaColorSwatch extends ColorSwatch {
/// Returns the color shade for a subtle visual element depending on the ZetaContrast value.
///
- /// For both [ZetaContrast.aa] and [ZetaContrast.aaa], it returns 40.
+ /// For [ZetaContrast.aa], it returns 40.
+ /// For [ZetaContrast.aaa], it returns 60.
Color get subtle => shade(contrast.subtle);
/// Returns the color shade for a surface depending on the ZetaContrast value.
@@ -185,14 +187,19 @@ class ZetaColorSwatch extends ColorSwatch {
}
@override
- bool operator ==(Object other) =>
- identical(this, other) ||
- super == other &&
- other is ZetaColorSwatch &&
- runtimeType == other.runtimeType &&
- brightness == other.brightness &&
- contrast == other.contrast;
-
- @override
- int get hashCode => super.hashCode ^ brightness.hashCode ^ contrast.hashCode;
+ List