data_builder_test 0.10.0
data_builder_test: ^0.10.0 copied to clipboard
craft_runner builder plus annotations that generate immutable fluent data builders from @dataBuilder-annotated test classes.
data_builder_test #
A craft_runner builder that turns a
plain schema class into an immutable fluent builder, for constructing test
fixtures without a wall of map literals.
final body = const OrderBuilder()
.withId('ord_1')
.withTotal(4200)
.build(); // => {'id': 'ord_1', 'total': 4200, 'status': 'pending'}
Every field you don't touch falls back to the default declared on the schema, so a test states only what it actually cares about.
Setup #
dev_dependencies:
data_builder_test: ^0.10.0
Declare the builder in craft_runner.yaml:
roots: [test]
exclude: ['.data_builder.dart']
builders:
data_builder_test:DataBuilderCraftBuilder:
Then run craft_runner craft, or craft_runner watch to regenerate on save.
Writing a schema #
Annotate a class with @dataBuilder, have it extend its own generated builder,
and declare a part:
import 'package:data_builder_test/annotations.dart';
part 'order.data_builder.dart';
@dataBuilder
class Order extends OrderBuilder {
String id = 'ord_1';
int total = 0;
String status = 'pending';
@DataField(key: 'created_at')
String? createdAt;
}
craft_runner writes order.data_builder.dart next to it containing
OrderBuilder extends Buildable — a const default constructor, a withX(...)
per field, and build(). All storage is private, and every withX returns a
new instance.
@DataField #
| option | effect |
|---|---|
key |
map key to serialize under (defaults to the field name) |
includeIfNull |
when false, the entry is dropped from build() if null |
settable |
when false, no withX is generated and the field always serializes its default |
Defaults #
Defaults are not seeded through the constructor. Each field carries a private
_<field>IsSet flag and build() emits isSet ? value : default, so an
untouched field falls back to its declared initializer (or null). This keeps
the const constructor trivial and avoids non-const collection literals in a
const context.
Nested builders #
A field whose type isn't a known scalar is treated as a nested builder: its
storage type becomes <Type>Builder and build() serializes it recursively —
value.build() for a single field, value.map((e) => e.build()).toList() for a
List<...>.
@dataBuilder
class Cart extends CartBuilder {
List<Order> orders = [];
}
const CartBuilder().withOrders([const OrderBuilder().withId('ord_2')]).build();
Notes #
- Parsing is syntactic only, inherited from craft_runner — the schema's fields must be declared on the class itself, not inherited from elsewhere.
- Generated files end in
.data_builder.dart; add that toexcludeso the builder doesn't read its own output.
License #
MIT