Allow malformed UTF-8. (dart-lang/test_descriptor#3)
diff --git a/pkgs/test_descriptor/CHANGELOG.md b/pkgs/test_descriptor/CHANGELOG.md
index 5b26ad3..77b3561 100644
--- a/pkgs/test_descriptor/CHANGELOG.md
+++ b/pkgs/test_descriptor/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.1
+
+* `FileDescriptor.validate()` now allows invalid UTF-8 files.
+
## 1.0.0
* Initial version.
diff --git a/pkgs/test_descriptor/lib/src/file_descriptor.dart b/pkgs/test_descriptor/lib/src/file_descriptor.dart
index d648894..e10c2c6 100644
--- a/pkgs/test_descriptor/lib/src/file_descriptor.dart
+++ b/pkgs/test_descriptor/lib/src/file_descriptor.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
-import 'dart:convert';
import 'dart:io';
import 'dart:math' as math;
@@ -87,7 +86,7 @@
/// Reads and decodes the contents of this descriptor as a UTF-8 string.
///
/// This isn't supported for matcher descriptors.
- Future<String> read() => UTF8.decodeStream(readAsBytes());
+ Future<String> read() => utf8.decodeStream(readAsBytes());
/// Reads the contents of this descriptor as a byte stream.
///
@@ -121,10 +120,10 @@
Future<String> read() async => _contents;
Stream<List<int>> readAsBytes() =>
- new Stream.fromIterable([UTF8.encode(_contents)]);
+ new Stream.fromIterable([utf8.encode(_contents)]);
Future _validate(String prettyPath, List<int> actualContents) {
- var actualContentsText = UTF8.decode(actualContents);
+ var actualContentsText = utf8.decode(actualContents);
if (_contents == actualContentsText) return null;
throw fail(_textMismatchMessage(prettyPath, _contents, actualContentsText));
}
@@ -184,7 +183,7 @@
void _validate(String prettyPath, List<int> actualContents) {
try {
expect(
- _isBinary ? actualContents : UTF8.decode(actualContents),
+ _isBinary ? actualContents : utf8.decode(actualContents),
_matcher);
} on TestFailure catch (error) {
throw new TestFailure(
diff --git a/pkgs/test_descriptor/lib/src/utils.dart b/pkgs/test_descriptor/lib/src/utils.dart
index 385f4de..bd2d78c 100644
--- a/pkgs/test_descriptor/lib/src/utils.dart
+++ b/pkgs/test_descriptor/lib/src/utils.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'dart:convert';
import 'package:path/path.dart' as p;
import 'package:term_glyph/term_glyph.dart' as glyph;
@@ -10,6 +11,9 @@
import 'sandbox.dart';
+/// A UTF-8 codec that allows malformed byte sequences.
+final utf8 = const Utf8Codec(allowMalformed: true);
+
/// Prepends a vertical bar to [text].
String addBar(String text) => prefixLines(text, "${glyph.verticalLine} ",
first: "${glyph.downEnd} ",
diff --git a/pkgs/test_descriptor/test/file_test.dart b/pkgs/test_descriptor/test/file_test.dart
index 08da999..4cdc184 100644
--- a/pkgs/test_descriptor/test/file_test.dart
+++ b/pkgs/test_descriptor/test/file_test.dart
@@ -66,6 +66,11 @@
.validate();
});
+ test('succeeds if invalid UTF-8 matches a text matcher', () async {
+ await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0xC3, 0x28]);
+ await d.file('name.txt', isNot(isEmpty)).validate();
+ });
+
test("fails if the text contents don't match", () async {
await new File(p.join(d.sandbox, 'name.txt')).writeAsString('wrong');
@@ -99,6 +104,14 @@
'Invalid contents for file "name.txt":'))));
});
+ test("fails if invalid UTF-8 doesn't match a text matcher", () async {
+ await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0xC3, 0x28]);
+ expect(d.file('name.txt', isEmpty).validate(), throwsA(toString(allOf([
+ startsWith('Invalid contents for file "name.txt":'),
+ contains('�')
+ ]))));
+ });
+
test("fails if there's no file", () {
expect(d.file('name.txt', 'contents').validate(),
throwsA(toString(equals('File not found: "name.txt".'))));
diff --git a/pkgs/test_descriptor/test/utils.dart b/pkgs/test_descriptor/test/utils.dart
index d58f7ba..d6359f1 100644
--- a/pkgs/test_descriptor/test/utils.dart
+++ b/pkgs/test_descriptor/test/utils.dart
@@ -4,7 +4,6 @@
import 'dart:async';
-import 'package:test_descriptor/test_descriptor.dart' as d;
import 'package:test/test.dart';
/// Converts a [Stream<List<int>>] to a flat byte future.