blob: d22e1e3c77b275efb497ca4b5d886696ebafe28e [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library message_extraction_test;
import 'package:unittest/unittest.dart';
import 'dart:io';
import 'dart:async';
import 'dart:convert';
import 'package:path/path.dart' as path;
import '../data_directory.dart';
final dart = Platform.executable;
/// Should we use deferred loading.
bool useDeferredLoading = true;
String get _deferredLoadPrefix => useDeferredLoading ? '' : 'no-';
String get deferredLoadArg => '--${_deferredLoadPrefix}use-deferred-loading';
/// The VM arguments we were given, most important package-root.
final vmArgs = Platform.executableArguments;
/// For testing we move the files into a temporary directory so as not to leave
/// generated files around after a failed test. For debugging, we omit that
/// step if [useLocalDirectory] is true. The place we move them to is saved as
/// [tempDir].
String get tempDir => _tempDir == null ? _tempDir = _createTempDir() : _tempDir;
var _tempDir;
_createTempDir() => useLocalDirectory
? '.'
: Directory.systemTemp.createTempSync('message_extraction_test').path;
var useLocalDirectory = false;
/// Translate a relative file path into this test directory. This is
/// applied to all the arguments of [run]. It will ignore a string that
/// is an absolute path or begins with "--", because some of the arguments
/// might be command-line options.
String asTestDirPath([String s]) {
if (s == null || s.startsWith("--") || path.isAbsolute(s)) return s;
return path.join(intlDirectory, 'test', 'message_extraction', s);
}
/// Translate a relative file path into our temp directory. This is
/// applied to all the arguments of [run]. It will ignore a string that
/// is an absolute path or begins with "--", because some of the arguments
/// might be command-line options.
String asTempDirPath([String s]) {
if (s == null || s.startsWith("--") || path.isAbsolute(s)) return s;
return path.join(tempDir, s);
}
typedef ProcessResult ThenResult(ProcessResult _);
main(arguments) {
// If debugging, use --local to avoid copying everything to temporary
// directories to make it even harder to debug. Note that this will also
// not delete the generated files, so may require manual cleanup.
if (arguments.contains("--local")) {
print("Testing using local directory for generated files");
useLocalDirectory = true;
}
setUp(copyFilesToTempDirectory);
tearDown(deleteGeneratedFiles);
test("Test round trip message extraction, translation, code generation, "
"and printing", () {
var makeSureWeVerify = expectAsync(runAndVerify) as ThenResult;
return extractMessages(null).then((result) {
return generateTranslationFiles(result);
}).then((result) {
return generateCodeFromTranslation(result);
}).then(makeSureWeVerify).then(checkResult);
});
}
void copyFilesToTempDirectory() {
if (useLocalDirectory) return;
var files = [
asTestDirPath('sample_with_messages.dart'),
asTestDirPath('part_of_sample_with_messages.dart'),
asTestDirPath('verify_messages.dart'),
asTestDirPath('run_and_verify.dart'),
asTestDirPath('embedded_plural_text_before.dart'),
asTestDirPath('embedded_plural_text_after.dart'),
asTestDirPath('print_to_list.dart')
];
for (var filename in files) {
var file = new File(filename);
file.copySync(path.join(tempDir, path.basename(filename)));
}
}
void deleteGeneratedFiles() {
if (useLocalDirectory) return;
try {
new Directory(tempDir).deleteSync(recursive: true);
} on Error catch (e) {
print("Failed to delete $tempDir");
print("Exception:\n$e");
}
}
/// Run the process with the given list of filenames, which we assume
/// are in dir() and need to be qualified in case that's not our working
/// directory.
Future<ProcessResult> run(
ProcessResult previousResult, List<String> filenames) {
// If there's a failure in one of the sub-programs, print its output.
checkResult(previousResult);
var filesInTheRightDirectory = filenames
.map((x) => asTempDirPath(x))
.map((x) => path.normalize(x))
.toList();
// Inject the script argument --output-dir in between the script and its
// arguments.
List<String> args = []
..addAll(vmArgs)
..add(filesInTheRightDirectory.first)
..addAll(["--output-dir=$tempDir"])
..addAll(filesInTheRightDirectory.skip(1));
var result =
Process.run(dart, args, stdoutEncoding: UTF8, stderrEncoding: UTF8);
return result;
}
checkResult(ProcessResult previousResult) {
if (previousResult != null) {
if (previousResult.exitCode != 0) {
print("Error running sub-program:");
}
print(previousResult.stdout);
print(previousResult.stderr);
print("exitCode=${previousResult.exitCode}");
// Fail the test.
expect(previousResult.exitCode, 0);
}
}
Future<ProcessResult> extractMessages(ProcessResult previousResult) => run(
previousResult, [
asTestDirPath('../../bin/extract_to_arb.dart'),
'--suppress-warnings',
'sample_with_messages.dart',
'part_of_sample_with_messages.dart'
]);
Future<ProcessResult> generateTranslationFiles(ProcessResult previousResult) =>
run(previousResult, [
asTestDirPath('make_hardcoded_translation.dart'),
'intl_messages.arb'
]);
Future<ProcessResult> generateCodeFromTranslation(
ProcessResult previousResult) => run(previousResult, [
asTestDirPath('../../bin/generate_from_arb.dart'),
deferredLoadArg,
'--generated-file-prefix=foo_',
'sample_with_messages.dart',
'part_of_sample_with_messages.dart',
'translation_fr.arb',
'translation_de_DE.arb'
]);
Future<ProcessResult> runAndVerify(ProcessResult previousResult) =>
run(previousResult, [asTempDirPath('run_and_verify.dart')]);