|
| 1 | +#!/usr/bin/env dart |
| 2 | +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 3 | +// for details. All rights reserved. Use of this source code is governed by a |
| 4 | +// BSD-style license that can be found in the LICENSE file. |
| 5 | + |
| 6 | +// testing ../../../tools/addlatexhash.dart |
| 7 | + |
| 8 | +import 'dart:io'; |
| 9 | +import 'package:path/path.dart' as path; |
| 10 | +import '../../../tools/addlatexhash.dart'; |
| 11 | + |
| 12 | +final execDir = path.dirname(Platform.resolvedExecutable); |
| 13 | +final dartRootDir = path.dirname(path.dirname(execDir)); |
| 14 | +final dartRootPath = dartRootDir.toString(); |
| 15 | + |
| 16 | +List<String> packageOptions() { |
| 17 | + if (Platform.packageRoot != null) { |
| 18 | + return <String>['--package-root=${Platform.packageRoot}']; |
| 19 | + } else if (Platform.packageConfig != null) { |
| 20 | + return <String>['--packages=${Platform.packageConfig}']; |
| 21 | + } else { |
| 22 | + return <String>[]; |
| 23 | + } |
| 24 | +} |
| 25 | + |
| 26 | +// Check that the given ProcessResult indicates success; if so |
| 27 | +// return the standard output, otherwise report the failure |
| 28 | +checkAction(result, errorMessage) { |
| 29 | + if (result.exitCode != 0) { |
| 30 | + print(result.stdout); |
| 31 | + print(result.stderr); |
| 32 | + throw errorMessage; |
| 33 | + } |
| 34 | + return result.stdout; |
| 35 | +} |
| 36 | + |
| 37 | +oneTestCutMatch(line, re, expected) { |
| 38 | + var result = cutMatch(line, new RegExp(re).firstMatch(line)); |
| 39 | + if (result != expected) { |
| 40 | + throw "cutMatch '$re' from '$line' yields '$result' != '$expected'"; |
| 41 | + } |
| 42 | +} |
| 43 | + |
| 44 | +void testCutMatch() { |
| 45 | + oneTestCutMatch("test", "", "test"); |
| 46 | + oneTestCutMatch("test", "e", "tst"); |
| 47 | + oneTestCutMatch("test", "te", "st"); |
| 48 | + oneTestCutMatch("test", "st", "te"); |
| 49 | + oneTestCutMatch("test", "test", ""); |
| 50 | +} |
| 51 | + |
| 52 | +oneTestSisp(sispFun, nameSuffix, line, expected) { |
| 53 | + var result = sispFun(line); |
| 54 | + if (result != expected) { |
| 55 | + throw "sispIsDart$nameSuffix '$line' yields $result"; |
| 56 | + } |
| 57 | +} |
| 58 | + |
| 59 | +testSisp() { |
| 60 | + oneTestSisp(sispIsDartBegin, "Begin", "\\begin{dartCode}\n", true); |
| 61 | + oneTestSisp(sispIsDartBegin, "Begin", " \\begin{dartCode}\n", true); |
| 62 | + oneTestSisp(sispIsDartBegin, "Begin", "whatever else ..", false); |
| 63 | + oneTestSisp(sispIsDartEnd, "End", "\\end{dartCode}", true); |
| 64 | + oneTestSisp(sispIsDartEnd, "End", " \\end{dartCode}\t \n", true); |
| 65 | + oneTestSisp(sispIsDartEnd, "End", "whatever else ..", false); |
| 66 | +} |
| 67 | + |
| 68 | +// Check that the hash values of paragraphs in the specially prepared |
| 69 | +// LaTeX source 'addlatexhash_test_src.tex' are identical in groups |
| 70 | +// of eight (so we get 8 identical hash values, then another hash |
| 71 | +// value 8 times, etc.) |
| 72 | +testSameHash(String tmpDirPath) { |
| 73 | + // file names/paths for file containing groups of 8 variants of a paragraph |
| 74 | + const par8timesName = "addlatexhash_test_src"; |
| 75 | + const par8timesFileName = "$par8timesName.tex"; |
| 76 | + final par8timesDirPath = |
| 77 | + path.join(dartRootDir, "tests", "standalone_2", "io"); |
| 78 | + final par8timesPath = path.join(par8timesDirPath, par8timesFileName); |
| 79 | + final tmpPar8timesPath = path.join(tmpDirPath, par8timesFileName); |
| 80 | + |
| 81 | + // file names paths for output |
| 82 | + final hashName = par8timesName + "-hash"; |
| 83 | + final hashFileName = "$hashName.tex"; |
| 84 | + final hashPath = path.join(tmpDirPath, hashFileName); |
| 85 | + final listName = par8timesName + "-list"; |
| 86 | + final listFileName = "$listName.txt"; |
| 87 | + final listPath = path.join(tmpDirPath, listFileName); |
| 88 | + |
| 89 | + // dart executable |
| 90 | + final dartExecutable = Platform.executable; |
| 91 | + if (dartExecutable == "") throw "dart executable not available"; |
| 92 | + |
| 93 | + // actions to take |
| 94 | + runAddHash() { |
| 95 | + var args = <String>[]..addAll(Platform.executableArguments); |
| 96 | + args.addAll([ |
| 97 | + path.join(dartRootPath, "tools", "addlatexhash.dart"), |
| 98 | + tmpPar8timesPath, |
| 99 | + hashPath, |
| 100 | + listPath |
| 101 | + ]); |
| 102 | + return Process.runSync(dartExecutable, args); |
| 103 | + } |
| 104 | + |
| 105 | + // perform test |
| 106 | + new File(par8timesPath).copySync(tmpPar8timesPath); |
| 107 | + checkAction(runAddHash(), "addlatexhash.dart failed"); |
| 108 | + var listFile = new File(listPath); |
| 109 | + var listLines = listFile.readAsLinesSync(); |
| 110 | + var latestLine = null; |
| 111 | + var sameCount = 0; |
| 112 | + for (var line in listLines) { |
| 113 | + if (!line.startsWith(" ")) continue; // section marker |
| 114 | + if (line.startsWith(" %")) continue; // transformed text "comment" |
| 115 | + if (line != latestLine) { |
| 116 | + // new hash, check for number of equal hashes, then reset |
| 117 | + if (sameCount % 8 == 0) { |
| 118 | + // saw zero or more blocks of 8 identical hash values: OK |
| 119 | + latestLine = line; |
| 120 | + sameCount = 1; |
| 121 | + } else { |
| 122 | + throw "normalization failed to produce same result"; |
| 123 | + } |
| 124 | + } else { |
| 125 | + sameCount++; |
| 126 | + } |
| 127 | + } |
| 128 | +} |
| 129 | + |
| 130 | +// Check that the LaTeX source transformation done by addlatexhash.dart |
| 131 | +// does not affect the generated output, as seen via dvi2tty and diff. |
| 132 | +// NB: Not part of normal testing (only local): latex and dvi2tty are |
| 133 | +// not installed in the standard test environment. |
| 134 | +testSameDVI(String tmpDirPath) { |
| 135 | + // file names/paths for original spec |
| 136 | + const specName = "dartLangSpec"; |
| 137 | + const specFileName = "$specName.tex"; |
| 138 | + final specDirPath = path.join(dartRootDir, "docs", "language"); |
| 139 | + final specPath = path.join(specDirPath, specFileName); |
| 140 | + final tmpSpecPath = path.join(tmpDirPath, specFileName); |
| 141 | + const specDviFileName = "$specName.dvi"; |
| 142 | + final specDviPath = path.join(tmpDirPath, specDviFileName); |
| 143 | + |
| 144 | + // file names/paths for associated sty |
| 145 | + const styFileName = "dart.sty"; |
| 146 | + final styPath = path.join(specDirPath, styFileName); |
| 147 | + final tmpStyPath = path.join(tmpDirPath, styFileName); |
| 148 | + |
| 149 | + // file names paths for output |
| 150 | + const hashName = "dartLangSpec-hash"; |
| 151 | + const hashFileName = "$hashName.tex"; |
| 152 | + final hashPath = path.join(tmpDirPath, hashFileName); |
| 153 | + final hashDviPath = path.join(tmpDirPath, "$hashName.dvi"); |
| 154 | + |
| 155 | + final listName = "$specName-list"; |
| 156 | + final listFileName = "$listName.txt"; |
| 157 | + final listPath = path.join(tmpDirPath, listFileName); |
| 158 | + |
| 159 | + // dart executable |
| 160 | + final dartExecutable = Platform.executable; |
| 161 | + if (dartExecutable == "") throw "dart executable not available"; |
| 162 | + |
| 163 | + // actions to take; rely on having latex and dvi2tty in PATH |
| 164 | + runLatex(fileName, workingDirectory) => |
| 165 | + Process.runSync("latex", [fileName], workingDirectory: workingDirectory); |
| 166 | + |
| 167 | + runAddHash() { |
| 168 | + var args = packageOptions(); |
| 169 | + args.addAll([ |
| 170 | + path.join(dartRootPath, "tools", "addlatexhash.dart"), |
| 171 | + tmpSpecPath, |
| 172 | + hashPath, |
| 173 | + listPath |
| 174 | + ]); |
| 175 | + return Process.runSync(dartExecutable, args); |
| 176 | + } |
| 177 | + |
| 178 | + runDvi2tty(dviFile) => |
| 179 | + Process.runSync("dvi2tty", [dviFile], workingDirectory: tmpDirPath); |
| 180 | + |
| 181 | + chkDvi2tty(file, subject) => |
| 182 | + checkAction(runDvi2tty(file), "dvitty on $subject failed"); |
| 183 | + |
| 184 | + // perform test |
| 185 | + var renewLMHashCmd = r"\renewcommand{\LMHash}[1]{\OriginalLMHash{xxxx}}"; |
| 186 | + new File(styPath) |
| 187 | + .copySync(tmpStyPath) |
| 188 | + .writeAsStringSync(renewLMHashCmd, mode: FileMode.append); |
| 189 | + new File(specPath).copySync(tmpSpecPath); |
| 190 | + |
| 191 | + checkAction(runAddHash(), "addlatexhash.dart failed"); |
| 192 | + for (var i = 0; i < 5; i++) { |
| 193 | + checkAction(runLatex(specName, tmpDirPath), "LaTeX on spec failed"); |
| 194 | + } |
| 195 | + for (var i = 0; i < 5; i++) { |
| 196 | + checkAction(runLatex(hashFileName, tmpDirPath), "LaTeX on output failed"); |
| 197 | + } |
| 198 | + if (chkDvi2tty(specDviPath, "spec") != chkDvi2tty(hashDviPath, "output")) { |
| 199 | + throw "dvi2tty spec != dvitty output"; |
| 200 | + } |
| 201 | +} |
| 202 | + |
| 203 | +runWithTempDir(void test(String tempDir)) { |
| 204 | + final tempDir = Directory.systemTemp.createTempSync("addlatexhash_test"); |
| 205 | + try { |
| 206 | + test(tempDir.path); |
| 207 | + } finally { |
| 208 | + tempDir.delete(recursive: true); |
| 209 | + } |
| 210 | +} |
| 211 | + |
| 212 | +main([args]) { |
| 213 | + testCutMatch(); |
| 214 | + testSisp(); |
| 215 | + |
| 216 | + runWithTempDir(testSameHash); |
| 217 | + // latex and dvi2tty are not installed in the standard test environment |
| 218 | + if (args.length > 0 && args[0] == "local") { |
| 219 | + runWithTempDir(testSameDVI); |
| 220 | + } |
| 221 | +} |
0 commit comments