Skip to content

Commit 327e866

Browse files
Generator: switch to new build_test 3 APIs #152
1 parent 5f15053 commit 327e866

File tree

6 files changed

+132
-112
lines changed

6 files changed

+132
-112
lines changed

generator/build.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ builders:
2929
builder_factories: ["codeGeneratorFactory"]
3030
# build_extensions: Required. A map from input extension to the list of output extensions that may be created
3131
# for that input. This must match the merged buildExtensions maps from each Builder in builder_factories.
32+
# See notes on CodeBuilder.buildExtensions.
3233
build_extensions:
3334
"$lib$": ["objectbox.g.dart"]
34-
"$test": ["objectbox.g.dart"]
35+
"$test$": ["objectbox.g.dart"]
3536
required_inputs: ['.objectbox.info']
3637
auto_apply: dependents
3738
build_to: source

generator/lib/src/builder_dirs.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import 'package:build/build.dart';
21
import 'package:path/path.dart' as path;
32

43
import 'config.dart';
@@ -12,11 +11,15 @@ class BuilderDirs {
1211

1312
BuilderDirs._(this.root, this.out);
1413

15-
factory BuilderDirs(BuildStep buildStep, Config config) {
14+
/// For [pathInSourceRoot] expects the path to a file in the source root
15+
/// directory (currently only lib or test are supported). It's used to
16+
/// determine the [root] source path and [out] path for generated code.
17+
/// A [config] may customize the [out] path relative to [root].
18+
factory BuilderDirs(String pathInSourceRoot, Config config) {
1619
// Paths from Config are supplied by the user and may contain duplicate
1720
// slashes or be empty: normalize all paths to not return duplicate or
1821
// trailing slashes to ensure they can be compared via strings.
19-
final root = path.normalize(path.dirname(buildStep.inputId.path));
22+
final root = path.normalize(path.dirname(pathInSourceRoot));
2023
final String out;
2124
if (root.endsWith('test')) {
2225
out = path.normalize('$root/${config.outDirTest}');

generator/lib/src/code_builder.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,17 @@ class CodeBuilder extends Builder {
2929

3030
@override
3131
late final buildExtensions = {
32+
// lib/$lib$ and test/$test$ are placeholder files of build_runner which are
33+
// used as there is no clear primary input file for this builder.
3234
r'$lib$': [path.join(_config.outDirLib, _config.codeFile)],
3335
r'$test$': [path.join(_config.outDirTest, _config.codeFile)]
3436
};
3537

3638
@override
3739
FutureOr<void> build(BuildStep buildStep) async {
38-
final builderDirs = BuilderDirs(buildStep, _config);
40+
// This is only called twice, once with path lib/$lib$ and once with test/$test$
41+
final inputFilePath = buildStep.inputId.path;
42+
final builderDirs = BuilderDirs(inputFilePath, _config);
3943

4044
// build() will be called only twice, once for the `lib` directory and once for the `test` directory
4145
// map from file name to a 'json' representation of entities

generator/pubspec.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ environment:
1111
dependencies:
1212
objectbox: 4.3.0
1313
analyzer: '>=6.5.0 <8.0.0' # dart_style 2.3.7 requires 6.5.0
14-
build: '>=2.4.1 <2.5.0' # 2.5.0 has breaking changes for code_builder_test.dart, adapt before allowing
14+
build: ^2.5.0 # TODO Tighten further as Dart 3.7.0 is required by build_test anyhow?
1515
collection: ^1.18.0 # Would require 1.19.1, but Flutter 3.24.0 has 1.18.0 pinned
1616
dart_style: '>=2.3.7 <4.0.0' # require 2.3.7 for languageVersion in DartFormatter constructor
1717
glob: ^2.1.3
@@ -27,4 +27,6 @@ dev_dependencies:
2727
lints: ^3.0.0
2828
pub_semver: ^2.2.0
2929
package_config: ^2.2.0
30-
build_test: ^2.2.2
30+
build_test: ^3.0.0
31+
build_runner_core: ^9.0.0
32+
logging: ^1.3.0

generator/test/code_builder_test.dart

Lines changed: 54 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,100 @@
1-
import 'dart:async';
1+
import 'dart:io';
22

3-
import 'package:build/build.dart';
4-
import 'package:build/src/builder/build_step_impl.dart';
5-
import 'package:build_test/build_test.dart';
3+
import 'package:build_runner_core/build_runner_core.dart';
4+
import 'package:logging/logging.dart';
65
import 'package:objectbox/internal.dart';
76
import 'package:objectbox_generator/src/builder_dirs.dart';
87
import 'package:objectbox_generator/src/code_builder.dart';
98
import 'package:objectbox_generator/src/config.dart';
10-
import 'package:package_config/package_config.dart';
119
import 'package:path/path.dart' as path;
1210
import 'package:source_gen/source_gen.dart';
1311
import 'package:test/test.dart';
1412

1513
import 'generator_test_env.dart';
1614

1715
void main() {
18-
var reader = StubAssetReader();
19-
var writer = StubAssetWriter();
20-
final resourceManager = ResourceManager();
21-
// Default directory structure: sources inside lib folder.
22-
final testBuildStep = BuildStepImpl(
23-
AssetId("objectbox_generator_test", "lib/\$lib\$"),
24-
[],
25-
reader,
26-
writer,
27-
null,
28-
resourceManager,
29-
_unsupported);
16+
// lib/$lib$ is a placeholder file of build_runner, it's one of the two
17+
// input files used by CodeBuilder.
18+
final inputPathLib = 'lib/\$lib\$';
3019

3120
group('getRootDir and getOutDir', () {
32-
test('lib', () {
33-
final builderDirs = BuilderDirs(testBuildStep, Config());
21+
test('lib', () async {
22+
final builderDirs = BuilderDirs(inputPathLib, Config());
3423
expect(builderDirs.root, equals('lib'));
3524
expect(builderDirs.out, equals('lib'));
3625
});
3726

38-
test('test', () {
39-
final testBuildStepTest = BuildStepImpl(
40-
AssetId("objectbox_generator_test", "test/\$test\$"),
41-
[],
42-
reader,
43-
writer,
44-
null,
45-
resourceManager,
46-
_unsupported);
47-
final builderDirs = BuilderDirs(testBuildStepTest, Config());
27+
test('test', () async {
28+
// test/$test$ is a placeholder file of build_runner, it's the other one
29+
// of the two input files used by CodeBuilder.
30+
final inputPathTest = 'test/\$test\$';
31+
final builderDirs = BuilderDirs(inputPathTest, Config());
4832
expect(builderDirs.root, equals('test'));
4933
expect(builderDirs.out, equals('test'));
5034
});
5135

5236
test('not supported', () {
53-
final testBuildStepNotSupported = BuildStepImpl(
54-
AssetId("objectbox_generator_test", "custom/\$custom\$"),
55-
[],
56-
reader,
57-
writer,
58-
null,
59-
resourceManager,
60-
_unsupported);
37+
// For completeness, test an unsupported input file path.
38+
// Currently, CodeBuilder (and therefore BuilderDirs) never gets called
39+
// with one as its buildExtensions restricts it to the special placeholder
40+
// files $lib$ and $test$ (see tests above).
41+
final customPath = 'lib/custom/custom.dart';
6142
expect(
62-
() => BuilderDirs(testBuildStepNotSupported, Config()),
63-
throwsA(predicate((e) =>
64-
e is ArgumentError &&
65-
e.message == 'Is not lib or test directory: "custom"')));
43+
() => BuilderDirs(customPath, Config()),
44+
throwsA(isA<ArgumentError>().having((e) => e.message, 'message',
45+
'Is not lib or test directory: "lib${Platform.pathSeparator}custom"')));
6646
});
6747

6848
test('out dir with redundant slash', () {
69-
final builderDirs = BuilderDirs(testBuildStep, Config(outDirLib: '/'));
49+
final builderDirs = BuilderDirs(inputPathLib, Config(outDirLib: '/'));
7050
expect(builderDirs.root, equals('lib'));
7151
expect(builderDirs.out, equals(path.normalize('lib')));
7252
});
7353

7454
test('out dir not in root dir', () {
7555
final builderDirs =
76-
BuilderDirs(testBuildStep, Config(outDirLib: '../sibling'));
56+
BuilderDirs(inputPathLib, Config(outDirLib: '../sibling'));
7757
expect(builderDirs.root, equals('lib'));
7858
expect(builderDirs.out, equals(path.normalize('sibling')));
7959
});
8060

8161
test('out dir below root dir', () {
8262
final builderDirs =
83-
BuilderDirs(testBuildStep, Config(outDirLib: 'below/root'));
63+
BuilderDirs(inputPathLib, Config(outDirLib: 'below/root'));
8464
expect(builderDirs.root, equals('lib'));
8565
expect(builderDirs.out, equals(path.normalize('lib/below/root')));
8666
});
8767
});
8868

8969
group('getPrefixFor', () {
9070
test('out dir is root dir', () {
91-
expect(CodeBuilder.getPrefixFor(BuilderDirs(testBuildStep, Config())),
71+
expect(CodeBuilder.getPrefixFor(BuilderDirs(inputPathLib, Config())),
9272
equals(''));
9373
});
9474

9575
test('out dir redundant slash', () {
9676
expect(
9777
CodeBuilder.getPrefixFor(
98-
BuilderDirs(testBuildStep, Config(outDirLib: '/'))),
78+
BuilderDirs(inputPathLib, Config(outDirLib: '/'))),
9979
equals(''));
10080
expect(
10181
CodeBuilder.getPrefixFor(
102-
BuilderDirs(testBuildStep, Config(outDirLib: '//below/'))),
82+
BuilderDirs(inputPathLib, Config(outDirLib: '//below/'))),
10383
equals('../'));
10484
});
10585

10686
test('out dir not in root dir', () {
10787
expect(
10888
() => CodeBuilder.getPrefixFor(
109-
BuilderDirs(testBuildStep, Config(outDirLib: '../sibling'))),
89+
BuilderDirs(inputPathLib, Config(outDirLib: '../sibling'))),
11090
throwsA(predicate((e) =>
11191
e is InvalidGenerationSourceError &&
11292
e.message
11393
.contains("is not a subdirectory of the source directory"))));
11494

11595
expect(
11696
() => CodeBuilder.getPrefixFor(
117-
BuilderDirs(testBuildStep, Config(outDirLib: '../../above'))),
97+
BuilderDirs(inputPathLib, Config(outDirLib: '../../above'))),
11898
throwsA(predicate((e) =>
11999
e is InvalidGenerationSourceError &&
120100
e.message
@@ -124,11 +104,11 @@ void main() {
124104
test('out dir below root dir', () {
125105
expect(
126106
CodeBuilder.getPrefixFor(
127-
BuilderDirs(testBuildStep, Config(outDirLib: 'below'))),
107+
BuilderDirs(inputPathLib, Config(outDirLib: 'below'))),
128108
equals('../'));
129109
expect(
130110
CodeBuilder.getPrefixFor(
131-
BuilderDirs(testBuildStep, Config(outDirLib: 'below/lower'))),
111+
BuilderDirs(inputPathLib, Config(outDirLib: 'below/lower'))),
132112
equals('../../'));
133113
});
134114
});
@@ -186,10 +166,15 @@ void main() {
186166
}
187167
''';
188168

189-
await expectLater(
190-
() async => await testEnv.run(source),
191-
throwsA(isA<InvalidGenerationSourceError>().having((e) => e.message,
192-
'message', contains("@Index/@Unique is not supported"))));
169+
final result = await testEnv.run(source, expectNoOutput: true);
170+
171+
expect(result.builderResult.buildResult.status, BuildStatus.failure);
172+
expect(
173+
result.logs,
174+
contains(isA<LogRecord>()
175+
.having((r) => r.level, 'level', Level.SEVERE)
176+
.having((r) => r.message, 'message',
177+
contains('@Index/@Unique is not supported'))));
193178
}
194179

195180
// floating point types
@@ -259,13 +244,20 @@ void main() {
259244
''';
260245

261246
final testEnv = GeneratorTestEnv();
262-
await expectLater(
263-
() async => await testEnv.run(source),
264-
throwsA(isA<InvalidGenerationSourceError>().having(
265-
(e) => e.message,
266-
'message',
267-
contains(
268-
"@HnswIndex is only supported for float vector properties."))));
247+
final result = await testEnv.run(source, expectNoOutput: true);
248+
249+
expect(result.builderResult.buildResult.status, BuildStatus.failure);
250+
expect(
251+
result.logs,
252+
contains(isA<LogRecord>()
253+
.having((r) => r.level, 'level', Level.SEVERE)
254+
.having(
255+
(r) => r.message,
256+
'message',
257+
contains(
258+
'@HnswIndex is only supported for float vector properties.',
259+
))),
260+
);
269261
});
270262

271263
test('HNSW annotation default', () async {
@@ -465,7 +457,3 @@ void main() {
465457
});
466458
});
467459
}
468-
469-
Future<PackageConfig> _unsupported() {
470-
return Future.error(UnsupportedError('stub'));
471-
}

0 commit comments

Comments
 (0)