Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
9e3e44ee
Commit
9e3e44ee
authored
Apr 19, 2019
by
Kate Lovett
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Committing test progress.
parent
4f29c310
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
154 additions
and
61 deletions
+154
-61
flutter_goldens.dart
packages/flutter_goldens/lib/flutter_goldens.dart
+5
-2
flutter_goldens_test.dart
packages/flutter_goldens/test/flutter_goldens_test.dart
+59
-51
client.dart
packages/flutter_goldens_client/lib/client.dart
+8
-8
matchers_test.dart
packages/flutter_test/test/matchers_test.dart
+82
-0
No files found.
packages/flutter_goldens/lib/flutter_goldens.dart
View file @
9e3e44ee
// Copyright 2018 The Chromium Authors. 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:async'
;
import
'dart:io'
;
import
'dart:typed_data'
;
...
...
@@ -13,7 +14,7 @@ import 'package:test_api/test_api.dart' as test_package show TestFailure;
import
'package:flutter_goldens_client/client.dart'
;
export
'package:flutter_goldens_client/client.dart'
;
//TODO(katelovett): Tests
[flutter_goldens_test.dart] and inline documentation
//TODO(katelovett): Tests
const
String
_kFlutterRootKey
=
'FLUTTER_ROOT'
;
/// Main method that can be used in a `flutter_test_config.dart` file to set
...
...
@@ -80,6 +81,9 @@ class FlutterGoldenFileComparator implements GoldenFileComparator {
Future
<
bool
>
compare
(
Uint8List
imageBytes
,
Uri
golden
)
async
{
final
bool
authorized
=
await
_skiaClient
.
auth
(
fs
.
directory
(
basedir
));
final
File
goldenFile
=
_getGoldenFile
(
golden
);
if
(!
goldenFile
.
existsSync
())
{
throw
test_package
.
TestFailure
(
'Could not be compared against non-existent file: "
$golden
"'
);
}
if
(!
authorized
)
throw
test_package
.
TestFailure
(
'Could not authorize golctl.'
);
...
...
@@ -96,5 +100,4 @@ class FlutterGoldenFileComparator implements GoldenFileComparator {
File
_getGoldenFile
(
Uri
uri
)
{
return
fs
.
directory
(
basedir
).
childFile
(
fs
.
file
(
uri
).
path
);
}
}
packages/flutter_goldens/test/flutter_goldens_test.dart
View file @
9e3e44ee
...
...
@@ -14,49 +14,44 @@ import 'package:platform/platform.dart';
import
'package:process/process.dart'
;
const
String
_kFlutterRoot
=
'/flutter'
;
const
String
_k
Repository
Root
=
'
$_kFlutterRoot
/bin/cache/pkg/goldens'
;
const
String
_kVersionFile
=
'
$_kFlutterRoot
/bin/internal/goldens.version'
;
const
String
_kGoldensVersion
=
'123456abcdef'
;
const
String
_k
Golden
Root
=
'
$_kFlutterRoot
/bin/cache/pkg/goldens'
;
//
const String _kVersionFile = '$_kFlutterRoot/bin/internal/goldens.version';
//
const String _kGoldensVersion = '123456abcdef';
void
main
(
)
{
MemoryFileSystem
fs
;
FakePlatform
platform
;
MockProcessManager
process
;
Directory
flutter
;
Directory
golden
;
setUp
(()
{
setUp
(()
async
{
fs
=
MemoryFileSystem
();
platform
=
FakePlatform
(
environment:
<
String
,
String
>{
'FLUTTER_ROOT'
:
_kFlutterRoot
});
process
=
MockProcessManager
();
f
s
.
directory
(
_kFlutterRoot
).
createSync
(
recursive:
true
);
fs
.
directory
(
_kRepositoryRoot
).
createSync
(
recursive:
true
);
fs
.
file
(
_kVersionFile
).
createSync
(
recursive:
true
);
fs
.
file
(
_kVersionFile
).
writeAsStringSync
(
_kGoldensVersion
);
f
lutter
=
await
fs
.
directory
(
_kFlutterRoot
).
create
(
recursive:
true
);
golden
=
await
fs
.
directory
(
_kGoldenRoot
).
create
(
recursive:
true
);
//
fs.file(_kVersionFile).createSync(recursive: true);
//
fs.file(_kVersionFile).writeAsStringSync(_kGoldensVersion);
});
group
(
'
Goldens
Client'
,
()
{
GoldensClient
goldens
;
group
(
'
SkiaGold
Client'
,
()
{
SkiaGoldClient
skiaGold
;
setUp
(()
{
goldens
=
Goldens
Client
(
skiaGold
=
SkiaGold
Client
(
fs:
fs
,
platform:
platform
,
process:
process
,
);
});
group
(
'prepare'
,
()
{
test
(
'performs minimal work if versions match'
,
()
async
{
when
(
process
.
run
(
any
,
workingDirectory:
anyNamed
(
'workingDirectory'
)))
.
thenAnswer
((
_
)
=>
Future
<
io
.
ProcessResult
>.
value
(
io
.
ProcessResult
(
123
,
0
,
_kGoldensVersion
,
''
)));
await
goldens
.
prepare
();
// Verify that we only spawned `git rev-parse HEAD`
final
VerificationResult
verifyProcessRun
=
verify
(
process
.
run
(
captureAny
,
workingDirectory:
captureAnyNamed
(
'workingDirectory'
)));
verifyProcessRun
.
called
(
1
);
expect
(
verifyProcessRun
.
captured
.
first
,
<
String
>[
'git'
,
'rev-parse'
,
'HEAD'
]);
expect
(
verifyProcessRun
.
captured
.
last
,
_kRepositoryRoot
);
});
group
(
'auth'
,
()
{
});
group
(
'imgtest'
,
()
{
});
});
...
...
@@ -74,45 +69,58 @@ void main() {
group
(
'fromDefaultComparator'
,
()
{
test
(
'calculates the basedir correctly'
,
()
async
{
final
MockGoldensClient
goldens
=
MockGoldens
Client
();
final
MockLocalFileComparator
defaultComparator
=
MockLocalFileComparator
();
final
Directory
flutterRoot
=
fs
.
directory
(
'/foo'
)..
createSync
(
recursive:
true
);
final
Directory
goldens
Root
=
flutterRoot
.
childDirectory
(
'bar'
)..
createSync
(
recursive:
true
);
when
(
goldens
.
fs
).
thenReturn
(
fs
);
when
(
goldens
.
flutterRoot
).
thenReturn
(
flutterRoot
);
when
(
goldens
.
repositoryRoot
).
thenReturn
(
goldens
Root
);
when
(
defaultComparator
.
basedir
).
thenReturn
(
flutterRoot
.
childDirectory
(
'baz'
).
uri
);
comparator
=
await
FlutterGoldenFileComparator
.
fromDefaultComparator
(
goldens:
goldens
,
defaultComparator:
defaultComparator
);
expect
(
comparator
.
basedir
,
fs
.
directory
(
'/foo/bar/baz'
).
uri
);
// final MockSkiaGoldClient skiaGold = MockSkiaGold
Client();
//
final MockLocalFileComparator defaultComparator = MockLocalFileComparator();
//
final Directory flutterRoot = fs.directory('/foo')..createSync(recursive: true);
// final Directory skiaGold
Root = flutterRoot.childDirectory('bar')..createSync(recursive: true);
// when(skiaGold
.fs).thenReturn(fs);
// when(skiaGold
.flutterRoot).thenReturn(flutterRoot);
// when(skiaGold.repositoryRoot).thenReturn(skiaGold
Root);
//
when(defaultComparator.basedir).thenReturn(flutterRoot.childDirectory('baz').uri);
//
comparator = await FlutterGoldenFileComparator.fromDefaultComparator(
//
goldens: goldens, defaultComparator: defaultComparator);
//
expect(comparator.basedir, fs.directory('/foo/bar/baz').uri);
});
});
group
(
'compare'
,
()
{
test
(
'throws if golden file is not found'
,
()
async
{
test
(
'throws if goldctl has not been authorized'
,
()
async
{
// Create file
final
File
goldenFile
=
fs
.
file
(
'/path/to/flutter/bin/cache/goldens/test/foo/bar/test.png'
)
..
createSync
(
recursive:
true
);
try
{
await
comparator
.
compare
(
Uint8List
.
fromList
(<
int
>[
1
,
2
,
3
]),
Uri
.
parse
(
'test.png'
));
fail
(
'TestFailure expected but not thrown'
);
}
on
TestFailure
catch
(
error
)
{
expect
(
error
.
message
,
contains
(
'Could not
be compared against non-existent file
'
));
expect
(
error
.
message
,
contains
(
'Could not
authorize goldctl.
'
));
}
});
test
(
'returns false if golden bytes do not match'
,
()
async
{
final
File
goldenFile
=
fs
.
file
(
'/path/to/flutter/bin/cache/goldens/test/foo/bar/test.png'
)
..
createSync
(
recursive:
true
);
goldenFile
.
writeAsBytesSync
(<
int
>[
4
,
5
,
6
],
flush:
true
);
final
bool
result
=
await
comparator
.
compare
(
Uint8List
.
fromList
(<
int
>[
1
,
2
,
3
]),
Uri
.
parse
(
'test.png'
));
expect
(
result
,
isFalse
);
test
(
'throws if golden file is not found'
,
()
async
{
try
{
await
comparator
.
compare
(
Uint8List
.
fromList
(<
int
>[
1
,
2
,
3
]),
Uri
.
parse
(
'test.png'
));
fail
(
'TestFailure expected but not thrown'
);
}
on
TestFailure
catch
(
error
)
{
expect
(
error
.
message
,
contains
(
'Could not be compared against non-existent file'
));
}
});
test
(
'returns true if golden bytes match'
,
()
async
{
final
File
goldenFile
=
fs
.
file
(
'/path/to/flutter/bin/cache/goldens/test/foo/bar/test.png'
)
..
createSync
(
recursive:
true
);
goldenFile
.
writeAsBytesSync
(<
int
>[
1
,
2
,
3
],
flush:
true
);
final
bool
result
=
await
comparator
.
compare
(
Uint8List
.
fromList
(<
int
>[
1
,
2
,
3
]),
Uri
.
parse
(
'test.png'
));
expect
(
result
,
isTrue
);
});
// test('returns false if skia gold test fails', () async {
// final File goldenFile = fs.file('/path/to/flutter/bin/cache/goldens/test/foo/bar/test.png')
// ..createSync(recursive: true);
// goldenFile.writeAsBytesSync(<int>[4, 5, 6], flush: true);
// final bool result = await comparator.compare(Uint8List.fromList(<int>[1, 2, 3]), Uri.parse('test.png'));
// expect(result, isFalse);
// });
// test('returns true if skia gold test passes', () async {
// final File goldenFile = fs.file('/path/to/flutter/bin/cache/goldens/test/foo/bar/test.png')
// ..createSync(recursive: true);
// goldenFile.writeAsBytesSync(<int>[1, 2, 3], flush: true);
// final bool result = await comparator.compare(Uint8List.fromList(<int>[1, 2, 3]), Uri.parse('test.png'));
// expect(result, isTrue);
// });
});
group
(
'update'
,
()
{
...
...
@@ -136,5 +144,5 @@ void main() {
}
class
MockProcessManager
extends
Mock
implements
ProcessManager
{}
class
Mock
GoldensClient
extends
Mock
implements
Goldens
Client
{}
class
Mock
SkiaGoldClient
extends
Mock
implements
SkiaGold
Client
{}
class
MockLocalFileComparator
extends
Mock
implements
LocalFileComparator
{}
packages/flutter_goldens_client/lib/client.dart
View file @
9e3e44ee
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//TODO(katelovett): Change to Skia Gold Client
import
'dart:async'
;
import
'dart:convert'
as
convert
;
import
'dart:io'
as
io
;
...
...
@@ -14,7 +14,7 @@ import 'package:process/process.dart';
// If you are here trying to figure out how to use golden files in the Flutter
// repo itself, consider reading this wiki page:
// https://github.com/flutter/flutter/wiki/Writing-a-golden-file-test-for-package%3Aflutter
//TODO(katelovett): Tests
[flutter_goldens_test.dart] and inline documentation
//TODO(katelovett): Tests
const
String
_kFlutterRootKey
=
'FLUTTER_ROOT'
;
const
String
_kGoldctlKey
=
'GOLDCTL'
;
const
String
_kServiceAccountKey
=
'GOLD_SERVICE_ACCOUNT'
;
...
...
@@ -31,7 +31,7 @@ class SkiaGoldClient {
/// The file system to use for storing local files for running imgtests.
///
/// This is useful
e
in tests, where a local file system (the default) can be
/// This is useful in tests, where a local file system (the default) can be
/// replaced by a memory file system.
final
FileSystem
fs
;
...
...
@@ -41,11 +41,11 @@ class SkiaGoldClient {
/// replaced by a mock platform instance.
final
Platform
platform
;
/// A controller for launching subprocesses.
/// A controller for launching sub
-
processes.
///
/// This is useful in tests, where the real process manager (the default) can
/// be replaced by a mock process manager that doesn't really create
/// subprocesses.
/// sub
-
processes.
final
ProcessManager
process
;
Directory
_workDirectory
;
...
...
@@ -70,7 +70,7 @@ class SkiaGoldClient {
/// The local [Directory] where the Flutter repository is hosted.
///
/// Uses the [fs] file system.
Directory
get
_
flutterRoot
=>
fs
.
directory
(
platform
.
environment
[
_kFlutterRootKey
]);
Directory
get
flutterRoot
=>
fs
.
directory
(
platform
.
environment
[
_kFlutterRootKey
]);
/// Prepares the local work space for golden file testing and initializes the
/// goldctl authorization for executing tests.
...
...
@@ -145,12 +145,12 @@ class SkiaGoldClient {
}
Future
<
String
>
_getCommitHash
()
async
{
if
(!
_
flutterRoot
.
existsSync
())
{
if
(!
flutterRoot
.
existsSync
())
{
return
null
;
}
else
{
final
io
.
ProcessResult
revParse
=
await
process
.
run
(
<
String
>[
'git'
,
'rev-parse'
,
'HEAD'
],
workingDirectory:
_
flutterRoot
.
path
,
workingDirectory:
flutterRoot
.
path
,
);
return
revParse
.
exitCode
==
0
?
revParse
.
stdout
.
trim
()
:
null
;
}
...
...
packages/flutter_test/test/matchers_test.dart
View file @
9e3e44ee
...
...
@@ -384,6 +384,88 @@ void main() {
});
});
group
(
'matchesSkiaGoldFile'
,
()
{
_FakeComparator
comparator
;
Widget
boilerplate
(
Widget
child
)
{
return
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
child
,
);
}
setUp
(()
{
comparator
=
_FakeComparator
();
goldenFileComparator
=
comparator
;
});
group
(
'matches'
,
()
{
testWidgets
(
'if comparator succeeds'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
boilerplate
(
const
Text
(
'hello'
)));
final
Finder
finder
=
find
.
byType
(
Text
);
await
expectLater
(
finder
,
matchesSkiaGoldFile
(
'foo.png'
));
expect
(
comparator
.
invocation
,
_ComparatorInvocation
.
compare
);
expect
(
comparator
.
imageBytes
,
null
);
expect
(
comparator
.
golden
,
Uri
.
parse
(
'foo.png'
));
});
});
group
(
'does not match'
,
()
{
testWidgets
(
'if comparator returns false'
,
(
WidgetTester
tester
)
async
{
comparator
.
behavior
=
_ComparatorBehavior
.
returnFalse
;
await
tester
.
pumpWidget
(
boilerplate
(
const
Text
(
'hello'
)));
final
Finder
finder
=
find
.
byType
(
Text
);
try
{
await
expectLater
(
finder
,
matchesSkiaGoldFile
(
'foo.png'
));
fail
(
'TestFailure expected but not thrown'
);
}
on
TestFailure
catch
(
error
)
{
expect
(
comparator
.
invocation
,
_ComparatorInvocation
.
compare
);
expect
(
error
.
message
,
contains
(
'does not match'
));
}
});
testWidgets
(
'if comparator throws'
,
(
WidgetTester
tester
)
async
{
comparator
.
behavior
=
_ComparatorBehavior
.
throwTestFailure
;
await
tester
.
pumpWidget
(
boilerplate
(
const
Text
(
'hello'
)));
final
Finder
finder
=
find
.
byType
(
Text
);
try
{
await
expectLater
(
finder
,
matchesSkiaGoldFile
(
'foo.png'
));
fail
(
'TestFailure expected but not thrown'
);
}
on
TestFailure
catch
(
error
)
{
expect
(
comparator
.
invocation
,
_ComparatorInvocation
.
compare
);
expect
(
error
.
message
,
contains
(
'fake message'
));
}
});
testWidgets
(
'if finder finds no widgets'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
boilerplate
(
Container
()));
final
Finder
finder
=
find
.
byType
(
Text
);
try
{
await
expectLater
(
finder
,
matchesSkiaGoldFile
(
'foo.png'
));
fail
(
'TestFailure expected but not thrown'
);
}
on
TestFailure
catch
(
error
)
{
expect
(
comparator
.
invocation
,
isNull
);
expect
(
error
.
message
,
contains
(
'no widget was found'
));
}
});
testWidgets
(
'if finder finds multiple widgets'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
boilerplate
(
Column
(
children:
const
<
Widget
>[
Text
(
'hello'
),
Text
(
'world'
)],
)));
final
Finder
finder
=
find
.
byType
(
Text
);
try
{
await
expectLater
(
finder
,
matchesSkiaGoldFile
(
'foo.png'
));
fail
(
'TestFailure expected but not thrown'
);
}
on
TestFailure
catch
(
error
)
{
expect
(
comparator
.
invocation
,
isNull
);
expect
(
error
.
message
,
contains
(
'too many widgets'
));
}
});
});
});
group
(
'matchesSemanticsData'
,
()
{
testWidgets
(
'matches SemanticsData'
,
(
WidgetTester
tester
)
async
{
final
SemanticsHandle
handle
=
tester
.
ensureSemantics
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment