Skip to content

Commit bb1fc5b

Browse files
committed
check tests
1 parent b2bd5fd commit bb1fc5b

File tree

6 files changed

+217
-31
lines changed

6 files changed

+217
-31
lines changed

example/lib/gate/gate_provider.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ import 'package:gate_example/database/repositories/user_repository.dart' as _i2;
44
import 'package:gate_example/database/repositories/library_repository.dart'
55
as _i3;
66
import 'package:gate_example/services/auth_service.dart' as _i4;
7-
import 'package:gate_example/services/user_service.dart' as _i5;
7+
import 'package:gate_example/services/user_service.dart'
8+
as _i5; // coverage:ignore-file
89

910
// ********************************
10-
// Gate AppProvider generated file
11+
// Gate generated file
1112
// Do not modify by hand
1213
// ********************************
14+
// ignore_for_file: type=lint
15+
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
1316
class AppProvider {
1417
AppProvider._();
1518

example/pubspec.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,9 @@ packages:
203203
gate:
204204
dependency: "direct main"
205205
description:
206-
path: "../packages/gate"
207-
relative: true
208-
source: path
206+
name: gate
207+
url: "https://pub.dartlang.org"
208+
source: hosted
209209
version: "1.0.0"
210210
gate_generator:
211211
dependency: "direct dev"

example/pubspec.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ dependencies:
3131
cupertino_icons: ^1.0.5
3232
flutter:
3333
sdk: flutter
34-
gate:
35-
path: ../packages/gate
34+
gate: ^1.0.0
35+
# gate:
36+
# path: ../packages/gate
3637

3738
dev_dependencies:
3839
gate_generator:

packages/gate/README.md

Lines changed: 188 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,203 @@
1-
<!--
2-
This README describes the package. If you publish this package to pub.dev,
3-
this README's contents appear on the landing page for your package.
1+
# Gate
2+
**Dart/Flutter Dependency injection generator**
3+
4+
<p align="center">
5+
<img src="https://github.com/Apparence-io/gate/raw/master/packages/gate_generator/doc/images/cover.png" alt="flutter anchored onboarding screen" />
6+
</p>
47

5-
For information about how to write a good package README, see the guide for
6-
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
8+
<p align="center">
9+
<a href="https://pub.dev/packages/gate_generator"><img src="https://img.shields.io/pub/v/gate_generator" alt="pubdev" style="max-width: 100%;"></a>
10+
<a href="https://github.com/Apparence-io/gate/actions"><img src="https://github.com/Apparence-io/gate/workflows/Dart%20CI/badge.svg" alt="ci" style="max-width: 100%;"></a>
11+
<a href="https://opensource.org/licenses/MIT" rel="nofollow"><img src="https://camo.githubusercontent.com/83d3746e5881c1867665223424263d8e604df233d0a11aae0813e0414d433943/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="License: MIT" data-canonical-src="https://img.shields.io/badge/license-MIT-blue.svg" style="max-width: 100%;"></a>
12+
</p>
713

8-
For general information about developing packages, see the Dart guide for
9-
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
10-
and the Flutter guide for
11-
[developing packages and plugins](https://flutter.dev/developing-packages).
12-
-->
13-
14-
TODO: Put a short description of the package here that helps potential users
15-
know whether this package might be useful for them.
14+
## Motivation
15+
Providing Service should be independant from your pages or other code.
16+
The DI pattern separates the responsibility of creating an object of the service class out of the client class.
17+
Also using code generation we can get rid of the boilerplate part.
1618

1719
## Features
18-
19-
TODO: List what your package can do. Maybe include images, gifs, or videos.
20+
- provide Injectable as a singleton
21+
- provide Injectable as a dynamic service
22+
- Inject an Injectable class into another
2023

2124
## Getting started
25+
install gate with build_runner in you pubspec.yaml
26+
```
27+
dependencies:
28+
build_runner: ^X.X.X
29+
gate: ^X.X.X
30+
31+
dev_dependencies:
32+
gate_generator: ^X.X.X
33+
```
34+
> replace X.X.X with last available version on pub.dev.
2235
23-
TODO: List prerequisites and provide or point to information on how to
24-
start using the package.
2536

2637
## Usage
2738

28-
TODO: Include short and useful examples for package users. Add longer examples
29-
to `/example` folder.
39+
### 1 - Create a class you want to inject
3040

3141
```dart
32-
const like = 'sample';
42+
import 'package:gate/gate.dart';
43+
44+
@Injectable()
45+
class CoffeeService {
46+
final S1 s1;
47+
48+
CoffeeService._(this.s1);
49+
50+
@Singleton()
51+
factory CoffeeService.simple(S1 s1) => CoffeeService._(s1);
52+
53+
void pump() {
54+
print("CoffeeService it's working");
55+
}
56+
}
3357
```
3458

35-
## Additional information
59+
You just have to
60+
- add @Injectable() above your class
61+
- add @Singleton() or @Provide() above a factory
62+
63+
### 2 - inject dependency
64+
65+
We can now inject our Injectables using @Inject annotation.
66+
InjectedChild use
67+
- Type you want to inject
68+
- the name of the factory you want to use (you can have multiple provided factories)
69+
- the attribute name (just in case you want to rename it or make it private...)
70+
71+
```dart
72+
import 'package:gate_example/gate/gate_provider.dart';
73+
import 'package:gate_example/gate/coffee_service.dart';
74+
part 'coffee_page.gate_inject.g.part';
75+
76+
@Inject(children: [
77+
InjectedChild(S1, factoryName: "build"),
78+
InjectedChild(CoffeeService, factoryName: "simple", attrName: "coffeeService"),
79+
])
80+
class CoffeePage extends StatelessWidget {
81+
const CoffeePage({Key? key}) : super(key: key);
82+
83+
@override
84+
Widget build(BuildContext context) {
85+
coffeeService.pump();
86+
return Container();
87+
}
88+
}
89+
```
90+
You can inject as many dependency as you want into your class as long as their are Injectable.
91+
> ```part 'coffee_page.gate_inject.g.part';``` will be be added to your file
92+
> this file will be genererated on next step
93+
> don't forget to import "gate_provider.dart" that is generated next
94+
95+
96+
### 3 - generate code
97+
Using build runner you can run the command in your shell
98+
```shell
99+
flutter packages pub run build_runner build --delete-conflicting-outputs
100+
```
101+
102+
Once build runner is done, you can run your flutter app and use all injected class.
103+
104+
> If you change your factory or wants to inject other class... just rerun the build_runner :)
105+
106+
## Properties
107+
| Annotation | Description |
108+
|--------------|---------------------------------------------------------------------:|
109+
| Injectable | mark a class as containing Singleton or Provide factories |
110+
| Singleton | mark a factory as a Singleton Injectable |
111+
| Provide | mark a factory as a Dymamic Injectable. Each time you inject will create a new instance of that class |
112+
| Inject | mark a class to inject dependencies |
113+
114+
115+
### Inject annotation
116+
| Property | Description |
117+
|-----------------|---------------------------------------------------------------------:|
118+
| children | a list of InjectedChild |
119+
120+
121+
### InjectedChild annotation
122+
| Property | Description |
123+
|-----------------|---------------------------------------------------------------------:|
124+
| type | The type to inject |
125+
| factoryName | The factory name to use |
126+
| attrName | *(optionnal)* The attribute name to call it from your class |
127+
128+
129+
## Mock an injected dependency for testing
130+
To remplace your service by mocks, you have to set them, before testing.
131+
Gate will generate all methods for you.
132+
133+
First, declare your mocked services with your prefered libraries.
134+
135+
Then use the "appProvider" to set mocks.
136+
137+
Finally, don't forget to reset mocks by setting them to null.
138+
139+
140+
```dart
141+
class CoffeeServiceMock extends Mock implements CoffeeService {}
142+
143+
class S1ServiceMock extends Mock implements S1 {}
144+
145+
class S2BServiceMock extends Mock implements S2B {}
146+
147+
class TodoServiceMock extends Mock implements TodoService {}
148+
149+
void main() {
150+
// Initialize mocks
151+
final CoffeeService coffeeServiceMock = CoffeeServiceMock();
152+
final S1 s1ServiceMock = S1ServiceMock();
153+
final S2B s2BServiceMock = S2BServiceMock();
154+
final TodoService todoServiceMock = TodoServiceMock();
155+
156+
group('Mock injection group', () {
157+
setUp(() {
158+
when(() => coffeeServiceMock.getMenu()).thenReturn("Best menu");
159+
// Set injected services with mocks
160+
appProvider.setCoffeeServiceSimpleMock(coffeeServiceMock);
161+
appProvider.setS1BuildMock(s1ServiceMock);
162+
appProvider.setS2BBuildMock(s2BServiceMock);
163+
appProvider.setTodoServiceBeanMock(todoServiceMock);
164+
});
165+
166+
tearDownAll(() {
167+
// Remove mocks from appProvider (real ones will be used)
168+
appProvider.setCoffeeServiceSimpleMock(null);
169+
appProvider.setS1BuildMock(null);
170+
appProvider.setS2BBuildMock(null);
171+
appProvider.setTodoServiceBeanMock(null);
172+
});
173+
174+
test('Test mocks injection', () async {
175+
expect(appProvider.getCoffeeServiceSimple().getMenu(),
176+
equals('Best menu')); // Mocked returned value
177+
178+
appProvider.setCoffeeServiceSimpleMock(null);
179+
180+
expect(appProvider.getCoffeeServiceSimple().getMenu(),
181+
equals('No menu')); // True value (not mocked)
182+
});
183+
});
184+
}
185+
```
186+
187+
## Run tests
188+
```bash
189+
dart pub global activate coverage
190+
dart test --coverage="coverage"
191+
format_coverage --lcov --in=coverage --out=coverage.lcov --packages=.packages --report-on=lib
192+
```
193+
194+
<hr/>
195+
196+
## FAQ
197+
*To be done*
198+
199+
<hr/>
200+
<br><br>
201+
<a href="https://en.apparence.io"><img src="https://github.com/Apparence-io/bart/raw/master/.github/img/logo.png" alt="Apparence.io logo"></a>
202+
<p><small>Developed with 💙 &nbsp;by Apparence.io</small></p>
36203

37-
TODO: Tell users more about the package: where to find more information, how to
38-
contribute to the package, how to file issues, what response they can expect
39-
from the package authors, and more.

packages/gate_generator/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.0.0
2+
- upgrade dependencies
3+
- upgrade to 1.0.0 as it's stable
4+
15
## 0.0.3+7
26
- upgrade dependencies
37

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// coverage:ignore-file
2+
// ********************************
3+
// Gate generated file
4+
// Do not modify by hand
5+
// ********************************
6+
// ignore_for_file: type=lint
7+
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
8+
class AppProvider {
9+
AppProvider._();
10+
11+
static final AppProvider instance = AppProvider._();
12+
}
13+
14+
final AppProvider appProvider = AppProvider.instance;

0 commit comments

Comments
 (0)