Skip to content

Enhance coverage to cover all appropriate binary-level tests #1879

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ dart:
- stable
- "dev/raw/latest"
env:
- DARTDOC_BOT=main
- DARTDOC_BOT=flutter
- DARTDOC_BOT=sdk-analyzer
- DARTDOC_BOT=main
- DARTDOC_BOT=packages
- DARTDOC_BOT=sdk-docs
script: ./tool/travis.sh
Expand Down
3 changes: 0 additions & 3 deletions lib/src/io_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ final libraryNameRegexp = new RegExp('[.:]');
final partOfRegexp = new RegExp('part of ');
final newLinePartOfRegexp = new RegExp('\npart of ');


/// Best used with Future<void>.
class MultiFutureTracker<T> {
/// Approximate maximum number of simultaneous active Futures.
Expand Down Expand Up @@ -113,5 +112,3 @@ class MultiFutureTracker<T> {
/// Wait until all futures added so far have completed.
Future<void> wait() async => await _waitUntil(0);
}


7 changes: 4 additions & 3 deletions lib/src/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -464,8 +464,8 @@ class Accessor extends ModelElement implements EnclosedElement {
@override
void warn(PackageWarning kind,
{String message,
Iterable<Locatable> referredFrom,
Iterable<String> extendedDebug}) {
Iterable<Locatable> referredFrom,
Iterable<String> extendedDebug}) {
enclosingCombo.warn(kind,
message: message,
referredFrom: referredFrom,
Expand Down Expand Up @@ -2031,7 +2031,8 @@ abstract class GetterSetterCombo implements ModelElement {
if (writeOnly) return r'&#8592;';
// ↔
if (readWrite) return r'&#8596;';
throw UnsupportedError('GetterSetterCombo must be one of readOnly, writeOnly, or readWrite');
throw UnsupportedError(
'GetterSetterCombo must be one of readOnly, writeOnly, or readWrite');
}

bool get readOnly => hasPublicGetter && !hasPublicSetter;
Expand Down
99 changes: 50 additions & 49 deletions test/compare_output_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import 'package:dartdoc/src/package_meta.dart';
import 'package:path/path.dart' as pathLib;
import 'package:test/test.dart';

import 'src/utils.dart';

const List<String> _filesToIgnore = const <String>['.DS_Store'];

const String gitBinName = 'git';
Expand Down Expand Up @@ -40,10 +42,20 @@ String get _testPackageFlutterPluginPath => pathLib
void main() {
group('compare outputs', () {
Directory tempDir;
CoverageSubprocessLauncher subprocessLauncher;

var dartdocBin =
pathLib.fromUri(_currentFileUri.resolve('../bin/dartdoc.dart'));

setUpAll(() {
subprocessLauncher =
new CoverageSubprocessLauncher('compare_output_test-subprocesses');
});

tearDownAll(() async {
await Future.wait(CoverageSubprocessLauncher.coverageResults);
});

setUp(() {
tempDir = Directory.systemTemp.createTempSync('dartdoc.test.');
});
Expand All @@ -55,27 +67,38 @@ void main() {
});

test('Validate missing FLUTTER_ROOT exception is clean', () async {
StringBuffer output = new StringBuffer();
var args = <String>[dartdocBin];
var result = Process.runSync(Platform.resolvedExecutable, args,
Future run = subprocessLauncher.runStreamed(
Platform.resolvedExecutable, args,
environment: new Map.from(Platform.environment)
..remove('FLUTTER_ROOT'),
includeParentEnvironment: false,
workingDirectory: _testPackageFlutterPluginPath);
workingDirectory: _testPackageFlutterPluginPath, perLine: (s) {
output.writeln(s);
});
// Asynchronous exception, but we still need the output, too.
expect(run, throwsA(new TypeMatcher<ProcessException>()));
try {
await run;
} on ProcessException catch (_) {}

expect(
result.stderr,
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(result.stderr, isNot(contains('asynchronous gap')));
expect(result.exitCode, isNot(0));
expect(output.toString(), isNot(contains('asynchronous gap')));
});

test("Validate --version works", () async {
StringBuffer output = new StringBuffer();
var args = <String>[dartdocBin, '--version'];
var result = Process.runSync(Platform.resolvedExecutable, args,
workingDirectory: _testPackagePath);
await subprocessLauncher.runStreamed(Platform.resolvedExecutable, args,
workingDirectory: _testPackagePath,
perLine: (s) => output.writeln(s));
PackageMeta dartdocMeta = new PackageMeta.fromFilename(dartdocBin);
expect(
result.stdout, equals('dartdoc version: ${dartdocMeta.version}\n'));
expect(output.toString(),
endsWith('dartdoc version: ${dartdocMeta.version}\n'));
});

test("Validate html output of test_package", () async {
Expand All @@ -100,6 +123,8 @@ void main() {
'--pretty-index-json',
];

// Deliberately use runSync here to avoid counting this test as
// "test coverage".
var result = Process.runSync(Platform.resolvedExecutable, args,
workingDirectory: _testPackagePath);

Expand Down Expand Up @@ -157,7 +182,8 @@ void main() {
fail(message.join('\n'));
});

test('Check for sample code in examples', () {
test('Check for sample code in examples', () async {
StringBuffer output = new StringBuffer();
var args = <String>[
dartdocBin,
'--include',
Expand All @@ -167,28 +193,21 @@ void main() {
tempDir.path
];

var result = Process.runSync(Platform.resolvedExecutable, args,
workingDirectory: _testPackagePath);

if (result.exitCode != 0) {
print(result.exitCode);
print(result.stdout);
print(result.stderr);
fail('dartdoc failed');
}
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 (!result.stderr.contains(firstUnfoundExample)) {
fail('Should warn about unfound @example files: \n'
'stdout:\n${result.stdout}\nstderr:\n${result.stderr}');
if (!output.toString().contains(firstUnfoundExample)) {
fail('Should warn about unfound @example files');
}
});

test('Validate JSON output', () {
test('Validate JSON output', () async {
var args = <String>[
dartdocBin,
'--include',
Expand All @@ -199,28 +218,15 @@ void main() {
'--json'
];

var result = Process.runSync(Platform.resolvedExecutable, args,
Iterable<Map> jsonValues = await subprocessLauncher.runStreamed(
Platform.resolvedExecutable, args,
workingDirectory: _testPackagePath);

if (result.exitCode != 0) {
print(result.exitCode);
print(result.stdout);
print(result.stderr);
fail('dartdoc failed');
}

var jsonValues = LineSplitter.split(result.stdout)
.map((j) => json.decode(j) as Map<String, dynamic>)
.toList();

expect(jsonValues, isNotEmpty,
reason: 'All STDOUT lines should be JSON-encoded maps.');
}, timeout: new Timeout.factor(2));

expect(result.stderr as String, isEmpty,
reason: 'STDERR should be empty.');
});

test('--footer-text includes text', () {
test('--footer-text includes text', () async {
String footerTextPath =
pathLib.join(Directory.systemTemp.path, 'footer.txt');
new File(footerTextPath).writeAsStringSync(' footer text include ');
Expand All @@ -234,20 +240,15 @@ void main() {
tempDir.path
];

var result = Process.runSync(Platform.resolvedExecutable, args,
await subprocessLauncher.runStreamed(Platform.resolvedExecutable, args,
workingDirectory: _testPackagePath);

if (result.exitCode != 0) {
print(result.exitCode);
print(result.stdout);
print(result.stderr);
fail('dartdoc failed');
}

File outFile = new File(pathLib.join(tempDir.path, 'index.html'));
expect(outFile.readAsStringSync(), contains('footer text include'));
});
}, onPlatform: {'windows': new Skip('Avoiding parsing git output')});
},
onPlatform: {'windows': new Skip('Avoiding parsing git output')},
timeout: new Timeout.factor(3));
}

Map<String, String> _parseOutput(
Expand Down
34 changes: 21 additions & 13 deletions test/dartdoc_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ void main() {
group('dartdoc with generators', () {
Directory tempDir;
List<String> 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(
Expand All @@ -38,6 +42,7 @@ void main() {
});

tearDown(() async {
await Future.wait(CoverageSubprocessLauncher.coverageResults);
tempDir.listSync().forEach((FileSystemEntity f) {
f.deleteSync(recursive: true);
});
Expand Down Expand Up @@ -112,21 +117,24 @@ void main() {
String dartdocPath = pathLib.join('bin', 'dartdoc.dart');

test('errors cause non-zero exit when warnings are off', () async {
ProcessResult result = Process.runSync(Platform.resolvedExecutable, [
dartdocPath,
'--input=$testPackageToolError',
'--output=${pathLib.join(tempDir.absolute.path, 'test_package_tool_error')}',
]);
expect(result.exitCode, isNonZero);
expect(
() => subprocessLauncher.runStreamed(Platform.resolvedExecutable, [
dartdocPath,
'--input=${testPackageToolError.path}',
'--output=${pathLib.join(tempDir.absolute.path, 'test_package_tool_error')}'
]),
throwsA(const TypeMatcher<ProcessException>()));
});

test('errors cause non-zero exit when warnings are on', () async {
ProcessResult result = Process.runSync(Platform.resolvedExecutable, [
dartdocPath,
'--input=$testPackageToolError',
'--output=${pathLib.join(tempDir.absolute.path, 'test_package_tool_error')}',
'--show-warnings',
]);
expect(result.exitCode, isNonZero);
expect(
() => subprocessLauncher.runStreamed(Platform.resolvedExecutable, [
dartdocPath,
'--input=${testPackageToolError.path}',
'--output=${pathLib.join(tempDir.absolute.path, 'test_package_tool_error')}',
'--show-warnings',
]),
throwsA(const TypeMatcher<ProcessException>()));
});
});

Expand Down
Loading