mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 13:58:47 +00:00
refactor Result class, remove asOk and asError (#2542)
As discussed in the PR for the Result pattern implementation (https://github.com/flutter/website/pull/11444) @parlough recommended that `asError` and `asOk` should be not be used, and instead we should use proper exhaustiveness checking. This PR removes the two "convenience" methods and refactors code. In some cases, it was enough with writing a proper `if` clause, while in others it was necessary to use a `switch`. Still, they are present in the `testing` folder, as they can be useful for testing purposes. ## 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
This commit is contained in:
@@ -24,8 +24,8 @@ class ActivityRepositoryRemote implements ActivityRepository {
|
|||||||
if (!_cachedData.containsKey(ref)) {
|
if (!_cachedData.containsKey(ref)) {
|
||||||
// No cached data, request activities
|
// No cached data, request activities
|
||||||
final result = await _apiClient.getActivityByDestination(ref);
|
final result = await _apiClient.getActivityByDestination(ref);
|
||||||
if (result is Ok) {
|
if (result is Ok<List<Activity>>) {
|
||||||
_cachedData[ref] = result.asOk.value;
|
_cachedData[ref] = result.value;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -42,18 +42,22 @@ class BookingRepositoryRemote implements BookingRepository {
|
|||||||
try {
|
try {
|
||||||
// Get booking by ID from server
|
// Get booking by ID from server
|
||||||
final resultBooking = await _apiClient.getBooking(id);
|
final resultBooking = await _apiClient.getBooking(id);
|
||||||
if (resultBooking is Error<BookingApiModel>) {
|
switch (resultBooking) {
|
||||||
|
case Error<BookingApiModel>():
|
||||||
return Result.error(resultBooking.error);
|
return Result.error(resultBooking.error);
|
||||||
|
case Ok<BookingApiModel>():
|
||||||
}
|
}
|
||||||
final booking = resultBooking.asOk.value;
|
final booking = resultBooking.value;
|
||||||
|
|
||||||
// Load destinations if not loaded yet
|
// Load destinations if not loaded yet
|
||||||
if (_cachedDestinations == null) {
|
if (_cachedDestinations == null) {
|
||||||
final resultDestination = await _apiClient.getDestinations();
|
final resultDestination = await _apiClient.getDestinations();
|
||||||
if (resultDestination is Error<List<Destination>>) {
|
switch (resultDestination) {
|
||||||
|
case Error<List<Destination>>():
|
||||||
return Result.error(resultDestination.error);
|
return Result.error(resultDestination.error);
|
||||||
|
case Ok<List<Destination>>():
|
||||||
}
|
}
|
||||||
_cachedDestinations = resultDestination.asOk.value;
|
_cachedDestinations = resultDestination.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get destination for booking
|
// Get destination for booking
|
||||||
@@ -62,11 +66,12 @@ class BookingRepositoryRemote implements BookingRepository {
|
|||||||
|
|
||||||
final resultActivities =
|
final resultActivities =
|
||||||
await _apiClient.getActivityByDestination(destination.ref);
|
await _apiClient.getActivityByDestination(destination.ref);
|
||||||
|
switch (resultActivities) {
|
||||||
if (resultActivities is Error<List<Activity>>) {
|
case Error<List<Activity>>():
|
||||||
return Result.error(resultActivities.error);
|
return Result.error(resultActivities.error);
|
||||||
|
case Ok<List<Activity>>():
|
||||||
}
|
}
|
||||||
final activities = resultActivities.asOk.value
|
final activities = resultActivities.value
|
||||||
.where((activity) => booking.activitiesRef.contains(activity.ref))
|
.where((activity) => booking.activitiesRef.contains(activity.ref))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
@@ -88,10 +93,9 @@ class BookingRepositoryRemote implements BookingRepository {
|
|||||||
Future<Result<List<BookingSummary>>> getBookingsList() async {
|
Future<Result<List<BookingSummary>>> getBookingsList() async {
|
||||||
try {
|
try {
|
||||||
final result = await _apiClient.getBookings();
|
final result = await _apiClient.getBookings();
|
||||||
if (result is Error<List<BookingApiModel>>) {
|
switch (result) {
|
||||||
return Result.error(result.error);
|
case Ok<List<BookingApiModel>>():
|
||||||
}
|
final bookingsApi = result.value;
|
||||||
final bookingsApi = result.asOk.value;
|
|
||||||
return Result.ok(bookingsApi
|
return Result.ok(bookingsApi
|
||||||
.map(
|
.map(
|
||||||
(bookingApi) => BookingSummary(
|
(bookingApi) => BookingSummary(
|
||||||
@@ -102,6 +106,9 @@ class BookingRepositoryRemote implements BookingRepository {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.toList());
|
.toList());
|
||||||
|
case Error<List<BookingApiModel>>():
|
||||||
|
return Result.error(result.error);
|
||||||
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
return Result.error(e);
|
return Result.error(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ class ContinentRepositoryRemote implements ContinentRepository {
|
|||||||
if (_cachedData == null) {
|
if (_cachedData == null) {
|
||||||
// No cached data, request continents
|
// No cached data, request continents
|
||||||
final result = await _apiClient.getContinents();
|
final result = await _apiClient.getContinents();
|
||||||
if (result is Ok) {
|
if (result is Ok<List<Continent>>) {
|
||||||
// Store value if result Ok
|
// Store value if result Ok
|
||||||
_cachedData = result.asOk.value;
|
_cachedData = result.value;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ class DestinationRepositoryRemote implements DestinationRepository {
|
|||||||
if (_cachedData == null) {
|
if (_cachedData == null) {
|
||||||
// No cached data, request destinations
|
// No cached data, request destinations
|
||||||
final result = await _apiClient.getDestinations();
|
final result = await _apiClient.getDestinations();
|
||||||
if (result is Ok) {
|
if (result is Ok<List<Destination>>) {
|
||||||
// Store value if result Ok
|
// Store value if result Ok
|
||||||
_cachedData = result.asOk.value;
|
_cachedData = result.value;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -40,11 +40,13 @@ class BookingCreateUseCase {
|
|||||||
}
|
}
|
||||||
final destinationResult =
|
final destinationResult =
|
||||||
await _fetchDestination(itineraryConfig.destination!);
|
await _fetchDestination(itineraryConfig.destination!);
|
||||||
if (destinationResult is Error<Destination>) {
|
switch (destinationResult) {
|
||||||
|
case Ok<Destination>():
|
||||||
|
_log.fine('Destination loaded: ${destinationResult.value.ref}');
|
||||||
|
case Error<Destination>():
|
||||||
_log.warning('Error fetching destination: ${destinationResult.error}');
|
_log.warning('Error fetching destination: ${destinationResult.error}');
|
||||||
return Result.error(destinationResult.error);
|
return Result.error(destinationResult.error);
|
||||||
}
|
}
|
||||||
_log.fine('Destination loaded: ${destinationResult.asOk.value.ref}');
|
|
||||||
|
|
||||||
// Get Activity objects from repository
|
// Get Activity objects from repository
|
||||||
if (itineraryConfig.activities.isEmpty) {
|
if (itineraryConfig.activities.isEmpty) {
|
||||||
@@ -54,11 +56,13 @@ class BookingCreateUseCase {
|
|||||||
final activitiesResult = await _activityRepository.getByDestination(
|
final activitiesResult = await _activityRepository.getByDestination(
|
||||||
itineraryConfig.destination!,
|
itineraryConfig.destination!,
|
||||||
);
|
);
|
||||||
if (activitiesResult is Error<List<Activity>>) {
|
switch (activitiesResult) {
|
||||||
|
case Error<List<Activity>>():
|
||||||
_log.warning('Error fetching activities: ${activitiesResult.error}');
|
_log.warning('Error fetching activities: ${activitiesResult.error}');
|
||||||
return Result.error(activitiesResult.error);
|
return Result.error(activitiesResult.error);
|
||||||
|
case Ok<List<Activity>>():
|
||||||
}
|
}
|
||||||
final activities = activitiesResult.asOk.value
|
final activities = activitiesResult.value
|
||||||
.where(
|
.where(
|
||||||
(activity) => itineraryConfig.activities.contains(activity.ref),
|
(activity) => itineraryConfig.activities.contains(activity.ref),
|
||||||
)
|
)
|
||||||
@@ -74,7 +78,7 @@ class BookingCreateUseCase {
|
|||||||
final booking = Booking(
|
final booking = Booking(
|
||||||
startDate: itineraryConfig.startDate!,
|
startDate: itineraryConfig.startDate!,
|
||||||
endDate: itineraryConfig.endDate!,
|
endDate: itineraryConfig.endDate!,
|
||||||
destination: destinationResult.asOk.value,
|
destination: destinationResult.value,
|
||||||
activity: activities,
|
activity: activities,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:logging/logging.dart';
|
|||||||
import '../../../data/repositories/activity/activity_repository.dart';
|
import '../../../data/repositories/activity/activity_repository.dart';
|
||||||
import '../../../data/repositories/itinerary_config/itinerary_config_repository.dart';
|
import '../../../data/repositories/itinerary_config/itinerary_config_repository.dart';
|
||||||
import '../../../domain/models/activity/activity.dart';
|
import '../../../domain/models/activity/activity.dart';
|
||||||
|
import '../../../domain/models/itinerary_config/itinerary_config.dart';
|
||||||
import '../../../utils/command.dart';
|
import '../../../utils/command.dart';
|
||||||
import '../../../utils/result.dart';
|
import '../../../utils/result.dart';
|
||||||
|
|
||||||
@@ -45,21 +46,23 @@ class ActivitiesViewModel extends ChangeNotifier {
|
|||||||
|
|
||||||
Future<Result<void>> _loadActivities() async {
|
Future<Result<void>> _loadActivities() async {
|
||||||
final result = await _itineraryConfigRepository.getItineraryConfig();
|
final result = await _itineraryConfigRepository.getItineraryConfig();
|
||||||
if (result is Error) {
|
switch (result) {
|
||||||
|
case Error<ItineraryConfig>():
|
||||||
_log.warning(
|
_log.warning(
|
||||||
'Failed to load stored ItineraryConfig',
|
'Failed to load stored ItineraryConfig',
|
||||||
result.asError.error,
|
result.error,
|
||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
|
case Ok<ItineraryConfig>():
|
||||||
}
|
}
|
||||||
|
|
||||||
final destinationRef = result.asOk.value.destination;
|
final destinationRef = result.value.destination;
|
||||||
if (destinationRef == null) {
|
if (destinationRef == null) {
|
||||||
_log.severe('Destination missing in ItineraryConfig');
|
_log.severe('Destination missing in ItineraryConfig');
|
||||||
return Result.error(Exception('Destination not found'));
|
return Result.error(Exception('Destination not found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
_selectedActivities.addAll(result.asOk.value.activities);
|
_selectedActivities.addAll(result.value.activities);
|
||||||
|
|
||||||
final resultActivities =
|
final resultActivities =
|
||||||
await _activityRepository.getByDestination(destinationRef);
|
await _activityRepository.getByDestination(destinationRef);
|
||||||
@@ -120,21 +123,23 @@ class ActivitiesViewModel extends ChangeNotifier {
|
|||||||
|
|
||||||
Future<Result<void>> _saveActivities() async {
|
Future<Result<void>> _saveActivities() async {
|
||||||
final resultConfig = await _itineraryConfigRepository.getItineraryConfig();
|
final resultConfig = await _itineraryConfigRepository.getItineraryConfig();
|
||||||
if (resultConfig is Error) {
|
switch (resultConfig) {
|
||||||
|
case Error<ItineraryConfig>():
|
||||||
_log.warning(
|
_log.warning(
|
||||||
'Failed to load stored ItineraryConfig',
|
'Failed to load stored ItineraryConfig',
|
||||||
resultConfig.asError.error,
|
resultConfig.error,
|
||||||
);
|
);
|
||||||
return resultConfig;
|
return resultConfig;
|
||||||
|
case Ok<ItineraryConfig>():
|
||||||
}
|
}
|
||||||
|
|
||||||
final itineraryConfig = resultConfig.asOk.value;
|
final itineraryConfig = resultConfig.value;
|
||||||
final result = await _itineraryConfigRepository.setItineraryConfig(
|
final result = await _itineraryConfigRepository.setItineraryConfig(
|
||||||
itineraryConfig.copyWith(activities: _selectedActivities.toList()));
|
itineraryConfig.copyWith(activities: _selectedActivities.toList()));
|
||||||
if (result is Error) {
|
if (result is Error) {
|
||||||
_log.warning(
|
_log.warning(
|
||||||
'Failed to store ItineraryConfig',
|
'Failed to store ItineraryConfig',
|
||||||
result.asError.error,
|
result.error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class BookingViewModel extends ChangeNotifier {
|
|||||||
case Error<Booking>():
|
case Error<Booking>():
|
||||||
_log.warning('Booking error: ${result.error}');
|
_log.warning('Booking error: ${result.error}');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return Result.error(result.asError.error);
|
return Result.error(result.error);
|
||||||
}
|
}
|
||||||
case Error<ItineraryConfig>():
|
case Error<ItineraryConfig>():
|
||||||
_log.warning('ItineraryConfig error: ${itineraryConfig.error}');
|
_log.warning('ItineraryConfig error: ${itineraryConfig.error}');
|
||||||
|
|||||||
@@ -50,14 +50,16 @@ class ResultsViewModel extends ChangeNotifier {
|
|||||||
Future<Result<void>> _search() async {
|
Future<Result<void>> _search() async {
|
||||||
// Load current itinerary config
|
// Load current itinerary config
|
||||||
final resultConfig = await _itineraryConfigRepository.getItineraryConfig();
|
final resultConfig = await _itineraryConfigRepository.getItineraryConfig();
|
||||||
if (resultConfig is Error) {
|
switch (resultConfig) {
|
||||||
|
case Error<ItineraryConfig>():
|
||||||
_log.warning(
|
_log.warning(
|
||||||
'Failed to load stored ItineraryConfig',
|
'Failed to load stored ItineraryConfig',
|
||||||
resultConfig.asError.error,
|
resultConfig.error,
|
||||||
);
|
);
|
||||||
return resultConfig;
|
return resultConfig;
|
||||||
|
case Ok<ItineraryConfig>():
|
||||||
}
|
}
|
||||||
_itineraryConfig = resultConfig.asOk.value;
|
_itineraryConfig = resultConfig.value;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
final result = await _destinationRepository.getDestinations();
|
final result = await _destinationRepository.getDestinations();
|
||||||
@@ -86,15 +88,17 @@ class ResultsViewModel extends ChangeNotifier {
|
|||||||
assert(destinationRef.isNotEmpty, "destinationRef should not be empty");
|
assert(destinationRef.isNotEmpty, "destinationRef should not be empty");
|
||||||
|
|
||||||
final resultConfig = await _itineraryConfigRepository.getItineraryConfig();
|
final resultConfig = await _itineraryConfigRepository.getItineraryConfig();
|
||||||
if (resultConfig is Error) {
|
switch (resultConfig) {
|
||||||
|
case Error<ItineraryConfig>():
|
||||||
_log.warning(
|
_log.warning(
|
||||||
'Failed to load stored ItineraryConfig',
|
'Failed to load stored ItineraryConfig',
|
||||||
resultConfig.asError.error,
|
resultConfig.error,
|
||||||
);
|
);
|
||||||
return resultConfig;
|
return resultConfig;
|
||||||
|
case Ok<ItineraryConfig>():
|
||||||
}
|
}
|
||||||
|
|
||||||
final itineraryConfig = resultConfig.asOk.value;
|
final itineraryConfig = resultConfig.value;
|
||||||
final result = await _itineraryConfigRepository
|
final result = await _itineraryConfigRepository
|
||||||
.setItineraryConfig(itineraryConfig.copyWith(
|
.setItineraryConfig(itineraryConfig.copyWith(
|
||||||
destination: destinationRef,
|
destination: destinationRef,
|
||||||
@@ -103,7 +107,7 @@ class ResultsViewModel extends ChangeNotifier {
|
|||||||
if (result is Error) {
|
if (result is Error) {
|
||||||
_log.warning(
|
_log.warning(
|
||||||
'Failed to store ItineraryConfig',
|
'Failed to store ItineraryConfig',
|
||||||
result.asError.error,
|
result.error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -99,14 +99,10 @@ class SearchFormViewModel extends ChangeNotifier {
|
|||||||
final result = await _continentRepository.getContinents();
|
final result = await _continentRepository.getContinents();
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Ok():
|
case Ok():
|
||||||
{
|
|
||||||
_continents = result.value;
|
_continents = result.value;
|
||||||
_log.fine('Continents (${_continents.length}) loaded');
|
_log.fine('Continents (${_continents.length}) loaded');
|
||||||
}
|
|
||||||
case Error():
|
case Error():
|
||||||
{
|
_log.warning('Failed to load continents', result.error);
|
||||||
_log.warning('Failed to load continents', result.asError.error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return result;
|
return result;
|
||||||
@@ -116,7 +112,6 @@ class SearchFormViewModel extends ChangeNotifier {
|
|||||||
final result = await _itineraryConfigRepository.getItineraryConfig();
|
final result = await _itineraryConfigRepository.getItineraryConfig();
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Ok<ItineraryConfig>():
|
case Ok<ItineraryConfig>():
|
||||||
{
|
|
||||||
final itineraryConfig = result.value;
|
final itineraryConfig = result.value;
|
||||||
_selectedContinent = itineraryConfig.continent;
|
_selectedContinent = itineraryConfig.continent;
|
||||||
if (itineraryConfig.startDate != null &&
|
if (itineraryConfig.startDate != null &&
|
||||||
@@ -129,15 +124,12 @@ class SearchFormViewModel extends ChangeNotifier {
|
|||||||
_guests = itineraryConfig.guests ?? 0;
|
_guests = itineraryConfig.guests ?? 0;
|
||||||
_log.fine('ItineraryConfig loaded');
|
_log.fine('ItineraryConfig loaded');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
|
||||||
case Error<ItineraryConfig>():
|
case Error<ItineraryConfig>():
|
||||||
{
|
|
||||||
_log.warning(
|
_log.warning(
|
||||||
'Failed to load stored ItineraryConfig',
|
'Failed to load stored ItineraryConfig',
|
||||||
result.asError.error,
|
result.error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,6 @@ sealed class Result<T> {
|
|||||||
|
|
||||||
/// Creates an error [Result], completed with the specified [error].
|
/// Creates an error [Result], completed with the specified [error].
|
||||||
const factory Result.error(Exception error) = Error._;
|
const factory Result.error(Exception error) = Error._;
|
||||||
|
|
||||||
/// Convenience method to cast to Ok
|
|
||||||
Ok<T> get asOk => this as Ok<T>;
|
|
||||||
|
|
||||||
/// Convenience method to cast to Error
|
|
||||||
Error get asError => this as Error<T>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subclass of Result for values
|
/// Subclass of Result for values
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import 'package:compass_app/data/services/local/local_data_service.dart';
|
|||||||
import 'package:compass_app/utils/result.dart';
|
import 'package:compass_app/utils/result.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import '../../../../testing/utils/result.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('ActivityRepositoryLocal tests', () {
|
group('ActivityRepositoryLocal tests', () {
|
||||||
// To load assets
|
// To load assets
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:compass_app/utils/result.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import '../../../../testing/fakes/services/fake_api_client.dart';
|
import '../../../../testing/fakes/services/fake_api_client.dart';
|
||||||
|
import '../../../../testing/utils/result.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('ActivityRepositoryRemote tests', () {
|
group('ActivityRepositoryRemote tests', () {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
|
|
||||||
import '../../../../testing/fakes/services/fake_api_client.dart';
|
import '../../../../testing/fakes/services/fake_api_client.dart';
|
||||||
import '../../../../testing/models/booking.dart';
|
import '../../../../testing/models/booking.dart';
|
||||||
|
import '../../../../testing/utils/result.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('BookingRepositoryRemote tests', () {
|
group('BookingRepositoryRemote tests', () {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:compass_app/utils/result.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import '../../../../testing/fakes/services/fake_api_client.dart';
|
import '../../../../testing/fakes/services/fake_api_client.dart';
|
||||||
|
import '../../../../testing/utils/result.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('ContinentRepositoryRemote tests', () {
|
group('ContinentRepositoryRemote tests', () {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import 'package:compass_app/utils/result.dart';
|
|||||||
import 'package:compass_app/data/repositories/destination/destination_repository_local.dart';
|
import 'package:compass_app/data/repositories/destination/destination_repository_local.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import '../../../../testing/utils/result.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('DestinationRepositoryLocal tests', () {
|
group('DestinationRepositoryLocal tests', () {
|
||||||
// To load assets
|
// To load assets
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:compass_app/utils/result.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import '../../../../testing/fakes/services/fake_api_client.dart';
|
import '../../../../testing/fakes/services/fake_api_client.dart';
|
||||||
|
import '../../../../testing/utils/result.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('DestinationRepositoryRemote tests', () {
|
group('DestinationRepositoryRemote tests', () {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import '../../../../testing/models/activity.dart';
|
|||||||
import '../../../../testing/models/booking.dart';
|
import '../../../../testing/models/booking.dart';
|
||||||
import '../../../../testing/models/destination.dart';
|
import '../../../../testing/models/destination.dart';
|
||||||
import '../../../../testing/models/user.dart';
|
import '../../../../testing/models/user.dart';
|
||||||
|
import '../../../../testing/utils/result.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('ApiClient', () {
|
group('ApiClient', () {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:compass_app/data/services/api/model/login_response/login_respons
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import '../../../../testing/mocks.dart';
|
import '../../../../testing/mocks.dart';
|
||||||
|
import '../../../../testing/utils/result.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('AuthApiClient', () {
|
group('AuthApiClient', () {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import '../../../../testing/fakes/repositories/fake_destination_repository.dart'
|
|||||||
import '../../../../testing/models/activity.dart';
|
import '../../../../testing/models/activity.dart';
|
||||||
import '../../../../testing/models/booking.dart';
|
import '../../../../testing/models/booking.dart';
|
||||||
import '../../../../testing/models/destination.dart';
|
import '../../../../testing/models/destination.dart';
|
||||||
|
import '../../../../testing/utils/result.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('BookingCreateUseCase tests', () {
|
group('BookingCreateUseCase tests', () {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import 'package:compass_app/utils/command.dart';
|
|||||||
import 'package:compass_app/utils/result.dart';
|
import 'package:compass_app/utils/result.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import '../../testing/utils/result.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('Command0 tests', () {
|
group('Command0 tests', () {
|
||||||
test('should complete void command', () async {
|
test('should complete void command', () async {
|
||||||
@@ -89,7 +91,7 @@ void main() {
|
|||||||
test('should complete bool command, bool argument', () async {
|
test('should complete bool command, bool argument', () async {
|
||||||
// Action that returns bool argument
|
// Action that returns bool argument
|
||||||
final command =
|
final command =
|
||||||
Command1<bool, bool>((a) => Future.value(Result.ok(true)));
|
Command1<bool, bool>((a) => Future.value(const Result.ok(true)));
|
||||||
|
|
||||||
// Run action with result and argument
|
// Run action with result and argument
|
||||||
await command.execute(true);
|
await command.execute(true);
|
||||||
|
|||||||
9
compass_app/app/testing/utils/result.dart
Normal file
9
compass_app/app/testing/utils/result.dart
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import 'package:compass_app/utils/result.dart';
|
||||||
|
|
||||||
|
extension ResultCast<T> on Result<T> {
|
||||||
|
/// Convenience method to cast to Ok
|
||||||
|
Ok<T> get asOk => this as Ok<T>;
|
||||||
|
|
||||||
|
/// Convenience method to cast to Error
|
||||||
|
Error get asError => this as Error<T>;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user