From 3fcb5268f620669f01535515e00c334df5a4cff3 Mon Sep 17 00:00:00 2001 From: Gabriel Costa de Oliveira Date: Thu, 16 Jan 2025 18:46:59 -0300 Subject: [PATCH] fix(#118): corrije erro no command --- lib/core/state/command.dart | 26 +++++++- test/core/state/command_test.dart | 102 ++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 test/core/state/command_test.dart diff --git a/lib/core/state/command.dart b/lib/core/state/command.dart index 29c64e6..fc6e3eb 100644 --- a/lib/core/state/command.dart +++ b/lib/core/state/command.dart @@ -5,12 +5,22 @@ abstract class Command extends ChangeNotifier { Result? _result; bool _running = false; + bool _isError = false; + bool _isOk = false; Command(); - bool get isError => result?.asError != null; + bool get isError { + bool tmp = _isError; + _isError = false; + return tmp; + } - bool get isOk => result?.asValue != null; + bool get isOk { + bool tmp = _isOk; + _isOk = false; + return tmp; + } Result? get result => _result; @@ -21,14 +31,24 @@ abstract class Command extends ChangeNotifier { _result = null; _running = true; + _isOk = false; + _isError = false; notifyListeners(); try { _result = await action(); + + if (_result?.asError != null) { + _isError = true; + } else { + _isOk = true; + } + } catch (e) { _result = Result.error(e); + _isError = true; } finally { - _running = false; + _running = false; notifyListeners(); } } diff --git a/test/core/state/command_test.dart b/test/core/state/command_test.dart new file mode 100644 index 0000000..10c4f27 --- /dev/null +++ b/test/core/state/command_test.dart @@ -0,0 +1,102 @@ +import 'package:aranduapp/core/state/command.dart'; +import 'package:async/async.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('Successful execution updates state and result', () async { + Command0 command = Command0(() async { + await Future.delayed(const Duration(seconds: 1)); + return Result.value('Success'); + }); + + expect(command.running, false); + expect(command.result, null); + + final future = command.execute(); + + expect(command.running, true); + await future; + + expect(command.running, false); + expect(command.isOk, true); + expect(command.result?.asValue?.value, 'Success'); + }); + + test('Execution with error updates state and sets error', () async { + Command0 command = Command0(() async { + throw Exception('An error occurred'); + }); + + expect(command.running, false); + expect(command.result, null); + + final future = command.execute(); + + expect(command.running, true); + await future; + + expect(command.running, false); + expect(command.isError, true); + expect(command.result?.asError?.error, isA()); + }); + + test('No re-execution when already running', () async { + //TODO: No re-execution when already running + }); + + test('Notifies listeners on state changes', () async { + Command0 command = Command0(() async => Result.value('Success')); + + int notifyCount = 0; + command.addListener(() { + notifyCount++; + }); + + await command.execute(); + + expect(notifyCount, greaterThan(0)); + }); + + test('Result on second access is ok', () async { + Command0 command = Command0(() async => Result.value('Success')); + + await command.execute(); + + final firstAccess = command.isOk; + + final secondAccess = command.isOk; + + expect(firstAccess, true); + expect(command.result!.asValue!.value, 'Success'); + expect(secondAccess, false); + }); + + test('Result on second access is error', () async { + Command0 command = Command0(() async => Result.error('error')); + + await command.execute(); + + final firstAccess = command.isError; + + final secondAccess = command.isError; + + expect(firstAccess, true); + expect(command.result!.asError!.error, 'error'); + expect(secondAccess, false); + }); + + test('Result on second access is error with exception', () async { + Command0 command = Command0(() async => throw Exception('error')); + + await command.execute(); + + final firstAccess = command.isError; + + final secondAccess = command.isError; + + expect(firstAccess, true); + expect( + command.result?.asError?.error.toString(), equals('Exception: error')); + expect(secondAccess, false); + }); +}