• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:async';
6import 'dart:io' as io;
7import 'dart:typed_data';
8
9import 'package:file/memory.dart';
10import 'package:flutter_test/flutter_test.dart' hide test;
11import 'package:flutter_test/flutter_test.dart' as test_package;
12
13const List<int> _kExpectedBytes = <int>[1, 2, 3];
14
15void main() {
16  MemoryFileSystem fs;
17
18  setUp(() {
19    final FileSystemStyle style = io.Platform.isWindows
20        ? FileSystemStyle.windows
21        : FileSystemStyle.posix;
22    fs = MemoryFileSystem(style: style);
23  });
24
25  /// Converts posix-style paths to the style associated with [fs].
26  ///
27  /// This allows us to deal in posix-style paths in the tests.
28  String fix(String path) {
29    if (path.startsWith('/')) {
30      path = '${fs.style.drive}$path';
31    }
32    return path.replaceAll('/', fs.path.separator);
33  }
34
35  void test(String description, FutureOr<void> body()) {
36    test_package.test(description, () {
37      return io.IOOverrides.runZoned<FutureOr<void>>(
38        body,
39        createDirectory: (String path) => fs.directory(path),
40        createFile: (String path) => fs.file(path),
41        createLink: (String path) => fs.link(path),
42        getCurrentDirectory: () => fs.currentDirectory,
43        setCurrentDirectory: (String path) => fs.currentDirectory = path,
44        getSystemTempDirectory: () => fs.systemTempDirectory,
45        stat: (String path) => fs.stat(path),
46        statSync: (String path) => fs.statSync(path),
47        fseIdentical: (String p1, String p2) => fs.identical(p1, p2),
48        fseIdenticalSync: (String p1, String p2) => fs.identicalSync(p1, p2),
49        fseGetType: (String path, bool followLinks) => fs.type(path, followLinks: followLinks),
50        fseGetTypeSync: (String path, bool followLinks) => fs.typeSync(path, followLinks: followLinks),
51        fsWatch: (String a, int b, bool c) => throw UnsupportedError('unsupported'),
52        fsWatchIsSupported: () => fs.isWatchSupported,
53      );
54    });
55  }
56
57  group('goldenFileComparator', () {
58    test('is initialized by test framework', () {
59      expect(goldenFileComparator, isNotNull);
60      expect(goldenFileComparator, isInstanceOf<LocalFileComparator>());
61      final LocalFileComparator comparator = goldenFileComparator;
62      expect(comparator.basedir.path, contains('flutter_test'));
63    });
64  });
65
66  group('LocalFileComparator', () {
67    LocalFileComparator comparator;
68
69    setUp(() {
70      comparator = LocalFileComparator(fs.file(fix('/golden_test.dart')).uri, pathStyle: fs.path.style);
71    });
72
73    test('calculates basedir correctly', () {
74      expect(comparator.basedir, fs.file(fix('/')).uri);
75      comparator = LocalFileComparator(fs.file(fix('/foo/bar/golden_test.dart')).uri, pathStyle: fs.path.style);
76      expect(comparator.basedir, fs.directory(fix('/foo/bar/')).uri);
77    });
78
79    test('can be instantiated with uri that represents file in same folder', () {
80      comparator = LocalFileComparator(Uri.parse('foo_test.dart'), pathStyle: fs.path.style);
81      expect(comparator.basedir, Uri.parse('./'));
82    });
83
84    group('compare', () {
85      Future<bool> doComparison([ String golden = 'golden.png' ]) {
86        final Uri uri = fs.file(fix(golden)).uri;
87        return comparator.compare(
88          Uint8List.fromList(_kExpectedBytes),
89          uri,
90        );
91      }
92
93      group('succeeds', () {
94        test('when golden file is in same folder as test', () async {
95          fs.file(fix('/golden.png')).writeAsBytesSync(_kExpectedBytes);
96          final bool success = await doComparison();
97          expect(success, isTrue);
98        });
99
100        test('when golden file is in subfolder of test', () async {
101          fs.file(fix('/sub/foo.png'))
102            ..createSync(recursive: true)
103            ..writeAsBytesSync(_kExpectedBytes);
104          final bool success = await doComparison('sub/foo.png');
105          expect(success, isTrue);
106        });
107
108        group('when comparator instantiated with uri that represents file in same folder', () {
109          test('and golden file is in same folder as test', () async {
110            fs.file(fix('/foo/bar/golden.png'))
111              ..createSync(recursive: true)
112              ..writeAsBytesSync(_kExpectedBytes);
113            fs.currentDirectory = fix('/foo/bar');
114            comparator = LocalFileComparator(Uri.parse('local_test.dart'), pathStyle: fs.path.style);
115            final bool success = await doComparison('golden.png');
116            expect(success, isTrue);
117          });
118
119          test('and golden file is in subfolder of test', () async {
120            fs.file(fix('/foo/bar/baz/golden.png'))
121              ..createSync(recursive: true)
122              ..writeAsBytesSync(_kExpectedBytes);
123            fs.currentDirectory = fix('/foo/bar');
124            comparator = LocalFileComparator(Uri.parse('local_test.dart'), pathStyle: fs.path.style);
125            final bool success = await doComparison('baz/golden.png');
126            expect(success, isTrue);
127          });
128        });
129      });
130
131      group('fails', () {
132        test('when golden file does not exist', () async {
133          final Future<bool> comparison = doComparison();
134          expect(comparison, throwsA(isInstanceOf<TestFailure>()));
135        });
136
137        test('when golden bytes are leading subset of image bytes', () async {
138          fs.file(fix('/golden.png')).writeAsBytesSync(<int>[1, 2]);
139          expect(await doComparison(), isFalse);
140        });
141
142        test('when golden bytes are leading superset of image bytes', () async {
143          fs.file(fix('/golden.png')).writeAsBytesSync(<int>[1, 2, 3, 4]);
144          expect(await doComparison(), isFalse);
145        });
146
147        test('when golden bytes are trailing subset of image bytes', () async {
148          fs.file(fix('/golden.png')).writeAsBytesSync(<int>[2, 3]);
149          expect(await doComparison(), isFalse);
150        });
151
152        test('when golden bytes are trailing superset of image bytes', () async {
153          fs.file(fix('/golden.png')).writeAsBytesSync(<int>[0, 1, 2, 3]);
154          expect(await doComparison(), isFalse);
155        });
156
157        test('when golden bytes are disjoint from image bytes', () async {
158          fs.file(fix('/golden.png')).writeAsBytesSync(<int>[4, 5, 6]);
159          expect(await doComparison(), isFalse);
160        });
161
162        test('when golden bytes are empty', () async {
163          fs.file(fix('/golden.png')).writeAsBytesSync(<int>[]);
164          expect(await doComparison(), isFalse);
165        });
166      });
167    });
168
169    group('update', () {
170      test('updates existing file', () async {
171        fs.file(fix('/golden.png')).writeAsBytesSync(_kExpectedBytes);
172        const List<int> newBytes = <int>[11, 12, 13];
173        await comparator.update(fs.file('golden.png').uri, Uint8List.fromList(newBytes));
174        expect(fs.file(fix('/golden.png')).readAsBytesSync(), newBytes);
175      });
176
177      test('creates non-existent file', () async {
178        expect(fs.file(fix('/foo.png')).existsSync(), isFalse);
179        const List<int> newBytes = <int>[11, 12, 13];
180        await comparator.update(fs.file('foo.png').uri, Uint8List.fromList(newBytes));
181        expect(fs.file(fix('/foo.png')).existsSync(), isTrue);
182        expect(fs.file(fix('/foo.png')).readAsBytesSync(), newBytes);
183      });
184    });
185
186    group('getTestUri', () {
187      test('updates file name with version number', () {
188        final Uri key = Uri.parse('foo.png');
189        final Uri key1 = comparator.getTestUri(key, 1);
190        expect(key1, Uri.parse('foo.1.png'));
191      });
192      test('does nothing for null version number', () {
193        final Uri key = Uri.parse('foo.png');
194        final Uri keyNull = comparator.getTestUri(key, null);
195        expect(keyNull, Uri.parse('foo.png'));
196      });
197    });
198  });
199}
200