1// @allowUnreachableCode: true 2// @module: commonjs 3 4//import FileManager = require('filemanager'); 5//import App = require('app'); 6 7declare var FileManager: any; 8declare var App: any; 9 10var TestFileDir = ".\\TempTestFiles"; 11 12export class TestCase { 13 constructor (public name: string, public test: ()=>boolean, public errorMessageRegEx?: string) { 14 } 15} 16export class TestRunner { 17 private tests: TestCase[] = []; 18 19 static arrayCompare(arg1: any[], arg2: any[]): boolean { 20 return (arg1.every(function (val, index) { return val === arg2[index] })); 21 } 22 23 public addTest(test: TestCase) { 24 this.tests.push(test); 25 } 26 public run() { 27 var success = true; 28 for (var test in this.tests) { 29 var exception = false; 30 var testcase = <TestCase>this.tests[test] 31 var testResult: boolean = false; 32 try { 33 testResult = testcase.test(); 34 } 35 catch (e) { 36 exception = true; 37 testResult = false; 38 if (typeof testcase.errorMessageRegEx === "string") { 39 if (testcase.errorMessageRegEx === "") { // Any error is fine 40 testResult = true; 41 } else if (e.message) { 42 var regex = new RegExp(testcase.errorMessageRegEx); 43 testResult = regex.test(e.message); 44 } 45 } 46 if (testResult === false) { 47 //console.log(e.message); 48 } 49 } 50 if ((testcase.errorMessageRegEx !== undefined) && !exception) { 51 success = false; 52 } else if (!testResult) { 53 success = false; 54 } 55 } 56 if (success) { 57 } else { 58 } 59 } 60} 61 62export var tests: TestRunner = (function () { 63 var testRunner = new TestRunner(); 64 // First 3 are for simple harness validation 65 testRunner.addTest(new TestCase("Basic test", function () { return true; })); 66 testRunner.addTest(new TestCase("Test for any error", function () { throw new Error(); return false; }, "")); 67 testRunner.addTest(new TestCase("Test RegEx error message match", function () { throw new Error("Should also pass"); return false; }, "Should [also]+ pass")); 68 testRunner.addTest(new TestCase("Test array compare true", function () { return TestRunner.arrayCompare([1, 2, 3], [1, 2, 3]); })); 69 testRunner.addTest(new TestCase("Test array compare false", function () { return !TestRunner.arrayCompare([3, 2, 3], [1, 2, 3]); })); 70 71 // File detection tests 72 testRunner.addTest(new TestCase("Check file exists", 73 function () { 74 return FileManager.DirectoryManager.fileExists(TestFileDir + "\\Test.txt"); 75 })); 76 testRunner.addTest(new TestCase("Check file doesn't exist", 77 function () { 78 return !FileManager.DirectoryManager.fileExists(TestFileDir + "\\Test2.txt"); 79 })); 80 81 // File pattern matching tests 82 testRunner.addTest(new TestCase("Check text file match", 83 function () { 84 return (FileManager.FileBuffer.isTextFile("C:\\somedir\\readme.txt") && 85 FileManager.FileBuffer.isTextFile("C:\\spaces path\\myapp.str") && 86 FileManager.FileBuffer.isTextFile("C:\\somedir\\code.js")) 87 })); 88 testRunner.addTest(new TestCase("Check makefile match", 89 function () { 90 return FileManager.FileBuffer.isTextFile("C:\\some dir\\makefile"); 91 })); 92 testRunner.addTest(new TestCase("Check binary file doesn't match", 93 function () { 94 return (!FileManager.FileBuffer.isTextFile("C:\\somedir\\app.exe") && 95 !FileManager.FileBuffer.isTextFile("C:\\somedir\\my lib.dll")); 96 })); 97 98 // Command-line parameter tests 99 testRunner.addTest(new TestCase("Check App defaults", 100 function () { 101 var app = new App.App([]); 102 return (app.fixLines === false && 103 app.recurse === true && 104 app.lineEndings === "CRLF" && 105 app.matchPattern === undefined && 106 app.rootDirectory === ".\\" && 107 app.encodings[0] === "ascii" && 108 app.encodings[1] === "utf8nobom"); 109 })); 110 testRunner.addTest(new TestCase("Check App params", 111 function () { 112 var app = new App.App(["-dir=C:\\test dir", "-lineEndings=LF", "-encodings=utf16be,ascii", "-recurse=false", "-fixlines"]); 113 return (app.fixLines === true && 114 app.lineEndings === "LF" && 115 app.recurse === false && 116 app.matchPattern === undefined && 117 app.rootDirectory === "C:\\test dir" && 118 app.encodings[0] === "utf16be" && 119 app.encodings[1] === "ascii" && 120 app.encodings.length === 2); 121 })); 122 123 // File BOM detection tests 124 testRunner.addTest(new TestCase("Check encoding detection no BOM", 125 function () { 126 var fb = new FileManager.FileBuffer(TestFileDir + "\\noBOM.txt"); 127 return fb.bom === 'none' && fb.encoding === 'utf8'; 128 })); 129 testRunner.addTest(new TestCase("Check encoding detection UTF8 BOM", 130 function () { 131 var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF8BOM.txt"); 132 return fb.bom === 'utf8' && fb.encoding === 'utf8'; 133 })); 134 testRunner.addTest(new TestCase("Check encoding detection UTF16be BOM", 135 function () { 136 var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF16BE.txt"); 137 return fb.bom === 'utf16be' && fb.encoding === 'utf16be'; 138 })); 139 testRunner.addTest(new TestCase("Check encoding detection UTF16le BOM", 140 function () { 141 var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF16LE.txt"); 142 return fb.bom === 'utf16le' && fb.encoding === 'utf16le'; 143 })); 144 testRunner.addTest(new TestCase("Check encoding on 1 bytes file", 145 function () { 146 var fb = new FileManager.FileBuffer(TestFileDir + "\\1bytefile.txt"); 147 return fb.bom === 'none' && fb.encoding === 'utf8'; 148 })); 149 testRunner.addTest(new TestCase("Check encoding on 0 bytes file", 150 function () { 151 var fb = new FileManager.FileBuffer(TestFileDir + "\\0bytefile.txt"); 152 return fb.bom === 'none' && fb.encoding === 'utf8'; 153 })); 154 155 // UTF8 encoding tests 156 testRunner.addTest(new TestCase("Check byte reader", 157 function () { 158 var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF8BOM.txt"); 159 var chars = []; 160 for (var i = 0; i < 11; i++) { 161 chars.push(fb.readByte()); 162 } 163 return TestRunner.arrayCompare(chars, [0x54, 0xC3, 0xA8, 0xE1, 0xB4, 0xA3, 0xE2, 0x80, 0xA0, 0x0D, 0x0A]); 164 })); 165 166 167 testRunner.addTest(new TestCase("Check UTF8 decoding", 168 function () { 169 var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF8BOM.txt"); 170 var chars = []; 171 for (var i = 0; i < 6; i++) { 172 chars.push(fb.readUtf8CodePoint()); 173 } 174 return TestRunner.arrayCompare(chars, [0x0054, 0x00E8, 0x1D23, 0x2020, 0x000D, 0x000A]); 175 })); 176 177 testRunner.addTest(new TestCase("Check UTF8 encoding", 178 function () { 179 var fb = new FileManager.FileBuffer(20); 180 fb.writeUtf8Bom(); 181 var chars = [0x0054, 0x00E8, 0x1D23, 0x2020, 0x000D, 0x000A]; 182 for (var i in chars) { 183 fb.writeUtf8CodePoint(chars[i]); 184 } 185 fb.index = 0; 186 var bytes = []; 187 for (var i = 0; i < 14; i++) { 188 bytes.push(fb.readByte()); 189 } 190 var expected = [0xEF, 0xBB, 0xBF, 0x54, 0xC3, 0xA8, 0xE1, 0xB4, 0xA3, 0xE2, 0x80, 0xA0, 0x0D, 0x0A]; 191 return TestRunner.arrayCompare(bytes, expected); 192 })); 193 194 // Test reading and writing files 195 testRunner.addTest(new TestCase("Check saving a file", 196 function () { 197 var filename = TestFileDir + "\\tmpUTF16LE.txt"; 198 var fb = new FileManager.FileBuffer(14); 199 fb.writeUtf16leBom(); 200 var chars = [0x0054, 0x00E8, 0x1D23, 0x2020, 0x000D, 0x000A]; 201 chars.forEach(function (val) { fb.writeUtf16CodePoint(val, false); }); 202 fb.save(filename); 203 204 var savedFile = new FileManager.FileBuffer(filename); 205 if (savedFile.encoding !== 'utf16le') { 206 throw Error("Incorrect encoding"); 207 } 208 var expectedBytes = [0xFF, 0xFE, 0x54, 0x00, 0xE8, 0x00, 0x23, 0x1D, 0x20, 0x20, 0x0D, 0x00, 0x0A, 0x00] 209 savedFile.index = 0; 210 expectedBytes.forEach(function (val) { 211 var byteVal = savedFile.readByte(); 212 if (byteVal !== val) { 213 throw Error("Incorrect byte value"); 214 } 215 }); 216 return true; 217 })); 218 219 testRunner.addTest(new TestCase("Check reading past buffer asserts", 220 function () { 221 var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF8BOM.txt"); 222 var result = fb.readByte(200); 223 return true; 224 }, "read beyond buffer length")); 225 testRunner.addTest(new TestCase("Check writing past buffer asserts", 226 function () { 227 var fb = new FileManager.FileBuffer(TestFileDir + "\\UTF8BOM.txt"); 228 fb.writeByte(5, 200); 229 return true; 230 }, "write beyond buffer length")); 231 232 // Non-BMP unicode char tests 233 testRunner.addTest(new TestCase("Read non-BMP utf16 chars", 234 function () { 235 var savedFile = new FileManager.FileBuffer(TestFileDir + "\\utf16leNonBmp.txt"); 236 if (savedFile.encoding !== 'utf16le') { 237 throw Error("Incorrect encoding"); 238 } 239 240 var codePoints = []; 241 for (var i = 0; i < 6; i++) { 242 codePoints.push(savedFile.readUtf16CodePoint(false)); 243 } 244 var expectedCodePoints = [0x10480, 0x10481, 0x10482, 0x54, 0x68, 0x69]; 245 return TestRunner.arrayCompare(codePoints, expectedCodePoints); 246 })); 247 248 testRunner.addTest(new TestCase("Read non-BMP utf8 chars", 249 function () { 250 var savedFile = new FileManager.FileBuffer(TestFileDir + "\\utf8NonBmp.txt"); 251 if (savedFile.encoding !== 'utf8') { 252 throw Error("Incorrect encoding"); 253 } 254 255 var codePoints = []; 256 for (var i = 0; i < 6; i++) { 257 codePoints.push(savedFile.readUtf8CodePoint()); 258 } 259 var expectedCodePoints = [0x10480, 0x10481, 0x10482, 0x54, 0x68, 0x69]; 260 return TestRunner.arrayCompare(codePoints, expectedCodePoints); 261 })); 262 263 testRunner.addTest(new TestCase("Write non-BMP utf8 chars", 264 function () { 265 var filename = TestFileDir + "\\tmpUTF8nonBmp.txt"; 266 var fb = new FileManager.FileBuffer(15); 267 var chars = [0x10480, 0x10481, 0x10482, 0x54, 0x68, 0x69]; 268 chars.forEach(function (val) { fb.writeUtf8CodePoint(val); }); 269 fb.save(filename); 270 271 var savedFile = new FileManager.FileBuffer(filename); 272 if (savedFile.encoding !== 'utf8') { 273 throw Error("Incorrect encoding"); 274 } 275 var expectedBytes = [0xF0, 0x90, 0x92, 0x80, 0xF0, 0x90, 0x92, 0x81, 0xF0, 0x90, 0x92, 0x82, 0x54, 0x68, 0x69]; 276 expectedBytes.forEach(function (val) { 277 var byteVal = savedFile.readByte(); 278 if (byteVal !== val) { 279 throw Error("Incorrect byte value"); 280 } 281 }); 282 return true; 283 })); 284 285 testRunner.addTest(new TestCase("Test invalid lead UTF8 byte", 286 function () { 287 var filename = TestFileDir + "\\utf8BadLeadByte.txt"; 288 var fb = new FileManager.FileBuffer(filename); 289 return true; 290 }, "Invalid UTF8 byte sequence at index: 4")); 291 292 testRunner.addTest(new TestCase("Test invalid tail UTF8 byte", 293 function () { 294 var filename = TestFileDir + "\\utf8InvalidTail.txt"; 295 var fb = new FileManager.FileBuffer(filename); 296 return true; 297 }, "Trailing byte invalid at index: 8")); 298 299 testRunner.addTest(new TestCase("Test ANSI fails validation", 300 function () { 301 var filename = TestFileDir + "\\ansi.txt"; 302 var fb = new FileManager.FileBuffer(filename); 303 return true; 304 }, "Trailing byte invalid at index: 6")); 305 306 testRunner.addTest(new TestCase("Test UTF-16LE with invalid surrogate trail fails", 307 function () { 308 var filename = TestFileDir + "\\utf16leInvalidSurrogate.txt"; 309 var fb = new FileManager.FileBuffer(filename); 310 return true; 311 }, "Trail surrogate has an invalid value")); 312 313 testRunner.addTest(new TestCase("Test UTF-16BE with invalid surrogate head fails", 314 function () { 315 var filename = TestFileDir + "\\UTF16BEInvalidSurrogate.txt"; 316 var fb = new FileManager.FileBuffer(filename); 317 return true; 318 }, "Byte sequence starts with a trail surrogate")); 319 320 testRunner.addTest(new TestCase("Test UTF-16LE with missing trail surrogate fails", 321 function () { 322 var filename = TestFileDir + "\\utf16leMissingTrailSurrogate.txt"; 323 var fb = new FileManager.FileBuffer(filename); 324 return true; 325 }, "Trail surrogate has an invalid value")); 326 327 // Count of CRs & LFs 328 testRunner.addTest(new TestCase("Count character occurrences", 329 function () { 330 var filename = TestFileDir + "\\charCountASCII.txt"; 331 var fb = new FileManager.FileBuffer(filename); 332 var result = (fb.countCR === 5 && fb.countLF === 4 && fb.countCRLF === 5 && fb.countHT === 3); 333 return result; 334 })); 335 336 // Control characters in text 337 testRunner.addTest(new TestCase("Test file with control character", 338 function () { 339 var filename = TestFileDir + "\\controlChar.txt"; 340 var fb = new FileManager.FileBuffer(filename); 341 return true; 342 }, "Codepoint at index: 3 has control value: 8")); 343 344 return testRunner; 345})(); 346