blob: e77b584ad180e3dc40da3d09fec1c75692befe99 [file] [log] [blame]
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart'
show AnalysisContextCollectionImpl;
import 'package:path/path.dart' as path;
import 'package:test_descriptor/test_descriptor.dart' as d;
import '../../tool/mustachio/builder.dart';
import '../src/test_descriptor_utils.dart';
export '../../tool/mustachio/builder.dart';
/// The build package Asset for a copy of the Renderer annotation for tests.
///
/// In testing builders, the builder cannot access both in-line assets specified
/// in tests, _and_ assets on disk in the package.
// Update this when [Renderer] and [Context] are updated.
const annotationsContent = '''
class Renderer {
final Symbol name;
final Context context;
final Set<Type> visibleTypes;
final String standardHtmlTemplate;
final String standardMdTemplate;
const Renderer(
this.name,
this.context,
String standardTemplateBasename, {
this.visibleTypes = const {},
}) : standardHtmlTemplate = 'lib/templates/\${standardTemplateBasename}.html';
}
class Context<T> {
const Context();
}
''';
/// Front matter for a library which declares a Renderer for `Foo`.
const libraryFrontMatter = '''
@Renderer(#renderFoo, Context<Foo>(), 'foo', visibleTypes: {Bar, Baz})
library foo;
import 'annotations.dart';
''';
/// Tests the Mustachio builder using in-memory Assets.
Future<void> testMustachioBuilder(
String sourceLibraryContent, {
String libraryFrontMatter = libraryFrontMatter,
Iterable<DirectoryDescriptor> Function()? additionalAssets,
}) async {
sourceLibraryContent = '''
$libraryFrontMatter
$sourceLibraryContent
''';
additionalAssets ??= () => [];
await d.dir('foo_package', [
d.dir('lib', [
d.file('annotations.dart', annotationsContent),
d.file('foo.dart', sourceLibraryContent),
d.dir('templates', [
d.file('foo.html', 's1 is {{ s1 }}'),
d.file('bar.html', 'EMPTY'),
d.file('baz.html', 'EMPTY'),
]),
]),
]).create();
await d.dir('foo_package', [...additionalAssets()]).create();
await build(path.join(d.sandbox, 'foo_package', 'lib/foo.dart'),
root: path.join(d.sandbox, 'foo_package'));
}
Future<LibraryElement2> resolveGeneratedLibrary2(String libraryPath) async {
var contextCollection = AnalysisContextCollectionImpl(
includedPaths: [d.sandbox],
// TODO(jcollins-g): should we pass excluded directories here instead of
// handling it ourselves?
resourceProvider: PhysicalResourceProvider.INSTANCE,
sdkPath: sdkPath,
);
var analysisContext = contextCollection.contextFor(d.sandbox);
final libraryResult =
await analysisContext.currentSession.getResolvedLibrary(libraryPath);
if (libraryResult is! ResolvedLibraryResult) {
throw StateError(
'Expected library result to be ResolvedLibraryResult, but is '
'${libraryResult.runtimeType}');
}
return libraryResult.element2;
}