dbe5039f15
Change-Id: Id1a2cc48c30e50850d79e26d39783b5c8ea03b4b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/180040 Reviewed-by: Phil Quitslund <pquitslund@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Devon Carew <devoncarew@google.com>
335 lines
6.9 KiB
Dart
335 lines
6.9 KiB
Dart
// 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 'dart:io';
|
|
|
|
import 'package:cli_util/cli_logging.dart';
|
|
import 'package:path/path.dart' as path;
|
|
import 'package:test/test.dart';
|
|
|
|
import '../utils.dart';
|
|
|
|
void main() {
|
|
group('fix', defineFix, timeout: longTimeout);
|
|
}
|
|
|
|
/// Enable to run from local source (useful in development).
|
|
const runFromSource = false;
|
|
|
|
void defineFix() {
|
|
TestProject p;
|
|
|
|
ProcessResult result;
|
|
|
|
final bullet = Logger.standard().ansi.bullet;
|
|
|
|
setUp(() => p = null);
|
|
|
|
tearDown(() => p?.dispose());
|
|
|
|
void assertResult({int exitCode = 0}) {
|
|
String message;
|
|
if (result.exitCode != exitCode) {
|
|
if (result.stderr.isNotEmpty) {
|
|
message = 'Error code was ${result.exitCode} and stderr was not empty';
|
|
} else {
|
|
message = 'Error code was ${result.exitCode}';
|
|
}
|
|
} else if (result.stderr.isNotEmpty) {
|
|
message = 'stderr was not empty';
|
|
} else {
|
|
return;
|
|
}
|
|
fail('''
|
|
$message
|
|
|
|
stdout:
|
|
${result.stdout}
|
|
|
|
stderr:
|
|
${result.stderr}
|
|
''');
|
|
}
|
|
|
|
ProcessResult runFix(List<String> args, {String workingDir}) {
|
|
if (runFromSource) {
|
|
var binary = path.join(Directory.current.path, 'bin', 'dartdev.dart');
|
|
return p.runSync([binary, 'fix', ...?args], workingDir: workingDir);
|
|
}
|
|
return p.runSync(['fix', ...args], workingDir: workingDir);
|
|
}
|
|
|
|
test('help', () {
|
|
p = project(mainSrc: 'int get foo => 1;\n');
|
|
|
|
var result = runFix([p.dirPath, '--help']);
|
|
|
|
expect(result.exitCode, 0);
|
|
expect(result.stderr, isEmpty);
|
|
expect(
|
|
result.stdout, contains('Apply automated fixes to Dart source code.'));
|
|
});
|
|
|
|
test('none', () {
|
|
p = project(mainSrc: 'int get foo => 1;\n');
|
|
|
|
var result = runFix([p.dirPath]);
|
|
|
|
expect(result.exitCode, 0);
|
|
expect(result.stderr, isEmpty);
|
|
expect(
|
|
result.stdout, contains('Apply automated fixes to Dart source code.'));
|
|
});
|
|
|
|
test('--apply (none)', () {
|
|
p = project(mainSrc: 'int get foo => 1;\n');
|
|
|
|
var result = runFix(['--apply', p.dirPath]);
|
|
|
|
expect(result.exitCode, 0);
|
|
expect(result.stderr, isEmpty);
|
|
expect(result.stdout, contains('Nothing to fix!'));
|
|
});
|
|
|
|
test('--apply (no args)', () {
|
|
p = project(
|
|
mainSrc: '''
|
|
var x = "";
|
|
''',
|
|
analysisOptions: '''
|
|
linter:
|
|
rules:
|
|
- prefer_single_quotes
|
|
''',
|
|
);
|
|
|
|
var result = runFix(['--apply'], workingDir: p.dirPath);
|
|
expect(result.exitCode, 0);
|
|
expect(result.stderr, isEmpty);
|
|
expect(
|
|
result.stdout,
|
|
stringContainsInOrder([
|
|
'Applying fixes...',
|
|
'lib${Platform.pathSeparator}main.dart',
|
|
' prefer_single_quotes $bullet 1 fix',
|
|
]));
|
|
});
|
|
|
|
test('--dry-run', () {
|
|
p = project(
|
|
mainSrc: '''
|
|
class A {
|
|
String a() => "";
|
|
}
|
|
|
|
class B extends A {
|
|
String a() => "";
|
|
}
|
|
''',
|
|
analysisOptions: '''
|
|
linter:
|
|
rules:
|
|
- annotate_overrides
|
|
- prefer_single_quotes
|
|
''',
|
|
);
|
|
var result = runFix(['--dry-run', '.'], workingDir: p.dirPath);
|
|
expect(result.exitCode, 0);
|
|
expect(result.stderr, isEmpty);
|
|
expect(
|
|
result.stdout,
|
|
stringContainsInOrder([
|
|
'3 proposed fixes in 1 file.',
|
|
'lib${Platform.pathSeparator}main.dart',
|
|
' annotate_overrides $bullet 1 fix',
|
|
' prefer_single_quotes $bullet 2 fixes',
|
|
]));
|
|
});
|
|
|
|
test('--apply (.)', () {
|
|
p = project(
|
|
mainSrc: '''
|
|
var x = "";
|
|
''',
|
|
analysisOptions: '''
|
|
linter:
|
|
rules:
|
|
- prefer_single_quotes
|
|
''',
|
|
);
|
|
var result = runFix(['--apply', '.'], workingDir: p.dirPath);
|
|
expect(result.exitCode, 0);
|
|
expect(result.stderr, isEmpty);
|
|
expect(
|
|
result.stdout,
|
|
stringContainsInOrder([
|
|
'Applying fixes...',
|
|
'lib${Platform.pathSeparator}main.dart',
|
|
' prefer_single_quotes $bullet 1 fix',
|
|
'1 fix made in 1 file.',
|
|
]));
|
|
});
|
|
|
|
test('--apply (excludes)', () {
|
|
p = project(
|
|
mainSrc: '''
|
|
var x = "";
|
|
''',
|
|
analysisOptions: '''
|
|
analyzer:
|
|
exclude:
|
|
- lib/**
|
|
linter:
|
|
rules:
|
|
- prefer_single_quotes
|
|
''',
|
|
);
|
|
var result = runFix(['--apply', '.'], workingDir: p.dirPath);
|
|
expect(result.exitCode, 0);
|
|
expect(result.stderr, isEmpty);
|
|
expect(result.stdout, contains('Nothing to fix!'));
|
|
});
|
|
|
|
test('--apply (ignores)', () {
|
|
p = project(
|
|
mainSrc: '''
|
|
// ignore: prefer_single_quotes
|
|
var x = "";
|
|
''',
|
|
analysisOptions: '''
|
|
linter:
|
|
rules:
|
|
- prefer_single_quotes
|
|
''',
|
|
);
|
|
var result = runFix(['--apply', '.'], workingDir: p.dirPath);
|
|
expect(result.exitCode, 0);
|
|
expect(result.stderr, isEmpty);
|
|
expect(result.stdout, contains('Nothing to fix!'));
|
|
});
|
|
|
|
group('compare-to-golden', () {
|
|
test('applied fixes do not match expected', () {
|
|
p = project(
|
|
mainSrc: '''
|
|
class A {
|
|
String a() => "";
|
|
}
|
|
|
|
class B extends A {
|
|
String a() => "";
|
|
}
|
|
''',
|
|
analysisOptions: '''
|
|
linter:
|
|
rules:
|
|
- annotate_overrides
|
|
- prefer_single_quotes
|
|
''',
|
|
);
|
|
p.file('lib/main.dart.expect', '''
|
|
class A {
|
|
String a() => '';
|
|
}
|
|
|
|
class B extends A {
|
|
String a() => '';
|
|
}
|
|
''');
|
|
result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
|
|
assertResult(exitCode: 1);
|
|
});
|
|
|
|
test('applied fixes match expected', () {
|
|
p = project(
|
|
mainSrc: '''
|
|
class A {
|
|
String a() => "";
|
|
}
|
|
|
|
class B extends A {
|
|
String a() => "";
|
|
}
|
|
''',
|
|
analysisOptions: '''
|
|
linter:
|
|
rules:
|
|
- annotate_overrides
|
|
- prefer_single_quotes
|
|
''',
|
|
);
|
|
p.file('lib/main.dart.expect', '''
|
|
class A {
|
|
String a() => '';
|
|
}
|
|
|
|
class B extends A {
|
|
@override
|
|
String a() => '';
|
|
}
|
|
''');
|
|
result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
|
|
assertResult();
|
|
});
|
|
|
|
test('missing expect', () {
|
|
p = project(
|
|
mainSrc: '''
|
|
class A {
|
|
String a() => "";
|
|
}
|
|
|
|
class B extends A {
|
|
String a() => "";
|
|
}
|
|
''',
|
|
analysisOptions: '''
|
|
linter:
|
|
rules:
|
|
- annotate_overrides
|
|
- prefer_single_quotes
|
|
''',
|
|
);
|
|
result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
|
|
assertResult(exitCode: 1);
|
|
});
|
|
|
|
test('missing original', () {
|
|
p = project(mainSrc: '''
|
|
class C {}
|
|
''');
|
|
p.file('lib/main.dart.expect', '''
|
|
class C {}
|
|
''');
|
|
p.file('lib/secondary.dart.expect', '''
|
|
class A {}
|
|
''');
|
|
result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
|
|
assertResult(exitCode: 1);
|
|
});
|
|
|
|
test('no fixes to apply does not match expected', () {
|
|
p = project(
|
|
mainSrc: '''
|
|
class A {
|
|
String a() => "";
|
|
}
|
|
''',
|
|
analysisOptions: '''
|
|
linter:
|
|
rules:
|
|
- annotate_overrides
|
|
''',
|
|
);
|
|
p.file('lib/main.dart.expect', '''
|
|
class A {
|
|
String a() => '';
|
|
}
|
|
''');
|
|
result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
|
|
assertResult(exitCode: 1);
|
|
});
|
|
});
|
|
}
|