blob: 5b0d8f8e75dde06fe5ec6f675536ebcc8aef4558 [file] [log] [blame]
// Copyright (c) 2020, 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/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:dartdoc/dartdoc.dart';
import 'package:dartdoc/src/generator/generator_frontend.dart';
import 'package:dartdoc/src/generator/html_generator.dart';
import 'package:dartdoc/src/generator/html_resources.g.dart';
import 'package:dartdoc/src/generator/resource_loader.dart';
import 'package:dartdoc/src/generator/templates.dart';
import 'package:dartdoc/src/package_config_provider.dart';
import 'package:dartdoc/src/package_meta.dart';
import 'package:dartdoc/src/warnings.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'src/utils.dart' as utils;
void main() {
MemoryResourceProvider resourceProvider;
p.Context pathContext;
PackageMetaProvider packageMetaProvider;
FakePackageConfigProvider packageConfigProvider;
Templates templates;
GeneratorFrontEnd generator;
DartdocFileWriter writer;
Folder projectRoot;
String projectPath;
setUp(() async {
packageMetaProvider = utils.testPackageMetaProvider;
resourceProvider = packageMetaProvider.resourceProvider;
pathContext = resourceProvider.pathContext;
packageConfigProvider = utils
.getTestPackageConfigProvider(packageMetaProvider.defaultSdkDir.path);
var resourceLoader = ResourceLoader(resourceProvider);
for (var template in [
'_accessor_getter',
'_accessor_setter',
'_callable',
'_callable_multiline',
'_categorization',
'_class',
'_constant',
'_documentation',
'_extension',
'_features',
'_feature_set',
'_footer',
'_head',
'_library',
'_mixin',
'_name_summary',
'_packages',
'_property',
'_search_sidebar',
'_sidebar_for_category',
'_sidebar_for_container',
'_sidebar_for_library',
'_source_code',
'_source_link',
'404error',
'category',
'class',
'constructor',
'enum',
'extension',
'function',
'index',
'library',
'method',
'mixin',
'property',
'top_level_property',
'typedef',
]) {
await resourceLoader.writeDartdocResource(
'templates/html/$template.html', 'CONTENT');
}
for (var resource in [
'favicon.png',
'github.css',
'highlight.pack.js',
'play_button.svg',
'readme.md',
'script.js',
'styles.css',
'typeahead.bundle.min.js',
]) {
await resourceLoader.writeDartdocResource(
'resources/$resource', 'CONTENT');
}
templates = await Templates.createDefault('html', loader: resourceLoader);
generator = GeneratorFrontEnd(HtmlGeneratorBackend(null, templates));
projectRoot = utils.writePackage(
'my_package', resourceProvider, packageConfigProvider);
projectPath = projectRoot.path;
var outputPath = projectRoot.getChildAssumingFolder('doc').path;
writer = DartdocFileWriter(outputPath, resourceProvider);
});
File getConvertedFile(String path) =>
resourceProvider.getFile(resourceProvider.convertPath(path));
tearDown(() {
projectRoot = null;
projectPath = null;
clearPackageMetaCache();
});
test('a null package has some assets', () async {
await generator.generate(null, writer);
var outputPath = projectRoot.getChildAssumingFolder('doc').path;
var output = resourceProvider
.getFolder(pathContext.join(outputPath, 'static-assets'));
expect(output, doesExist);
for (var resource in resource_names.map((r) =>
pathContext.relative(Uri.parse(r).path, from: 'dartdoc/resources'))) {
expect(resourceProvider.getFile(pathContext.join(output.path, resource)),
doesExist);
}
});
test('libraries with no duplicates are not warned about', () async {
getConvertedFile('$projectPath/lib/a.dart').writeAsStringSync('library a;');
getConvertedFile('$projectPath/lib/b.dart').writeAsStringSync('library b;');
var packageGraph = await utils.bootBasicPackage(
projectPath, packageMetaProvider, packageConfigProvider);
await generator.generate(packageGraph, writer);
expect(packageGraph.packageWarningCounter.errorCount, 0);
}, onPlatform: {'windows': Skip('Test does not work on Windows (#2446)')});
test('libraries with duplicate names are warned about', () async {
getConvertedFile('$projectPath/lib/a.dart').writeAsStringSync('library a;');
getConvertedFile('$projectPath/lib/b.dart').writeAsStringSync('library a;');
var packageGraph = await utils.bootBasicPackage(
projectPath, packageMetaProvider, packageConfigProvider);
await generator.generate(packageGraph, writer);
var expectedPath = pathContext.join('a', 'a-library.html');
expect(
packageGraph.localPublicLibraries,
anyElement((l) => packageGraph.packageWarningCounter
.hasWarning(l, PackageWarning.duplicateFile, expectedPath)));
}, onPlatform: {'windows': Skip('Test does not work on Windows (#2446)')});
test('has HTML templates', () async {
expect(templates.indexTemplate, isNotNull);
expect(templates.libraryTemplate, isNotNull);
expect(templates.classTemplate, isNotNull);
expect(templates.functionTemplate, isNotNull);
expect(templates.constructorTemplate, isNotNull);
expect(templates.methodTemplate, isNotNull);
expect(templates.propertyTemplate, isNotNull);
expect(templates.topLevelPropertyTemplate, isNotNull);
}, onPlatform: {'windows': Skip('Test does not work on Windows (#2446)')});
}
const Matcher doesExist = _DoesExist();
class _DoesExist extends Matcher {
const _DoesExist();
@override
bool matches(Object item, Map matchState) => (item as Resource).exists;
@override
Description describe(Description description) => description.add('exists');
@override
Description describeMismatch(Object item, Description mismatchDescription,
Map matchState, bool verbose) {
if (item is! File && item is! Folder) {
return mismatchDescription
.addDescriptionOf(item)
.add('is not a file or directory');
} else {
return mismatchDescription.add(' does not exist');
}
}
}
/// Extension methods just for tests.
extension on ResourceLoader {
Future<void> writeDartdocResource(String path, String content) async {
var filePath =
(await resolveUri(Uri.parse('package:dartdoc/$path'))).toFilePath();
provider.getFile(filePath).writeAsStringSync(content);
}
}