Skip to content
Merged
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
11 changes: 10 additions & 1 deletion example/config/coap_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import 'package:coap/coap.dart';
/// the config file to contain only those entries that override the defaults.
/// The file can't be empty, so version must as a minimum be present.
class CoapConfig extends DefaultCoapConfig {
@override
int get version => 1;

@override
int get defaultPort => 5683;

Expand Down Expand Up @@ -52,6 +55,9 @@ class CoapConfig extends DefaultCoapConfig {
@override
int get notificationReregistrationBackoff => 2000;

@override
String get deduplicator => 'MarkAndSweep';

@override
int get cropRotationPeriod => 2000;

Expand All @@ -65,5 +71,8 @@ class CoapConfig extends DefaultCoapConfig {
int get channelReceivePacketSize => 2048;

@override
String get deduplicator => 'MarkAndSweep';
bool get dtlsVerify => false;

@override
bool get dtlsWithTrustedRoots => false;
}
3 changes: 3 additions & 0 deletions example/config/coap_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

# Protocol section

# Version of the config file (required).
version: 1

# The default CoAP port for normal CoAP communication (not secure).
defaultPort: 5683

Expand Down
5 changes: 3 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ environment:
sdk: '>=3.7.0 <4.0.0'

dependencies:
build: ^2.4.1
build: '>=3.0.0 <5.0.0'
characters: ^1.4.0
collection: ^1.18.0
convert: ^3.1.1
Expand All @@ -25,7 +25,8 @@ dependencies:
yaml: ^3.1.2

dev_dependencies:
build_runner: ^2.4.12
build_runner: '>=2.4.12 <3.0.0'
build_test: ^3.5.0
lints: ^5.1.0
test: ^1.25.8

Expand Down
271 changes: 271 additions & 0 deletions test/coap_builder_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
import 'dart:io';

import 'package:build/build.dart';
import 'package:build_test/build_test.dart';
import 'package:coap/builder.dart';
import 'package:test/test.dart';

void main() {
final builder = configBuilder(const BuilderOptions({}));

group('configBuilder', () {
group('buildExtensions', () {
test('maps .yaml to .dart', () {
expect(builder.buildExtensions, equals({'.yaml': ['.dart']}));
});
});

group('generateClassName', () {
test('single word', () {
expect(generateClassName('coap_config.yaml'), 'CoapConfig');
});

test('multiple underscores', () {
expect(generateClassName('coap_config_all.yaml'), 'CoapConfigAll');
});

test('already capitalized segments', () {
expect(generateClassName('coap_config_default.yaml'), 'CoapConfigDefault');
});
});

group('build output', () {
test('generates Dart class from minimal config with version key', () async {
await testBuilder(
builder,
{
'coap|lib/coap_config.yaml': '''
version: 1
''',
},
outputs: {
'coap|lib/coap_config.dart': decodedMatches(
allOf(
contains("// GENERATED CODE, do not edit this file."),
contains("class CoapConfig extends DefaultCoapConfig {"),
contains("int get version => 1;"),
),
),
},
);
});

test('generates int getters', () async {
await testBuilder(
builder,
{
'coap|lib/coap_config.yaml': '''
version: 1
defaultPort: 5683
maxRetransmit: 4
''',
},
outputs: {
'coap|lib/coap_config.dart': decodedMatches(
allOf(
contains('int get defaultPort => 5683;'),
contains('int get maxRetransmit => 4;'),
),
),
},
);
});

test('generates double getters', () async {
await testBuilder(
builder,
{
'coap|lib/coap_config.yaml': '''
version: 1
ackRandomFactor: 1.5
ackTimeoutScale: 2.0
''',
},
outputs: {
'coap|lib/coap_config.dart': decodedMatches(
allOf(
contains('double get ackRandomFactor => 1.5;'),
contains('double get ackTimeoutScale => 2.0;'),
),
),
},
);
});

test('generates bool getters', () async {
await testBuilder(
builder,
{
'coap|lib/coap_config.yaml': '''
version: 1
useRandomIDStart: false
''',
},
outputs: {
'coap|lib/coap_config.dart': decodedMatches(
contains('bool get useRandomIDStart => false;'),
),
},
);
});

test('generates string getters', () async {
await testBuilder(
builder,
{
'coap|lib/coap_config.yaml': '''
version: 1
deduplicator: "MarkAndSweep"
''',
},
outputs: {
'coap|lib/coap_config.dart': decodedMatches(
contains("String get deduplicator => 'MarkAndSweep';"),
),
},
);
});

test('generates nested YAML keys with camelCase names', () async {
await testBuilder(
builder,
{
'coap|lib/coap_config.yaml': '''
version: 1
dtls:
verify: false
withTrustedRoots: true
''',
},
outputs: {
'coap|lib/coap_config.dart': decodedMatches(
allOf(
contains('bool get dtlsVerify => false;'),
contains('bool get dtlsWithTrustedRoots => true;'),
),
),
},
);
});

test('skips null values', () async {
await testBuilder(
builder,
{
'coap|lib/coap_config.yaml': '''
version: 1
dtls:
ciphers: null
''',
},
outputs: {
'coap|lib/coap_config.dart': decodedMatches(
isNot(contains('dtlsCiphers')),
),
},
);
});

test('generates dtlsBackend getter with DtlsBackend prefix', () async {
await testBuilder(
builder,
{
'coap|lib/coap_config.yaml': '''
version: 1
dtlsBackend: openSsl
''',
},
outputs: {
'coap|lib/coap_config.dart': decodedMatches(
contains('DtlsBackend? get dtlsBackend => DtlsBackend.openSsl;'),
),
},
);
});

test('non-matching filename is ignored and produces no output', () async {
await testBuilder(
builder,
{
'coap|lib/other_config.yaml': '''
version: 1
defaultPort: 5683
''',
},
outputs: {},
);
});

test('generates class name from multi-part filename', () async {
await testBuilder(
builder,
{
'coap|lib/coap_config_custom.yaml': '''
version: 1
''',
},
outputs: {
'coap|lib/coap_config_custom.dart': decodedMatches(
contains('class CoapConfigCustom extends DefaultCoapConfig {'),
),
},
);
});

test('includes import of package:coap/coap.dart', () async {
await testBuilder(
builder,
{
'coap|lib/coap_config.yaml': '''
version: 1
''',
},
outputs: {
'coap|lib/coap_config.dart': decodedMatches(
contains("import 'package:coap/coap.dart';"),
),
},
);
});

test('throws when version key is missing', () async {
final result = await testBuilder(
builder,
{
'coap|lib/coap_config.yaml': '''
defaultPort: 5683
''',
},
outputs: {},
);
expect(result.succeeded, isFalse);
expect(
result.errors.any((e) => e.contains('version')),
isTrue,
);
});
});

group('example config', () {
test(
'example/config/coap_config.yaml generates example/config/coap_config.dart',
() async {
final yamlContent = await File(
'example/config/coap_config.yaml',
).readAsString();
final dartContent = (await File(
'example/config/coap_config.dart',
).readAsString()).replaceAll('\r\n', '\n');

await testBuilder(
builder,
{'coap|example/config/coap_config.yaml': yamlContent},
outputs: {
'coap|example/config/coap_config.dart': dartContent,
},
);
},
);
});
});
}
Loading