diff --git a/test/dartdoc_test.dart b/test/dartdoc_test.dart index 2ccee81a77..af0b7d9851 100644 --- a/test/dartdoc_test.dart +++ b/test/dartdoc_test.dart @@ -6,6 +6,7 @@ library dartdoc.dartdoc_test; import 'dart:async'; import 'dart:io'; +import 'dart:mirrors'; import 'package:dartdoc/dartdoc.dart'; import 'package:dartdoc/src/logging.dart'; @@ -17,6 +18,13 @@ import 'package:test/test.dart'; import 'src/utils.dart'; +Uri get _currentFileUri => + (reflect(main) as ClosureMirror).function.location.sourceUri; +String get _testPackagePath => + pathLib.fromUri(_currentFileUri.resolve('../testing/test_package')); +String get _testPackageFlutterPluginPath => pathLib + .fromUri(_currentFileUri.resolve('../testing/test_package_flutter_plugin')); + class DartdocLoggingOptionContext extends DartdocGeneratorOptionContext with LoggingContext { DartdocLoggingOptionContext(DartdocOptionSet optionSet, Directory dir) @@ -27,11 +35,8 @@ void main() { group('dartdoc with generators', () { Directory tempDir; List outputParam; - CoverageSubprocessLauncher subprocessLauncher; setUpAll(() async { - subprocessLauncher = - new CoverageSubprocessLauncher('dartdoc_test-subprocesses'); tempDir = Directory.systemTemp.createTempSync('dartdoc.test.'); outputParam = ['--output', tempDir.path]; DartdocOptionSet optionSet = await DartdocOptionSet.fromOptionGenerators( @@ -42,7 +47,6 @@ void main() { }); tearDown(() async { - await Future.wait(CoverageSubprocessLauncher.coverageResults); tempDir.listSync().forEach((FileSystemEntity f) { f.deleteSync(recursive: true); }); @@ -114,7 +118,18 @@ void main() { }); group('Invoking command-line dartdoc', () { - String dartdocPath = pathLib.join('bin', 'dartdoc.dart'); + String dartdocPath = + pathLib.canonicalize(pathLib.join('bin', 'dartdoc.dart')); + CoverageSubprocessLauncher subprocessLauncher; + + setUpAll(() { + subprocessLauncher = + new CoverageSubprocessLauncher('dartdoc_test-subprocesses'); + }); + + tearDownAll(() async { + await Future.wait(CoverageSubprocessLauncher.coverageResults); + }); test('errors cause non-zero exit when warnings are off', () async { expect( @@ -136,7 +151,108 @@ void main() { ]), throwsA(const TypeMatcher())); }); - }); + + test('Validate missing FLUTTER_ROOT exception is clean', () async { + StringBuffer output = new StringBuffer(); + var args = [dartdocPath]; + Future run = subprocessLauncher.runStreamed( + Platform.resolvedExecutable, args, + environment: new Map.from(Platform.environment) + ..remove('FLUTTER_ROOT'), + includeParentEnvironment: false, + workingDirectory: _testPackageFlutterPluginPath, perLine: (s) { + output.writeln(s); + }); + // Asynchronous exception, but we still need the output, too. + expect(run, throwsA(new TypeMatcher())); + try { + await run; + } on ProcessException catch (_) {} + + expect( + output.toString(), + contains(new RegExp( + 'Top level package requires Flutter but FLUTTER_ROOT environment variable not set|test_package_flutter_plugin requires the Flutter SDK, version solving failed'))); + expect(output.toString(), isNot(contains('asynchronous gap'))); + }); + + test("Validate --version works", () async { + StringBuffer output = new StringBuffer(); + var args = [dartdocPath, '--version']; + await subprocessLauncher.runStreamed(Platform.resolvedExecutable, args, + workingDirectory: _testPackagePath, + perLine: (s) => output.writeln(s)); + PackageMeta dartdocMeta = new PackageMeta.fromFilename(dartdocPath); + expect(output.toString(), + endsWith('dartdoc version: ${dartdocMeta.version}\n')); + }); + + test('Check for sample code in examples', () async { + StringBuffer output = new StringBuffer(); + var args = [ + dartdocPath, + '--include', + 'ex', + '--no-include-source', + '--output', + tempDir.path + ]; + + await subprocessLauncher.runStreamed(Platform.resolvedExecutable, args, + workingDirectory: _testPackagePath, + perLine: (s) => output.writeln(s)); + + // Examples are reported as unfound because we (purposefully) + // did not use --example-path-prefix above. + final sep = '.'; // We don't care what the path separator character is + final firstUnfoundExample = + new RegExp('warning: lib${sep}example.dart: ' + '@example file not found.*test_package${sep}dog${sep}food.md'); + if (!output.toString().contains(firstUnfoundExample)) { + fail('Should warn about unfound @example files'); + } + }); + + test('Validate JSON output', () async { + var args = [ + dartdocPath, + '--include', + 'ex', + '--no-include-source', + '--output', + tempDir.path, + '--json' + ]; + + Iterable jsonValues = await subprocessLauncher.runStreamed( + Platform.resolvedExecutable, args, + workingDirectory: _testPackagePath); + + expect(jsonValues, isNotEmpty, + reason: 'All STDOUT lines should be JSON-encoded maps.'); + }, timeout: new Timeout.factor(2)); + + test('--footer-text includes text', () async { + String footerTextPath = + pathLib.join(Directory.systemTemp.path, 'footer.txt'); + new File(footerTextPath).writeAsStringSync(' footer text include '); + + var args = [ + dartdocPath, + '--footer-text=${footerTextPath}', + '--include', + 'ex', + '--output', + tempDir.path + ]; + + await subprocessLauncher.runStreamed(Platform.resolvedExecutable, args, + workingDirectory: _testPackagePath); + + File outFile = new File(pathLib.join(tempDir.path, 'index.html')); + expect(outFile.readAsStringSync(), contains('footer text include')); + }); + }, timeout: new Timeout.factor(3)); group('Option handling with cross-linking', () { DartdocResults results;