From 93d4593a52e26544eebca2cd6d45dba802bd8609 Mon Sep 17 00:00:00 2001 From: evanweible-wf Date: Wed, 3 Apr 2019 17:30:23 -0600 Subject: [PATCH] Warn if .over_react.g.dart part is missing. --- lib/src/builder/builder.dart | 20 +++++---- .../builder/over_react_builder_test.dart | 41 +++++++++++-------- .../missing_over_react_g_part/library.dart | 3 ++ .../missing_over_react_g_part/part.dart | 17 ++++++++ 4 files changed, 58 insertions(+), 23 deletions(-) create mode 100644 test_fixtures/source_files/missing_over_react_g_part/library.dart create mode 100644 test_fixtures/source_files/missing_over_react_g_part/part.dart diff --git a/lib/src/builder/builder.dart b/lib/src/builder/builder.dart index 20d84dc87..91d6a8a7f 100644 --- a/lib/src/builder/builder.dart +++ b/lib/src/builder/builder.dart @@ -21,10 +21,6 @@ class OverReactBuilder extends Builder { @override FutureOr build(BuildStep buildStep) async { final source = await buildStep.readAsString(buildStep.inputId); - if (!_mightContainDeclarations(source)) { - return; - } - final libraryUnit = _tryParseCompilationUnit(source, buildStep.inputId); if (libraryUnit == null) { return; @@ -79,7 +75,18 @@ class OverReactBuilder extends Builder { } if (outputs.isNotEmpty) { - await _writePart(buildStep, outputs); + final outputId = buildStep.inputId.changeExtension(outputExtension); + + // Verify that the library file has an `.over_react.g.dart` part. + final expectedPart = p.basename(outputId.path); + final partUris = libraryUnit.directives + .whereType() + .map((p) => p.uri.stringValue); + if (!partUris.contains(expectedPart)) { + log.warning('Missing "part \'$expectedPart\';".'); + } + + await _writePart(buildStep, outputId, outputs); } } @@ -111,8 +118,7 @@ class OverReactBuilder extends Builder { } } - static FutureOr _writePart(BuildStep buildStep, Iterable outputs) async { - final outputId = buildStep.inputId.changeExtension(outputExtension); + static FutureOr _writePart(BuildStep buildStep, AssetId outputId, Iterable outputs) async { final partOf = "'${p.basename(buildStep.inputId.uri.toString())}'"; final buffer = new StringBuffer() diff --git a/test/vm_tests/builder/over_react_builder_test.dart b/test/vm_tests/builder/over_react_builder_test.dart index 692075376..f8151c656 100644 --- a/test/vm_tests/builder/over_react_builder_test.dart +++ b/test/vm_tests/builder/over_react_builder_test.dart @@ -1,4 +1,5 @@ @TestOn('vm') +import 'dart:async'; import 'dart:io'; import 'package:build/build.dart'; @@ -14,12 +15,14 @@ typedef void LogRecordFunction(LogRecord record); main() { group('overReactBuilder', () { final builder = overReactBuilder(null); + final logger = Logger('overReactBuilderTestLogger'); AssetReader reader; InMemoryAssetWriter writer; AssetWriterSpy writerSpy; - List logMsgs = []; - List logLevels = []; + StreamSubscription logSub; + List logs = []; + setUp(() async { reader = await PackageAssetReader.currentIsolate( rootPackage: 'over_react', @@ -27,23 +30,22 @@ main() { writer = new InMemoryAssetWriter(); writerSpy = AssetWriterSpy(writer); + + logSub = logger.onRecord.listen(logs.add); }); - tearDown(() { - logMsgs.clear(); + tearDown(() async { + await logSub?.cancel(); + logs.clear(); reader = null; writer = null; writerSpy = null; }); void verifyNoErrorLogs() { - expect(logLevels, isNot(contains(Level.SEVERE))); - expect(logLevels, isNot(contains(Level.WARNING))); - } - - void recordLogs(LogRecord record) { - logMsgs.add(record.message); - logLevels.add(record.level); + expect(logs.where((log) => log.level >= Level.WARNING), isEmpty, + reason: 'Expected no logs at WARNING or SEVERE level, but got:\n' + '\t${logs.join('\n\t')}'); } void checkBuildForFile(String assetPath, String expectedOutputAssetPath, @@ -55,11 +57,8 @@ main() { expectedOutputAssetPath : expectedContent }; - final logger = Logger('overReactBuilderTestLogger'); - final sub = logger.onRecord.listen(recordLogs); await runBuilder(builder, [inputAsset], reader, writerSpy, AnalyzerResolvers(), logger: logger); final actual = writerSpy.assetsWritten; - sub.cancel(); checkOutputs(expected, actual, writer); verifyNoErrorLogs(); @@ -67,7 +66,7 @@ main() { test('does not produce a build output for a file with no over_react annotations', () async { var basicAsset = makeAssetId('over_react|test_fixtures/source_files/no_annotations.dart'); - await runBuilder(builder, [basicAsset], reader, writerSpy, AnalyzerResolvers()); + await runBuilder(builder, [basicAsset], reader, writerSpy, AnalyzerResolvers(), logger: logger); expect(writerSpy.assetsWritten, isEmpty); verifyNoErrorLogs(); @@ -75,12 +74,22 @@ main() { test('does not produce a build output for just a part file', () async { var basicAsset = makeAssetId('over_react|test_fixtures/source_files/part_of_basic_library.dart'); - await runBuilder(builder, [basicAsset], reader, writerSpy, AnalyzerResolvers()); + await runBuilder(builder, [basicAsset], reader, writerSpy, AnalyzerResolvers(), logger: logger); expect(writerSpy.assetsWritten, isEmpty); verifyNoErrorLogs(); }); + test('warns if the .over_react.g.dart part is missing', () async { + var libraryAsset = makeAssetId('over_react|test_fixtures/source_files/missing_over_react_g_part/library.dart'); + await runBuilder(builder, [libraryAsset], reader, writerSpy, AnalyzerResolvers(), logger: logger); + final expectedWarning = logs.firstWhere((log) { + return log.level == Level.WARNING && log.message == 'Missing "part \'library.over_react.g.dart\';".'; + }, orElse: () => null); + expect(expectedWarning, isNotNull, + reason: 'Expected a WARNING log for the missing over_react part.'); + }); + group('for backwards compatible boilerplate:', () { test('builds from basic component file', () async { await checkBuildForFile( diff --git a/test_fixtures/source_files/missing_over_react_g_part/library.dart b/test_fixtures/source_files/missing_over_react_g_part/library.dart new file mode 100644 index 000000000..44571c4b1 --- /dev/null +++ b/test_fixtures/source_files/missing_over_react_g_part/library.dart @@ -0,0 +1,3 @@ +import 'package:over_react/over_react.dart'; + +part 'part.dart'; \ No newline at end of file diff --git a/test_fixtures/source_files/missing_over_react_g_part/part.dart b/test_fixtures/source_files/missing_over_react_g_part/part.dart new file mode 100644 index 000000000..3f45f1fdc --- /dev/null +++ b/test_fixtures/source_files/missing_over_react_g_part/part.dart @@ -0,0 +1,17 @@ +part of 'library.dart'; + +@Factory() +UiFactory BasicPartOfLib = _$BasicPartOfLib; + +@Props() +class _$BasicPartOfLibProps extends UiProps { + String basicProp; +} + +@Component() +class BasicPartOfLibComponent extends UiComponent { + @override + render() { + return Dom.div()('foo'); + } +}