Unverified Commit 77c3807c authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Revert "Make tests more resilient to Skia gold failures and refactor...

Revert "Make tests more resilient to Skia gold failures and refactor flutter_goldens for extensive technical debt removal (#140101)" (#141814)

Reverts https://github.com/flutter/flutter/pull/140101

That PR somehow made non-matching gold tests not fail at HEAD.

Fixes https://github.com/flutter/flutter/issues/141880
- Blocked by https://github.com/flutter/flutter/issues/140169
  - https://github.com/flutter/flutter/pull/141427
parent 49447fc6
[0-9]+:[0-9]+ [+]0: Local passes non-existent baseline for new test, null expectation *
*No expectations provided by Skia Gold for test: library.flutter.new_golden_test.1.png. This may be a new test. If this is an unexpected result, check https://flutter-gold.skia.org.
*Validate image output found at flutter/test/library/
[0-9]+:[0-9]+ [+]1: Local passes non-existent baseline for new test, empty expectation *
*No expectations provided by Skia Gold for test: library.flutter.new_golden_test.2.png. This may be a new test. If this is an unexpected result, check https://flutter-gold.skia.org.
*Validate image output found at flutter/test/library/
[0-9]+:[0-9]+ [+]2: All tests passed! * [0-9]+:[0-9]+ [+]2: All tests passed! *
...@@ -21,7 +21,6 @@ const List<int> _kFailPngBytes = <int>[ ...@@ -21,7 +21,6 @@ const List<int> _kFailPngBytes = <int>[
]; ];
void main() { void main() {
final List<String> log = <String>[];
final MemoryFileSystem fs = MemoryFileSystem(); final MemoryFileSystem fs = MemoryFileSystem();
final Directory basedir = fs.directory('flutter/test/library/') final Directory basedir = fs.directory('flutter/test/library/')
..createSync(recursive: true); ..createSync(recursive: true);
...@@ -35,7 +34,6 @@ void main() { ...@@ -35,7 +34,6 @@ void main() {
environment: <String, String>{'FLUTTER_ROOT': '/flutter'}, environment: <String, String>{'FLUTTER_ROOT': '/flutter'},
operatingSystem: 'macos' operatingSystem: 'macos'
), ),
log: log.add,
); );
test('Local passes non-existent baseline for new test, null expectation', () async { test('Local passes non-existent baseline for new test, null expectation', () async {
...@@ -46,12 +44,6 @@ void main() { ...@@ -46,12 +44,6 @@ void main() {
), ),
isTrue, isTrue,
); );
expect(log, <String>[
// ignore: no_adjacent_strings_in_list
'No expectations provided by Skia Gold for test: library.flutter.new_golden_test.1.png. '
'This may be a new test. If this is an unexpected result, check https://flutter-gold.skia.org.\n'
'Validate image output found at flutter/test/library/'
]);
}); });
test('Local passes non-existent baseline for new test, empty expectation', () async { test('Local passes non-existent baseline for new test, empty expectation', () async {
...@@ -62,16 +54,6 @@ void main() { ...@@ -62,16 +54,6 @@ void main() {
), ),
isTrue, isTrue,
); );
expect(log, <String>[
// ignore: no_adjacent_strings_in_list
'No expectations provided by Skia Gold for test: library.flutter.new_golden_test.1.png. '
'This may be a new test. If this is an unexpected result, check https://flutter-gold.skia.org.\n'
'Validate image output found at flutter/test/library/',
// ignore: no_adjacent_strings_in_list
'No expectations provided by Skia Gold for test: library.flutter.new_golden_test.2.png. '
'This may be a new test. If this is an unexpected result, check https://flutter-gold.skia.org.\n'
'Validate image output found at flutter/test/library/',
]);
}); });
} }
......
...@@ -65,7 +65,7 @@ dependencies: ...@@ -65,7 +65,7 @@ dependencies:
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -75,4 +75,4 @@ flutter: ...@@ -75,4 +75,4 @@ flutter:
assets: assets:
- icon/test.png - icon/test.png
# PUBSPEC CHECKSUM: 04e8 # PUBSPEC CHECKSUM: 8fe9
...@@ -75,7 +75,7 @@ dev_dependencies: ...@@ -75,7 +75,7 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -86,4 +86,4 @@ flutter: ...@@ -86,4 +86,4 @@ flutter:
- packages/flutter_gallery_assets/people/square/ali.png - packages/flutter_gallery_assets/people/square/ali.png
- packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png - packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png
# PUBSPEC CHECKSUM: 40c1 # PUBSPEC CHECKSUM: ebc2
...@@ -18,7 +18,7 @@ dependencies: ...@@ -18,7 +18,7 @@ dependencies:
# flutter update-packages --force-upgrade # flutter update-packages --force-upgrade
flutter_gallery_assets: 1.0.2 flutter_gallery_assets: 1.0.2
web: 0.4.1 web: 0.4.2
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -213,4 +213,4 @@ flutter: ...@@ -213,4 +213,4 @@ flutter:
fonts: fonts:
- asset: packages/flutter_gallery_assets/fonts/GalleryIcons.ttf - asset: packages/flutter_gallery_assets/fonts/GalleryIcons.ttf
# PUBSPEC CHECKSUM: 40c1 # PUBSPEC CHECKSUM: ebc2
...@@ -66,7 +66,7 @@ dependencies: ...@@ -66,7 +66,7 @@ dependencies:
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -140,4 +140,4 @@ flutter: ...@@ -140,4 +140,4 @@ flutter:
- packages/flutter_gallery_assets/people/square/stella.png - packages/flutter_gallery_assets/people/square/stella.png
- packages/flutter_gallery_assets/people/square/trevor.png - packages/flutter_gallery_assets/people/square/trevor.png
# PUBSPEC CHECKSUM: 1e38 # PUBSPEC CHECKSUM: a939
...@@ -17,7 +17,7 @@ dependencies: ...@@ -17,7 +17,7 @@ dependencies:
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.18.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.18.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
ffi: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" ffi: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http: 0.13.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http: 0.13.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.8.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" material_color_utilities: 0.8.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -25,7 +25,7 @@ dependencies: ...@@ -25,7 +25,7 @@ dependencies:
path: 1.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_android: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_android: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_foundation: 2.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_foundation: 2.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_linux: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_linux: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_platform_interface: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_platform_interface: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_windows: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_windows: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -47,4 +47,4 @@ flutter: ...@@ -47,4 +47,4 @@ flutter:
androidPackage: com.example.multiple_flutters_module androidPackage: com.example.multiple_flutters_module
iosBundleIdentifier: com.example.multipleFluttersModule iosBundleIdentifier: com.example.multipleFluttersModule
# PUBSPEC CHECKSUM: 61ab # PUBSPEC CHECKSUM: 81ae
...@@ -67,7 +67,7 @@ dependencies: ...@@ -67,7 +67,7 @@ dependencies:
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -77,4 +77,4 @@ dev_dependencies: ...@@ -77,4 +77,4 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: c824 # PUBSPEC CHECKSUM: 5425
...@@ -73,7 +73,7 @@ dev_dependencies: ...@@ -73,7 +73,7 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -84,4 +84,4 @@ flutter: ...@@ -84,4 +84,4 @@ flutter:
- packages/flutter_gallery_assets/people/square/ali.png - packages/flutter_gallery_assets/people/square/ali.png
- packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png - packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png
# PUBSPEC CHECKSUM: 40c1 # PUBSPEC CHECKSUM: ebc2
...@@ -73,7 +73,7 @@ dev_dependencies: ...@@ -73,7 +73,7 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -84,4 +84,4 @@ flutter: ...@@ -84,4 +84,4 @@ flutter:
- packages/flutter_gallery_assets/people/square/ali.png - packages/flutter_gallery_assets/people/square/ali.png
- packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png - packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png
# PUBSPEC CHECKSUM: 40c1 # PUBSPEC CHECKSUM: ebc2
...@@ -70,7 +70,7 @@ dev_dependencies: ...@@ -70,7 +70,7 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -79,4 +79,4 @@ dev_dependencies: ...@@ -79,4 +79,4 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: d5e3 # PUBSPEC CHECKSUM: 81e4
...@@ -66,7 +66,7 @@ dependencies: ...@@ -66,7 +66,7 @@ dependencies:
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
xml: 6.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" xml: 6.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -75,4 +75,4 @@ dependencies: ...@@ -75,4 +75,4 @@ dependencies:
dev_dependencies: dev_dependencies:
test_api: 0.6.1 test_api: 0.6.1
# PUBSPEC CHECKSUM: 69d9 # PUBSPEC CHECKSUM: 09da
...@@ -61,9 +61,9 @@ dev_dependencies: ...@@ -61,9 +61,9 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 4018 # PUBSPEC CHECKSUM: cb19
...@@ -51,9 +51,9 @@ dev_dependencies: ...@@ -51,9 +51,9 @@ dev_dependencies:
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 3a63 # PUBSPEC CHECKSUM: c564
...@@ -21,7 +21,7 @@ dependencies: ...@@ -21,7 +21,7 @@ dependencies:
shelf_static: 1.1.2 shelf_static: 1.1.2
stack_trace: 1.11.1 stack_trace: 1.11.1
vm_service: 13.0.0 vm_service: 13.0.0
web: 0.4.1 web: 0.4.2
webkit_inspection_protocol: 1.2.1 webkit_inspection_protocol: 1.2.1
xml: 6.5.0 xml: 6.5.0
standard_message_codec: 0.0.1+4 standard_message_codec: 0.0.1+4
...@@ -73,4 +73,4 @@ dev_dependencies: ...@@ -73,4 +73,4 @@ dev_dependencies:
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: a647 # PUBSPEC CHECKSUM: 4648
...@@ -61,7 +61,7 @@ dependencies: ...@@ -61,7 +61,7 @@ dependencies:
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -69,4 +69,4 @@ dependencies: ...@@ -69,4 +69,4 @@ dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: 76e0 # PUBSPEC CHECKSUM: 02e1
...@@ -74,9 +74,9 @@ dev_dependencies: ...@@ -74,9 +74,9 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 3f27 # PUBSPEC CHECKSUM: ea28
...@@ -25,13 +25,13 @@ dependencies: ...@@ -25,13 +25,13 @@ dependencies:
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
ffi: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" ffi: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 7.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 7.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.16+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.8.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" material_color_utilities: 0.8.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_foundation: 2.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_foundation: 2.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_linux: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_linux: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_platform_interface: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_platform_interface: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_windows: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_windows: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -87,7 +87,7 @@ dev_dependencies: ...@@ -87,7 +87,7 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -95,4 +95,4 @@ dev_dependencies: ...@@ -95,4 +95,4 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: 5622 # PUBSPEC CHECKSUM: 0f26
...@@ -68,7 +68,7 @@ dev_dependencies: ...@@ -68,7 +68,7 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -83,4 +83,4 @@ flutter: ...@@ -83,4 +83,4 @@ flutter:
assets: assets:
- customassets/flutter_logo.png - customassets/flutter_logo.png
# PUBSPEC CHECKSUM: 3f27 # PUBSPEC CHECKSUM: ea28
...@@ -56,7 +56,7 @@ dependencies: ...@@ -56,7 +56,7 @@ dependencies:
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -65,4 +65,4 @@ dependencies: ...@@ -65,4 +65,4 @@ dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: 1d69 # PUBSPEC CHECKSUM: c86a
...@@ -58,7 +58,7 @@ dependencies: ...@@ -58,7 +58,7 @@ dependencies:
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -85,4 +85,4 @@ flutter: ...@@ -85,4 +85,4 @@ flutter:
flavors: flavors:
- free - free
# PUBSPEC CHECKSUM: 3f27 # PUBSPEC CHECKSUM: ea28
...@@ -36,7 +36,7 @@ dependencies: ...@@ -36,7 +36,7 @@ dependencies:
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
url_launcher_android: 6.2.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" url_launcher_android: 6.2.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
url_launcher_ios: 6.2.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" url_launcher_ios: 6.2.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
url_launcher_linux: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" url_launcher_linux: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
url_launcher_macos: 3.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" url_launcher_macos: 3.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
url_launcher_platform_interface: 2.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" url_launcher_platform_interface: 2.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -44,10 +44,10 @@ dependencies: ...@@ -44,10 +44,10 @@ dependencies:
url_launcher_windows: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" url_launcher_windows: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
video_player_android: 2.4.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" video_player_android: 2.4.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
video_player_avfoundation: 2.5.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" video_player_avfoundation: 2.5.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
video_player_platform_interface: 6.2.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" video_player_platform_interface: 6.2.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
video_player_web: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" video_player_web: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
...@@ -277,4 +277,4 @@ flutter: ...@@ -277,4 +277,4 @@ flutter:
- asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Regular.ttf - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Regular.ttf
- asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Light.ttf - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Light.ttf
# PUBSPEC CHECKSUM: 7f94 # PUBSPEC CHECKSUM: f797
...@@ -10,7 +10,7 @@ dependencies: ...@@ -10,7 +10,7 @@ dependencies:
camera: 0.10.5+9 camera: 0.10.5+9
camera_android: 0.10.8+16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" camera_android: 0.10.8+16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
camera_avfoundation: 0.9.13+9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" camera_avfoundation: 0.9.13+10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
camera_platform_interface: 2.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" camera_platform_interface: 2.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
camera_web: 0.3.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" camera_web: 0.3.2+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -22,9 +22,9 @@ dependencies: ...@@ -22,9 +22,9 @@ dependencies:
plugin_platform_interface: 2.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" plugin_platform_interface: 2.1.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
stream_transform: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_transform: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: c4cc # PUBSPEC CHECKSUM: 8ef5
...@@ -22,14 +22,14 @@ dependencies: ...@@ -22,14 +22,14 @@ dependencies:
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
ffi: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" ffi: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 7.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 7.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.16+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.8.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" material_color_utilities: 0.8.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" meta: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_android: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_android: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_foundation: 2.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_foundation: 2.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_linux: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_linux: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_platform_interface: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_platform_interface: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_windows: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path_provider_windows: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -85,7 +85,7 @@ dev_dependencies: ...@@ -85,7 +85,7 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -93,4 +93,4 @@ dev_dependencies: ...@@ -93,4 +93,4 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: 5622 # PUBSPEC CHECKSUM: 0f26
...@@ -68,7 +68,7 @@ dev_dependencies: ...@@ -68,7 +68,7 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -80,4 +80,4 @@ flutter: ...@@ -80,4 +80,4 @@ flutter:
# the material Icons class. # the material Icons class.
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: 3f27 # PUBSPEC CHECKSUM: ea28
...@@ -56,7 +56,7 @@ dependencies: ...@@ -56,7 +56,7 @@ dependencies:
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -65,4 +65,4 @@ dependencies: ...@@ -65,4 +65,4 @@ dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: 1d69 # PUBSPEC CHECKSUM: c86a
...@@ -57,7 +57,7 @@ dependencies: ...@@ -57,7 +57,7 @@ dependencies:
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -79,4 +79,4 @@ flutter: ...@@ -79,4 +79,4 @@ flutter:
assets: assets:
- assets/foo.png - assets/foo.png
# PUBSPEC CHECKSUM: 3f27 # PUBSPEC CHECKSUM: ea28
...@@ -82,9 +82,9 @@ dev_dependencies: ...@@ -82,9 +82,9 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: bf0d # PUBSPEC CHECKSUM: 6b0e
...@@ -56,10 +56,10 @@ dependencies: ...@@ -56,10 +56,10 @@ dependencies:
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 1d69 # PUBSPEC CHECKSUM: c86a
...@@ -51,9 +51,9 @@ dev_dependencies: ...@@ -51,9 +51,9 @@ dev_dependencies:
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 3a63 # PUBSPEC CHECKSUM: c564
...@@ -53,9 +53,9 @@ dev_dependencies: ...@@ -53,9 +53,9 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: e75e # PUBSPEC CHECKSUM: 735f
...@@ -57,9 +57,9 @@ dev_dependencies: ...@@ -57,9 +57,9 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 0275 # PUBSPEC CHECKSUM: 8d76
...@@ -84,7 +84,7 @@ dev_dependencies: ...@@ -84,7 +84,7 @@ dev_dependencies:
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -93,4 +93,4 @@ dev_dependencies: ...@@ -93,4 +93,4 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: a812 # PUBSPEC CHECKSUM: 5413
...@@ -65,10 +65,10 @@ dev_dependencies: ...@@ -65,10 +65,10 @@ dev_dependencies:
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 3f27 # PUBSPEC CHECKSUM: ea28
...@@ -65,7 +65,7 @@ dev_dependencies: ...@@ -65,7 +65,7 @@ dev_dependencies:
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -74,4 +74,4 @@ dev_dependencies: ...@@ -74,4 +74,4 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: 3f27 # PUBSPEC CHECKSUM: ea28
...@@ -65,7 +65,7 @@ dev_dependencies: ...@@ -65,7 +65,7 @@ dev_dependencies:
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -74,4 +74,4 @@ dev_dependencies: ...@@ -74,4 +74,4 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: 3f27 # PUBSPEC CHECKSUM: ea28
...@@ -62,9 +62,9 @@ dev_dependencies: ...@@ -62,9 +62,9 @@ dev_dependencies:
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 76e0 # PUBSPEC CHECKSUM: 02e1
...@@ -26,15 +26,14 @@ dev_dependencies: ...@@ -26,15 +26,14 @@ dev_dependencies:
fake_async: 1.3.1 fake_async: 1.3.1
# To track memory leaks. # To track memory leaks.
leak_tracker_flutter_testing: 2.0.3 leak_tracker_flutter_testing: 2.0.3
web: 0.4.1 leak_tracker_testing: 2.0.2
leak_tracker: 10.0.1
web: 0.4.2
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 7.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 7.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
leak_tracker: 10.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
leak_tracker_testing: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.16+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" path: 1.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
platform: 3.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" platform: 3.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -45,7 +44,6 @@ dev_dependencies: ...@@ -45,7 +44,6 @@ dev_dependencies:
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: a90c # PUBSPEC CHECKSUM: 27ab
...@@ -41,10 +41,8 @@ dev_dependencies: ...@@ -41,10 +41,8 @@ dev_dependencies:
sdk: flutter sdk: flutter
fake_async: 1.3.1 fake_async: 1.3.1
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 7.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" file: 7.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
platform: 3.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" platform: 3.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
process: 5.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" process: 5.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 3680 # PUBSPEC CHECKSUM: 4e1f
...@@ -70,9 +70,9 @@ dev_dependencies: ...@@ -70,9 +70,9 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: ce2f # PUBSPEC CHECKSUM: 7a30
This package is an internal implementation detail for our testing
infrastructure. It enables the framework to use the Skia Gold
infrastructure for tracking golden image tests.
See also:
* https://skia.org/docs/dev/testing/skiagold/
* https://flutter-gold.skia.org/
* https://github.com/flutter/flutter/wiki/Writing-a-golden-file-test-for-package:flutter
tags:
# This tag tells the test framework to not shuffle the test order according to
# the --test-randomize-ordering-seed for the suites that have this tag.
no-shuffle:
allow_test_randomization: false
...@@ -3,28 +3,23 @@ ...@@ -3,28 +3,23 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async' show FutureOr; import 'dart:async' show FutureOr;
import 'dart:io' as io; import 'dart:io' as io show OSError, SocketException;
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/local.dart'; import 'package:file/local.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_goldens_client/skia_client.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:process/process.dart';
import 'skia_client.dart'; export 'package:flutter_goldens_client/skia_client.dart';
export 'skia_client.dart';
// If you are here trying to figure out how to use golden files in the Flutter // If you are here trying to figure out how to use golden files in the Flutter
// repo itself, consider reading this wiki page: // repo itself, consider reading this wiki page:
// https://github.com/flutter/flutter/wiki/Writing-a-golden-file-test-for-package%3Aflutter // https://github.com/flutter/flutter/wiki/Writing-a-golden-file-test-for-package%3Aflutter
const String _kFlutterRootKey = 'FLUTTER_ROOT'; const String _kFlutterRootKey = 'FLUTTER_ROOT';
final RegExp _kMainBranch = RegExp(r'master|main');
bool _isMainBranch(String? branch) {
return branch == 'main'
|| branch == 'master';
}
/// Main method that can be used in a `flutter_test_config.dart` file to set /// Main method that can be used in a `flutter_test_config.dart` file to set
/// [goldenFileComparator] to an instance of [FlutterGoldenFileComparator] that /// [goldenFileComparator] to an instance of [FlutterGoldenFileComparator] that
...@@ -33,51 +28,18 @@ bool _isMainBranch(String? branch) { ...@@ -33,51 +28,18 @@ bool _isMainBranch(String? branch) {
/// ///
/// When set, the `namePrefix` is prepended to the names of all gold images. /// When set, the `namePrefix` is prepended to the names of all gold images.
Future<void> testExecutable(FutureOr<void> Function() testMain, {String? namePrefix}) async { Future<void> testExecutable(FutureOr<void> Function() testMain, {String? namePrefix}) async {
assert(goldenFileComparator is LocalFileComparator);
const Platform platform = LocalPlatform(); const Platform platform = LocalPlatform();
const FileSystem fs = LocalFileSystem(); if (FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform)) {
const ProcessManager process = LocalProcessManager(); goldenFileComparator = await FlutterPostSubmitFileComparator.fromDefaultComparator(platform, namePrefix: namePrefix);
final io.HttpClient httpClient = io.HttpClient(); } else if (FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform)) {
if (FlutterPostSubmitFileComparator.isRecommendedForEnvironment(platform)) { goldenFileComparator = await FlutterPreSubmitFileComparator.fromDefaultComparator(platform, namePrefix: namePrefix);
goldenFileComparator = await FlutterPostSubmitFileComparator.fromLocalFileComparator( } else if (FlutterSkippingFileComparator.isAvailableForEnvironment(platform)) {
localFileComparator: goldenFileComparator as LocalFileComparator, goldenFileComparator = FlutterSkippingFileComparator.fromDefaultComparator(
namePrefix: namePrefix, 'Golden file testing is not executed on Cirrus, or LUCI environments outside of flutter/flutter.',
platform: platform, namePrefix: namePrefix
fs: fs,
process: process,
httpClient: httpClient,
log: print,
);
} else if (FlutterPreSubmitFileComparator.isRecommendedForEnvironment(platform)) {
goldenFileComparator = await FlutterPreSubmitFileComparator.fromLocalFileComparator(
localFileComparator: goldenFileComparator as LocalFileComparator,
namePrefix: namePrefix,
platform: platform,
fs: fs,
process: process,
httpClient: httpClient,
log: print,
);
} else if (FlutterSkippingFileComparator.isRecommendedForEnvironment(platform)) {
goldenFileComparator = FlutterSkippingFileComparator.fromLocalFileComparator(
localFileComparator: goldenFileComparator as LocalFileComparator,
namePrefix: namePrefix,
reason: 'Golden file testing is not executed on Cirrus, or LUCI environments outside of flutter/flutter.',
platform: platform,
fs: fs,
process: process,
httpClient: httpClient,
log: print,
); );
} else { } else {
goldenFileComparator = await FlutterLocalFileComparator.fromLocalFileComparator( goldenFileComparator = await FlutterLocalFileComparator.fromDefaultComparator(platform);
localFileComparator: goldenFileComparator as LocalFileComparator,
platform: platform,
fs: fs,
process: process,
httpClient: httpClient,
log: print,
);
} }
await testMain(); await testMain();
...@@ -126,12 +88,12 @@ abstract class FlutterGoldenFileComparator extends GoldenFileComparator { ...@@ -126,12 +88,12 @@ abstract class FlutterGoldenFileComparator extends GoldenFileComparator {
/// ///
/// The [fs] and [platform] parameters are useful in tests, where the default /// The [fs] and [platform] parameters are useful in tests, where the default
/// file system and platform can be replaced by mock instances. /// file system and platform can be replaced by mock instances.
@visibleForTesting
FlutterGoldenFileComparator( FlutterGoldenFileComparator(
this.basedir, this.basedir,
this.skiaClient, { this.skiaClient, {
required this.fs, this.fs = const LocalFileSystem(),
required this.platform, this.platform = const LocalPlatform(),
required this.log,
this.namePrefix, this.namePrefix,
}); });
...@@ -151,9 +113,6 @@ abstract class FlutterGoldenFileComparator extends GoldenFileComparator { ...@@ -151,9 +113,6 @@ abstract class FlutterGoldenFileComparator extends GoldenFileComparator {
@visibleForTesting @visibleForTesting
final Platform platform; final Platform platform;
/// The logging function to use when reporting messages to the console.
final LogCallback log;
/// The prefix that is added to all golden names. /// The prefix that is added to all golden names.
final String? namePrefix; final String? namePrefix;
...@@ -176,11 +135,11 @@ abstract class FlutterGoldenFileComparator extends GoldenFileComparator { ...@@ -176,11 +135,11 @@ abstract class FlutterGoldenFileComparator extends GoldenFileComparator {
@protected @protected
@visibleForTesting @visibleForTesting
static Directory getBaseDirectory( static Directory getBaseDirectory(
LocalFileComparator defaultComparator, { LocalFileComparator defaultComparator,
Platform platform, {
String? suffix, String? suffix,
required Platform platform,
required FileSystem fs,
}) { }) {
const FileSystem fs = LocalFileSystem();
final Directory flutterRoot = fs.directory(platform.environment[_kFlutterRootKey]); final Directory flutterRoot = fs.directory(platform.environment[_kFlutterRootKey]);
Directory comparisonRoot; Directory comparisonRoot;
...@@ -255,48 +214,34 @@ class FlutterPostSubmitFileComparator extends FlutterGoldenFileComparator { ...@@ -255,48 +214,34 @@ class FlutterPostSubmitFileComparator extends FlutterGoldenFileComparator {
FlutterPostSubmitFileComparator( FlutterPostSubmitFileComparator(
super.basedir, super.basedir,
super.skiaClient, { super.skiaClient, {
required super.fs, super.fs,
required super.platform, super.platform,
required super.log,
super.namePrefix, super.namePrefix,
}); });
/// Creates a new [FlutterPostSubmitFileComparator] that mirrors the relative /// Creates a new [FlutterPostSubmitFileComparator] that mirrors the relative
/// path resolution of the default [goldenFileComparator]. /// path resolution of the default [goldenFileComparator].
static Future<FlutterPostSubmitFileComparator> fromLocalFileComparator({ ///
required LocalFileComparator localFileComparator, /// The [goldens] and [defaultComparator] parameters are visible for testing
/// purposes only.
static Future<FlutterPostSubmitFileComparator> fromDefaultComparator(
final Platform platform, {
SkiaGoldClient? goldens,
LocalFileComparator? defaultComparator,
String? namePrefix, String? namePrefix,
required Platform platform,
required FileSystem fs,
required ProcessManager process,
required io.HttpClient httpClient,
required LogCallback log,
}) async { }) async {
defaultComparator ??= goldenFileComparator as LocalFileComparator;
final Directory baseDirectory = FlutterGoldenFileComparator.getBaseDirectory( final Directory baseDirectory = FlutterGoldenFileComparator.getBaseDirectory(
localFileComparator, defaultComparator,
platform,
suffix: 'flutter_goldens_postsubmit.', suffix: 'flutter_goldens_postsubmit.',
platform: platform,
fs: fs,
); );
baseDirectory.createSync(recursive: true); baseDirectory.createSync(recursive: true);
final SkiaGoldClient goldens = SkiaGoldClient( goldens ??= SkiaGoldClient(baseDirectory);
baseDirectory,
fs: fs,
process: process,
platform: platform,
httpClient: httpClient,
log: log,
);
await goldens.auth(); await goldens.auth();
return FlutterPostSubmitFileComparator( return FlutterPostSubmitFileComparator(baseDirectory.uri, goldens, namePrefix: namePrefix);
baseDirectory.uri,
goldens,
fs: fs,
platform: platform,
log: log,
namePrefix: namePrefix,
);
} }
@override @override
...@@ -305,17 +250,21 @@ class FlutterPostSubmitFileComparator extends FlutterGoldenFileComparator { ...@@ -305,17 +250,21 @@ class FlutterPostSubmitFileComparator extends FlutterGoldenFileComparator {
golden = _addPrefix(golden); golden = _addPrefix(golden);
await update(golden, imageBytes); await update(golden, imageBytes);
final File goldenFile = getGoldenFile(golden); final File goldenFile = getGoldenFile(golden);
await skiaClient.imgtestAdd(golden.path, goldenFile); // throws if the result is false
return true; return skiaClient.imgtestAdd(golden.path, goldenFile);
} }
/// Decides based on the current environment if goldens tests should be /// Decides based on the current environment if goldens tests should be
/// executed through Skia Gold. /// executed through Skia Gold.
static bool isRecommendedForEnvironment(Platform platform) { static bool isAvailableForEnvironment(Platform platform) {
return platform.environment.containsKey('SWARMING_TASK_ID') // Indicates LUCI environment. final bool luciPostSubmit = platform.environment.containsKey('SWARMING_TASK_ID')
&& platform.environment.containsKey('GOLDCTL') // Needed to use Gold. && platform.environment.containsKey('GOLDCTL')
&& !platform.environment.containsKey('GOLD_TRYJOB') // Indicates a pre-submit environment on LUCI. // Luci tryjob environments contain this value to inform the [FlutterPreSubmitComparator].
&& _isMainBranch(platform.environment['GIT_BRANCH']); && !platform.environment.containsKey('GOLD_TRYJOB')
// Only run on main branch.
&& _kMainBranch.hasMatch(platform.environment['GIT_BRANCH'] ?? '');
return luciPostSubmit;
} }
} }
...@@ -342,49 +291,41 @@ class FlutterPreSubmitFileComparator extends FlutterGoldenFileComparator { ...@@ -342,49 +291,41 @@ class FlutterPreSubmitFileComparator extends FlutterGoldenFileComparator {
FlutterPreSubmitFileComparator( FlutterPreSubmitFileComparator(
super.basedir, super.basedir,
super.skiaClient, { super.skiaClient, {
required super.fs, super.fs,
required super.platform, super.platform,
required super.log,
super.namePrefix, super.namePrefix,
}); });
/// Creates a new [FlutterPreSubmitFileComparator] that mirrors the /// Creates a new [FlutterPreSubmitFileComparator] that mirrors the
/// relative path resolution of the default [goldenFileComparator]. /// relative path resolution of the default [goldenFileComparator].
static Future<FlutterGoldenFileComparator> fromLocalFileComparator({ ///
required LocalFileComparator localFileComparator, /// The [goldens] and [defaultComparator] parameters are visible for testing
/// purposes only.
static Future<FlutterGoldenFileComparator> fromDefaultComparator(
final Platform platform, {
SkiaGoldClient? goldens,
LocalFileComparator? defaultComparator,
Directory? testBasedir, Directory? testBasedir,
String? namePrefix, String? namePrefix,
required Platform platform,
required FileSystem fs,
required ProcessManager process,
required io.HttpClient httpClient,
required LogCallback log,
}) async { }) async {
defaultComparator ??= goldenFileComparator as LocalFileComparator;
final Directory baseDirectory = testBasedir ?? FlutterGoldenFileComparator.getBaseDirectory( final Directory baseDirectory = testBasedir ?? FlutterGoldenFileComparator.getBaseDirectory(
localFileComparator, defaultComparator,
platform,
suffix: 'flutter_goldens_presubmit.', suffix: 'flutter_goldens_presubmit.',
platform: platform,
fs: fs,
); );
if (!baseDirectory.existsSync()) { if (!baseDirectory.existsSync()) {
baseDirectory.createSync(recursive: true); baseDirectory.createSync(recursive: true);
} }
final SkiaGoldClient goldens = SkiaGoldClient( goldens ??= SkiaGoldClient(baseDirectory);
baseDirectory,
fs: fs,
process: process,
platform: platform,
httpClient: httpClient,
log: log,
);
await goldens.auth(); await goldens.auth();
return FlutterPreSubmitFileComparator( return FlutterPreSubmitFileComparator(
baseDirectory.uri, baseDirectory.uri,
goldens, goldens, platform: platform,
fs: fs,
platform: platform,
log: log,
namePrefix: namePrefix, namePrefix: namePrefix,
); );
} }
...@@ -405,19 +346,21 @@ class FlutterPreSubmitFileComparator extends FlutterGoldenFileComparator { ...@@ -405,19 +346,21 @@ class FlutterPreSubmitFileComparator extends FlutterGoldenFileComparator {
/// Decides based on the current environment if goldens tests should be /// Decides based on the current environment if goldens tests should be
/// executed as pre-submit tests with Skia Gold. /// executed as pre-submit tests with Skia Gold.
static bool isRecommendedForEnvironment(Platform platform) { static bool isAvailableForEnvironment(Platform platform) {
return platform.environment.containsKey('SWARMING_TASK_ID') // Indicates LUCI environment. final bool luciPreSubmit = platform.environment.containsKey('SWARMING_TASK_ID')
&& platform.environment.containsKey('GOLDCTL') // Needed to use Gold. && platform.environment.containsKey('GOLDCTL')
&& platform.environment.containsKey('GOLD_TRYJOB') // Indicates a pre-submit environment on LUCI. && platform.environment.containsKey('GOLD_TRYJOB')
&& _isMainBranch(platform.environment['GIT_BRANCH']); // Only run on the main branch
&& _kMainBranch.hasMatch(platform.environment['GIT_BRANCH'] ?? '');
return luciPreSubmit;
} }
} }
/// A [FlutterGoldenFileComparator] for testing conditions that do not execute /// A [FlutterGoldenFileComparator] for testing conditions that do not execute
/// golden file tests. /// golden file tests.
/// ///
/// Currently, this comparator is used on Cirrus, or in Luci environments when /// Currently, this comparator is used on Cirrus, or in Luci environments when executing tests
/// executing tests outside of the flutter/flutter repository. /// outside of the flutter/flutter repository.
/// ///
/// See also: /// See also:
/// ///
...@@ -436,9 +379,6 @@ class FlutterSkippingFileComparator extends FlutterGoldenFileComparator { ...@@ -436,9 +379,6 @@ class FlutterSkippingFileComparator extends FlutterGoldenFileComparator {
super.basedir, super.basedir,
super.skiaClient, super.skiaClient,
this.reason, { this.reason, {
required super.fs,
required super.platform,
required super.log,
super.namePrefix, super.namePrefix,
}); });
...@@ -447,39 +387,25 @@ class FlutterSkippingFileComparator extends FlutterGoldenFileComparator { ...@@ -447,39 +387,25 @@ class FlutterSkippingFileComparator extends FlutterGoldenFileComparator {
/// Creates a new [FlutterSkippingFileComparator] that mirrors the /// Creates a new [FlutterSkippingFileComparator] that mirrors the
/// relative path resolution of the default [goldenFileComparator]. /// relative path resolution of the default [goldenFileComparator].
static FlutterSkippingFileComparator fromLocalFileComparator({ static FlutterSkippingFileComparator fromDefaultComparator(
required LocalFileComparator localFileComparator, String reason, {
LocalFileComparator? defaultComparator,
String? namePrefix, String? namePrefix,
required String reason,
required FileSystem fs,
required ProcessManager process,
required Platform platform,
required io.HttpClient httpClient,
required LogCallback log,
}) { }) {
final Uri basedir = localFileComparator.basedir; defaultComparator ??= goldenFileComparator as LocalFileComparator;
final SkiaGoldClient skiaClient = SkiaGoldClient( const FileSystem fs = LocalFileSystem();
fs.directory(basedir), final Uri basedir = defaultComparator.basedir;
fs: fs, final SkiaGoldClient skiaClient = SkiaGoldClient(fs.directory(basedir));
process: process, return FlutterSkippingFileComparator(basedir, skiaClient, reason, namePrefix: namePrefix);
platform: platform,
httpClient: httpClient,
log: log,
);
return FlutterSkippingFileComparator(
basedir,
skiaClient,
reason,
fs: fs,
platform: platform,
log: log,
namePrefix: namePrefix,
);
} }
@override @override
Future<bool> compare(Uint8List imageBytes, Uri golden) async { Future<bool> compare(Uint8List imageBytes, Uri golden) async {
log('Auto-passing "$golden" test without checking: $reason'); // Ideally we would use markTestSkipped here but in some situations,
// comparators are called outside of tests.
// See also: https://github.com/flutter/flutter/issues/91285
// ignore: avoid_print
print('Skipping "$golden" test: $reason');
return true; return true;
} }
...@@ -490,10 +416,13 @@ class FlutterSkippingFileComparator extends FlutterGoldenFileComparator { ...@@ -490,10 +416,13 @@ class FlutterSkippingFileComparator extends FlutterGoldenFileComparator {
/// used. /// used.
/// ///
/// If we are in a CI environment, LUCI or Cirrus, but are not using the other /// If we are in a CI environment, LUCI or Cirrus, but are not using the other
/// comparators (determined by checking this after the others), we skip. /// comparators, we skip.
static bool isRecommendedForEnvironment(Platform platform) { static bool isAvailableForEnvironment(Platform platform) {
return platform.environment.containsKey('SWARMING_TASK_ID') // Indicates LUCI environment. return (platform.environment.containsKey('SWARMING_TASK_ID')
|| platform.environment.containsKey('CIRRUS_CI'); // Indicates Cirrus environment. // Some builds are still being run on Cirrus, we should skip these.
|| platform.environment.containsKey('CIRRUS_CI'))
// If we are in CI, skip on branches that are not main.
&& !_kMainBranch.hasMatch(platform.environment['GIT_BRANCH'] ?? '');
} }
} }
...@@ -503,7 +432,7 @@ class FlutterSkippingFileComparator extends FlutterGoldenFileComparator { ...@@ -503,7 +432,7 @@ class FlutterSkippingFileComparator extends FlutterGoldenFileComparator {
/// This comparator utilizes the [SkiaGoldClient] to request baseline images for /// This comparator utilizes the [SkiaGoldClient] to request baseline images for
/// the given device under test for comparison. This comparator is initialized /// the given device under test for comparison. This comparator is initialized
/// when conditions for all other [FlutterGoldenFileComparators] have not been /// when conditions for all other [FlutterGoldenFileComparators] have not been
/// met, see the `isRecommendedForEnvironment` method for each one listed below. /// met, see the `isAvailableForEnvironment` method for each one listed below.
/// ///
/// The [FlutterLocalFileComparator] is intended to run on local machines and /// The [FlutterLocalFileComparator] is intended to run on local machines and
/// serve as a smoke test during development. As such, it will not be able to /// serve as a smoke test during development. As such, it will not be able to
...@@ -532,56 +461,68 @@ class FlutterLocalFileComparator extends FlutterGoldenFileComparator with LocalC ...@@ -532,56 +461,68 @@ class FlutterLocalFileComparator extends FlutterGoldenFileComparator with LocalC
FlutterLocalFileComparator( FlutterLocalFileComparator(
super.basedir, super.basedir,
super.skiaClient, { super.skiaClient, {
required super.fs, super.fs,
required super.platform, super.platform,
required super.log,
}); });
/// Creates a new [FlutterLocalFileComparator] that mirrors the /// Creates a new [FlutterLocalFileComparator] that mirrors the
/// relative path resolution of the default [goldenFileComparator]. /// relative path resolution of the default [goldenFileComparator].
static Future<FlutterGoldenFileComparator> fromLocalFileComparator({ ///
required LocalFileComparator localFileComparator, /// The [goldens], [defaultComparator], and [baseDirectory] parameters are
required Platform platform, /// visible for testing purposes only.
required FileSystem fs, static Future<FlutterGoldenFileComparator> fromDefaultComparator(
required ProcessManager process, final Platform platform, {
required io.HttpClient httpClient, SkiaGoldClient? goldens,
required LogCallback log, LocalFileComparator? defaultComparator,
Directory? baseDirectory,
}) async { }) async {
final Directory baseDirectory = FlutterGoldenFileComparator.getBaseDirectory( defaultComparator ??= goldenFileComparator as LocalFileComparator;
localFileComparator, baseDirectory ??= FlutterGoldenFileComparator.getBaseDirectory(
platform: platform, defaultComparator,
fs: fs, platform,
); );
if (!baseDirectory.existsSync()) { if (!baseDirectory.existsSync()) {
baseDirectory.createSync(recursive: true); baseDirectory.createSync(recursive: true);
} }
final SkiaGoldClient goldens = SkiaGoldClient( goldens ??= SkiaGoldClient(baseDirectory);
baseDirectory, try {
fs: fs, // Check if we can reach Gold.
process: process, await goldens.getExpectationForTest('');
platform: platform, } on io.OSError catch (_) {
httpClient: httpClient, return FlutterSkippingFileComparator(
log: log, baseDirectory.uri,
goldens,
'OSError occurred, could not reach Gold. '
'Switching to FlutterSkippingGoldenFileComparator.',
); );
return FlutterLocalFileComparator( } on io.SocketException catch (_) {
return FlutterSkippingFileComparator(
baseDirectory.uri, baseDirectory.uri,
goldens, goldens,
fs: fs, 'SocketException occurred, could not reach Gold. '
platform: platform, 'Switching to FlutterSkippingGoldenFileComparator.',
log: log,
); );
} }
return FlutterLocalFileComparator(baseDirectory.uri, goldens);
}
@override @override
Future<bool> compare(Uint8List imageBytes, Uri golden) async { Future<bool> compare(Uint8List imageBytes, Uri golden) async {
golden = _addPrefix(golden); golden = _addPrefix(golden);
final String testName = skiaClient.cleanTestName(golden.path); final String testName = skiaClient.cleanTestName(golden.path);
late String? testExpectation; late String? testExpectation;
try {
testExpectation = await skiaClient.getExpectationForTest(testName); testExpectation = await skiaClient.getExpectationForTest(testName);
if (testExpectation == null || testExpectation.isEmpty) { if (testExpectation == null || testExpectation.isEmpty) {
log( // There is no baseline for this test.
// Ideally we would use markTestSkipped here but in some situations,
// comparators are called outside of tests.
// See also: https://github.com/flutter/flutter/issues/91285
// ignore: avoid_print
print(
'No expectations provided by Skia Gold for test: $golden. ' 'No expectations provided by Skia Gold for test: $golden. '
'This may be a new test. If this is an unexpected result, check ' 'This may be a new test. If this is an unexpected result, check '
'https://flutter-gold.skia.org.\n' 'https://flutter-gold.skia.org.\n'
...@@ -590,14 +531,6 @@ class FlutterLocalFileComparator extends FlutterGoldenFileComparator with LocalC ...@@ -590,14 +531,6 @@ class FlutterLocalFileComparator extends FlutterGoldenFileComparator with LocalC
update(golden, imageBytes); update(golden, imageBytes);
return true; return true;
} }
} on Exception catch (error) {
if (error is! io.SocketException &&
error is! io.OSError) {
rethrow; // "uncaught error"
}
log('Auto-passing "$golden" test, ignoring network error when contacting Skia.');
return true;
}
ComparisonResult result; ComparisonResult result;
final List<int> goldenBytes = await skiaClient.getImageBytes(testExpectation); final List<int> goldenBytes = await skiaClient.getImageBytes(testExpectation);
......
...@@ -12,24 +12,26 @@ dependencies: ...@@ -12,24 +12,26 @@ dependencies:
sdk: flutter sdk: flutter
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_goldens_client:
path: ../flutter_goldens_client
file: 7.0.0 file: 7.0.0
meta: 1.11.0 meta: 1.11.0
platform: 3.1.4 platform: 3.1.4
process: 5.0.2 process: 5.0.2
crypto: 3.0.3
path: 1.9.0
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.18.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.18.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
leak_tracker: 10.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" leak_tracker: 10.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
leak_tracker_flutter_testing: 2.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" leak_tracker_flutter_testing: 2.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
leak_tracker_testing: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" leak_tracker_testing: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.16+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.8.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" material_color_utilities: 0.8.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_goldens/flutter_goldens.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:platform/platform.dart';
enum _Comparator { post, pre, skip, local }
_Comparator _testRecommendations({
bool hasFlutterRoot = false,
bool hasLuci = false,
bool hasCirrus = false,
bool hasGold = false,
bool hasTryJob = false,
String branch = 'main',
String os = 'macos',
}) {
final Platform platform = FakePlatform(
environment: <String, String>{
if (hasFlutterRoot)
'FLUTTER_ROOT': '/flutter',
if (hasLuci)
'SWARMING_TASK_ID': '8675309',
if (hasCirrus)
'CIRRUS_CI': 'true',
if (hasCirrus)
'CIRRUS_PR': '',
if (hasCirrus)
'CIRRUS_BRANCH': branch,
if (hasGold)
'GOLDCTL': 'goldctl',
if (hasGold && hasCirrus)
'GOLD_SERVICE_ACCOUNT': 'service account...',
if (hasTryJob)
'GOLD_TRYJOB': 'git/ref/12345/head',
'GIT_BRANCH': branch,
},
operatingSystem: os,
);
if (FlutterPostSubmitFileComparator.isRecommendedForEnvironment(platform)) {
return _Comparator.post;
}
if (FlutterPreSubmitFileComparator.isRecommendedForEnvironment(platform)) {
return _Comparator.pre;
}
if (FlutterSkippingFileComparator.isRecommendedForEnvironment(platform)) {
return _Comparator.skip;
}
return _Comparator.local;
}
void main() {
test('Comparator recommendations - main branch', () {
// If we're running locally (no CI), use a local comparator.
expect(_testRecommendations(), _Comparator.local);
expect(_testRecommendations(hasFlutterRoot: true), _Comparator.local);
expect(_testRecommendations(hasGold: true), _Comparator.local);
expect(_testRecommendations(hasFlutterRoot: true, hasGold: true), _Comparator.local);
// If we don't have gold but are on CI, we skip regardless.
expect(_testRecommendations(hasLuci: true), _Comparator.skip);
expect(_testRecommendations(hasLuci: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(hasCirrus: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(hasLuci: true, hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(hasLuci: true, hasCirrus: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(hasFlutterRoot: true, hasLuci: true), _Comparator.skip);
expect(_testRecommendations(hasFlutterRoot: true, hasLuci: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(hasFlutterRoot: true, hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(hasFlutterRoot: true, hasCirrus: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(hasFlutterRoot: true, hasLuci: true, hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(hasFlutterRoot: true, hasLuci: true, hasCirrus: true, hasTryJob: true), _Comparator.skip);
// On Luci, with Gold, post-submit. Flutter root and Cirrus variables should have no effect.
expect(_testRecommendations(hasGold: true, hasLuci: true), _Comparator.post);
expect(_testRecommendations(hasGold: true, hasLuci: true, hasCirrus: true), _Comparator.post);
expect(_testRecommendations(hasGold: true, hasLuci: true, hasFlutterRoot: true), _Comparator.post);
expect(_testRecommendations(hasGold: true, hasLuci: true, hasFlutterRoot: true, hasCirrus: true), _Comparator.post);
// On Luci, with Gold, pre-submit. Flutter root and Cirrus variables should have no effect.
expect(_testRecommendations(hasGold: true, hasLuci: true, hasTryJob: true), _Comparator.pre);
expect(_testRecommendations(hasGold: true, hasLuci: true, hasCirrus: true, hasTryJob: true), _Comparator.pre);
expect(_testRecommendations(hasGold: true, hasLuci: true, hasFlutterRoot: true, hasTryJob: true), _Comparator.pre);
expect(_testRecommendations(hasGold: true, hasLuci: true, hasFlutterRoot: true, hasCirrus: true, hasTryJob: true), _Comparator.pre);
// On Cirrus (with Gold and not on Luci), we skip regardless.
expect(_testRecommendations(hasCirrus: true, hasGold: true, hasFlutterRoot: true), _Comparator.skip);
expect(_testRecommendations(hasCirrus: true, hasGold: true, hasFlutterRoot: true, hasTryJob: true), _Comparator.skip);
});
test('Comparator recommendations - release branch', () {
// If we're running locally (no CI), use a local comparator.
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0'), _Comparator.local);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasFlutterRoot: true), _Comparator.local);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasGold: true), _Comparator.local);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasFlutterRoot: true, hasGold: true), _Comparator.local);
// If we don't have gold but are on CI, we skip regardless.
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasLuci: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasLuci: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasCirrus: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasLuci: true, hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasLuci: true, hasCirrus: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasFlutterRoot: true, hasLuci: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasFlutterRoot: true, hasLuci: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasFlutterRoot: true, hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasFlutterRoot: true, hasCirrus: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasFlutterRoot: true, hasLuci: true, hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasFlutterRoot: true, hasLuci: true, hasCirrus: true, hasTryJob: true), _Comparator.skip);
// On Luci, with Gold, post-submit. Flutter root and Cirrus variables should have no effect. Branch should make us skip.
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasGold: true, hasLuci: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasGold: true, hasLuci: true, hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasGold: true, hasLuci: true, hasFlutterRoot: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasGold: true, hasLuci: true, hasFlutterRoot: true, hasCirrus: true), _Comparator.skip);
// On Luci, with Gold, pre-submit. Flutter root and Cirrus variables should have no effect. Branch should make us skip.
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasGold: true, hasLuci: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasGold: true, hasLuci: true, hasCirrus: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasGold: true, hasLuci: true, hasFlutterRoot: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasGold: true, hasLuci: true, hasFlutterRoot: true, hasCirrus: true, hasTryJob: true), _Comparator.skip);
// On Cirrus (with Gold and not on Luci), we skip regardless.
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasCirrus: true, hasGold: true, hasFlutterRoot: true), _Comparator.skip);
expect(_testRecommendations(branch: 'flutter-3.16-candidate.0', hasCirrus: true, hasGold: true, hasFlutterRoot: true, hasTryJob: true), _Comparator.skip);
});
test('Comparator recommendations - Linux', () {
// If we're running locally (no CI), use a local comparator.
expect(_testRecommendations(os: 'linux'), _Comparator.local);
expect(_testRecommendations(os: 'linux', hasFlutterRoot: true), _Comparator.local);
expect(_testRecommendations(os: 'linux', hasGold: true), _Comparator.local);
expect(_testRecommendations(os: 'linux', hasFlutterRoot: true, hasGold: true), _Comparator.local);
// If we don't have gold but are on CI, we skip regardless.
expect(_testRecommendations(os: 'linux', hasLuci: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasLuci: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasCirrus: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasLuci: true, hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasLuci: true, hasCirrus: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasFlutterRoot: true, hasLuci: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasFlutterRoot: true, hasLuci: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasFlutterRoot: true, hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasFlutterRoot: true, hasCirrus: true, hasTryJob: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasFlutterRoot: true, hasLuci: true, hasCirrus: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasFlutterRoot: true, hasLuci: true, hasCirrus: true, hasTryJob: true), _Comparator.skip);
// On Luci, with Gold, post-submit. Flutter root and Cirrus variables should have no effect.
expect(_testRecommendations(os: 'linux', hasGold: true, hasLuci: true), _Comparator.post);
expect(_testRecommendations(os: 'linux', hasGold: true, hasLuci: true, hasCirrus: true), _Comparator.post);
expect(_testRecommendations(os: 'linux', hasGold: true, hasLuci: true, hasFlutterRoot: true), _Comparator.post);
expect(_testRecommendations(os: 'linux', hasGold: true, hasLuci: true, hasFlutterRoot: true, hasCirrus: true), _Comparator.post);
// On Luci, with Gold, pre-submit. Flutter root and Cirrus variables should have no effect.
expect(_testRecommendations(os: 'linux', hasGold: true, hasLuci: true, hasTryJob: true), _Comparator.pre);
expect(_testRecommendations(os: 'linux', hasGold: true, hasLuci: true, hasCirrus: true, hasTryJob: true), _Comparator.pre);
expect(_testRecommendations(os: 'linux', hasGold: true, hasLuci: true, hasFlutterRoot: true, hasTryJob: true), _Comparator.pre);
expect(_testRecommendations(os: 'linux', hasGold: true, hasLuci: true, hasFlutterRoot: true, hasCirrus: true, hasTryJob: true), _Comparator.pre);
// On Cirrus (with Gold and not on Luci), we skip regardless.
expect(_testRecommendations(os: 'linux', hasCirrus: true, hasGold: true, hasFlutterRoot: true), _Comparator.skip);
expect(_testRecommendations(os: 'linux', hasCirrus: true, hasGold: true, hasFlutterRoot: true, hasTryJob: true), _Comparator.skip);
});
}
...@@ -5,14 +5,13 @@ ...@@ -5,14 +5,13 @@
// See also dev/automated_tests/flutter_test/flutter_gold_test.dart // See also dev/automated_tests/flutter_test/flutter_gold_test.dart
import 'dart:convert'; import 'dart:convert';
import 'dart:io' as io; import 'dart:io' hide Directory;
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_goldens/flutter_goldens.dart'; import 'package:flutter_goldens/flutter_goldens.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:path/path.dart' as path;
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
...@@ -28,26 +27,41 @@ const List<int> _kTestPngBytes = <int>[ ...@@ -28,26 +27,41 @@ const List<int> _kTestPngBytes = <int>[
78, 68, 174, 66, 96, 130, 78, 68, 174, 66, 96, 130,
]; ];
FileSystem createFakeFileSystem() { void main() {
return MemoryFileSystem() late MemoryFileSystem fs;
..directory(_kFlutterRoot).createSync(recursive: true); late FakePlatform platform;
} late FakeProcessManager process;
late FakeHttpClient fakeHttpClient;
setUp(() {
fs = MemoryFileSystem();
platform = FakePlatform(
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos'
);
process = FakeProcessManager();
fakeHttpClient = FakeHttpClient();
fs.directory(_kFlutterRoot).createSync(recursive: true);
});
(FileSystem, Directory) createFakeFileSystemWithWorkDirectory() { group('SkiaGoldClient', () {
final FileSystem fs = createFakeFileSystem(); late SkiaGoldClient skiaClient;
final Directory workDirectory = fs.directory('/workDirectory')..createSync(recursive: true); late Directory workDirectory;
return (fs, workDirectory);
}
(FileSystem, Directory) createFakeFileSystemWithLibDirectory() { setUp(() {
final FileSystem fs = createFakeFileSystem(); workDirectory = fs.directory('/workDirectory')
final Directory lib = fs.directory('$_kFlutterRoot/test/library/')..createSync(recursive: true); ..createSync(recursive: true);
return (fs, lib); skiaClient = SkiaGoldClient(
} workDirectory,
fs: fs,
process: process,
platform: platform,
httpClient: fakeHttpClient,
);
});
void main() { test('web HTML test', () async {
test('SkiaGoldClient - web HTML test', () async { platform = FakePlatform(
final Platform platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'GOLDCTL': 'goldctl', 'GOLDCTL': 'goldctl',
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
...@@ -56,19 +70,15 @@ void main() { ...@@ -56,19 +70,15 @@ void main() {
}, },
operatingSystem: 'macos' operatingSystem: 'macos'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory(); skiaClient = SkiaGoldClient(
final FakeProcessManager process = FakeProcessManager();
final io.HttpClient httpClient = ThrowingHttpClient();
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: httpClient, httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
final File goldenFile = workDirectory.childFile('temp/golden_file_test.png') final File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
..createSync(recursive: true); ..createSync(recursive: true);
const RunInvocation goldctlInvocation = RunInvocation( const RunInvocation goldctlInvocation = RunInvocation(
...@@ -85,12 +95,16 @@ void main() { ...@@ -85,12 +95,16 @@ void main() {
], ],
null, null,
); );
process.processResults[goldctlInvocation] = io.ProcessResult(123, 0, '', ''); process.processResults[goldctlInvocation] = ProcessResult(123, 0, '', '');
await skiaClient.imgtestAdd('golden_file_test.png', goldenFile);
expect(
await skiaClient.imgtestAdd('golden_file_test.png', goldenFile),
isTrue,
);
}); });
test('SkiaGoldClient - web CanvasKit test', () async { test('web CanvasKit test', () async {
final Platform platform = FakePlatform( platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'GOLDCTL': 'goldctl', 'GOLDCTL': 'goldctl',
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
...@@ -99,19 +113,15 @@ void main() { ...@@ -99,19 +113,15 @@ void main() {
}, },
operatingSystem: 'macos' operatingSystem: 'macos'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory(); skiaClient = SkiaGoldClient(
final FakeProcessManager process = FakeProcessManager();
final io.HttpClient httpClient = FakeHttpClient();
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: httpClient, httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
final File goldenFile = workDirectory.childFile('temp/golden_file_test.png') final File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
..createSync(recursive: true); ..createSync(recursive: true);
const RunInvocation goldctlInvocation = RunInvocation( const RunInvocation goldctlInvocation = RunInvocation(
...@@ -125,101 +135,75 @@ void main() { ...@@ -125,101 +135,75 @@ void main() {
], ],
null, null,
); );
process.processResults[goldctlInvocation] = io.ProcessResult(123, 0, '', ''); process.processResults[goldctlInvocation] = ProcessResult(123, 0, '', '');
await skiaClient.imgtestAdd('golden_file_test.png', goldenFile); expect(
await skiaClient.imgtestAdd('golden_file_test.png', goldenFile),
isTrue,
);
}); });
test('SkiaGoldClient - auth performs minimal work if already authorized', () async { test('auth performs minimal work if already authorized', () async {
final Platform platform = FakePlatform( final File authFile = fs.file('/workDirectory/temp/auth_opt.json')
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos'
);
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final FakeProcessManager process = FakeProcessManager();
final File authFile = workDirectory.childFile('temp/auth_opt.json')
..createSync(recursive: true); ..createSync(recursive: true);
authFile.writeAsStringSync(authTemplate()); authFile.writeAsStringSync(authTemplate());
process.fallbackProcessResult = io.ProcessResult(123, 0, '', ''); process.fallbackProcessResult = ProcessResult(123, 0, '', '');
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory,
fs: fs,
process: process,
platform: platform,
httpClient: ThrowingHttpClient(),
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
);
await skiaClient.auth(); await skiaClient.auth();
expect(process.workingDirectories, isEmpty); expect(process.workingDirectories, isEmpty);
}); });
test('SkiaGoldClient - gsutil is checked when authorization file is present', () async { test('gsutil is checked when authorization file is present', () async {
final Platform platform = FakePlatform( final File authFile = fs.file('/workDirectory/temp/auth_opt.json')
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos'
);
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final ProcessManager process = FakeProcessManager();
final File authFile = workDirectory.childFile('temp/auth_opt.json')
..createSync(recursive: true); ..createSync(recursive: true);
authFile.writeAsStringSync(authTemplate(gsutil: true)); authFile.writeAsStringSync(authTemplate(gsutil: true));
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory,
fs: fs,
process: process,
platform: platform,
httpClient: ThrowingHttpClient(),
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
);
expect( expect(
await skiaClient.clientIsAuthorized(), await skiaClient.clientIsAuthorized(),
isFalse, isFalse,
); );
}); });
test('SkiaGoldClient - throws for error state from auth', () async { test('throws for error state from auth', () async {
final Platform platform = FakePlatform( platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLD_SERVICE_ACCOUNT': 'Service Account', 'GOLD_SERVICE_ACCOUNT' : 'Service Account',
'GOLDCTL': 'goldctl', 'GOLDCTL' : 'goldctl',
}, },
operatingSystem: 'macos' operatingSystem: 'macos'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final FakeProcessManager process = FakeProcessManager(); skiaClient = SkiaGoldClient(
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: ThrowingHttpClient(), httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
process.fallbackProcessResult = io.ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');
process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');
expect( expect(
skiaClient.auth(), skiaClient.auth(),
throwsException, throwsException,
); );
}); });
test('SkiaGoldClient - throws for error state from init', () { test('throws for error state from init', () {
final Platform platform = FakePlatform( platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'goldctl', 'GOLDCTL' : 'goldctl',
}, },
operatingSystem: 'macos' operatingSystem: 'macos'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final FakeProcessManager process = FakeProcessManager(); skiaClient = SkiaGoldClient(
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: ThrowingHttpClient(), httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
const RunInvocation gitInvocation = RunInvocation( const RunInvocation gitInvocation = RunInvocation(
...@@ -239,9 +223,9 @@ void main() { ...@@ -239,9 +223,9 @@ void main() {
], ],
null, null,
); );
process.processResults[gitInvocation] = io.ProcessResult(12345678, 0, '12345678', ''); process.processResults[gitInvocation] = ProcessResult(12345678, 0, '12345678', '');
process.processResults[goldctlInvocation] = io.ProcessResult(123, 1, 'Expected failure', 'Expected failure'); process.processResults[goldctlInvocation] = ProcessResult(123, 1, 'Expected failure', 'Expected failure');
process.fallbackProcessResult = io.ProcessResult(123, 1, 'Fallback failure', 'Fallback failure'); process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');
expect( expect(
skiaClient.imgtestInit(), skiaClient.imgtestInit(),
...@@ -249,23 +233,21 @@ void main() { ...@@ -249,23 +233,21 @@ void main() {
); );
}); });
test('SkiaGoldClient - Only calls init once', () async { test('Only calls init once', () async {
final Platform platform = FakePlatform( platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'goldctl', 'GOLDCTL' : 'goldctl',
}, },
operatingSystem: 'macos', operatingSystem: 'macos'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final FakeProcessManager process = FakeProcessManager(); skiaClient = SkiaGoldClient(
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: ThrowingHttpClient(), httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
const RunInvocation gitInvocation = RunInvocation( const RunInvocation gitInvocation = RunInvocation(
...@@ -285,9 +267,9 @@ void main() { ...@@ -285,9 +267,9 @@ void main() {
], ],
null, null,
); );
process.processResults[gitInvocation] = io.ProcessResult(1234, 0, '1234', ''); process.processResults[gitInvocation] = ProcessResult(1234, 0, '1234', '');
process.processResults[goldctlInvocation] = io.ProcessResult(5678, 0, '5678', ''); process.processResults[goldctlInvocation] = ProcessResult(5678, 0, '5678', '');
process.fallbackProcessResult = io.ProcessResult(123, 1, 'Fallback failure', 'Fallback failure'); process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');
// First call // First call
await skiaClient.imgtestInit(); await skiaClient.imgtestInit();
...@@ -300,26 +282,24 @@ void main() { ...@@ -300,26 +282,24 @@ void main() {
await skiaClient.imgtestInit(); await skiaClient.imgtestInit();
}); });
test('SkiaGoldClient - Only calls tryjob init once', () async { test('Only calls tryjob init once', () async {
final Platform platform = FakePlatform( platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'goldctl', 'GOLDCTL' : 'goldctl',
'SWARMING_TASK_ID': '4ae997b50dfd4d11', 'SWARMING_TASK_ID' : '4ae997b50dfd4d11',
'LOGDOG_STREAM_PREFIX': 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672', 'LOGDOG_STREAM_PREFIX' : 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672',
'GOLD_TRYJOB': 'refs/pull/49815/head', 'GOLD_TRYJOB' : 'refs/pull/49815/head',
}, },
operatingSystem: 'macos' operatingSystem: 'macos'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final FakeProcessManager process = FakeProcessManager(); skiaClient = SkiaGoldClient(
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: ThrowingHttpClient(), httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
const RunInvocation gitInvocation = RunInvocation( const RunInvocation gitInvocation = RunInvocation(
...@@ -344,9 +324,9 @@ void main() { ...@@ -344,9 +324,9 @@ void main() {
], ],
null, null,
); );
process.processResults[gitInvocation] = io.ProcessResult(1234, 0, '1234', ''); process.processResults[gitInvocation] = ProcessResult(1234, 0, '1234', '');
process.processResults[goldctlInvocation] = io.ProcessResult(5678, 0, '5678', ''); process.processResults[goldctlInvocation] = ProcessResult(5678, 0, '5678', '');
process.fallbackProcessResult = io.ProcessResult(123, 1, 'Fallback failure', 'Fallback failure'); process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');
// First call // First call
await skiaClient.tryjobInit(); await skiaClient.tryjobInit();
...@@ -359,25 +339,23 @@ void main() { ...@@ -359,25 +339,23 @@ void main() {
await skiaClient.tryjobInit(); await skiaClient.tryjobInit();
}); });
test('SkiaGoldClient - throws for error state from imgtestAdd', () { test('throws for error state from imgtestAdd', () {
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory(); final File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
final File goldenFile = workDirectory.childFile('temp/golden_file_test.png')
..createSync(recursive: true); ..createSync(recursive: true);
final FakeProcessManager process = FakeProcessManager(); platform = FakePlatform(
final Platform platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'goldctl', 'GOLDCTL' : 'goldctl',
}, },
operatingSystem: 'macos', operatingSystem: 'macos'
); );
final SkiaGoldClient skiaClient = SkiaGoldClient(
skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: ThrowingHttpClient(), httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
const RunInvocation goldctlInvocation = RunInvocation( const RunInvocation goldctlInvocation = RunInvocation(
...@@ -391,8 +369,8 @@ void main() { ...@@ -391,8 +369,8 @@ void main() {
], ],
null, null,
); );
process.processResults[goldctlInvocation] = io.ProcessResult(123, 1, 'Expected failure', 'Expected failure'); process.processResults[goldctlInvocation] = ProcessResult(123, 1, 'Expected failure', 'Expected failure');
process.fallbackProcessResult = io.ProcessResult(123, 1, 'Fallback failure', 'Fallback failure'); process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');
expect( expect(
skiaClient.imgtestAdd('golden_file_test', goldenFile), skiaClient.imgtestAdd('golden_file_test', goldenFile),
...@@ -400,26 +378,24 @@ void main() { ...@@ -400,26 +378,24 @@ void main() {
); );
}); });
test('SkiaGoldClient - correctly inits tryjob for luci', () async { test('correctly inits tryjob for luci', () async {
final Platform platform = FakePlatform( platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'goldctl', 'GOLDCTL' : 'goldctl',
'SWARMING_TASK_ID': '4ae997b50dfd4d11', 'SWARMING_TASK_ID' : '4ae997b50dfd4d11',
'LOGDOG_STREAM_PREFIX': 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672', 'LOGDOG_STREAM_PREFIX' : 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672',
'GOLD_TRYJOB': 'refs/pull/49815/head', 'GOLD_TRYJOB' : 'refs/pull/49815/head',
}, },
operatingSystem: 'macos' operatingSystem: 'macos'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final ProcessManager process = FakeProcessManager(); skiaClient = SkiaGoldClient(
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: ThrowingHttpClient(), httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
final List<String> ciArguments = skiaClient.getCIArguments(); final List<String> ciArguments = skiaClient.getCIArguments();
...@@ -436,107 +412,100 @@ void main() { ...@@ -436,107 +412,100 @@ void main() {
); );
}); });
test('SkiaGoldClient - Creates traceID correctly - Linux', () async { test('Creates traceID correctly', () async {
final Platform platform = FakePlatform( String traceID;
platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'goldctl', 'GOLDCTL' : 'goldctl',
'SWARMING_TASK_ID': '4ae997b50dfd4d11', 'SWARMING_TASK_ID' : '4ae997b50dfd4d11',
'LOGDOG_STREAM_PREFIX': 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672', 'LOGDOG_STREAM_PREFIX' : 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672',
'GOLD_TRYJOB': 'refs/pull/49815/head', 'GOLD_TRYJOB' : 'refs/pull/49815/head',
}, },
operatingSystem: 'linux', operatingSystem: 'linux'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final ProcessManager process = FakeProcessManager(); skiaClient = SkiaGoldClient(
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: ThrowingHttpClient(), httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
traceID = skiaClient.getTraceID('flutter.golden.1');
expect( expect(
skiaClient.getTraceID('flutter.golden.1'), traceID,
equals('ae18c7a6aa48e0685525dfe8fdf79003'), equals('ae18c7a6aa48e0685525dfe8fdf79003'),
); );
});
test('SkiaGoldClient - Creates traceID correctly - Linux web', () async { // Browser
final Platform platform = FakePlatform( platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'goldctl', 'GOLDCTL' : 'goldctl',
'SWARMING_TASK_ID': '4ae997b50dfd4d11', 'SWARMING_TASK_ID' : '4ae997b50dfd4d11',
'LOGDOG_STREAM_PREFIX': 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672', 'LOGDOG_STREAM_PREFIX' : 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672',
'GOLD_TRYJOB': 'refs/pull/49815/head', 'GOLD_TRYJOB' : 'refs/pull/49815/head',
'FLUTTER_TEST_BROWSER': 'chrome', // flips browser bit 'FLUTTER_TEST_BROWSER' : 'chrome',
}, },
operatingSystem: 'linux', operatingSystem: 'linux'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final ProcessManager process = FakeProcessManager(); skiaClient = SkiaGoldClient(
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: ThrowingHttpClient(), httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
traceID = skiaClient.getTraceID('flutter.golden.1');
expect( expect(
skiaClient.getTraceID('flutter.golden.1'), traceID,
equals('e9d5c296c48e7126808520e9cc191243'), equals('e9d5c296c48e7126808520e9cc191243'),
); );
});
test('SkiaGoldClient - Creates traceID correctly - Linux', () async { // Locally - should defer to luci traceID
final Platform platform = FakePlatform( platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'goldctl',
'SWARMING_TASK_ID': '4ae997b50dfd4d11',
'LOGDOG_STREAM_PREFIX': 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672',
'GOLD_TRYJOB': 'refs/pull/49815/head',
}, },
operatingSystem: 'macos', // different operating system operatingSystem: 'macos'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final ProcessManager process = FakeProcessManager(); skiaClient = SkiaGoldClient(
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: ThrowingHttpClient(), httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
traceID = skiaClient.getTraceID('flutter.golden.1');
expect( expect(
skiaClient.getTraceID('flutter.golden.1'), traceID,
equals('9968695b9ae78cdb77cbb2be621ca2d6'), equals('9968695b9ae78cdb77cbb2be621ca2d6'),
); );
}); });
test('SkiaGoldClient - throws for error state from imgtestAdd', () { test('throws for error state from imgtestAdd', () {
final Platform platform = FakePlatform( final File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
..createSync(recursive: true);
platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'goldctl', 'GOLDCTL' : 'goldctl',
}, },
operatingSystem: 'macos', operatingSystem: 'macos'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final File goldenFile = workDirectory.childFile('temp/golden_file_test.png') skiaClient = SkiaGoldClient(
..createSync(recursive: true);
final FakeProcessManager process = FakeProcessManager();
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: ThrowingHttpClient(), httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
const RunInvocation goldctlInvocation = RunInvocation( const RunInvocation goldctlInvocation = RunInvocation(
...@@ -550,47 +519,37 @@ void main() { ...@@ -550,47 +519,37 @@ void main() {
], ],
null, null,
); );
process.processResults[goldctlInvocation] = io.ProcessResult(123, 1, 'Expected failure', 'Expected failure'); process.processResults[goldctlInvocation] = ProcessResult(123, 1, 'Expected failure', 'Expected failure');
process.fallbackProcessResult = io.ProcessResult(123, 1, 'Fallback failure', 'Fallback failure'); process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');
expect( expect(
skiaClient.imgtestAdd('golden_file_test', goldenFile), skiaClient.imgtestAdd('golden_file_test', goldenFile),
throwsA( throwsA(
isA<SkiaException>().having((SkiaException error) => error.message, isA<SkiaException>().having((SkiaException error) => error.message,
'message', 'message',
'Golden test for "golden_file_test" failed for a reason unrelated to pixel comparison.\n' contains('result-state.json'),
'\n'
'imgtest add failed with exit code 1.\n'
'\n'
'stdout from gold:\n'
' Fallback failure\n'
'\n'
'stderr from gold:\n'
' Fallback failure\n',
), ),
), ),
); );
}); });
test('SkiaGoldClient - throws for error state from tryjobAdd', () { test('throws for error state from tryjobAdd', () {
final Platform platform = FakePlatform( final File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
..createSync(recursive: true);
platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'goldctl', 'GOLDCTL' : 'goldctl',
}, },
operatingSystem: 'macos', operatingSystem: 'macos'
); );
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final File goldenFile = workDirectory.childFile('temp/golden_file_test.png') skiaClient = SkiaGoldClient(
..createSync(recursive: true);
final FakeProcessManager process = FakeProcessManager();
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory, workDirectory,
fs: fs, fs: fs,
process: process, process: process,
platform: platform, platform: platform,
httpClient: ThrowingHttpClient(), httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
const RunInvocation goldctlInvocation = RunInvocation( const RunInvocation goldctlInvocation = RunInvocation(
...@@ -604,40 +563,27 @@ void main() { ...@@ -604,40 +563,27 @@ void main() {
], ],
null, null,
); );
process.processResults[goldctlInvocation] = io.ProcessResult(123, 1, 'Expected failure', 'Expected failure'); process.processResults[goldctlInvocation] = ProcessResult(123, 1, 'Expected failure', 'Expected failure');
process.fallbackProcessResult = io.ProcessResult(123, 1, 'Fallback failure', 'Fallback failure'); process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');
expect( expect(
skiaClient.tryjobAdd('golden_file_test', goldenFile), skiaClient.tryjobAdd('golden_file_test', goldenFile),
throwsA( throwsA(
isA<SkiaException>().having((SkiaException error) => error.message, isA<SkiaException>().having((SkiaException error) => error.message,
'message', 'message',
'Golden test for "golden_file_test" failed for a reason unrelated to pixel comparison.\n' contains('result-state.json'),
'\n'
'imgtest add failed with exit code 1.\n'
'\n'
'stdout from gold:\n'
' Fallback failure\n'
'\n'
'stderr from gold:\n'
' Fallback failure\n',
), ),
), ),
); );
}); });
test('SkiaGoldClient - Request Handling - image bytes are processed properly', () async { group('Request Handling', () {
const String expectation = '55109a4bed52acc780530f7a9aeff6c0'; const String expectation = '55109a4bed52acc780530f7a9aeff6c0';
final Platform platform = FakePlatform(
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot}, test('image bytes are processed properly', () async {
operatingSystem: 'macos'
);
final (FileSystem fs, Directory workDirectory) = createFakeFileSystemWithWorkDirectory();
final ProcessManager process = FakeProcessManager();
final Uri imageUrl = Uri.parse( final Uri imageUrl = Uri.parse(
'https://flutter-gold.skia.org/img/images/$expectation.png' 'https://flutter-gold.skia.org/img/images/$expectation.png'
); );
final FakeHttpClient fakeHttpClient = FakeHttpClient();
final FakeHttpClientRequest fakeImageRequest = FakeHttpClientRequest(); final FakeHttpClientRequest fakeImageRequest = FakeHttpClientRequest();
final FakeHttpImageResponse fakeImageResponse = FakeHttpImageResponse( final FakeHttpImageResponse fakeImageResponse = FakeHttpImageResponse(
imageResponseTemplate() imageResponseTemplate()
...@@ -646,26 +592,29 @@ void main() { ...@@ -646,26 +592,29 @@ void main() {
fakeHttpClient.request = fakeImageRequest; fakeHttpClient.request = fakeImageRequest;
fakeImageRequest.response = fakeImageResponse; fakeImageRequest.response = fakeImageResponse;
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory,
fs: fs,
process: process,
platform: platform,
httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
);
final List<int> masterBytes = await skiaClient.getImageBytes(expectation); final List<int> masterBytes = await skiaClient.getImageBytes(expectation);
expect(fakeHttpClient.lastUri, imageUrl); expect(fakeHttpClient.lastUri, imageUrl);
expect(masterBytes, equals(_kTestPngBytes)); expect(masterBytes, equals(_kTestPngBytes));
}); });
});
});
test('FlutterGoldenFileComparator - calculates the basedir correctly from defaultComparator for local testing', () async { group('FlutterGoldenFileComparator', () {
final Platform platform = FakePlatform( late FlutterGoldenFileComparator comparator;
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos' setUp(() {
final Directory basedir = fs.directory('flutter/test/library/')
..createSync(recursive: true);
comparator = FlutterPostSubmitFileComparator(
basedir.uri,
FakeSkiaGoldClient(),
fs: fs,
platform: platform,
); );
final FileSystem fs = createFakeFileSystem(); });
test('calculates the basedir correctly from defaultComparator for local testing', () async {
final FakeLocalFileComparator defaultComparator = FakeLocalFileComparator(); final FakeLocalFileComparator defaultComparator = FakeLocalFileComparator();
final Directory flutterRoot = fs.directory(platform.environment['FLUTTER_ROOT']) final Directory flutterRoot = fs.directory(platform.environment['FLUTTER_ROOT'])
..createSync(recursive: true); ..createSync(recursive: true);
...@@ -673,8 +622,7 @@ void main() { ...@@ -673,8 +622,7 @@ void main() {
final Directory basedir = FlutterGoldenFileComparator.getBaseDirectory( final Directory basedir = FlutterGoldenFileComparator.getBaseDirectory(
defaultComparator, defaultComparator,
platform: platform, platform,
fs: fs,
); );
expect( expect(
basedir.uri, basedir.uri,
...@@ -682,44 +630,23 @@ void main() { ...@@ -682,44 +630,23 @@ void main() {
); );
}); });
test('FlutterGoldenFileComparator - ignores version number', () { test('ignores version number', () {
final Platform platform = FakePlatform(
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos'
);
final (FileSystem fs, Directory libDirectory) = createFakeFileSystemWithLibDirectory();
final List<String> log = <String>[];
final FlutterGoldenFileComparator comparator = FlutterPostSubmitFileComparator(
libDirectory.uri,
FakeSkiaGoldClient(),
fs: fs,
platform: platform,
log: log.add,
);
final Uri key = comparator.getTestUri(Uri.parse('foo.png'), 1); final Uri key = comparator.getTestUri(Uri.parse('foo.png'), 1);
expect(key, Uri.parse('foo.png')); expect(key, Uri.parse('foo.png'));
expect(log, isEmpty);
}); });
test('FlutterGoldenFileComparator - adds namePrefix', () async { test('adds namePrefix', () async {
final Platform platform = FakePlatform(
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos'
);
const String libraryName = 'sidedishes'; const String libraryName = 'sidedishes';
const String namePrefix = 'tomatosalad'; const String namePrefix = 'tomatosalad';
const String fileName = 'lettuce.png'; const String fileName = 'lettuce.png';
final FileSystem fs = createFakeFileSystem(); final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
final Directory basedir = fs.directory('flutter/test/$libraryName/') final Directory basedir = fs.directory('flutter/test/$libraryName/')
..createSync(recursive: true); ..createSync(recursive: true);
final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
final List<String> log = <String>[];
final FlutterGoldenFileComparator comparator = FlutterPostSubmitFileComparator( final FlutterGoldenFileComparator comparator = FlutterPostSubmitFileComparator(
basedir.uri, basedir.uri,
fakeSkiaClient, fakeSkiaClient,
fs: fs, fs: fs,
platform: platform, platform: platform,
log: log.add,
namePrefix: namePrefix, namePrefix: namePrefix,
); );
await comparator.compare( await comparator.compare(
...@@ -727,24 +654,24 @@ void main() { ...@@ -727,24 +654,24 @@ void main() {
Uri.parse(fileName), Uri.parse(fileName),
); );
expect(fakeSkiaClient.testNames.single, '$namePrefix.$libraryName.$fileName'); expect(fakeSkiaClient.testNames.single, '$namePrefix.$libraryName.$fileName');
expect(log, isEmpty);
}); });
test('FlutterGoldenFileComparator - Post-Submit - asserts .png format', () async { group('Post-Submit', () {
final Platform platform = FakePlatform( late FakeSkiaGoldClient fakeSkiaClient;
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos' setUp(() {
); fakeSkiaClient = FakeSkiaGoldClient();
final (FileSystem fs, Directory libDirectory) = createFakeFileSystemWithLibDirectory(); final Directory basedir = fs.directory('flutter/test/library/')
final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient(); ..createSync(recursive: true);
final List<String> log = <String>[]; comparator = FlutterPostSubmitFileComparator(
final FlutterGoldenFileComparator comparator = FlutterPostSubmitFileComparator( basedir.uri,
libDirectory.uri,
fakeSkiaClient, fakeSkiaClient,
fs: fs, fs: fs,
platform: platform, platform: platform,
log: log.add,
); );
});
test('asserts .png format', () async {
await expectLater( await expectLater(
() async { () async {
return comparator.compare( return comparator.compare(
...@@ -762,68 +689,156 @@ void main() { ...@@ -762,68 +689,156 @@ void main() {
), ),
), ),
); );
expect(log, isEmpty);
}); });
test('FlutterGoldenFileComparator - Post-Submit - calls init during compare', () async { test('calls init during compare', () {
final Platform platform = FakePlatform(
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos'
);
final (FileSystem fs, Directory libDirectory) = createFakeFileSystemWithLibDirectory();
final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
final List<String> log = <String>[];
final FlutterGoldenFileComparator comparator = FlutterPostSubmitFileComparator(
libDirectory.uri,
fakeSkiaClient,
fs: fs,
platform: platform,
log: log.add,
);
expect(fakeSkiaClient.initCalls, 0); expect(fakeSkiaClient.initCalls, 0);
await comparator.compare( comparator.compare(
Uint8List.fromList(_kTestPngBytes), Uint8List.fromList(_kTestPngBytes),
Uri.parse('flutter.golden_test.1.png'), Uri.parse('flutter.golden_test.1.png'),
); );
expect(fakeSkiaClient.initCalls, 1); expect(fakeSkiaClient.initCalls, 1);
expect(log, isEmpty);
}); });
test('FlutterGoldenFileComparator - Post-Submit - does not call init in during construction', () { test('does not call init in during construction', () {
final Platform platform = FakePlatform( expect(fakeSkiaClient.initCalls, 0);
FlutterPostSubmitFileComparator.fromDefaultComparator(
platform,
goldens: fakeSkiaClient,
);
expect(fakeSkiaClient.initCalls, 0);
});
group('correctly determines testing environment', () {
test('returns true for configured Luci', () {
platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'testctl', 'SWARMING_TASK_ID' : '12345678990',
'GOLDCTL' : 'goldctl',
'GIT_BRANCH' : 'master',
}, },
operatingSystem: 'macos' operatingSystem: 'macos',
); );
final FileSystem fs = createFakeFileSystem(); expect(
final List<String> log = <String>[]; FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
FlutterPostSubmitFileComparator.fromLocalFileComparator( isTrue,
localFileComparator: LocalFileComparator(Uri.parse('/test'), pathStyle: path.Style.posix),
platform: platform,
fs: fs,
process: LoggingProcessManager(log),
httpClient: ThrowingHttpClient(),
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
); );
expect(log, isEmpty);
}); });
test('FlutterGoldenFileComparator - Pre-Submit - asserts .png format', () async { test('returns false on release branches in postsubmit', () {
final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient(); platform = FakePlatform(
final (FileSystem fs, Directory libDirectory) = createFakeFileSystemWithLibDirectory(); environment: <String, String>{
final List<String> log = <String>[]; 'FLUTTER_ROOT': _kFlutterRoot,
final FlutterGoldenFileComparator comparator = FlutterPreSubmitFileComparator( 'SWARMING_TASK_ID' : 'sweet task ID',
libDirectory.uri, 'GOLDCTL' : 'some/path',
'GIT_BRANCH' : 'flutter-3.16-candidate.0',
},
operatingSystem: 'macos',
);
expect(
FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
isFalse,
);
});
test('returns true on master branch in postsubmit', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : 'sweet task ID',
'GOLDCTL' : 'some/path',
'GIT_BRANCH' : 'master',
},
operatingSystem: 'macos',
);
expect(
FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
isTrue,
);
});
test('returns true on main branch in postsubmit', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : 'sweet task ID',
'GOLDCTL' : 'some/path',
'GIT_BRANCH' : 'main',
},
operatingSystem: 'macos',
);
expect(
FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
isTrue,
);
});
test('returns false - GOLDCTL not present', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : '12345678990',
},
operatingSystem: 'macos',
);
expect(
FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
isFalse,
);
});
test('returns false - GOLD_TRYJOB active', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : '12345678990',
'GOLDCTL' : 'goldctl',
'GOLD_TRYJOB' : 'git/ref/12345/head',
},
operatingSystem: 'macos',
);
expect(
FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
isFalse,
);
});
test('returns false - on Cirrus', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'CIRRUS_CI': 'true',
'CIRRUS_PR': '',
'CIRRUS_BRANCH': 'master',
'GOLD_SERVICE_ACCOUNT': 'service account...',
},
operatingSystem: 'macos',
);
expect(
FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
isFalse,
);
});
});
});
group('Pre-Submit', () {
late FakeSkiaGoldClient fakeSkiaClient;
setUp(() {
fakeSkiaClient = FakeSkiaGoldClient();
final Directory basedir = fs.directory('flutter/test/library/')
..createSync(recursive: true);
comparator = FlutterPreSubmitFileComparator(
basedir.uri,
fakeSkiaClient, fakeSkiaClient,
fs: fs, fs: fs,
platform: FakePlatform( platform: platform,
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos',
),
log: log.add,
); );
});
test('asserts .png format', () async {
await expectLater( await expectLater(
() async { () async {
return comparator.compare( return comparator.compare(
...@@ -841,72 +856,259 @@ void main() { ...@@ -841,72 +856,259 @@ void main() {
), ),
), ),
); );
expect(log, isEmpty);
}); });
test('FlutterGoldenFileComparator - Pre-Submit - calls init during compare', () async { test('calls init during compare', () {
final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
final (FileSystem fs, Directory libDirectory) = createFakeFileSystemWithLibDirectory();
final List<String> log = <String>[];
final FlutterGoldenFileComparator comparator = FlutterPreSubmitFileComparator(
libDirectory.uri,
fakeSkiaClient,
fs: fs,
platform: FakePlatform(
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos',
),
log: log.add,
);
expect(fakeSkiaClient.tryInitCalls, 0); expect(fakeSkiaClient.tryInitCalls, 0);
await comparator.compare( comparator.compare(
Uint8List.fromList(_kTestPngBytes), Uint8List.fromList(_kTestPngBytes),
Uri.parse('flutter.golden_test.1.png'), Uri.parse('flutter.golden_test.1.png'),
); );
expect(fakeSkiaClient.tryInitCalls, 1); expect(fakeSkiaClient.tryInitCalls, 1);
expect(log, isEmpty);
}); });
test('FlutterGoldenFileComparator - Pre-Submit - does not call init in during construction', () async { test('does not call init in during construction', () {
final Platform platform = FakePlatform( expect(fakeSkiaClient.tryInitCalls, 0);
FlutterPostSubmitFileComparator.fromDefaultComparator(
platform,
goldens: fakeSkiaClient,
);
expect(fakeSkiaClient.tryInitCalls, 0);
});
group('correctly determines testing environment', () {
test('returns false on release branches in presubmit', () {
platform = FakePlatform(
environment: <String, String>{ environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot, 'FLUTTER_ROOT': _kFlutterRoot,
'GOLDCTL': 'testctl', 'SWARMING_TASK_ID' : 'sweet task ID',
'GOLDCTL' : 'some/path',
'GOLD_TRYJOB' : 'true',
'GIT_BRANCH' : 'flutter-3.16-candidate.0',
}, },
operatingSystem: 'macos', operatingSystem: 'macos',
); );
final FileSystem fs = createFakeFileSystem(); expect(
final List<String> log = <String>[]; FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
await FlutterPostSubmitFileComparator.fromLocalFileComparator( isFalse,
localFileComparator: LocalFileComparator(Uri.parse('/test'), pathStyle: path.Style.posix), );
platform: platform, });
fs: fs,
process: LoggingProcessManager(log), test('returns true on master branch in presubmit', () {
httpClient: FakeHttpClient(), platform = FakePlatform(
log: (String message) => fail('skia gold client printed unexpected output: "$message"'), environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : 'sweet task ID',
'GOLDCTL' : 'some/path',
'GOLD_TRYJOB' : 'true',
'GIT_BRANCH' : 'master',
},
operatingSystem: 'macos',
);
expect(
FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
isTrue,
);
});
test('returns true on main branch in presubmit', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : 'sweet task ID',
'GOLDCTL' : 'some/path',
'GOLD_TRYJOB' : 'true',
'GIT_BRANCH' : 'main',
},
operatingSystem: 'macos',
);
expect(
FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
isTrue,
);
});
test('returns true for Luci', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : '12345678990',
'GOLDCTL' : 'goldctl',
'GOLD_TRYJOB' : 'git/ref/12345/head',
'GIT_BRANCH' : 'master',
},
operatingSystem: 'macos',
);
expect(
FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
isTrue,
);
});
test('returns false - not on Luci', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
},
operatingSystem: 'macos',
);
expect(
FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
isFalse,
);
});
test('returns false - GOLDCTL missing', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : '12345678990',
'GOLD_TRYJOB' : 'git/ref/12345/head',
},
operatingSystem: 'macos',
);
expect(
FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
isFalse,
);
});
test('returns false - GOLD_TRYJOB missing', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : '12345678990',
'GOLDCTL' : 'goldctl',
},
operatingSystem: 'macos',
);
expect(
FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
isFalse,
);
});
test('returns false - on Cirrus', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'CIRRUS_CI': 'true',
'CIRRUS_PR': '',
'CIRRUS_BRANCH': 'master',
'GOLD_SERVICE_ACCOUNT': 'service account...',
},
operatingSystem: 'macos',
);
expect(
FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
isFalse,
);
});
});
});
group('Skipping', () {
group('correctly determines testing environment', () {
test('returns true on release branches in presubmit', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : 'sweet task ID',
'GOLDCTL' : 'some/path',
'GOLD_TRYJOB' : 'true',
'GIT_BRANCH' : 'flutter-3.16-candidate.0',
},
operatingSystem: 'macos',
);
expect(
FlutterSkippingFileComparator.isAvailableForEnvironment(platform),
isTrue,
);
});
test('returns true on release branches in postsubmit', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : 'sweet task ID',
'GOLDCTL' : 'some/path',
'GIT_BRANCH' : 'flutter-3.16-candidate.0',
},
operatingSystem: 'macos',
);
expect(
FlutterSkippingFileComparator.isAvailableForEnvironment(platform),
isTrue,
);
});
test('returns true on Cirrus builds', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'CIRRUS_CI' : 'yep',
},
operatingSystem: 'macos',
);
expect(
FlutterSkippingFileComparator.isAvailableForEnvironment(platform),
isTrue,
);
});
test('returns true on irrelevant LUCI builds', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
'SWARMING_TASK_ID' : '1234567890',
},
operatingSystem: 'macos'
);
expect(
FlutterSkippingFileComparator.isAvailableForEnvironment(platform),
isTrue,
);
});
test('returns false - not in CI', () {
platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': _kFlutterRoot,
},
operatingSystem: 'macos',
);
expect(
FlutterSkippingFileComparator.isAvailableForEnvironment(platform),
isFalse,
); );
expect(log, <String>['testctl auth --work-dir /.tmp_rand0/flutter_goldens_postsubmit.rand0/../temp --luci']); });
});
}); });
test('FlutterGoldenFileComparator - Local - asserts .png format', () async { group('Local', () {
late FlutterLocalFileComparator comparator;
final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient(); final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
final (FileSystem fs, Directory libDirectory) = createFakeFileSystemWithLibDirectory();
final List<String> log = <String>[]; setUp(() async {
final FlutterLocalFileComparator comparator = FlutterLocalFileComparator( final Directory basedir = fs.directory('flutter/test/library/')
libDirectory.uri, ..createSync(recursive: true);
comparator = FlutterLocalFileComparator(
basedir.uri,
fakeSkiaClient, fakeSkiaClient,
fs: fs, fs: fs,
platform: FakePlatform( platform: FakePlatform(
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot}, environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos', operatingSystem: 'macos',
), ),
log: log.add,
); );
const String hash = '55109a4bed52acc780530f7a9aeff6c0'; const String hash = '55109a4bed52acc780530f7a9aeff6c0';
fakeSkiaClient.expectationForTestValues['flutter.golden_test.1'] = hash; fakeSkiaClient.expectationForTestValues['flutter.golden_test.1'] = hash;
fakeSkiaClient.imageBytesValues[hash] =_kTestPngBytes; fakeSkiaClient.imageBytesValues[hash] =_kTestPngBytes;
fakeSkiaClient.cleanTestNameValues['library.flutter.golden_test.1.png'] = 'flutter.golden_test.1'; fakeSkiaClient.cleanTestNameValues['library.flutter.golden_test.1.png'] = 'flutter.golden_test.1';
});
test('asserts .png format', () async {
await expectLater( await expectLater(
() async { () async {
return comparator.compare( return comparator.compare(
...@@ -924,28 +1126,9 @@ void main() { ...@@ -924,28 +1126,9 @@ void main() {
), ),
), ),
); );
expect(log, isEmpty);
}); });
test('FlutterGoldenFileComparator - Local - passes when bytes match', () async { test('passes when bytes match', () async {
final List<String> log = <String>[];
final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
final (FileSystem fs, Directory libDirectory) = createFakeFileSystemWithLibDirectory();
final FlutterLocalFileComparator comparator = FlutterLocalFileComparator(
libDirectory.uri,
fakeSkiaClient,
fs: fs,
platform: FakePlatform(
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos',
),
log: log.add,
);
const String hash = '55109a4bed52acc780530f7a9aeff6c0';
fakeSkiaClient.expectationForTestValues['flutter.golden_test.1'] = hash;
fakeSkiaClient.imageBytesValues[hash] =_kTestPngBytes;
fakeSkiaClient.cleanTestNameValues['library.flutter.golden_test.1.png'] = 'flutter.golden_test.1';
expect( expect(
await comparator.compare( await comparator.compare(
Uint8List.fromList(_kTestPngBytes), Uint8List.fromList(_kTestPngBytes),
...@@ -953,37 +1136,34 @@ void main() { ...@@ -953,37 +1136,34 @@ void main() {
), ),
isTrue, isTrue,
); );
expect(log, isEmpty);
}); });
test('FlutterGoldenFileComparator - Local - skips when network connection is unavailable', () async { test('returns FlutterSkippingGoldenFileComparator when network connection is unavailable', () async {
final FileSystem fs = createFakeFileSystem(); final FakeDirectory fakeDirectory = FakeDirectory();
final FakeProcessManager process = FakeProcessManager() fakeDirectory.existsSyncValue = true;
..fallbackProcessResult = io.ProcessResult(123, 1, 'test resulted in a 502: 502 Bad Gateway\n', ''); fakeDirectory.uri = Uri.parse('/flutter');
final List<String> log = <String>[];
final FlutterGoldenFileComparator comparator = await FlutterLocalFileComparator.fromLocalFileComparator( fakeSkiaClient.getExpectationForTestThrowable = const OSError("Can't reach Gold");
localFileComparator: LocalFileComparator(Uri.parse('/test'), pathStyle: path.Style.posix),
platform: FakePlatform( FlutterGoldenFileComparator comparator = await FlutterLocalFileComparator.fromDefaultComparator(
environment: <String, String>{ platform,
'FLUTTER_ROOT': _kFlutterRoot, goldens: fakeSkiaClient,
}, baseDirectory: fakeDirectory,
operatingSystem: 'macos',
),
fs: fs,
process: process,
httpClient: ThrowingHttpClient(),
log: log.add,
); );
expect( expect(comparator.runtimeType, FlutterSkippingFileComparator);
await comparator.compare(
Uint8List.fromList(_kTestPngBytes), fakeSkiaClient.getExpectationForTestThrowable = const SocketException("Can't reach Gold");
Uri.parse('flutter.golden_test.1.png'),
), comparator = await FlutterLocalFileComparator.fromDefaultComparator(
isTrue, platform,
goldens: fakeSkiaClient,
baseDirectory: fakeDirectory,
); );
expect(log, <String>[ expect(comparator.runtimeType, FlutterSkippingFileComparator);
'Auto-passing "pkg.flutter.golden_test.1.png" test, ignoring network error when contacting Skia.' // reset property or it will carry on to other tests
]); fakeSkiaClient.getExpectationForTestThrowable = null;
});
});
}); });
} }
...@@ -1027,27 +1207,28 @@ class RunInvocation { ...@@ -1027,27 +1207,28 @@ class RunInvocation {
} }
class FakeProcessManager extends Fake implements ProcessManager { class FakeProcessManager extends Fake implements ProcessManager {
Map<RunInvocation, io.ProcessResult> processResults = <RunInvocation, io.ProcessResult>{}; Map<RunInvocation, ProcessResult> processResults = <RunInvocation, ProcessResult>{};
/// Used if [processResults] does not contain a matching invocation. /// Used if [processResults] does not contain a matching invocation.
io.ProcessResult? fallbackProcessResult; ProcessResult? fallbackProcessResult;
final List<String?> workingDirectories = <String?>[]; final List<String?> workingDirectories = <String?>[];
@override @override
Future<io.ProcessResult> run( Future<ProcessResult> run(
List<Object> command, { List<Object> command, {
String? workingDirectory, String? workingDirectory,
Map<String, String>? environment, Map<String, String>? environment,
bool includeParentEnvironment = true, bool includeParentEnvironment = true,
bool runInShell = false, bool runInShell = false,
Encoding? stdoutEncoding, Encoding? stdoutEncoding = systemEncoding,
Encoding? stderrEncoding, Encoding? stderrEncoding = systemEncoding,
}) async { }) async {
workingDirectories.add(workingDirectory); workingDirectories.add(workingDirectory);
final io.ProcessResult? result = processResults[RunInvocation(command.cast<String>(), workingDirectory)]; final ProcessResult? result = processResults[RunInvocation(command.cast<String>(), workingDirectory)];
if (result == null && fallbackProcessResult == null) { if (result == null && fallbackProcessResult == null) {
fail('ProcessManager.run was called with $command ($workingDirectory) unexpectedly - $processResults.'); printOnFailure('ProcessManager.run was called with $command ($workingDirectory) unexpectedly - $processResults.');
fail('See above.');
} }
return result ?? fallbackProcessResult!; return result ?? fallbackProcessResult!;
} }
...@@ -1057,10 +1238,8 @@ class FakeProcessManager extends Fake implements ProcessManager { ...@@ -1057,10 +1238,8 @@ class FakeProcessManager extends Fake implements ProcessManager {
class FakeSkiaGoldClient extends Fake implements SkiaGoldClient { class FakeSkiaGoldClient extends Fake implements SkiaGoldClient {
Map<String, String> expectationForTestValues = <String, String>{}; Map<String, String> expectationForTestValues = <String, String>{};
Exception? getExpectationForTestThrowable; Exception? getExpectationForTestThrowable;
@override @override
Future<String> getExpectationForTest(String testName) async { Future<String> getExpectationForTest(String testName) async {
await null; // force this to be async
if (getExpectationForTestThrowable != null) { if (getExpectationForTestThrowable != null) {
throw getExpectationForTestThrowable!; throw getExpectationForTestThrowable!;
} }
...@@ -1068,51 +1247,30 @@ class FakeSkiaGoldClient extends Fake implements SkiaGoldClient { ...@@ -1068,51 +1247,30 @@ class FakeSkiaGoldClient extends Fake implements SkiaGoldClient {
} }
@override @override
Future<void> auth() async { Future<void> auth() async {}
await null; // force this to be async
}
final List<String> testNames = <String>[]; final List<String> testNames = <String>[];
int initCalls = 0; int initCalls = 0;
@override @override
Future<void> imgtestInit() async { Future<void> imgtestInit() async => initCalls += 1;
await null; // force this to be async
initCalls += 1;
}
@override @override
Future<bool> imgtestAdd(String testName, File goldenFile) async { Future<bool> imgtestAdd(String testName, File goldenFile) async {
await null; // force this to be async
testNames.add(testName); testNames.add(testName);
return true; return true;
} }
int tryInitCalls = 0; int tryInitCalls = 0;
@override @override
Future<void> tryjobInit() async { Future<void> tryjobInit() async => tryInitCalls += 1;
await null; // force this to be async
tryInitCalls += 1;
}
@override @override
Future<bool> tryjobAdd(String testName, File goldenFile) async { Future<bool> tryjobAdd(String testName, File goldenFile) async => true;
await null; // force this to be async
return true;
}
Map<String, List<int>> imageBytesValues = <String, List<int>>{}; Map<String, List<int>> imageBytesValues = <String, List<int>>{};
@override @override
Future<List<int>> getImageBytes(String imageHash) async { Future<List<int>> getImageBytes(String imageHash) async => imageBytesValues[imageHash]!;
await null; // force this to be async
return imageBytesValues[imageHash]!;
}
Map<String, String> cleanTestNameValues = <String, String>{}; Map<String, String> cleanTestNameValues = <String, String>{};
@override @override
String cleanTestName(String fileName) => cleanTestNameValues[fileName] ?? ''; String cleanTestName(String fileName) => cleanTestNameValues[fileName] ?? '';
} }
...@@ -1122,34 +1280,36 @@ class FakeLocalFileComparator extends Fake implements LocalFileComparator { ...@@ -1122,34 +1280,36 @@ class FakeLocalFileComparator extends Fake implements LocalFileComparator {
late Uri basedir; late Uri basedir;
} }
class ThrowingHttpClient extends Fake implements io.HttpClient { class FakeDirectory extends Fake implements Directory {
late bool existsSyncValue;
@override @override
Future<io.HttpClientRequest> getUrl(Uri url) async { bool existsSync() => existsSyncValue;
throw const io.SocketException('test error');
} @override
late Uri uri;
} }
class FakeHttpClient extends Fake implements io.HttpClient { class FakeHttpClient extends Fake implements HttpClient {
late Uri lastUri; late Uri lastUri;
late FakeHttpClientRequest request; late FakeHttpClientRequest request;
@override @override
Future<io.HttpClientRequest> getUrl(Uri url) async { Future<HttpClientRequest> getUrl(Uri url) async {
lastUri = url; lastUri = url;
return request; return request;
} }
} }
class FakeHttpClientRequest extends Fake implements io.HttpClientRequest { class FakeHttpClientRequest extends Fake implements HttpClientRequest {
late FakeHttpImageResponse response; late FakeHttpImageResponse response;
@override @override
Future<io.HttpClientResponse> close() async { Future<HttpClientResponse> close() async {
return response; return response;
} }
} }
class FakeHttpImageResponse extends Fake implements io.HttpClientResponse { class FakeHttpImageResponse extends Fake implements HttpClientResponse {
FakeHttpImageResponse(this.response); FakeHttpImageResponse(this.response);
final List<List<int>> response; final List<List<int>> response;
...@@ -1159,22 +1319,3 @@ class FakeHttpImageResponse extends Fake implements io.HttpClientResponse { ...@@ -1159,22 +1319,3 @@ class FakeHttpImageResponse extends Fake implements io.HttpClientResponse {
response.forEach(action); response.forEach(action);
} }
} }
class LoggingProcessManager extends Fake implements ProcessManager {
LoggingProcessManager(this.log);
final List<String> log;
@override
Future<io.ProcessResult> run(List<Object> command, {
Map<String, String>? environment,
bool includeParentEnvironment = true,
bool runInShell = false,
Encoding? stderrEncoding,
Encoding? stdoutEncoding,
String? workingDirectory,
}) async {
log.add(command.join(' '));
return io.ProcessResult(0, 0, '200', '');
}
}
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'dart:io' show HttpClient, ProcessResult;
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_goldens/skia_client.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:platform/platform.dart';
import 'package:process/process.dart';
void main() {
test('502 retry', () async {
final List<String> log = <String>[];
await runZoned(
zoneSpecification: ZoneSpecification(
print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
fail('unexpected print: "$line"');
},
createTimer: (Zone self, ZoneDelegate parent, Zone zone, Duration duration, void Function() f) {
log.add('CREATED TIMER: $duration');
return parent.createTimer(zone, Duration.zero, f);
},
),
() async {
final FileSystem fs;
final SkiaGoldClient skiaClient = SkiaGoldClient(
fs: fs = MemoryFileSystem(),
process: FakeProcessManager(log),
platform: FakePlatform(
environment: const <String, String>{
'GOLDCTL': 'goldctl',
},
),
httpClient: FakeHttpClient(),
log: log.add,
fs.directory('/'),
);
log.add('START'); // ignore: avoid_print
await skiaClient.tryjobAdd('test', fs.file('golden'));
log.add('END'); // ignore: avoid_print
expect(log, <String>[
'START',
'EXEC: goldctl imgtest add --work-dir /temp --test-name t --png-file golden',
'Transient failure (exit code 1) from Skia Gold.',
'',
'stdout from gold:',
' test resulted in a 502: 502 Bad Gateway',
' ',
'',
'Retrying in 5 seconds.',
'CREATED TIMER: 0:00:05.000000',
'EXEC: goldctl imgtest add --work-dir /temp --test-name t --png-file golden',
'END',
]);
},
);
});
}
class FakeProcessManager extends Fake implements ProcessManager {
FakeProcessManager(this.log);
final List<String> log;
int _index = 0;
@override
Future<ProcessResult> run(List<Object> command, {
Map<String, String>? environment,
bool includeParentEnvironment = true,
bool runInShell = false,
Encoding? stderrEncoding,
Encoding? stdoutEncoding,
String? workingDirectory,
}) async {
log.add('EXEC: ${command.join(' ')}');
_index += 1;
switch (_index) {
case 1: return ProcessResult(0, 1, 'test resulted in a 502: 502 Bad Gateway\n', '');
case 2: return ProcessResult(0, 0, '200', '');
default: throw StateError('unexpected call to run');
}
}
}
class FakeHttpClient extends Fake implements HttpClient { }
...@@ -7,6 +7,7 @@ import 'dart:io' as io; ...@@ -7,6 +7,7 @@ import 'dart:io' as io;
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
...@@ -21,17 +22,6 @@ const String _kTestBrowserKey = 'FLUTTER_TEST_BROWSER'; ...@@ -21,17 +22,6 @@ const String _kTestBrowserKey = 'FLUTTER_TEST_BROWSER';
const String _kWebRendererKey = 'FLUTTER_WEB_RENDERER'; const String _kWebRendererKey = 'FLUTTER_WEB_RENDERER';
const String _kImpellerKey = 'FLUTTER_TEST_IMPELLER'; const String _kImpellerKey = 'FLUTTER_TEST_IMPELLER';
/// Signature of callbacks used to inject [print] replacements.
typedef LogCallback = void Function(String);
/// Signature of callbacks used to determine if a Skia Gold command succeeded,
/// and if not, what the error message should be.
///
/// Return null if the given arguments indicate success.
///
/// Otherwise, return the error message to show.
typedef SkiaErrorCallback = String? Function(int exitCode, String stdout, String stderr);
/// Exception thrown when an error is returned from the [SkiaClient]. /// Exception thrown when an error is returned from the [SkiaClient].
class SkiaException implements Exception { class SkiaException implements Exception {
/// Creates a new `SkiaException` with a required error [message]. /// Creates a new `SkiaException` with a required error [message].
...@@ -51,14 +41,16 @@ class SkiaException implements Exception { ...@@ -51,14 +41,16 @@ class SkiaException implements Exception {
/// Flutter Gold Dashboard. /// Flutter Gold Dashboard.
class SkiaGoldClient { class SkiaGoldClient {
/// Creates a [SkiaGoldClient] with the given [workDirectory]. /// Creates a [SkiaGoldClient] with the given [workDirectory].
///
/// All other parameters are optional. They may be provided in tests to
/// override the defaults for [fs], [process], [platform], and [httpClient].
SkiaGoldClient( SkiaGoldClient(
this.workDirectory, { this.workDirectory, {
required this.fs, this.fs = const LocalFileSystem(),
required this.process, this.process = const LocalProcessManager(),
required this.platform, this.platform = const LocalPlatform(),
required this.httpClient, io.HttpClient? httpClient,
required this.log, }) : httpClient = httpClient ?? io.HttpClient();
});
/// The file system to use for storing the local clone of the repository. /// The file system to use for storing the local clone of the repository.
/// ///
...@@ -66,6 +58,12 @@ class SkiaGoldClient { ...@@ -66,6 +58,12 @@ class SkiaGoldClient {
/// replaced by a memory file system. /// replaced by a memory file system.
final FileSystem fs; final FileSystem fs;
/// A wrapper for the [dart:io.Platform] API.
///
/// This is useful in tests, where the system platform (the default) can be
/// replaced by a mock platform instance.
final Platform platform;
/// A controller for launching sub-processes. /// A controller for launching sub-processes.
/// ///
/// This is useful in tests, where the real process manager (the default) can /// This is useful in tests, where the real process manager (the default) can
...@@ -73,18 +71,9 @@ class SkiaGoldClient { ...@@ -73,18 +71,9 @@ class SkiaGoldClient {
/// sub-processes. /// sub-processes.
final ProcessManager process; final ProcessManager process;
/// A wrapper for the [dart:io.Platform] API.
///
/// This is useful in tests, where the system platform (the default) can be
/// replaced by a mock platform instance.
final Platform platform;
/// A client for making Http requests to the Flutter Gold dashboard. /// A client for making Http requests to the Flutter Gold dashboard.
final io.HttpClient httpClient; final io.HttpClient httpClient;
/// The logging function to use when reporting messages to the console.
final void Function(String message) log;
/// The local [Directory] within the [comparisonRoot] for the current test /// The local [Directory] within the [comparisonRoot] for the current test
/// context. In this directory, the client will create image and JSON files /// context. In this directory, the client will create image and JSON files
/// for the goldctl tool to use. /// for the goldctl tool to use.
...@@ -103,117 +92,38 @@ class SkiaGoldClient { ...@@ -103,117 +92,38 @@ class SkiaGoldClient {
/// Uses the [platform] environment in this implementation. /// Uses the [platform] environment in this implementation.
String get _goldctl => platform.environment[_kGoldctlKey]!; String get _goldctl => platform.environment[_kGoldctlKey]!;
static void _indent(LogCallback writeln, String text) {
if (text.isEmpty) {
writeln(' <empty>');
} else {
for (final String line in text.split('\n')) {
writeln(' $line');
}
}
}
static void _dump(LogCallback writeln, String data, String label) {
if (data.isNotEmpty) {
writeln('');
writeln('$label:');
_indent(writeln, data);
}
}
Future<void> _retry({
required Future<io.ProcessResult> Function() task,
required String taskName,
SkiaErrorCallback? errorMessage,
}) async {
Duration delay = const Duration(seconds: 5);
while (true) {
final io.ProcessResult result = await task();
final String resultStdout = result.stdout as String;
final String resultStderr = result.stderr as String;
if (result.exitCode != 0 && resultStdout.contains('resulted in a 502: 502 Bad Gateway')) {
// Probably a transient error, try again.
// (See https://issues.skia.org/issues/40044713)
//
// This could have false-positives, because there's no standard format
// for the error messages from Skia gold. Maybe the test name is output
// and the test name contains the string above, who knows. For now it
// seems more likely that the server is flaking than that there's a
// false positive, and false positives seem less likely to be flaky so
// we're likely to catch them when they happen.
log('Transient failure (exit code ${result.exitCode}) from Skia Gold.');
_dump(log, resultStdout, 'stdout from gold');
_dump(log, resultStderr, 'stderr from gold');
log('');
log('Retrying in ${delay.inSeconds} seconds.');
await Future<void>.delayed(delay);
delay *= 2;
continue; // retry
}
String? message;
if (errorMessage != null) {
message = errorMessage(result.exitCode, resultStdout, resultStderr);
if (message == null) {
return; // success
}
} else {
if (result.exitCode == 0) {
return; // success
}
}
final StringBuffer buffer = StringBuffer();
if (message != null) {
buffer.writeln(message);
buffer.writeln();
}
buffer.writeln('$taskName failed with exit code ${result.exitCode}.');
_dump(buffer.writeln, resultStdout, 'stdout from gold');
_dump(buffer.writeln, resultStderr, 'stderr from gold');
final File resultFile = workDirectory.childFile('result-state.json');
if (await resultFile.exists()) {
_dump(buffer.writeln, resultFile.readAsStringSync(), 'result-state.json contents');
}
throw SkiaException(buffer.toString()); // failure
}
}
/// Prepares the local work space for golden file testing and calls the /// Prepares the local work space for golden file testing and calls the
/// goldctl `auth` command. /// goldctl `auth` command.
/// ///
/// This ensures that the goldctl tool is authorized and ready for testing. /// This ensures that the goldctl tool is authorized and ready for testing.
/// Used by the [FlutterPostSubmitFileComparator] and the /// Used by the [FlutterPostSubmitFileComparator] and the
/// [FlutterPreSubmitFileComparator]. /// [FlutterPreSubmitFileComparator].
///
/// Does nothing if [clientIsAuthorized] returns true.
Future<void> auth() async { Future<void> auth() async {
if (await clientIsAuthorized()) { if (await clientIsAuthorized()) {
return; return;
} }
final List<String> authCommand = <String>[
await _retry(
task: () => process.run(<String>[
_goldctl, _goldctl,
'auth', 'auth',
'--work-dir', workDirectory '--work-dir', workDirectory
.childDirectory('temp') .childDirectory('temp')
.path, .path,
'--luci', '--luci',
]), ];
taskName: 'auth',
errorMessage: (int exitCode, String resultStdout, String resultStderr) { final io.ProcessResult result = await process.run(authCommand);
if (exitCode == 0) {
return null; if (result.exitCode != 0) {
} final StringBuffer buf = StringBuffer()
return 'Skia Gold authorization failed.\n' ..writeln('Skia Gold authorization failed.')
'\n' ..writeln('Luci environments authenticate using the file provided '
'Luci environments authenticate using the file provided by ' 'by LUCI_CONTEXT. There may be an error with this file or Gold '
'LUCI_CONTEXT. There may be an error with this file or Gold ' 'authentication.')
'authentication.'; ..writeln('Debug information for Gold --------------------------------')
}, ..writeln('stdout: ${result.stdout}')
); ..writeln('stderr: ${result.stderr}');
throw SkiaException(buf.toString());
}
} }
/// Signals if this client is initialized for uploading images to the Gold /// Signals if this client is initialized for uploading images to the Gold
...@@ -229,8 +139,6 @@ class SkiaGoldClient { ...@@ -229,8 +139,6 @@ class SkiaGoldClient {
/// The `imgtest` command collects and uploads test results to the Skia Gold /// The `imgtest` command collects and uploads test results to the Skia Gold
/// backend, the `init` argument initializes the current test. Used by the /// backend, the `init` argument initializes the current test. Used by the
/// [FlutterPostSubmitFileComparator]. /// [FlutterPostSubmitFileComparator].
///
/// This function is idempotent.
Future<void> imgtestInit() async { Future<void> imgtestInit() async {
// This client has already been initialized // This client has already been initialized
if (_initialized) { if (_initialized) {
...@@ -266,16 +174,20 @@ class SkiaGoldClient { ...@@ -266,16 +174,20 @@ class SkiaGoldClient {
throw SkiaException(buf.toString()); throw SkiaException(buf.toString());
} }
await _retry( final io.ProcessResult result = await process.run(imgtestInitCommand);
task: () => process.run(imgtestInitCommand),
taskName: 'imgtest init', if (result.exitCode != 0) {
errorMessage: (int exitCode, String resultStdout, String resultStderr) { _initialized = false;
if (exitCode == 0) { final StringBuffer buf = StringBuffer()
return null; ..writeln('Skia Gold imgtest init failed.')
..writeln('An error occurred when initializing golden file test with ')
..writeln('goldctl.')
..writeln()
..writeln('Debug information for Gold --------------------------------')
..writeln('stdout: ${result.stdout}')
..writeln('stderr: ${result.stderr}');
throw SkiaException(buf.toString());
} }
return 'An error occurred when initializing golden file test with goldctl.';
},
);
_initialized = true; _initialized = true;
} }
...@@ -286,14 +198,10 @@ class SkiaGoldClient { ...@@ -286,14 +198,10 @@ class SkiaGoldClient {
/// returned from the invocation of this command that indicates a pass or fail /// returned from the invocation of this command that indicates a pass or fail
/// result. /// result.
/// ///
/// If an unapproved image has made it to post-submit, this throws, to close
/// the tree.
///
/// The [testName] and [goldenFile] parameters reference the current /// The [testName] and [goldenFile] parameters reference the current
/// comparison being evaluated by the [FlutterPostSubmitFileComparator]. /// comparison being evaluated by the [FlutterPostSubmitFileComparator].
Future<void> imgtestAdd(String testName, File goldenFile) async { Future<bool> imgtestAdd(String testName, File goldenFile) async {
await _retry( final List<String> imgtestCommand = <String>[
task: () => process.run(<String>[
_goldctl, _goldctl,
'imgtest', 'add', 'imgtest', 'add',
'--work-dir', workDirectory '--work-dir', workDirectory
...@@ -303,26 +211,40 @@ class SkiaGoldClient { ...@@ -303,26 +211,40 @@ class SkiaGoldClient {
'--png-file', goldenFile.path, '--png-file', goldenFile.path,
'--passfail', '--passfail',
..._getPixelMatchingArguments(), ..._getPixelMatchingArguments(),
]), ];
taskName: 'imgtest add',
errorMessage: (int exitCode, String resultStdout, String resultStderr) { final io.ProcessResult result = await process.run(imgtestCommand);
if (exitCode == 0) {
return null; if (result.exitCode != 0) {
} // If an unapproved image has made it to post-submit, throw to close the
if (resultStdout.contains('Untriaged') || // tree.
resultStdout.contains('negative image')) { String? resultContents;
return 'Skia Gold received an unapproved image in post-submit ' final File resultFile = workDirectory.childFile(fs.path.join(
'testing. Golden file images in flutter/flutter are triaged ' 'result-state.json',
'in pre-submit during code review for the given PR.\n' ));
'\n' if (await resultFile.exists()) {
'Visit https://flutter-gold.skia.org/ to view and approve ' resultContents = await resultFile.readAsString();
'the image(s), or revert the associated change. For more ' }
'information, visit the wiki:\n'
' https://github.com/flutter/flutter/wiki/Writing-a-golden-file-test-for-package:flutter'; final StringBuffer buf = StringBuffer()
} ..writeln('Skia Gold received an unapproved image in post-submit ')
return 'Golden test for "$testName" failed for a reason unrelated to pixel comparison.'; ..writeln('testing. Golden file images in flutter/flutter are triaged ')
}, ..writeln('in pre-submit during code review for the given PR.')
); ..writeln()
..writeln('Visit https://flutter-gold.skia.org/ to view and approve ')
..writeln('the image(s), or revert the associated change. For more ')
..writeln('information, visit the wiki: ')
..writeln('https://github.com/flutter/flutter/wiki/Writing-a-golden-file-test-for-package:flutter')
..writeln()
..writeln('Debug information for Gold --------------------------------')
..writeln('stdout: ${result.stdout}')
..writeln('stderr: ${result.stderr}')
..writeln()
..writeln('result-state.json: ${resultContents ?? 'No result file found.'}');
throw SkiaException(buf.toString());
}
return true;
} }
/// Signals if this client is initialized for uploading tryjobs to the Gold /// Signals if this client is initialized for uploading tryjobs to the Gold
...@@ -338,8 +260,6 @@ class SkiaGoldClient { ...@@ -338,8 +260,6 @@ class SkiaGoldClient {
/// The `imgtest` command collects and uploads test results to the Skia Gold /// The `imgtest` command collects and uploads test results to the Skia Gold
/// backend, the `init` argument initializes the current tryjob. Used by the /// backend, the `init` argument initializes the current tryjob. Used by the
/// [FlutterPreSubmitFileComparator]. /// [FlutterPreSubmitFileComparator].
///
/// This function is idempotent.
Future<void> tryjobInit() async { Future<void> tryjobInit() async {
// This client has already been initialized // This client has already been initialized
if (_tryjobInitialized) { if (_tryjobInitialized) {
...@@ -378,16 +298,20 @@ class SkiaGoldClient { ...@@ -378,16 +298,20 @@ class SkiaGoldClient {
throw SkiaException(buf.toString()); throw SkiaException(buf.toString());
} }
await _retry( final io.ProcessResult result = await process.run(imgtestInitCommand);
task: () => process.run(imgtestInitCommand),
taskName: 'imgtest init', if (result.exitCode != 0) {
errorMessage: (int exitCode, String resultStdout, String resultStderr) { _tryjobInitialized = false;
if (exitCode == 0) { final StringBuffer buf = StringBuffer()
return null; ..writeln('Skia Gold tryjobInit failure.')
..writeln('An error occurred when initializing golden file tryjob with ')
..writeln('goldctl.')
..writeln()
..writeln('Debug information for Gold --------------------------------')
..writeln('stdout: ${result.stdout}')
..writeln('stderr: ${result.stderr}');
throw SkiaException(buf.toString());
} }
return 'An error occurred when initializing golden file tryjob with goldctl.';
},
);
_tryjobInitialized = true; _tryjobInitialized = true;
} }
...@@ -401,25 +325,42 @@ class SkiaGoldClient { ...@@ -401,25 +325,42 @@ class SkiaGoldClient {
/// The [testName] and [goldenFile] parameters reference the current /// The [testName] and [goldenFile] parameters reference the current
/// comparison being evaluated by the [FlutterPreSubmitFileComparator]. /// comparison being evaluated by the [FlutterPreSubmitFileComparator].
Future<void> tryjobAdd(String testName, File goldenFile) async { Future<void> tryjobAdd(String testName, File goldenFile) async {
await _retry( final List<String> imgtestCommand = <String>[
task: () => process.run(<String>[
_goldctl, _goldctl,
'imgtest', 'add', 'imgtest', 'add',
'--work-dir', workDirectory.childDirectory('temp').path, '--work-dir', workDirectory
.childDirectory('temp')
.path,
'--test-name', cleanTestName(testName), '--test-name', cleanTestName(testName),
'--png-file', goldenFile.path, '--png-file', goldenFile.path,
..._getPixelMatchingArguments(), ..._getPixelMatchingArguments(),
]), ];
taskName: 'imgtest add',
errorMessage: (int exitCode, String resultStdout, String resultStderr) { final io.ProcessResult result = await process.run(imgtestCommand);
if (exitCode == 0 ||
resultStdout.contains('Untriaged') || final String/*!*/ resultStdout = result.stdout.toString();
resultStdout.contains('negative image')) { if (result.exitCode != 0 &&
return null; !(resultStdout.contains('Untriaged') || resultStdout.contains('negative image'))) {
} String? resultContents;
return 'Golden test for "$testName" failed for a reason unrelated to pixel comparison.'; final File resultFile = workDirectory.childFile(fs.path.join(
}, 'result-state.json',
); ));
if (await resultFile.exists()) {
resultContents = await resultFile.readAsString();
}
final StringBuffer buf = StringBuffer()
..writeln('Unexpected Gold tryjobAdd failure.')
..writeln('Tryjob execution for golden file test $testName failed for')
..writeln('a reason unrelated to pixel comparison.')
..writeln()
..writeln('Debug information for Gold --------------------------------')
..writeln('stdout: ${result.stdout}')
..writeln('stderr: ${result.stderr}')
..writeln()
..writeln()
..writeln('result-state.json: ${resultContents ?? 'No result file found.'}');
throw SkiaException(buf.toString());
}
} }
// Constructs arguments for `goldctl` for controlling how pixels are compared. // Constructs arguments for `goldctl` for controlling how pixels are compared.
...@@ -468,13 +409,15 @@ class SkiaGoldClient { ...@@ -468,13 +409,15 @@ class SkiaGoldClient {
} }
/// Returns the latest positive digest for the given test known to Flutter /// Returns the latest positive digest for the given test known to Flutter
/// Gold at head. Throws without retrying if there's a network failure. /// Gold at head.
Future<String?> getExpectationForTest(String testName) async { Future<String?> getExpectationForTest(String testName) async {
late String? expectation;
final String traceID = getTraceID(testName); final String traceID = getTraceID(testName);
await io.HttpOverrides.runWithHttpOverrides<Future<void>>(() async {
final Uri requestForExpectations = Uri.parse( final Uri requestForExpectations = Uri.parse(
'https://flutter-gold.skia.org/json/v2/latestpositivedigest/$traceID' 'https://flutter-gold.skia.org/json/v2/latestpositivedigest/$traceID'
); );
String? rawResponse; late String rawResponse;
try { try {
final io.HttpClientRequest request = await httpClient.getUrl(requestForExpectations); final io.HttpClientRequest request = await httpClient.getUrl(requestForExpectations);
final io.HttpClientResponse response = await request.close(); final io.HttpClientResponse response = await request.close();
...@@ -483,30 +426,41 @@ class SkiaGoldClient { ...@@ -483,30 +426,41 @@ class SkiaGoldClient {
if (jsonResponse is! Map<String, dynamic>) { if (jsonResponse is! Map<String, dynamic>) {
throw const FormatException('Skia gold expectations do not match expected format.'); throw const FormatException('Skia gold expectations do not match expected format.');
} }
return jsonResponse['digest'] as String?; // success expectation = jsonResponse['digest'] as String?;
} on FormatException catch (error) { } on FormatException catch (error) {
log( // Ideally we'd use something like package:test's printOnError, but best reliability
// in getting logs on CI for now we're just using print.
// See also: https://github.com/flutter/flutter/issues/91285
print( // ignore: avoid_print
'Formatting error detected requesting expectations from Flutter Gold.\n' 'Formatting error detected requesting expectations from Flutter Gold.\n'
'error: $error\n' 'error: $error\n'
'url: $requestForExpectations\n' 'url: $requestForExpectations\n'
'response: $rawResponse' 'response: $rawResponse'
); );
rethrow; // fail rethrow;
} }
},
SkiaGoldHttpOverrides(),
);
return expectation;
} }
/// Returns a list of bytes representing the golden image retrieved from the /// Returns a list of bytes representing the golden image retrieved from the
/// Flutter Gold dashboard. /// Flutter Gold dashboard.
/// ///
/// The provided image hash represents an expectation from Flutter Gold. /// The provided image hash represents an expectation from Flutter Gold.
Future<List<int>> getImageBytes(String imageHash) async { Future<List<int>>getImageBytes(String imageHash) async {
final List<int> imageBytes = <int>[]; final List<int> imageBytes = <int>[];
await io.HttpOverrides.runWithHttpOverrides<Future<void>>(() async {
final Uri requestForImage = Uri.parse( final Uri requestForImage = Uri.parse(
'https://flutter-gold.skia.org/img/images/$imageHash.png', 'https://flutter-gold.skia.org/img/images/$imageHash.png',
); );
final io.HttpClientRequest request = await httpClient.getUrl(requestForImage); final io.HttpClientRequest request = await httpClient.getUrl(requestForImage);
final io.HttpClientResponse response = await request.close(); final io.HttpClientResponse response = await request.close();
await response.forEach((List<int> bytes) => imageBytes.addAll(bytes)); await response.forEach((List<int> bytes) => imageBytes.addAll(bytes));
},
SkiaGoldHttpOverrides(),
);
return imageBytes; return imageBytes;
} }
...@@ -561,7 +515,7 @@ class SkiaGoldClient { ...@@ -561,7 +515,7 @@ class SkiaGoldClient {
final File authFile = workDirectory.childFile(fs.path.join( final File authFile = workDirectory.childFile(fs.path.join(
'temp', 'temp',
'auth_opt.json', 'auth_opt.json',
)); ))/*!*/;
if (await authFile.exists()) { if (await authFile.exists()) {
final String contents = await authFile.readAsString(); final String contents = await authFile.readAsString();
...@@ -623,3 +577,6 @@ class SkiaGoldClient { ...@@ -623,3 +577,6 @@ class SkiaGoldClient {
return md5Sum; return md5Sum;
} }
} }
/// Used to make HttpRequests during testing.
class SkiaGoldHttpOverrides extends io.HttpOverrides { }
name: flutter_goldens_client
environment:
sdk: '>=3.2.0-0 <4.0.0'
dependencies:
# To update these, use "flutter update-packages --force-upgrade".
crypto: 3.0.3
file: 7.0.0
platform: 3.1.4
process: 5.0.2
collection: 1.18.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dartdoc:
# Exclude this package from the hosted API docs.
nodoc: true
# PUBSPEC CHECKSUM: c72e
...@@ -28,4 +28,6 @@ const Map<String, String> kManuallyPinnedDependencies = <String, String>{ ...@@ -28,4 +28,6 @@ const Map<String, String> kManuallyPinnedDependencies = <String, String>{
'test_api': '0.6.1', // https://github.com/flutter/flutter/issues/140169 'test_api': '0.6.1', // https://github.com/flutter/flutter/issues/140169
'test_core': '0.5.9', // https://github.com/flutter/flutter/issues/140169 'test_core': '0.5.9', // https://github.com/flutter/flutter/issues/140169
'test': '1.24.9', // https://github.com/flutter/flutter/issues/140169 'test': '1.24.9', // https://github.com/flutter/flutter/issues/140169
'native_assets_builder': '0.3.0', // https://github.com/flutter/flutter/pull/141814
'native_assets_cli': '0.3.2', // https://github.com/flutter/flutter/pull/141814
}; };
...@@ -14,7 +14,7 @@ dependencies: ...@@ -14,7 +14,7 @@ dependencies:
args: 2.4.2 args: 2.4.2
browser_launcher: 1.1.1 browser_launcher: 1.1.1
dds: 3.1.0+1 dds: 3.1.0+1
dwds: 23.1.1 dwds: 23.2.0
completion: 1.0.1 completion: 1.0.1
coverage: 1.7.2 coverage: 1.7.2
crypto: 3.0.3 crypto: 3.0.3
...@@ -101,7 +101,7 @@ dependencies: ...@@ -101,7 +101,7 @@ dependencies:
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service_interface: 1.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service_interface: 1.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml_edit: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml_edit: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies: dev_dependencies:
...@@ -118,4 +118,4 @@ dartdoc: ...@@ -118,4 +118,4 @@ dartdoc:
# Exclude this package from the hosted API docs. # Exclude this package from the hosted API docs.
nodoc: true nodoc: true
# PUBSPEC CHECKSUM: eb68 # PUBSPEC CHECKSUM: cf69
...@@ -55,7 +55,7 @@ dev_dependencies: ...@@ -55,7 +55,7 @@ dev_dependencies:
test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" test_core: 0.5.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -64,4 +64,4 @@ dartdoc: ...@@ -64,4 +64,4 @@ dartdoc:
# Exclude this package from the hosted API docs. # Exclude this package from the hosted API docs.
nodoc: true nodoc: true
# PUBSPEC CHECKSUM: 5a6b # PUBSPEC CHECKSUM: e56c
...@@ -78,7 +78,7 @@ dev_dependencies: ...@@ -78,7 +78,7 @@ dev_dependencies:
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" vm_service: 13.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web: 0.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web: 0.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" web_socket_channel: 2.4.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webdriver: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -87,4 +87,4 @@ dev_dependencies: ...@@ -87,4 +87,4 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
# PUBSPEC CHECKSUM: 1596 # PUBSPEC CHECKSUM: c097
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