mirror of
https://github.com/flutter/samples.git
synced 2026-08-25 01:21:59 +00:00
Release 3.47 (#2879)
Minor updates for release 3.47 ## Pre-launch Checklist - [x] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [x] I signed the [CLA]. - [x] I read the [Contributors Guide]. - [x] I have added sample code updates to the [changelog]. - [x] I updated/added relevant documentation (doc comments with `///`). If you need help, consider asking for advice on the #hackers-devrel channel on [Discord]. <!-- Links --> [Flutter Style Guide]: https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md [CLA]: https://cla.developers.google.com/ [Discord]: https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md [Contributors Guide]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md [changelog]: ../CHANGELOG.md --------- Co-authored-by: Parker Lougheed <parlough@gmail.com>
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
- combinators_ordering
|
||||
@@ -9,3 +7,14 @@ linter:
|
||||
- prefer_final_in_for_each
|
||||
- prefer_final_locals
|
||||
- prefer_relative_imports
|
||||
|
||||
analyzer:
|
||||
exclude:
|
||||
- build/**
|
||||
- android/**
|
||||
- ios/**
|
||||
- web/**
|
||||
- windows/**
|
||||
- macos/**
|
||||
- linux/**
|
||||
|
||||
@@ -31,7 +31,7 @@ class BookingRepositoryRemote implements BookingRepository {
|
||||
.map((activity) => activity.ref)
|
||||
.toList(),
|
||||
);
|
||||
return _apiClient.postBooking(bookingApiModel);
|
||||
return await _apiClient.postBooking(bookingApiModel);
|
||||
} on Exception catch (e) {
|
||||
return Result.error(e);
|
||||
}
|
||||
@@ -121,7 +121,7 @@ class BookingRepositoryRemote implements BookingRepository {
|
||||
@override
|
||||
Future<Result<void>> delete(int id) async {
|
||||
try {
|
||||
return _apiClient.deleteBooking(id);
|
||||
return await _apiClient.deleteBooking(id);
|
||||
} on Exception catch (e) {
|
||||
return Result.error(e);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,6 @@ class BookingCreateUseCase {
|
||||
switch (saveBookingResult) {
|
||||
case Ok<void>():
|
||||
_log.fine('Booking saved successfully');
|
||||
break;
|
||||
case Error<void>():
|
||||
_log.warning('Failed to save booking', saveBookingResult.error);
|
||||
return Result.error(saveBookingResult.error);
|
||||
|
||||
@@ -46,9 +46,7 @@ GoRouter router(AuthRepository authRepository) => GoRouter(
|
||||
authRepository: context.read(),
|
||||
itineraryConfigRepository: context.read(),
|
||||
);
|
||||
return HomeScreenContainer(
|
||||
logoutViewModel: logoutViewModel,
|
||||
);
|
||||
return HomeScreenContainer(logoutViewModel: logoutViewModel);
|
||||
},
|
||||
routes: [
|
||||
GoRoute(
|
||||
|
||||
@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class AppLocalization {
|
||||
static AppLocalization of(BuildContext context) {
|
||||
return Localizations.of(context, AppLocalization);
|
||||
return Localizations.of<AppLocalization>(context, AppLocalization)!;
|
||||
}
|
||||
|
||||
static const _strings = <String, String>{
|
||||
|
||||
@@ -8,10 +8,7 @@ import '../view_models/home_viewmodel.dart';
|
||||
import 'home_screen.dart';
|
||||
|
||||
class HomeScreenContainer extends StatefulWidget {
|
||||
const HomeScreenContainer({
|
||||
super.key,
|
||||
required this.logoutViewModel,
|
||||
});
|
||||
const HomeScreenContainer({super.key, required this.logoutViewModel});
|
||||
|
||||
final LogoutViewModel logoutViewModel;
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class SearchFormContinent extends StatelessWidget {
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: viewModel.continents.length,
|
||||
padding: Dimens.of(context).edgeInsetsScreenHorizontal,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
itemBuilder: (context, index) {
|
||||
final Continent(:imageUrl, :name) = viewModel.continents[index];
|
||||
return _CarouselItem(
|
||||
key: ValueKey(name),
|
||||
@@ -61,7 +61,7 @@ class SearchFormContinent extends StatelessWidget {
|
||||
viewModel: viewModel,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
separatorBuilder: (context, index) {
|
||||
return const SizedBox(width: 8);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import path_provider_foundation
|
||||
import share_plus
|
||||
import shared_preferences_foundation
|
||||
import sqflite_darwin
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
|
||||
@@ -45,14 +45,14 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('should load screen', (WidgetTester tester) async {
|
||||
testWidgets('should load screen', (tester) async {
|
||||
await mockNetworkImages(() async {
|
||||
await loadScreen(tester);
|
||||
expect(find.byType(ActivitiesScreen), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('should list activity', (WidgetTester tester) async {
|
||||
testWidgets('should list activity', (tester) async {
|
||||
await mockNetworkImages(() async {
|
||||
await loadScreen(tester);
|
||||
expect(find.byType(ActivityEntry), findsOneWidget);
|
||||
@@ -60,9 +60,7 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('should select activity and confirm', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
testWidgets('should select activity and confirm', (tester) async {
|
||||
await mockNetworkImages(() async {
|
||||
await loadScreen(tester);
|
||||
// Select one activity
|
||||
|
||||
@@ -32,14 +32,14 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('should load screen', (WidgetTester tester) async {
|
||||
testWidgets('should load screen', (tester) async {
|
||||
await mockNetworkImages(() async {
|
||||
await loadScreen(tester);
|
||||
expect(find.byType(LoginScreen), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('should perform login', (WidgetTester tester) async {
|
||||
testWidgets('should perform login', (tester) async {
|
||||
await mockNetworkImages(() async {
|
||||
await loadScreen(tester);
|
||||
|
||||
|
||||
@@ -43,14 +43,14 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('should load widget', (WidgetTester tester) async {
|
||||
testWidgets('should load widget', (tester) async {
|
||||
await mockNetworkImages(() async {
|
||||
await loadScreen(tester);
|
||||
expect(find.byType(LogoutButton), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('should perform logout', (WidgetTester tester) async {
|
||||
testWidgets('should perform logout', (tester) async {
|
||||
await mockNetworkImages(() async {
|
||||
await loadScreen(tester);
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:compass_app/domain/models/itinerary_config/itinerary_config.dart';
|
||||
import 'package:compass_app/domain/use_cases/booking/booking_create_use_case.dart';
|
||||
import 'package:compass_app/domain/use_cases/booking/booking_share_use_case.dart';
|
||||
@@ -62,20 +64,20 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('should load screen', (WidgetTester tester) async {
|
||||
testWidgets('should load screen', (tester) async {
|
||||
await loadScreen(tester);
|
||||
expect(find.byType(BookingScreen), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should display booking from ID', (WidgetTester tester) async {
|
||||
testWidgets('should display booking from ID', (tester) async {
|
||||
// Add a booking to repository
|
||||
bookingRepository.createBooking(kBooking);
|
||||
unawaited(bookingRepository.createBooking(kBooking));
|
||||
|
||||
// Load screen
|
||||
await loadScreen(tester);
|
||||
|
||||
// Load booking with ID 0
|
||||
viewModel.loadBooking.execute(0);
|
||||
unawaited(viewModel.loadBooking.execute(0));
|
||||
|
||||
// Wait for booking to load
|
||||
await tester.pumpAndSettle();
|
||||
@@ -84,13 +86,11 @@ void main() {
|
||||
expect(find.text(kBooking.destination.tags.first), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should create booking from itinerary config', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
testWidgets('should create booking from itinerary config', (tester) async {
|
||||
await loadScreen(tester);
|
||||
|
||||
// Create a new booking from stored itinerary config
|
||||
viewModel.createBooking.execute();
|
||||
unawaited(viewModel.createBooking.execute());
|
||||
|
||||
// Wait for booking to load
|
||||
await tester.pumpAndSettle();
|
||||
@@ -102,10 +102,10 @@ void main() {
|
||||
expect(bookingRepository.bookings.length, 1);
|
||||
});
|
||||
|
||||
testWidgets('should share booking', (WidgetTester tester) async {
|
||||
bookingRepository.createBooking(kBooking);
|
||||
testWidgets('should share booking', (tester) async {
|
||||
unawaited(bookingRepository.createBooking(kBooking));
|
||||
await loadScreen(tester);
|
||||
viewModel.loadBooking.execute(0);
|
||||
unawaited(viewModel.loadBooking.execute(0));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('share-button')));
|
||||
expect(shared, true);
|
||||
|
||||
@@ -43,10 +43,7 @@ void main() {
|
||||
Future<void> loadWidget(WidgetTester tester) async {
|
||||
await testApp(
|
||||
tester,
|
||||
HomeScreen(
|
||||
viewModel: viewModel,
|
||||
logoutViewModel: logoutViewModel,
|
||||
),
|
||||
HomeScreen(viewModel: viewModel, logoutViewModel: logoutViewModel),
|
||||
goRouter: goRouter,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -42,14 +42,14 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('should load screen', (WidgetTester tester) async {
|
||||
testWidgets('should load screen', (tester) async {
|
||||
await mockNetworkImages(() async {
|
||||
await loadScreen(tester);
|
||||
expect(find.byType(ResultsScreen), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('should display destination', (WidgetTester tester) async {
|
||||
testWidgets('should display destination', (tester) async {
|
||||
await mockNetworkImages(() async {
|
||||
await loadScreen(tester);
|
||||
|
||||
@@ -62,9 +62,7 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('should tap and navigate to activities', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
testWidgets('should tap and navigate to activities', (tester) async {
|
||||
await mockNetworkImages(() async {
|
||||
await loadScreen(tester);
|
||||
|
||||
|
||||
@@ -25,9 +25,7 @@ void main() {
|
||||
await testApp(tester, SearchFormContinent(viewModel: viewModel));
|
||||
}
|
||||
|
||||
testWidgets('Should load and select continent', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
testWidgets('Should load and select continent', (tester) async {
|
||||
await loadWidget(tester);
|
||||
expect(find.byType(SearchFormContinent), findsOneWidget);
|
||||
|
||||
|
||||
@@ -26,9 +26,7 @@ void main() {
|
||||
await testApp(tester, SearchFormDate(viewModel: viewModel));
|
||||
}
|
||||
|
||||
testWidgets('should display date in different month', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
testWidgets('should display date in different month', (tester) async {
|
||||
await loadWidget(tester);
|
||||
expect(find.byType(SearchFormDate), findsOneWidget);
|
||||
|
||||
@@ -45,9 +43,7 @@ void main() {
|
||||
expect(find.text('12 Jun - 23 Jul'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should display date in same month', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
testWidgets('should display date in same month', (tester) async {
|
||||
await loadWidget(tester);
|
||||
expect(find.byType(SearchFormDate), findsOneWidget);
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ void main() {
|
||||
await testApp(tester, SearchFormGuests(viewModel: viewModel));
|
||||
}
|
||||
|
||||
testWidgets('Increase number of guests', (WidgetTester tester) async {
|
||||
testWidgets('Increase number of guests', (tester) async {
|
||||
await loadWidget(tester);
|
||||
expect(find.byType(SearchFormGuests), findsOneWidget);
|
||||
|
||||
@@ -39,7 +39,7 @@ void main() {
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Decrease number of guests', (WidgetTester tester) async {
|
||||
testWidgets('Decrease number of guests', (tester) async {
|
||||
await loadWidget(tester);
|
||||
expect(find.byType(SearchFormGuests), findsOneWidget);
|
||||
|
||||
|
||||
@@ -46,9 +46,7 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Should fill form and perform search', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
testWidgets('Should fill form and perform search', (tester) async {
|
||||
await loadWidget(tester);
|
||||
expect(find.byType(SearchFormScreen), findsOneWidget);
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Should be enabled and allow tap', (WidgetTester tester) async {
|
||||
testWidgets('Should be enabled and allow tap', (tester) async {
|
||||
await loadWidget(tester);
|
||||
expect(find.byType(SearchFormSubmit), findsOneWidget);
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:compass_app/utils/command.dart';
|
||||
import 'package:compass_app/utils/result.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@@ -53,10 +55,10 @@ void main() {
|
||||
final future = command.execute();
|
||||
|
||||
// Run multiple times
|
||||
command.execute();
|
||||
command.execute();
|
||||
command.execute();
|
||||
command.execute();
|
||||
unawaited(command.execute());
|
||||
unawaited(command.execute());
|
||||
unawaited(command.execute());
|
||||
unawaited(command.execute());
|
||||
|
||||
// Await execution
|
||||
await future;
|
||||
|
||||
Reference in New Issue
Block a user