template-tango
Version:
Tool for merging HTML templates between front and back end, making use of Beyond Compare folder comparison.
439 lines (344 loc) • 14 kB
text/typescript
import fs = require("fs-extra");
import _ = require("lodash");
import {IWalk,IMergableFiles} from "./interfaces";
var tt = require("./index.js").default
, utils = require("./utils.js").default
// stops console from clogging up with warnings during tests
tt.testable.suppressWarnings(true);
var MAIN_DIR = utils.normalizePaths(__dirname).split("dist")[0]
, TEST_RES = MAIN_DIR + "test-resources/"
, TEMP_DIR = MAIN_DIR + "dist/temp/"
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
describe("normalizePaths", () => {
var fun = utils.normalizePaths
it("should convert Windows paths to Unix paths", () => {
expect(fun('example\\windows\\path')).toBe('example/windows/path')
})
})
describe("checkVal", () => {
var fun = utils.checkVal
it("should return false for falsy input", () => {
var msg = "failed";
expect(fun(null, msg)).toBe(false);
expect(fun(undefined, msg)).toBe(false);
})
it("should return true for truthy input, zero and empty strings", () => {
var msg = "failed";
expect(fun("", msg)).toBe(true);
expect(fun(0, msg)).toBe(true);
expect(fun(1, msg)).toBe(true);
expect(fun("A value", msg)).toBe(true);
})
})
describe("getCWD", () => {
var fun = utils.getCWD
it("should return the current working directory with forward slashed paths", () => {
expect(fun()).toBe( process.cwd().split("\\").join("/") + "/" )
})
})
describe("ensureTrainlingSlash", () => {
var fun = utils.ensureTrainlingSlash
it("should make sure a path ends in a single slash", () => {
expect(fun('a')).toBe('a/')
expect(fun('a/b/')).toBe('a/b/')
})
})
describe("expectFiles", () => {
let fun = utils.expectFiles
, beFiles = TEST_RES + "back-end-files/"
it("should expect files to exist", (done:Function) => {
utils.expectFiles([
beFiles + "Components/SideNav/SideNav.cshtml"
, beFiles + "Views/Home/Index.cshtml"
], done);
})
})
describe("copyBackToFront", () => {
const COPY_FE = "should copy all test resources into temp dist folder and change the directory names and extensions to be front end values";
var fun = utils.copyBackToFront
, beFiles = TEST_RES + "back-end-files/"
, feModulesDir = "Widgets/"
, fePagesDir = "Pages/"
, feSubDir = "tmpl/"
, beOpts:IMergableFiles = {
rootDir: beFiles
, extension: ".cshtml"
, pagesDir: "Views/"
, modulesDir: "Components/"
, pageExclusions: null
, moduleExclusions: null
, subDir: ""
};
it("should trigger a callback when 'back to front' copy is complete", (done:Function) => {
let _beOpts = _.clone(beOpts);
_beOpts.completeCB = done;
fun(TEMP_DIR, _beOpts, ".vash", feSubDir, fePagesDir, feModulesDir);
})
it(COPY_FE, (done:Function) => {
let p:Promise<string> = fun(TEMP_DIR, beOpts, ".vash", feSubDir, fePagesDir, feModulesDir);
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([
TEMP_DIR + feModulesDir + "SideNav/"+ feSubDir +"SideNav.vash"
, TEMP_DIR + fePagesDir + "Home/"+ feSubDir +"Index.vash"
, TEMP_DIR + fePagesDir + "About/"+ feSubDir +"Index.vash"
, TEMP_DIR + fePagesDir + "Home/"+ feSubDir +"Index.vash"
, TEMP_DIR + fePagesDir + "Shared/"+ feSubDir +"Header.vash"
], done);
});
})
it(COPY_FE+", affecting modules only (excludes pages, using 'pageExclusions').", (done:Function) => {
// tt.testable.suppressWarnings(false);
let _beOpts:IMergableFiles = _.clone(beOpts);
_beOpts.pageExclusions = ["Views/**/*.cshtml"]; // glob pattern of files to exclude
let p:Promise<string> = fun(TEMP_DIR, _beOpts, ".vash", feSubDir, fePagesDir, feModulesDir);
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([TEMP_DIR + feModulesDir + "SideNav/"+ feSubDir +"SideNav.vash"], done);
});
})
it(COPY_FE+", affecting modules only (by having a null 'pagesDir').", (done:Function) => {
let _beOpts:IMergableFiles = _.clone(beOpts);
_beOpts.pagesDir = null;
let p:Promise<string> = fun(TEMP_DIR, _beOpts, ".vash", feSubDir, null, feModulesDir);
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([TEMP_DIR + feModulesDir + "SideNav/"+ feSubDir +"SideNav.vash"], done);
});
})
// related to 'src/_example-2.js'
it(COPY_FE+", affecting just modules and without a back end parent folder.", (done:Function) => {
let _beOpts:IMergableFiles = {
rootDir: beFiles + "Models/"
, extension: ".cs"
, pagesDir: null
, modulesDir: "/"
, pageExclusions: null
, moduleExclusions: null
, subDir: ""
}
let p:Promise<string> = fun(TEMP_DIR, _beOpts, ".cs", "mdl/", null, feModulesDir);
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([TEMP_DIR + feModulesDir + "SideNav/mdl/SideNav.cs"], done);
utils.expectFiles([TEMP_DIR + feModulesDir + "SurfNav/mdl/SurfNav.cs"], done);
utils.expectFiles([TEMP_DIR + feModulesDir + "TopNav/mdl/TopNav.cs"], done);
});
})
// related to 'src/_example-3.js'
it(COPY_FE+", affecting just modules and without a front end parent folder.", (done:Function) => {
let _beOpts:IMergableFiles = {
rootDir: beFiles
, extension: ".md"
, pagesDir: null
, modulesDir: "Components/"
, pageExclusions: null
, moduleExclusions: null
, subDir: "Docs/"
}
let p:Promise<string> = fun(TEMP_DIR + "Docs/", _beOpts, ".md", "", null, "/");
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([TEMP_DIR + "Docs/SideNav.md"], done);
});
})
// TODO: Test Pages without a parent folder
it(COPY_FE+", using 'nameMapGroup' for modules and pages.", (done:Function) => {
let _beOpts:IMergableFiles = _.clone(beOpts);
let nameMapGroup = { // maps template name exceptions between front and back end
pages: [{ backEnd: "DashboardPage/Home", frontEnd: "Dashboard/tmpl/Index" }],
modules: [{ backEnd: "AppNav/Index", frontEnd: "TopNav/tmpl/TopNav" }]
}
let p:Promise<string> = fun(TEMP_DIR, _beOpts, ".vash", feSubDir, fePagesDir, feModulesDir, nameMapGroup);
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([TEMP_DIR + fePagesDir + "Dashboard/"+ feSubDir +"Index.vash"], function() {
utils.expectFiles([TEMP_DIR + feModulesDir + "TopNav/"+ feSubDir +"TopNav.vash"], done);
});
});
})
})
describe("copyFrontToBack", () => {
const COPY_BE = "should copy all test resources into temp dist folder and change the directory names and extensions to be back end values";
var fun = utils.copyFrontToBack
, feFiles = TEST_RES + "front-end-files/"
, beModulesDir = "Components/"
, bePagesDir = "Views/"
, feOpts:IMergableFiles = {
rootDir: feFiles
, extension: ".vash"
, pagesDir: "Pages/"
, modulesDir: "Widgets/"
, pageExclusions: null
, moduleExclusions: null
, subDir: "tmpl/"
};
it("should trigger a callback when 'front to back' copy is complete", (done:Function) => {
let _feOpts = _.clone(feOpts);
_feOpts.completeCB = done;
fun(TEMP_DIR, _feOpts, ".cshtml", "", bePagesDir, beModulesDir);
})
it(COPY_BE, (done:Function) => {
let p:Promise<string> = fun(TEMP_DIR, feOpts, ".cshtml", "", bePagesDir, beModulesDir);
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([
TEMP_DIR + beModulesDir + "SideNav/SideNav.cshtml"
, TEMP_DIR + bePagesDir + "Home/Index.cshtml"
, TEMP_DIR + bePagesDir + "About/Index.cshtml"
, TEMP_DIR + bePagesDir + "Home/Index.cshtml"
, TEMP_DIR + bePagesDir + "Shared/Header.cshtml"
], done);
});
})
it(COPY_BE+" ---- affecting modules only (excludes pages using 'pageExclusions').", (done:Function) => {
let _feOpts:IMergableFiles = _.clone(feOpts);
_feOpts.pageExclusions = ["Pages/**/*.vash"]; // glob pattern of files to exclude
let p:Promise<string> = fun(TEMP_DIR, _feOpts, ".cshtml", "", bePagesDir, beModulesDir);
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([TEMP_DIR + beModulesDir + "SideNav/SideNav.cshtml"], done);
});
})
it(COPY_BE+" ---- affecting modules only (by having a null 'pagesDir').", (done:Function) => {
let _feOpts:IMergableFiles = _.clone(feOpts);
_feOpts.pagesDir = null;
let p:Promise<string> = fun(TEMP_DIR, _feOpts, ".cshtml", "", null, beModulesDir);
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([TEMP_DIR + beModulesDir + "SideNav/SideNav.cshtml"], done);
});
})
// related to 'src/_example-3.js'
it(COPY_BE+", affecting just modules and without a front end parent folder.", (done:Function) => {
let _feOpts:IMergableFiles = {
rootDir: feFiles + "Docs/"
, extension: ".md"
, pagesDir: null
, modulesDir: "/"
, pageExclusions: null
, moduleExclusions: null
, subDir: ""
}
let p:Promise<string> = fun(TEMP_DIR, _feOpts, ".md", "Docs/", null, beModulesDir);
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([TEMP_DIR + beModulesDir + "SideNav/Docs/SideNav.md"], done);
});
})
// related to 'src/_example-2.js'
it(COPY_BE+", affecting just modules and without a backend parent folder.", (done:Function) => {
let _feOpts:IMergableFiles = {
rootDir: feFiles
, extension: ".cs"
, pagesDir: null
, modulesDir: "Widgets/"
, pageExclusions: null
, moduleExclusions: null
, subDir: "mdl/"
}
let p:Promise<string> = fun(TEMP_DIR + "Models/", _feOpts, ".cs", "", null, "/");
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([TEMP_DIR + "Models/SurfNav.cs"], done);
});
})
// TODO: Test Pages without a parent folder
it(COPY_BE+" ---- using 'nameMapGroup' for modules and pages.", (done:Function) => {
let _feOpts:IMergableFiles = _.clone(feOpts);
let nameMapGroup = { // maps template name exceptions between front and back end
pages: [{ backEnd: "DashboardPage/Home", frontEnd: "Dashboard/tmpl/Index" }],
modules: [{ backEnd: "AppNav/Index", frontEnd: "TopNav/tmpl/TopNav" }]
}
let p:Promise<string> = fun(TEMP_DIR, _feOpts, ".cshtml", "", bePagesDir, beModulesDir, nameMapGroup);
let fileList:Array<string> = [];
p.then(() => {
utils.expectFiles([TEMP_DIR + bePagesDir + "DashboardPage/Home.cshtml"], function() {
utils.expectFiles([TEMP_DIR + beModulesDir + "AppNav/Index.cshtml"], done);
});
});
})
})
describe("copyToNewFolderStructure", () => {
let fun = utils.testable.copyToNewFolderStructure
, BASE_MSG = "should copy a file to new location and change the extension"
, feFiles = TEST_RES + "front-end-files/"
, beFiles = TEST_RES + "back-end-files/"
, feSubDir = "tmpl" // doesn't need trailing slash (it will get added it missed)
, beSubDir = ""
, originalPageDir:string = feFiles + "Pages/"
, originalPagePath:string = originalPageDir + "About/tmpl/Index.vash"
, newPageDir:string = TEMP_DIR + "Views/"
it("should copy a file to new location and change the extension", (done) => {
fun(originalPagePath, originalPageDir, newPageDir, ".cshtml", feSubDir, beSubDir, () => {
expect(fs.existsSync(newPageDir + "About/Index.cshtml")).toBe(true)
done();
})
})
it("should copy a file to new location as a single file without a parent folder", (done) => {
var feSubDir = "mdl"
, originalModulesDir:string = feFiles + "Widgets/"
, originalModulesPath:string = originalModulesDir + "SurfNav/mdl/SurfNav.cs"
, newModulesDir:string = TEMP_DIR + "Models/"
, justFile = true
fun(originalModulesPath, originalModulesDir, newModulesDir, ".cs", feSubDir, "", () => {
expect(fs.existsSync(newModulesDir + "SurfNav.cs")).toBe(true)
done();
}, null, null, null, justFile)
})
it("should add original file path to the 'success array', after copying", (done) => {
let successArray:Array<string> = []
fun(originalPagePath, originalPageDir, newPageDir, ".cshtml", feSubDir, beSubDir, () => {
expect(successArray).toContain(originalPagePath)
done();
}, successArray)
})
it("should add original file path to the 'error array', after failing to copy", (done) => {
let originalPagePath:string = originalPageDir + "SomethingThatDoesntExist.vash"
, failArray:Array<string> = []
fun(originalPagePath, originalPageDir, newPageDir, ".cshtml", feSubDir, beSubDir, () => {
expect(failArray).toContain(originalPagePath)
done();
}, null, failArray)
})
})
describe("getOptsFullPaths", () => {
let fun = utils.testable.getOptsFullPaths
, beFiles = TEST_RES + "back-end-files/"
, beOpts:IMergableFiles = {
rootDir: beFiles
, extension: ".cshtml"
, pagesDir: "Views/"
, modulesDir: "Components/"
, pageExclusions: [ "Views/Shared/**/*" ]
, moduleExclusions: null
, subDir: ""
};
it("should get an array of all back end page file paths, except excluded Shared ones", () => {
var pages:Array<string> = fun(beOpts, 'page', true);
expect(pages).toContain(beFiles + "Views/Home/Index.cshtml");
expect(pages).toContain(beFiles + "Views/About/Index.cshtml");
expect(pages).not.toContain(beFiles + "Views/Shared/Header.cshtml");
})
})
describe("bangUpExclusions", () => {
let fun = utils.testable.bangUpExclusions
it("should add a '!' character to a path that does not start with one", () => {
expect(fun(['path'], 'root/')).toContain('!root/path')
})
it("should only contain a single '!' character even though path already starts with one", () => {
expect(fun(['!path'], 'root/')).toContain('!root/path')
})
// just cleans up after last test
afterEach(() => {
fs.removeSync(TEMP_DIR);
})
})
/*
describe("XXXX", () => {
let fun = utils.XXXX
xit("should ", () => {
expect(fun('XXX')).toBe('XXX')
})
})
*/