Unverified Commit 1747adb6 authored by Dan Field's avatar Dan Field Committed by GitHub

Drop mockito for flutter_goldens (#74782)

parent fe921211
......@@ -30,7 +30,4 @@ dependencies:
test_api: 0.2.19-nullsafety.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.0-nullsafety.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
mockito: 4.1.1
# PUBSPEC CHECKSUM: 49d5
# PUBSPEC CHECKSUM: ae8f
......@@ -5,15 +5,17 @@
// @dart = 2.8
import 'dart:async';
import 'dart:convert';
import 'dart:core';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' show hashValues, hashList;
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_goldens/flutter_goldens.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:meta/meta.dart';
import 'package:platform/platform.dart';
import 'package:process/process.dart';
......@@ -49,8 +51,8 @@ Future<void> testWithOutput(String name, Future<void> body(), String expectedOut
void main() {
MemoryFileSystem fs;
FakePlatform platform;
MockProcessManager process;
MockHttpClient mockHttpClient;
FakeProcessManager process;
FakeHttpClient fakeHttpClient;
setUp(() {
fs = MemoryFileSystem();
......@@ -58,8 +60,8 @@ void main() {
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
operatingSystem: 'macos'
);
process = MockProcessManager();
mockHttpClient = MockHttpClient();
process = FakeProcessManager();
fakeHttpClient = FakeHttpClient();
fs.directory(_kFlutterRoot).createSync(recursive: true);
});
......@@ -75,7 +77,7 @@ void main() {
fs: fs,
process: process,
platform: platform,
httpClient: mockHttpClient,
httpClient: fakeHttpClient,
);
});
......@@ -83,15 +85,10 @@ void main() {
final File authFile = fs.file('/workDirectory/temp/auth_opt.json')
..createSync(recursive: true);
authFile.writeAsStringSync(authTemplate());
when(process.run(any))
.thenAnswer((_) => Future<ProcessResult>
.value(ProcessResult(123, 0, '', '')));
process.fallbackProcessResult = ProcessResult(123, 0, '', '');
await skiaClient.auth();
verifyNever(process.run(
captureAny,
workingDirectory: captureAnyNamed('workingDirectory'),
));
expect(process.workingDirectories, isEmpty);
});
test('gsutil is checked when authorization file is present', () async {
......@@ -119,16 +116,13 @@ void main() {
fs: fs,
process: process,
platform: platform,
httpClient: mockHttpClient,
httpClient: fakeHttpClient,
);
when(process.run(any))
.thenAnswer((_) => Future<ProcessResult>
.value(ProcessResult(123, 1, 'fail', 'fail')));
final Future<void> test = skiaClient.auth();
process.fallbackProcessResult = ProcessResult(123, 1, 'fail', 'fail');
expect(
test,
skiaClient.auth(),
throwsException,
);
});
......@@ -147,16 +141,14 @@ void main() {
fs: fs,
process: process,
platform: platform,
httpClient: mockHttpClient,
httpClient: fakeHttpClient,
);
when(process.run(
const RunInvocation gitInvocation = RunInvocation(
<String>['git', 'rev-parse', 'HEAD'],
workingDirectory: '/flutter',
)).thenAnswer((_) => Future<ProcessResult>
.value(ProcessResult(12345678, 0, '12345678', '')));
when(process.run(
'/flutter',
);
const RunInvocation goldctlInvocation = RunInvocation(
<String>[
'goldctl',
'imgtest', 'init',
......@@ -167,12 +159,13 @@ void main() {
'--failure-file', '/workDirectory/failures.json',
'--passfail',
],
)).thenAnswer((_) => Future<ProcessResult>
.value(ProcessResult(123, 1, 'fail', 'fail')));
final Future<void> test = skiaClient.imgtestInit();
null,
);
process.processResults[gitInvocation] = ProcessResult(12345678, 0, '12345678', '');
process.processResults[goldctlInvocation] = ProcessResult(123, 1, 'fail', 'fail');
expect(
test,
skiaClient.imgtestInit(),
throwsException,
);
});
......@@ -194,7 +187,7 @@ void main() {
fs: fs,
process: process,
platform: platform,
httpClient: mockHttpClient,
httpClient: fakeHttpClient,
);
final List<String> ciArguments = skiaClient.getCIArguments();
......@@ -229,7 +222,7 @@ void main() {
fs: fs,
process: process,
platform: platform,
httpClient: mockHttpClient,
httpClient: fakeHttpClient,
);
traceID = skiaClient.getTraceID('flutter.golden.1');
......@@ -257,7 +250,7 @@ void main() {
fs: fs,
process: process,
platform: platform,
httpClient: mockHttpClient,
httpClient: fakeHttpClient,
);
traceID = skiaClient.getTraceID('flutter.golden.1');
......@@ -280,7 +273,7 @@ void main() {
fs: fs,
process: process,
platform: platform,
httpClient: mockHttpClient,
httpClient: fakeHttpClient,
);
traceID = skiaClient.getTraceID('flutter.golden.1');
......@@ -302,17 +295,17 @@ void main() {
final Uri imageUrl = Uri.parse(
'https://flutter-gold.skia.org/img/images/$expectation.png'
);
final MockHttpClientRequest mockImageRequest = MockHttpClientRequest();
final MockHttpImageResponse mockImageResponse = MockHttpImageResponse(
final FakeHttpClientRequest fakeImageRequest = FakeHttpClientRequest();
final FakeHttpImageResponse fakeImageResponse = FakeHttpImageResponse(
imageResponseTemplate()
);
when(mockHttpClient.getUrl(imageUrl))
.thenAnswer((_) => Future<MockHttpClientRequest>.value(mockImageRequest));
when(mockImageRequest.close())
.thenAnswer((_) => Future<MockHttpImageResponse>.value(mockImageResponse));
fakeHttpClient.request = fakeImageRequest;
fakeImageRequest.response = fakeImageResponse;
final List<int> masterBytes = await skiaClient.getImageBytes(expectation);
expect(fakeHttpClient.lastUri, imageUrl);
expect(masterBytes, equals(_kTestPngBytes));
});
});
......@@ -326,17 +319,17 @@ void main() {
..createSync(recursive: true);
comparator = FlutterPostSubmitFileComparator(
basedir.uri,
MockSkiaGoldClient(),
FakeSkiaGoldClient(),
fs: fs,
platform: platform,
);
});
test('calculates the basedir correctly from defaultComparator for local testing', () async {
final MockLocalFileComparator defaultComparator = MockLocalFileComparator();
final FakeLocalFileComparator defaultComparator = FakeLocalFileComparator();
final Directory flutterRoot = fs.directory(platform.environment['FLUTTER_ROOT'])
..createSync(recursive: true);
when(defaultComparator.basedir).thenReturn(flutterRoot.childDirectory('baz').uri);
defaultComparator.basedir = flutterRoot.childDirectory('baz').uri;
final Directory basedir = FlutterGoldenFileComparator.getBaseDirectory(
defaultComparator,
......@@ -355,14 +348,14 @@ void main() {
});
group('Post-Submit', () {
final MockSkiaGoldClient mockSkiaClient = MockSkiaGoldClient();
final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
setUp(() {
final Directory basedir = fs.directory('flutter/test/library/')
..createSync(recursive: true);
comparator = FlutterPostSubmitFileComparator(
basedir.uri,
mockSkiaClient,
fakeSkiaClient,
fs: fs,
platform: platform,
);
......@@ -561,14 +554,14 @@ void main() {
group('Local', () {
FlutterLocalFileComparator comparator;
final MockSkiaGoldClient mockSkiaClient = MockSkiaGoldClient();
final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
setUp(() async {
final Directory basedir = fs.directory('flutter/test/library/')
..createSync(recursive: true);
comparator = FlutterLocalFileComparator(
basedir.uri,
mockSkiaClient,
fakeSkiaClient,
fs: fs,
platform: FakePlatform(
environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
......@@ -576,14 +569,11 @@ void main() {
),
);
when(mockSkiaClient.getExpectationForTest('flutter.golden_test.1'))
.thenAnswer((_) => Future<String>.value('55109a4bed52acc780530f7a9aeff6c0'));
when(mockSkiaClient.getExpectationForTest('flutter.new_golden_test.2'))
.thenAnswer((_) => Future<String>.value(''));
when(mockSkiaClient.getImageBytes('55109a4bed52acc780530f7a9aeff6c0'))
.thenAnswer((_) => Future<List<int>>.value(_kTestPngBytes));
when(mockSkiaClient.cleanTestName('library.flutter.golden_test.1.png'))
.thenReturn('flutter.golden_test.1');
const String hash = '55109a4bed52acc780530f7a9aeff6c0';
fakeSkiaClient.expectationForTestValues['flutter.golden_test.1'] = hash;
fakeSkiaClient.expectationForTestValues['flutter.new_golden_test.1'] = '';
fakeSkiaClient.imageBytesValues[hash] =_kTestPngBytes;
fakeSkiaClient.cleanTestNameValues['library.flutter.golden_test.1.png'] = 'flutter.golden_test.1';
});
test('passes when bytes match', () async {
......@@ -639,25 +629,25 @@ void main() {
});
test('returns FlutterSkippingGoldenFileComparator when network connection is unavailable', () async {
final MockDirectory mockDirectory = MockDirectory();
when(mockDirectory.existsSync()).thenReturn(true);
when(mockDirectory.uri).thenReturn(Uri.parse('/flutter'));
final FakeDirectory fakeDirectory = FakeDirectory();
fakeDirectory.existsSyncValue = true;
fakeDirectory.uri = Uri.parse('/flutter');
fakeSkiaClient.getExpectationForTestThrowable = const OSError("Can't reach Gold");
when(mockSkiaClient.getExpectationForTest(any))
.thenAnswer((_) => throw const OSError("Can't reach Gold"));
FlutterGoldenFileComparator comparator = await FlutterLocalFileComparator.fromDefaultComparator(
platform,
goldens: mockSkiaClient,
baseDirectory: mockDirectory,
goldens: fakeSkiaClient,
baseDirectory: fakeDirectory,
);
expect(comparator.runtimeType, FlutterSkippingFileComparator);
when(mockSkiaClient.getExpectationForTest(any))
.thenAnswer((_) => throw const SocketException("Can't reach Gold"));
fakeSkiaClient.getExpectationForTestThrowable = const SocketException("Can't reach Gold");
comparator = await FlutterLocalFileComparator.fromDefaultComparator(
platform,
goldens: mockSkiaClient,
baseDirectory: mockDirectory,
goldens: fakeSkiaClient,
baseDirectory: fakeDirectory,
);
expect(comparator.runtimeType, FlutterSkippingFileComparator);
});
......@@ -665,20 +655,130 @@ void main() {
});
}
class MockProcessManager extends Mock implements ProcessManager {}
@immutable
class RunInvocation {
const RunInvocation(this.command, this.workingDirectory);
final List<String> command;
final String workingDirectory;
@override
int get hashCode => hashValues(hashList(command), workingDirectory);
bool _commandEquals(List<String> other) {
if (other == command) {
return true;
}
if (other.length != command.length) {
return false;
}
for (int index = 0; index < other.length; index += 1) {
if (other[index] != command[index]) {
return false;
}
}
return true;
}
@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType) {
return false;
}
return other is RunInvocation
&& _commandEquals(other.command)
&& other.workingDirectory == workingDirectory;
}
class MockSkiaGoldClient extends Mock implements SkiaGoldClient {}
@override
String toString() => '$command ($workingDirectory)';
}
class MockLocalFileComparator extends Mock implements LocalFileComparator {}
class FakeProcessManager extends Fake implements ProcessManager {
Map<RunInvocation, ProcessResult> processResults = <RunInvocation, ProcessResult>{};
class MockDirectory extends Mock implements Directory {}
/// Used if [processResults] does not contain an matching invocation.
ProcessResult fallbackProcessResult;
class MockHttpClient extends Mock implements HttpClient {}
final List<String> workingDirectories = <String>[];
class MockHttpClientRequest extends Mock implements HttpClientRequest {}
@override
Future<ProcessResult> run(
List<dynamic> command, {
String workingDirectory,
Map<String, String> environment,
bool includeParentEnvironment = true,
bool runInShell = false,
Encoding stdoutEncoding = systemEncoding,
Encoding stderrEncoding = systemEncoding,
}) async {
workingDirectories.add(workingDirectory);
final ProcessResult result = processResults[RunInvocation(command.cast<String>(), workingDirectory)];
if (result == null && fallbackProcessResult == null) {
// Throwing here might gobble up the exception message if a test fails.
print('ProcessManager.run was called with $command ($workingDirectory) unexpectedly - $processResults.');
fail('see above');
}
return result ?? fallbackProcessResult;
}
}
class FakeSkiaGoldClient extends Fake implements SkiaGoldClient {
Map<String, String> expectationForTestValues = <String, String>{};
Object getExpectationForTestThrowable;
@override
Future<String> getExpectationForTest(String testName) async {
if (getExpectationForTestThrowable != null) {
throw getExpectationForTestThrowable;
}
return expectationForTestValues[testName];
}
Map<String, List<int>> imageBytesValues = <String, List<int>>{};
@override
Future<List<int>> getImageBytes(String imageHash) async => imageBytesValues[imageHash];
Map<String, String> cleanTestNameValues = <String, String>{};
@override
String cleanTestName(String fileName) => cleanTestNameValues[fileName];
}
class FakeLocalFileComparator extends Fake implements LocalFileComparator {
@override
Uri basedir;
}
class FakeDirectory extends Fake implements Directory {
bool existsSyncValue;
@override
bool existsSync() => existsSyncValue;
@override
Uri uri;
}
class FakeHttpClient extends Fake implements HttpClient {
Uri lastUri;
FakeHttpClientRequest request;
@override
Future<HttpClientRequest> getUrl(Uri url) async {
lastUri = url;
return request;
}
}
class FakeHttpClientRequest extends Fake implements HttpClientRequest {
FakeHttpImageResponse response;
@override
Future<HttpClientResponse> close() async {
return response;
}
}
class MockHttpClientResponse extends Mock implements HttpClientResponse {
MockHttpClientResponse(this.response);
class FakeHttpClientResponse extends Fake implements HttpClientResponse {
FakeHttpClientResponse(this.response);
final List<int> response;
......@@ -694,8 +794,8 @@ class MockHttpClientResponse extends Mock implements HttpClientResponse {
}
}
class MockHttpImageResponse extends Mock implements HttpClientResponse {
MockHttpImageResponse(this.response);
class FakeHttpImageResponse extends Fake implements HttpClientResponse {
FakeHttpImageResponse(this.response);
final List<List<int>> response;
......
......@@ -79,7 +79,8 @@ class SkiaGoldClient {
Future<void> auth() async {
if (await clientIsAuthorized())
return;
final List<String> authArguments = <String>[
final List<String> authCommand = <String>[
_goldctl,
'auth',
'--work-dir', workDirectory
.childDirectory('temp')
......@@ -87,10 +88,7 @@ class SkiaGoldClient {
'--luci',
];
final io.ProcessResult result = await io.Process.run(
_goldctl,
authArguments,
);
final io.ProcessResult result = await process.run(authCommand);
if (result.exitCode != 0) {
final StringBuffer buf = StringBuffer()
......@@ -118,7 +116,8 @@ class SkiaGoldClient {
await failures.create();
final String commitHash = await _getCurrentCommit();
final List<String> imgtestInitArguments = <String>[
final List<String> imgtestInitCommand = <String>[
_goldctl,
'imgtest', 'init',
'--instance', 'flutter',
'--work-dir', workDirectory
......@@ -130,19 +129,16 @@ class SkiaGoldClient {
'--passfail',
];
if (imgtestInitArguments.contains(null)) {
if (imgtestInitCommand.contains(null)) {
final StringBuffer buf = StringBuffer()
..writeln('A null argument was provided for Skia Gold imgtest init.')
..writeln('Please confirm the settings of your golden file test.')
..writeln('Arguments provided:');
imgtestInitArguments.forEach(buf.writeln);
imgtestInitCommand.forEach(buf.writeln);
throw Exception(buf.toString());
}
final io.ProcessResult result = await io.Process.run(
_goldctl,
imgtestInitArguments,
);
final io.ProcessResult result = await process.run(imgtestInitCommand);
if (result.exitCode != 0) {
final StringBuffer buf = StringBuffer()
......@@ -167,7 +163,8 @@ class SkiaGoldClient {
/// The [testName] and [goldenFile] parameters reference the current
/// comparison being evaluated by the [FlutterPostSubmitFileComparator].
Future<bool> imgtestAdd(String testName, File goldenFile) async {
final List<String> imgtestArguments = <String>[
final List<String> imgtestCommand = <String>[
_goldctl,
'imgtest', 'add',
'--work-dir', workDirectory
.childDirectory('temp')
......@@ -176,10 +173,7 @@ class SkiaGoldClient {
'--png-file', goldenFile.path,
];
final io.ProcessResult result = await io.Process.run(
_goldctl,
imgtestArguments,
);
final io.ProcessResult result = await process.run(imgtestCommand);
if (result.exitCode != 0) {
// We do not want to throw for non-zero exit codes here, as an intentional
......@@ -205,7 +199,8 @@ class SkiaGoldClient {
await failures.create();
final String commitHash = await _getCurrentCommit();
final List<String> imgtestInitArguments = <String>[
final List<String> imgtestInitCommand = <String>[
_goldctl,
'imgtest', 'init',
'--instance', 'flutter',
'--work-dir', workDirectory
......@@ -220,19 +215,16 @@ class SkiaGoldClient {
...getCIArguments(),
];
if (imgtestInitArguments.contains(null)) {
if (imgtestInitCommand.contains(null)) {
final StringBuffer buf = StringBuffer()
..writeln('A null argument was provided for Skia Gold tryjob init.')
..writeln('Please confirm the settings of your golden file test.')
..writeln('Arguments provided:');
imgtestInitArguments.forEach(buf.writeln);
imgtestInitCommand.forEach(buf.writeln);
throw Exception(buf.toString());
}
final io.ProcessResult result = await io.Process.run(
_goldctl,
imgtestInitArguments,
);
final io.ProcessResult result = await process.run(imgtestInitCommand);
if (result.exitCode != 0) {
final StringBuffer buf = StringBuffer()
......@@ -257,7 +249,8 @@ class SkiaGoldClient {
/// The [testName] and [goldenFile] parameters reference the current
/// comparison being evaluated by the [FlutterPreSubmitFileComparator].
Future<void> tryjobAdd(String testName, File goldenFile) async {
final List<String> imgtestArguments = <String>[
final List<String> imgtestCommand = <String>[
_goldctl,
'imgtest', 'add',
'--work-dir', workDirectory
.childDirectory('temp')
......@@ -266,10 +259,7 @@ class SkiaGoldClient {
'--png-file', goldenFile.path,
];
final io.ProcessResult result = await io.Process.run(
_goldctl,
imgtestArguments,
);
final io.ProcessResult result = await process.run(imgtestCommand);
final String/*!*/ resultStdout = result.stdout.toString();
if (result.exitCode != 0 &&
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment