Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library message_extraction_test; | |
| 6 | |
| 7 import 'package:unittest/unittest.dart'; | |
| 8 import 'dart:io'; | |
| 9 import 'dart:async'; | |
| 10 import 'package:pathos/path.dart' as path; | |
| 11 import '../data_directory.dart'; | |
| 12 | |
| 13 final dart = new Options().executable; | |
| 14 | |
| 15 // TODO(alanknight): We have no way of knowing what the package-root is, | |
| 16 // so when we're running under the test framework, which sets the | |
| 17 // package-root, we use a horrible hack and infer it from the executable. | |
| 18 final packageDir = _findPackageDir(dart); | |
| 19 | |
| 20 /** | |
| 21 * Find our package directory from the executable. If we seem to be running | |
| 22 * from out/Release<arch>/dart or the equivalent Debug, then use the packages | |
| 23 * directory under Release<arch>. Otherwise return null, indicating to use | |
| 24 * the normal pub packages directory. | |
| 25 */ | |
| 26 String _findPackageDir(executable) { | |
| 27 var oneUp = path.dirname(executable); | |
| 28 var tail = path.basename(oneUp); | |
| 29 // If we're running from test.dart, we want e.g. out/ReleaseIA32/packages | |
| 30 if (tail.contains('Release') || tail.contains('Debug')) { | |
| 31 return path.join(oneUp, 'packages/'); | |
| 32 } | |
| 33 // Otherwise we will rely on the normal packages directory. | |
| 34 return null; | |
| 35 } | |
| 36 | |
| 37 /** If our package root directory is set, return it as a VM argument. */ | |
| 38 final vmArgs = (packageDir == null) ? [] : ['--package-root=$packageDir']; | |
| 39 | |
| 40 /** | |
| 41 * Translate a file path into this test directory, regardless of the | |
| 42 * working directory. | |
| 43 */ | |
| 44 String dir([String s]) => | |
| 45 path.join(intlDirectory, 'test', 'message_extraction', s); | |
| 46 | |
| 47 main() { | |
| 48 test("Test round trip message generation, printing, and ", () { | |
| 49 deleteGeneratedFiles(); | |
| 50 extractMessages(null) | |
| 51 .then(expectAsync1((result) => generateTranslationFiles(result) | |
|
Emily Fortuna
2013/03/14 19:45:00
a handy new feature for our unittesting library we
Alan Knight
2013/03/14 20:50:04
Nice.
| |
| 52 .then(expectAsync1((result) => generateCodeFromTranslation(result) | |
| 53 .then(expectAsync1((result) => runGeneratedCode(result) | |
| 54 .then(expectAsync1(verifyResult), | |
| 55 onError: print)), | |
| 56 onError: print)), | |
| 57 onError: print)), | |
| 58 onError: print); | |
| 59 }); | |
| 60 } | |
| 61 | |
| 62 void deleteGeneratedFiles() { | |
| 63 var files = [dir('intl_messages.json'), dir('translation_fr.json'), | |
| 64 dir('messages_fr.dart'), dir('message_de_DE.dart'), | |
| 65 dir('messages_all.dart')]; | |
| 66 files.map((name) => new File(name)).forEach((x) { | |
| 67 if (x.existsSync()) x.deleteSync();}); | |
| 68 } | |
| 69 | |
| 70 /** | |
| 71 * Run the process with the given list of filenames, which we assume | |
| 72 * are in dir() and need to be qualified in case that's not our working | |
| 73 * directory. | |
| 74 */ | |
| 75 Future<ProcessResult> run(ProcessResult previousResult, List<String> filenames) | |
| 76 { | |
| 77 // If there's a failure in one of the sub-programs, print its output. | |
| 78 if (previousResult != null) { | |
| 79 if (previousResult.exitCode != 0) { | |
| 80 print("Error running sub-program:"); | |
| 81 } | |
| 82 print(previousResult.stdout); | |
| 83 print(previousResult.stderr); | |
| 84 print("exitCode=${previousResult.exitCode}"); | |
| 85 } | |
| 86 var filesInTheRightDirectory = filenames.map((x) => dir(x)).toList(); | |
| 87 // Inject the script argument --output-dir in between the script and its | |
| 88 // arguments. | |
| 89 var args = [] | |
| 90 ..addAll(vmArgs) | |
| 91 ..add(filesInTheRightDirectory.first) | |
| 92 ..addAll(["--output-dir=${dir()}"]) | |
| 93 ..addAll(filesInTheRightDirectory.skip(1)); | |
| 94 var result = Process.run(dart, args); | |
| 95 return result; | |
| 96 } | |
| 97 | |
| 98 Future<ProcessResult> extractMessages(ProcessResult previousResult) => run( | |
| 99 previousResult, | |
| 100 ['extract_to_json.dart', 'sample_with_messages.dart', | |
| 101 'part_of_sample_with_messages.dart']); | |
| 102 | |
| 103 Future<ProcessResult> generateTranslationFiles(ProcessResult previousResult) => | |
| 104 run( | |
| 105 previousResult, | |
| 106 ['make_hardcoded_translation.dart', 'intl_messages.json']); | |
| 107 | |
| 108 Future<ProcessResult> generateCodeFromTranslation(ProcessResult previousResult) | |
| 109 => run( | |
| 110 previousResult, | |
| 111 ['generate_from_json.dart', 'sample_with_messages.dart', | |
| 112 'part_of_sample_with_messages.dart', 'translation_fr.json', | |
| 113 'translation_de_DE.json' ]); | |
| 114 | |
| 115 Future<ProcessResult> runGeneratedCode(ProcessResult previousResult) => | |
| 116 run(previousResult, ['sample_with_messages.dart']); | |
| 117 | |
| 118 void verifyResult(results) { | |
| 119 var lineIterator; | |
| 120 verify(String s) { | |
| 121 lineIterator.moveNext(); | |
| 122 var value = lineIterator.current; | |
| 123 expect(value, s); | |
| 124 } | |
| 125 | |
| 126 var output = results.stdout; | |
| 127 var lines = output.split("\n"); | |
| 128 lineIterator = lines.iterator..moveNext(); | |
| 129 verify("Printing messages for en_US"); | |
| 130 verify("This is a message"); | |
| 131 verify("Another message with parameter hello"); | |
| 132 verify("Characters that need escaping, e.g slashes \\ dollars \${ " | |
| 133 "(curly braces are ok) and xml reserved characters <& and " | |
| 134 "quotes \" parameters 1, 2, and 3"); | |
| 135 verify("This string extends across multiple lines."); | |
| 136 verify("1, b, [c, d]"); | |
| 137 verify('"So-called"'); | |
| 138 verify("Cette chaîne est toujours traduit"); | |
| 139 verify("Interpolation is tricky when it ends a sentence like this."); | |
| 140 verify("This comes from a method"); | |
| 141 verify("This method is not a lambda"); | |
| 142 verify("This comes from a static method"); | |
| 143 verify("This is missing some translations"); | |
| 144 verify("Ancient Greek hangman characters: 𐅆𐅇."); | |
| 145 // verify("The thing is, well"); | |
| 146 // verify("One of the tricky things is the plural form"); | |
| 147 // verify("One of the tricky things is plural forms"); | |
| 148 verify("Escapable characters here: "); | |
| 149 | |
| 150 var fr_lines = lines.skip(1).skipWhile( | |
| 151 (line) => !line.contains('----')).toList(); | |
| 152 lineIterator = fr_lines.iterator..moveNext(); | |
| 153 verify("Printing messages for fr"); | |
| 154 verify("Il s'agit d'un message"); | |
| 155 verify("Un autre message avec un seul paramètre hello"); | |
| 156 verify( | |
| 157 "Caractères qui doivent être échapper, par exemple barres \\ " | |
| 158 "dollars \${ (les accolades sont ok), et xml/html réservés <& et " | |
| 159 "des citations \" " | |
| 160 "avec quelques paramètres ainsi 1, 2, et 3"); | |
| 161 verify("Cette message prend plusiers lignes."); | |
| 162 verify("1, b, [c, d]"); | |
| 163 verify('"Soi-disant"'); | |
| 164 verify("Cette chaîne est toujours traduit"); | |
| 165 verify( | |
| 166 "L'interpolation est délicate quand elle se termine une " | |
| 167 "phrase comme this."); | |
| 168 verify("Cela vient d'une méthode"); | |
| 169 verify("Cette méthode n'est pas un lambda"); | |
| 170 verify("Cela vient d'une méthode statique"); | |
| 171 verify("Ce manque certaines traductions"); | |
| 172 verify("Anciens caractères grecs jeux du pendu: 𐅆𐅇."); | |
| 173 // verify("La chose est, well"); | |
| 174 // verify("Une des choses difficiles est la forme plurielle"); | |
| 175 // verify("Une des choses difficiles est les formes plurielles"); | |
| 176 verify("Escapes: "); | |
| 177 verify("\r\f\b\t\v."); | |
| 178 | |
| 179 | |
| 180 var de_lines = fr_lines.skip(1).skipWhile( | |
| 181 (line) => !line.contains('----')).toList(); | |
| 182 lineIterator = de_lines.iterator..moveNext(); | |
| 183 verify("Printing messages for de_DE"); | |
| 184 verify("Dies ist eine Nachricht"); | |
| 185 verify("Eine weitere Meldung mit dem Parameter hello"); | |
| 186 verify( | |
| 187 "Zeichen, die Flucht benötigen, zB Schrägstriche \\ Dollar " | |
| 188 "\${ (geschweiften Klammern sind ok) und xml reservierte Zeichen <& und " | |
| 189 "Zitate \" Parameter 1, 2 und 3"); | |
| 190 verify("Dieser String erstreckt sich über mehrere " | |
| 191 "Zeilen erstrecken."); | |
| 192 verify("1, b, [c, d]"); | |
| 193 verify('"Sogenannt"'); | |
| 194 // This is correct, the message is forced to French, even in a German locale. | |
| 195 verify("Cette chaîne est toujours traduit"); | |
| 196 verify( | |
| 197 "Interpolation ist schwierig, wenn es einen Satz wie dieser endet this."); | |
| 198 verify("Dies ergibt sich aus einer Methode"); | |
| 199 verify("Diese Methode ist nicht eine Lambda"); | |
| 200 verify("Dies ergibt sich aus einer statischen Methode"); | |
| 201 verify("This is missing some translations"); | |
| 202 verify("Antike griechische Galgenmännchen Zeichen: 𐅆𐅇"); | |
| 203 // verify("Die Sache ist, well"); | |
| 204 // expect("Einer der knifflige Dinge ist der Plural"); | |
| 205 // expect("Zu den kniffligen Dinge Pluralformen"); | |
| 206 verify("Escapes: "); | |
| 207 verify("\r\f\b\t\v."); | |
| 208 } | |
| OLD | NEW |