marcglasberg / async_redux

Flutter Package: A Redux version tailored for Flutter, which is easy to learn, to use, to test, and has no boilerplate. Allows for both sync and async reducers.
Other
230 stars 41 forks source link

Ability to run tests via pub run test #90

Open crisboarna opened 3 years ago

crisboarna commented 3 years ago

Hello,

Firstly want to say I love the project. Very helpful and understandable state management tool.

I am looking to run the business logic tests independently of flutter, which I cannot do for the state files due to the user-exception file importing dart:ui. which leads to errors as below:

00:11 +0 -1: loading test/...action_test.dart [E]                                                                                                            
  Failed to load "test/...action_test.dart":
  Unable to spawn isolate: ../../../snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/async_redux-4.0.2/lib/src/user_exception.dart:1:8: Error: Not found: 'dart:ui'
  import 'dart:ui';

From the usage of all_imports pattern in your project I also cannot individually import what is needed to keep the package pure. This also prevents your suggestion in the readme with separating ui/business in separate packages, as in the end, even though business should not care about flutter, the tests for it can only be run with flutter test with help of flutter_test package instead of pure dart test package. Is there a way to truly separate business code from ui code and to be able to run them in pure dart vm ?

A way to run pub tests without dart:ui dependency would be greatly appreciated !

marcglasberg commented 3 years ago

To be honest with you, I have little to none experience with "Dart only", and what it takes to make it happen. I am under the assumptions you just can't use dart:ui and can't import package:flutter? I don't quite know what it takes to run tests via pub run, and I couldn't find detailed information on this subject. If you know this in detail, maybe you can help me understand it too.

In the docs, my suggestion that you separate your UI and business code doesn't mean that the business part mustn't include Flutter. Even if you can't achieve perfect separation, it is enough for a clean-code architecture that you don't use Widgets etc in the business code. Ideally yes, Flutter shouldn't be included, but if the above assumptions holds, it's very difficult to do that because Flutter actually contains some classes that you end up needing in the business code. For example, if you go to store.dart you will see it imports 'package:flutter/...'. I could try and separate this into different files, but even the @required annotation is in Flutter's 'foundation.dart'. This is annotation is turning into a required keyword in the next Dart version, so maybe then there is a chance to remove all Flutter references in the store after this.

Or, as I said, maybe my assumptions are wrong, and you can help me with that?

crisboarna commented 3 years ago

Hey,

  1. The @required is also part of meta package containing many other valuable annotations such as @immutable etc. without flutter framework dependency as pure Dart maintained by Dart developers themselves and it is also part of the Dart language now as you mentioned.

Having a look through your code some other tidbits such as listEquals can be replaced with ListEquality().equals() from package:collection/collection.dart.

  1. Pure Dart tests run on the Dart VM itself only which has no knowledge of any ui/web elements which is why for tests requiring dart:ui/dart:html there also needs to be a target platform specified with a driver that will run the code where these extra packages make sense, akin to how in NodeJS you can specify pure node or jsdom to provide the extra features such as a DOM.

In similar vein this superb project has glue code such as the StoreProvider that requires clear type linking with Flutter elements whereas a pure ReduxAction or StoreTester does not need to know anything about Flutter.

Now splitting this into separate packages would be too much, but adding library 'namespaces' for core and ui or such would allow imports in actions to only be for the core elements which would all be pure Dart.

marcglasberg commented 3 years ago

@crisboarna

Just broke some business/ui classes into different files, imported meta (@required), replaced listEquals with ListEquality.

Could you please have a look?

  async_redux:
    git:
      url: https://github.com/marcglasberg/async_redux
      ref: ac8415a0c705b81f195a3d8180ae7faa9dff62aa

I'd appreciate if now you could give me some more information/instructions about:

adding library 'namespaces' for core and ui

stefanschaller commented 3 years ago

@marcglasberg I created a similar issue.

It would be nice to fix this ASAP, so I could use this package for some applications / libraries in my work. (The syntax of your API is awesome and super clean! Good job! ❤️)

If you need any help, I could create the pull-request for you or at least give you a small introduction via private chat etc.

marcglasberg commented 3 years ago

@stefanschaller Sure. You can find me in the "Flutter Community" Slack group.