UNPKG

ar

Version:

ar - Read Unix archive files.

157 lines (146 loc) 4.87 kB
/// <reference path="../bower_components/DefinitelyTyped/node/node.d.ts" /> /** * ar test runner command line utility */ import ar = require('../ar'); import fs = require('fs'); import path = require('path'); import util = require('util'); var glob = require('glob'), cwd = process.cwd(); // Change to the test runner directory. process.chdir(__dirname); /** * Pads the number with zeroes so it is length long as a string. */ function padNumber(num: number, length: number): string { var numStr = "" + num; while (numStr.length < length) { numStr = "0" + numStr; } return numStr; } /** * Appends dots to the string until it is length long. */ function appendDots(str: string, length: number): string { while (str.length < length) { str = str + "."; } return str; } class Test { private archive: ar.Archive; private dirPath: string; /** * Constructs a new unit test. * Filename is the name of an archive file. */ constructor(private filename: string) {} /** * Compares the ar file against the real file on the hard drive. */ private testFile(arFile: ar.ARFile, filePath: string) { var realFileContents: NodeBuffer = fs.readFileSync(filePath), arFileContents: NodeBuffer = arFile.fileData(), i: number; if (realFileContents.length !== arFileContents.length) { throw new Error("Archive file's length does not match file: " + arFileContents.length + " bytes vs " + realFileContents.length + " bytes."); } // Compare contents, byte-by-byte. Yeah, this isn't efficient, but our tests // are small. for (i = 0; i < arFileContents.length; i++) { if (arFileContents.readUInt8(i) !== realFileContents.readUInt8(i)) { throw new Error("Archive file and file differ at byte " + i + "."); } } // All good! } /** * Run after archive initialization. Iterates over all of the files in the * archive, tests each against the folder's files, and ensures that no files * are missing. */ private testFiles() { var files: string[] = fs.readdirSync(this.dirPath), arFiles: ar.ARFile[] = this.archive.getFiles(), i: number, file: ar.ARFile, name: string, nameIdx: number; for (i = 0; i < arFiles.length; i++) { file = arFiles[i]; name = file.name(); nameIdx = files.indexOf(name); if (nameIdx === -1) { throw new Error("Archive file contains extraneous file \"" + name + "\"."); } this.testFile(file, path.resolve(this.dirPath, name)); // Remove this file, since we've tested it. files.splice(nameIdx, 1); } if (files.length > 0) { throw new Error("Archive file is missing the following files: " + files.toString()); } } /** * Runs the test, prints out status, and returns true if it passed. */ public run(testNumber: number, totalTests: number): boolean { var dirName: string; // Outputs a 76 character-wide line, without a newline. Leaves 4 characters // for test status. util.print(appendDots(["[", padNumber(testNumber, 2), "/", padNumber(totalTests, 2), "] ", this.filename, " "].join(''), 76)); try { this.archive = new ar.Archive(fs.readFileSync(this.filename)); dirName = path.basename(this.filename); // Strip extension. dirName = dirName.substr(0, dirName.length - 2); // Strip characters after first -. if (dirName.indexOf('-') !== -1) { dirName = dirName.substr(0, dirName.indexOf('-')); } this.dirPath = path.resolve(path.dirname(this.filename), dirName); if (!fs.existsSync(this.dirPath)) { throw new Error("Cannot find test data in folder \"" + this.dirPath + "\""); } this.testFiles(); util.print("..OK\n"); return true; } catch (e) { util.print("FAIL\n"); console.log("\t" + e); return false; } } } class TestSuite { private tests: Test[] = []; /** * Creates a test suite for the given set of files. */ constructor(filenames: string[]) { var i; for (i = 0; i < filenames.length; i++) { this.tests.push(new Test(filenames[i])); } } /** * Run all of the tests in the suite. */ public run(): void { var i, length = this.tests.length, passed = 0; console.log("Running " + length + " tests..."); for (i = 0; i < length; i++) { if (this.tests[i].run(i+1, length)) passed++; } console.log("Tests complete! " + passed + "/" + this.tests.length + " (" + ((passed / this.tests.length)*100) + "%) passed."); } } // Locate all of the archive files. glob("*.a", function (er, files: string[]) { if (er != null) throw er; (new TestSuite(files)).run(); // Change back to the directory the user ran the script from. process.chdir(cwd); });