Skip to content

Commit

Permalink
Determine encoding of source files used for coverage (#1691)
Browse files Browse the repository at this point in the history
Restore behavior that used to come from `package:http`,
check the headers to choose an encoding.
  • Loading branch information
jayudey-wf committed Apr 20, 2022
1 parent af8a9b2 commit d54846b
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
5 changes: 5 additions & 0 deletions pkgs/test/CHANGELOG.md
@@ -1,3 +1,8 @@
## 1.21.1

* Fix a bug loading JS sources with non-utf8 content while parsing coverage
information from chrome.

## 1.21.0

* Allow analyzer version `4.x`.
Expand Down
14 changes: 13 additions & 1 deletion pkgs/test/lib/src/runner/browser/chrome.dart
Expand Up @@ -194,11 +194,23 @@ Future<WipConnection> _connect(
}

extension on HttpClient {
Encoding determineEncoding(HttpHeaders headers) {
final contentType = headers.contentType?.charset;

/// Using the `charset` property of the `contentType` if available.
/// If it's unavailable or if the encoding name is unknown, [latin1] is used by default,
/// as per [RFC 2616][].
///
/// [RFC 2616]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html
return Encoding.getByName(contentType) ?? latin1;
}

Future<String?> getString(String url) async {
final request = await getUrl(Uri.parse(url));
final response = await request.close();
if (response.statusCode != HttpStatus.ok) return null;
var bytes = [await for (var chunk in response) ...chunk];
return utf8.decode(bytes);
final encoding = determineEncoding(response.headers);
return encoding.decode(bytes);
}
}
2 changes: 1 addition & 1 deletion pkgs/test/pubspec.yaml
@@ -1,5 +1,5 @@
name: test
version: 1.21.0
version: 1.21.1
description: >-
A full featured library for writing and running Dart tests across platforms.
repository: https://github.com/dart-lang/test/tree/master/pkgs/test
Expand Down
65 changes: 65 additions & 0 deletions pkgs/test/test/runner/coverage_test.dart
Expand Up @@ -62,5 +62,70 @@ void main() {
['--coverage', coverageDirectory.path, 'test.dart', '-p', 'chrome']);
await _validateCoverage(test, 'test.dart.chrome.json');
});

test(
'gathers coverage for Chrome tests when JS files contain unicode characters',
() async {
final sourceMapFileContent =
'{"version":3,"file":"","sources":[],"names":[],"mappings":""}';
final jsContent = '''
(function() {
'© '
window.foo = function foo() {
return 'foo';
};
})({
'© ': ''
});
''';
await d.file('file_with_unicode.js', jsContent).create();
await d.file('file_with_unicode.js.map', sourceMapFileContent).create();

await d.file('js_with_unicode_test.dart', '''
import 'dart:html';
import 'dart:js';
import 'package:test/test.dart';
Future<void> loadScript(String src) async {
final script = ScriptElement()..src = src;
final scriptLoaded = script.onLoad.first;
document.body!.append(script);
await scriptLoaded.timeout(Duration(seconds: 1));
}
void main() {
test("test 1", () async {
await loadScript('file_with_unicode.js');
expect(context['foo'], isNotNull);
context.callMethod('foo', []);
expect(true, isTrue);
});
}
''').create();

final jsBytes = utf8.encode(jsContent);
final jsLatin1 = latin1.decode(jsBytes);
final jsUtf8 = utf8.decode(jsBytes);
expect(jsLatin1, isNot(jsUtf8),
reason: 'test setup: should have decoded differently');

const functionPattern = 'function foo';
expect([jsLatin1, jsUtf8], everyElement(contains(functionPattern)));
expect(jsLatin1.indexOf(functionPattern),
isNot(jsUtf8.indexOf(functionPattern)),
reason:
'test setup: decoding should have shifted the position of the function');

var test = await runTest([
'--coverage',
coverageDirectory.path,
'js_with_unicode_test.dart',
'-p',
'chrome'
]);
await _validateCoverage(test, 'js_with_unicode_test.dart.chrome.json');
});
});
}

0 comments on commit d54846b

Please sign in to comment.