Skip to content

Commit 7ae5fba

Browse files
committed
Updated docs and tests.
1 parent 5c6892b commit 7ae5fba

File tree

3 files changed

+70
-48
lines changed

3 files changed

+70
-48
lines changed

README.md

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ and methods during the build process.
1010

1111
Source code generation relies heavily on *constants* known at compile time,
1212
represented by a [`DartObject`][DartObject].
13-
For built-in types, [`DartObject`][DartObject] has methods that
14-
allow reading the underlying constant object to obtain a runtime object.
13+
For core types, [`DartObject`][DartObject] has methods that
14+
allow reading the underlying constant object to create a runtime object.
1515

1616
The package [`generic_reader`][generic_reader] includes an extention on
1717
[`DartObject`][DartObject] that *simplifies* reading constants of
@@ -29,16 +29,33 @@ your pubspec.yaml file.
2929

3030
2. Register a [Decoder][Decoder] object for each *user defined*
3131
data-type `T` that is going to be read.
32-
Note: The built-in types `bool`, `double`, `int`, `num`,`String`, `Type`, `Symbol`
33-
do **not** require a decoder.
32+
Note: The following type are supported out-of-the-box and do *not* require a decoder:
33+
* `bool`, `double`, `int`, `num`,`String`, `Type`, `Symbol`,
34+
* `List<bool>`, `List<double>`, `List<int>`, `List<num>`,
35+
`List<String>`,`List<Symbol`,`List<Type`,
36+
* `Set<bool`, `Set<double`, `Set<int`, `Set<num`, `Set<String`, `Set<Symbol`,
37+
`Set<Type`,
38+
* `Iterable<bool`,`Iterable<double`,`Iterable<int`,`Iterable<num`,`Iterable<String`,
39+
`Iterable<Symbol`,`Iterable<Type`.
3440

3541
3. Use Dart's static [`analyzer`][analyzer] to read a library, get
3642
the relevant [`VariableElement`][VariableElement], and calculate the constant
3743
expression represented by a [`DartObject`][DartObject] using the method [`computeConstantValue()`][computeConstantValue()].
3844

39-
4. Read the compile-time constant values using the extension methods [`read<T>`][read],
40-
[`readList<T>`][readList], [`readIterator<T>`][readIterator]
41-
[`readSet<T>`][readSet], [`readMap<T>`][readMap].
45+
4. Read the compile-time constant values using the extension method: [`read<T>`][read]. <br/>
46+
47+
To read constant of a user-defined type `U`, add a suitable `Decoder<U>`:
48+
```Dart
49+
Reader.addDecoder<U>(decoder);
50+
51+
```
52+
53+
To read a constant representing a *collection* of a *user-defined* type `U`
54+
use the convenience methods [`readList<U>`][readList],
55+
[`readSet<U>`][readSet], [`readMap<K,U>`][readMap], and [`readIterator<U>`][readIterator].
56+
On first use, these methods register a decoder making the types:
57+
`List<U>`, `Set<U>`, `Map<K,U>`, `Iterable<U>` readable with [`read<U>`][read].
58+
4259

4360
5. Use the constant values to generate the source-code and complete the building
4461
process.
@@ -49,7 +66,6 @@ The extension [`Reader`][Reader] provides a systematic method of
4966
retrieving constants of
5067
arbitrary data-types by allowing users to register `Decoder` objects.
5168

52-
5369
`Decoder<T>` is an abstract
5470
parameterized class with a method `T read<T>(DartObject obj)`
5571
that attempt to read a variable of type `T` from `obj` and return the result.
@@ -85,7 +101,7 @@ Read.addDecoder(const AnnotationDecoder());
85101

86102
The example below show how to register a decoder for a Dart `Enum` and read
87103
an instance of the enumeration. In this case, instead of creating a custom
88-
decoder class we just register an instance of the already defined generic class
104+
decoder class we register an instance of the already defined generic class
89105
[`EnumDecoder`][EnumDecoder]:
90106

91107
<details> <summary> Click to show source-code. </summary>
@@ -138,6 +154,9 @@ Future<void> main() async {
138154
```
139155
</details>
140156

157+
158+
<br/>
159+
141160
The program listed below show how to read a constant of type
142161
`List<List<String>>`:
143162

@@ -188,13 +207,19 @@ Future<void> main() async {
188207
print('\nlistObj.readList<$listOfString>(): $list3\n');
189208
}
190209
```
210+
191211
</details>
192212

213+
214+
<br/>
215+
193216
The program above produces the following terminal output:
194217

218+
195219
<details> <summary> Click to show terminal output. </summary>
196220

197-
```
221+
222+
```Term
198223
$ dart example/bin/list_example.dart
199224
200225
Reading library: example
@@ -205,10 +230,12 @@ Reading library: example
205230
206231
Adding decoder for List<String> and List<List<String>>
207232
233+
208234
Reader:
209-
Registered types: (bool, double, int, num,
210-
String, Symbol, Type, List<String>, List<List<String>>)
211-
Mapped types : {}
235+
Decodable types: [bool, double, int, num, String, Symbol, Type,
236+
List<bool>, ..., Iterable<Type>, List<List<String>>]
237+
Resolved types: {}
238+
212239
213240
listObj.read<List<List<String>>>: [[a], [b]]
214241

test/decoder_test.dart

Lines changed: 0 additions & 13 deletions
This file was deleted.

test/reader_test.dart

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
// ignore_for_file: unused_local_variable
2+
13
import 'package:analyzer/dart/constant/value.dart' show DartObject;
24
import 'package:analyzer/dart/element/element.dart';
35
import 'package:build_test/build_test.dart' show resolveSource;
46
import 'package:exception_templates/exception_templates.dart';
57
import 'package:generic_reader/generic_reader.dart';
8+
import 'package:generic_reader/src/type/invalid_field_name.dart';
69

710
import 'package:test/test.dart';
811

@@ -81,13 +84,18 @@ Future<void> main() async {
8184
group('Decoders:', () {
8285
// Block the removal of decoders for built-in types.
8386
test('clearDecoder<String>()', () {
84-
Reader.removeDecoderFor<String>();
85-
expect(Reader.findDecoder<String>(), stringDecoder);
87+
expect(Reader.removeDecoderFor<String>(), null);
8688
});
8789
test('addDecoder<String>()', () {
88-
expect(Reader.addDecoder(stringDecoder), false);
90+
expect(Reader.addDecoder(StringDecoder()), false);
91+
});
92+
test('addDecoder<List>()', () {
93+
expect(Reader.addDecoder<List>(const ListDecoder<int>()), false);
94+
});
95+
test('addDecoder<List<dynamic>>', () {
96+
expect(Reader.addDecoder<List<dynamic>>(ListDecoder<dynamic>()), false);
97+
expect(Reader.hasDecoder<List<dynamic>>(), false);
8998
});
90-
test('addDecoder<List>()', () {});
9199
});
92100

93101
group('Reading Constants:', () {
@@ -120,37 +128,37 @@ Future<void> main() async {
120128
expect(isValidObj, isNotNull);
121129

122130
expect(
123-
isValidObj!.read<Runes>,
131+
isValidObj!.read<A>,
124132
throwsA(
125-
isA<ErrorOfType<DecoderNotFound>>().having(
133+
isA<ErrorOfType<InvalidFieldName>>().having(
126134
(e) => e.message,
127135
'message',
128-
'Decoder not found.',
136+
'Could not read a field with name: id.',
129137
),
130138
),
131139
);
132140
});
133-
test('ErrorOf<ConstantReader>: Wrong type', () {
134-
try {
135-
aObj?.read<String>();
136-
} on ErrorOf catch (e) {
137-
expect(e, isA<ErrorOf<Decoder>>());
138-
expect(e.message, 'Error reading const <String> value.');
139-
}
141+
test('ErrorOf<Reader>: Wrong type', () {
142+
expect(
143+
aObj!.read<String>,
144+
throwsA(
145+
isA<ErrorOf<Decoder>>().having(
146+
(e) => e.message,
147+
'message',
148+
'Error reading const <String> value.',
149+
),
150+
),
151+
);
140152
});
141153
});
142154
group('findDecoder:', () {
143155
test('bool', () {
144-
expect(Reader.findDecoder<bool>(), boolDecoder);
156+
final isValid = isValidObj?.read<bool>();
157+
expect(Reader.findDecoder<bool>(), const BoolDecoder());
145158
});
146159
test('int', () {
147-
expect(Reader.findDecoder<int>(), intDecoder);
148-
});
149-
test('double', () {
150-
expect(Reader.findDecoder<double>(), doubleDecoder);
151-
});
152-
test('num', () {
153-
expect(Reader.findDecoder<num>(), numDecoder);
160+
final id = idObj?.read<int>();
161+
expect(Reader.findDecoder<int>(), const IntDecoder());
154162
});
155163
});
156164
}

0 commit comments

Comments
 (0)