Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

w_flux Migration: Action class to ActionV2 #197

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions example/web/random_color/random_color.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ main() async {
}

class RandomColorActions {
final Action changeBackgroundColor = Action();
final ActionV2 changeBackgroundColor = ActionV2();
}

class RandomColorStore extends Store {
Expand Down Expand Up @@ -73,7 +73,7 @@ class _RandomColorComponent
'This module uses a flux pattern to change its background color.',
react.button({
'style': {'padding': '10px', 'margin': '10px'},
'onClick': (_) => actions.changeBackgroundColor()
'onClick': (_) => actions.changeBackgroundColor(null)
}, 'Change Background Color')
]);
}
Expand Down
8 changes: 4 additions & 4 deletions example/web/todo_app/actions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import 'package:w_flux/w_flux.dart';
import 'store.dart';

class ToDoActions {
final Action<Todo> createTodo = Action<Todo>();
final Action<Todo> completeTodo = Action<Todo>();
final Action<Todo> deleteTodo = Action<Todo>();
final Action clearTodoList = Action<Todo>();
final ActionV2<Todo> createTodo = ActionV2<Todo>();
final ActionV2<Todo> completeTodo = ActionV2<Todo>();
final ActionV2<Todo> deleteTodo = ActionV2<Todo>();
final ActionV2 clearTodoList = ActionV2<Todo>();
}
2 changes: 1 addition & 1 deletion example/web/todo_app/components/todo_app_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class _ToDoAppComponent extends FluxComponent<ToDoActions, ToDoStore> {
}

_clearList(_) {
this.actions.clearTodoList();
this.actions.clearTodoList(null);
}

_createTodo(String value) {
Expand Down
48 changes: 24 additions & 24 deletions test/action_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,27 @@ import 'package:test/test.dart';

void main() {
group('Action', () {
late Action<String> action;
late ActionV2<String> action;

setUp(() {
action = Action<String>();
action = ActionV2<String>();
addTearDown(action.dispose);
});

test('should only be equivalent to itself', () {
Action action = Action();
Action actionV2 = Action();
ActionV2 action = ActionV2();
ActionV2 actionV2 = ActionV2();
expect(action == action, isTrue);
expect(action == actionV2, isFalse);
});

test('should support dispatch without a payload', () async {
Action<String> action = Action<String>()
ActionV2<String> action = ActionV2<String>()
..listen(expectAsync1((payload) {
expect(payload, isNull);
}));

await action();
await action(null);
});

test('should support dispatch by default when called with a payload',
Expand All @@ -59,7 +59,7 @@ void main() {
'should invoke and complete synchronous listeners in future event in '
'event queue', () async {
var listenerCompleted = false;
var action = Action()
var action = ActionV2()
..listen((_) {
listenerCompleted = true;
});
Expand All @@ -76,7 +76,7 @@ void main() {
test(
'should invoke asynchronous listeners in future event and complete '
'in another future event', () async {
var action = Action();
var action = ActionV2();
var listenerInvoked = false;
var listenerCompleted = false;
action.listen((_) async {
Expand All @@ -99,67 +99,67 @@ void main() {
});

test('should complete future after listeners complete', () async {
var action = Action();
var action = ActionV2();
var asyncListenerCompleted = false;
action.listen((_) async {
await Future.delayed(Duration(milliseconds: 100), () {
asyncListenerCompleted = true;
});
});

Future<dynamic>? future = action();
Future<dynamic>? future = action(null);
expect(asyncListenerCompleted, isFalse);

await future;
expect(asyncListenerCompleted, isTrue);
});

test('should surface errors in listeners', () {
var action = Action()..listen((_) => throw UnimplementedError());
var action = ActionV2()..listen((_) => throw UnimplementedError());
expect(action(0), throwsUnimplementedError);
});
});

group('listen', () {
test('should stop listening when subscription is canceled', () async {
var action = Action();
var action = ActionV2();
var listened = false;
var subscription = action.listen((_) => listened = true);

await action();
await action(null);
expect(listened, isTrue);

listened = false;
subscription.cancel();
await action();
await action(null);
expect(listened, isFalse);
});

test('should stop listening when listeners are cleared', () async {
var action = Action();
var action = ActionV2();
var listened = false;
action.listen((_) => listened = true);

await action();
await action(null);
expect(listened, isTrue);

listened = false;
await action.dispose();
await action();
await action(null);
expect(listened, isFalse);
});

test('should stop listening when actions are disposed', () async {
var action = Action();
var action = ActionV2();
var listened = false;
action.listen((_) => listened = true);

await action();
await action(null);
expect(listened, isTrue);

listened = false;
await action.dispose();
await action();
await action(null);
expect(listened, isFalse);
});
});
Expand All @@ -169,12 +169,12 @@ void main() {
const int sampleSize = 1000;
var stopwatch = Stopwatch();

var awaitableAction = Action()
var awaitableAction = ActionV2()
..listen((_) => {})
..listen((_) async {});
stopwatch.start();
for (var i = 0; i < sampleSize; i++) {
await awaitableAction();
await awaitableAction(null);
}
stopwatch.stop();
var averageActionDispatchTime =
Expand All @@ -184,7 +184,7 @@ void main() {

late Completer syncCompleter;
late Completer asyncCompleter;
var action = Action()
var action = ActionV2()
..listen((_) => syncCompleter.complete())
..listen((_) async {
asyncCompleter.complete();
Expand All @@ -193,7 +193,7 @@ void main() {
for (var i = 0; i < sampleSize; i++) {
syncCompleter = Completer();
asyncCompleter = Completer();
await action();
await action(null);
await Future.wait([syncCompleter.future, asyncCompleter.future]);
}
stopwatch.stop();
Expand Down
22 changes: 11 additions & 11 deletions test/store_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ void main() {
});

test('should trigger in response to an action', () async {
Action _action = Action();
ActionV2 _action = ActionV2();
store.triggerOnActionV2(_action);

_action();
_action(null);
Store payload = await store.first;

expect(payload, store);
Expand All @@ -106,7 +106,7 @@ void main() {
test(
'should execute a given method and then trigger in response to an action',
() {
Action _action = Action();
ActionV2 _action = ActionV2();
bool methodCalled = false;
syncCallback(_) {
methodCalled = true;
Expand All @@ -117,13 +117,13 @@ void main() {
expect(payload, store);
expect(methodCalled, isTrue);
}) as StoreHandler);
_action();
_action(null);
});

test(
'should execute a given async method and then trigger in response to an action',
() {
Action _action = Action();
ActionV2 _action = ActionV2();
bool afterTimer = false;
asyncCallback(_) async {
await Future.delayed(Duration(milliseconds: 30));
Expand All @@ -135,13 +135,13 @@ void main() {
expect(payload, store);
expect(afterTimer, isTrue);
}) as StoreHandler);
_action();
_action(null);
});

test(
'should execute a given method and then trigger in response to an action with payload',
() {
Action<num> _action = Action<num>();
ActionV2<num> _action = ActionV2<num>();
num? counter = 0;
store.triggerOnActionV2(_action, (num? payload) => counter = payload);
store.listen(expectAsync1((payload) {
Expand Down Expand Up @@ -172,7 +172,7 @@ void main() {
test('cleans up its ActionSubscriptions on dispose', () {
bool afterDispose = false;

Action _action = Action();
ActionV2 _action = ActionV2();
store.triggerOnActionV2(_action);
store.listen(expectAsync1((payload) async {
// Safety check to avoid infinite trigger loop
Expand All @@ -183,15 +183,15 @@ void main() {
afterDispose = true;

// This should no longer fire after dispose
_action();
_action(null);
}) as StoreHandler);

_action();
_action(null);
});

test('does not allow adding action subscriptions after dispose', () async {
await store.dispose();
expect(() => store.triggerOnActionV2(Action()), throwsStateError);
expect(() => store.triggerOnActionV2(ActionV2()), throwsStateError);
});

test('does not allow listening after dispose', () async {
Expand Down
Loading