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.