300 lines
9.5 KiB
JavaScript
300 lines
9.5 KiB
JavaScript
"use strict";
|
|
|
|
var express = require('express');
|
|
var fs = require('fs');
|
|
var mkdirp = require('mkdirp');
|
|
var middleware = require('../lib/middleware');
|
|
var os = require('os');
|
|
var request = require('supertest');
|
|
var assert = require('assert');
|
|
var copySync = require('fs-extra').copySync;
|
|
var path = require('path');
|
|
|
|
var tmpDest = __dirname + '/artifacts';
|
|
var clearCache = function(filename) {
|
|
if(fs.existsSync(tmpDest + '/' + filename)) {
|
|
// Unlinking file since it is cached without reguard to params.
|
|
// TODO: Remove when the imports cache is aware of params.
|
|
fs.unlinkSync(tmpDest + '/' + filename);
|
|
}
|
|
};
|
|
|
|
var setupExpress = function(src, options, staticDest) {
|
|
staticDest = staticDest || options.dest;
|
|
options = options || {};
|
|
var app = express();
|
|
app.use(middleware(src, options));
|
|
app.use(express.static(staticDest));
|
|
return app;
|
|
}
|
|
|
|
describe('middleware', function(){
|
|
describe('simple', function(){
|
|
var app = setupExpress(__dirname + '/fixtures', {
|
|
dest: tmpDest
|
|
});
|
|
|
|
it('should process simple less files', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/simple-exp.css', 'utf8');
|
|
request(app)
|
|
.get('/simple.css')
|
|
.expect(200)
|
|
.expect(expected, done);
|
|
});
|
|
});
|
|
|
|
describe('source map', function(){
|
|
var app = setupExpress(__dirname + '/fixtures', {
|
|
dest: tmpDest,
|
|
force: true, // Need to force since using the same file as the simple test.
|
|
render: {
|
|
sourceMap: {
|
|
sourceMapBasepath: __dirname + '/fixtures'
|
|
}
|
|
}
|
|
});
|
|
|
|
it('should handle source map files', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/simple-exp.css.map', 'utf8');
|
|
request(app)
|
|
.get('/simple.css.map')
|
|
.expect(200)
|
|
.expect(expected, done);
|
|
});
|
|
});
|
|
|
|
describe('import', function(){
|
|
var app = setupExpress(__dirname + '/fixtures', {
|
|
dest: tmpDest
|
|
});
|
|
|
|
it('should process less files with imports', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/importSimple-exp.css', 'utf8');
|
|
request(app)
|
|
.get('/importSimple.css')
|
|
.expect(200)
|
|
.expect(expected, done);
|
|
});
|
|
|
|
it('should process less files with nested imports', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/import-exp.css', 'utf8');
|
|
request(app)
|
|
.get('/import.css')
|
|
.expect(200)
|
|
.expect(expected, done);
|
|
});
|
|
});
|
|
|
|
describe('options', function(){
|
|
describe('postprocess', function(){
|
|
describe('css', function(){
|
|
var app = setupExpress(__dirname + '/fixtures', {
|
|
dest: tmpDest,
|
|
postprocess: {
|
|
css: function(css, req) {
|
|
return '/* Prepended Comment */\n' + css;
|
|
}
|
|
}
|
|
});
|
|
|
|
it('should prepend the comment on all output css', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/postprocessCss-exp.css', 'utf8');
|
|
request(app)
|
|
.get('/postprocessCss.css')
|
|
.expect(200)
|
|
.expect(expected, done);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('preprocess', function(){
|
|
describe('less', function(){
|
|
var app = setupExpress(__dirname + '/fixtures', {
|
|
dest: tmpDest,
|
|
preprocess: {
|
|
less: function(src, req) {
|
|
if (req.query.namespace) {
|
|
src = req.query.namespace + " { " + src + " }";
|
|
}
|
|
return src;
|
|
}
|
|
}
|
|
});
|
|
|
|
it('should add namespace when found', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/preprocessLess-exp-a.css', 'utf8');
|
|
clearCache('preprocessLess.css');
|
|
request(app)
|
|
.get('/preprocessLess.css?namespace=h1')
|
|
.expect(200)
|
|
.expect(expected, done);
|
|
});
|
|
|
|
it('should not add namespace when none provided', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/preprocessLess-exp-b.css', 'utf8');
|
|
clearCache('preprocessLess.css');
|
|
request(app)
|
|
.get('/preprocessLess.css')
|
|
.expect(200)
|
|
.expect(expected, done);
|
|
});
|
|
});
|
|
|
|
describe('path', function(){
|
|
var app = setupExpress(__dirname + '/fixtures', {
|
|
dest: tmpDest,
|
|
preprocess: {
|
|
path: function(pathname, req) {
|
|
return pathname.replace('.ltr', '');
|
|
}
|
|
}
|
|
});
|
|
|
|
it('should remove .ltr from the less path when found', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/preprocessPath-exp.css', 'utf8');
|
|
request(app)
|
|
.get('/preprocessPath.ltr.css')
|
|
.expect(200)
|
|
.expect(expected, done);
|
|
});
|
|
|
|
it('should not change less path when no matching .ltr', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/preprocessPath-exp.css', 'utf8');
|
|
request(app)
|
|
.get('/preprocessPath.css')
|
|
.expect(200)
|
|
.expect(expected, done);
|
|
});
|
|
});
|
|
|
|
describe('importPaths', function(){
|
|
var app = setupExpress(__dirname + '/fixtures', {
|
|
dest: tmpDest,
|
|
preprocess: {
|
|
path: function(pathname, req) {
|
|
var returnPath = pathname.replace(/(\/[0-9\.0-9\.0-9].*\/)/, '/');
|
|
return returnPath;
|
|
},
|
|
importPaths: function(paths, req) {
|
|
var version = req.url.match(/\/([0-9\.0-9\.0-9]*)/);
|
|
var reqPath = path.join(__dirname, 'fixtures', 'external', version[1] , '/');
|
|
var paths = [
|
|
reqPath,
|
|
path.join(reqPath, 'ui')
|
|
];
|
|
return paths;
|
|
}
|
|
}
|
|
});
|
|
|
|
it('should respond with newly mapped paths', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/preprocessParserPaths-exp.css', 'utf8');
|
|
request(app)
|
|
.get('/2.43.3/preprocessParserPaths.css')
|
|
.expect(200)
|
|
.expect(expected, done);
|
|
});
|
|
});
|
|
|
|
describe('pathRoot', function(){
|
|
var app = setupExpress('/fixtures', {
|
|
dest: '/artifacts',
|
|
pathRoot: __dirname
|
|
}, tmpDest);
|
|
|
|
it('should process simple less files', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/pathRoot-exp.css', 'utf8');
|
|
request(app)
|
|
.get('/pathRoot.css')
|
|
.expect(200)
|
|
.expect(expected, done);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
describe('cacheFile', function() {
|
|
var middlewareSrc = tmpDest + '/fixturesCopy';
|
|
var dest = tmpDest + '/cacheFileTest';
|
|
var cacheFile = dest + '/cacheFile.json';
|
|
try {
|
|
mkdirp.sync(middlewareSrc);
|
|
} catch(e) {
|
|
if (e && e.code != 'EEXIST') throw e;
|
|
}
|
|
copySync(__dirname + '/fixtures', middlewareSrc);
|
|
var app;
|
|
|
|
var expandExpected = function(file) {
|
|
return file.replace(/\{\$\}/g, middlewareSrc);
|
|
}
|
|
|
|
var checkCacheFile = function(cacheFile, expectedFile){
|
|
var sortByPath = function(a, b) {
|
|
var keyA = a.path;
|
|
var keyB = b.path;
|
|
if(keyA < keyB) return -1;
|
|
if(keyA > keyB) return 1;
|
|
return 0;
|
|
};
|
|
|
|
return function(){
|
|
// Force cacheFile write.
|
|
middleware._saveCacheToFile();
|
|
|
|
var cacheFileExpected = JSON.parse(expandExpected(fs.readFileSync(expectedFile, 'utf8')));
|
|
var cacheFileOutput = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
|
|
|
|
for (var file in cacheFileExpected) {
|
|
assert(cacheFileOutput[file] != undefined);
|
|
|
|
var expectedImports = cacheFileExpected[file].imports.sort(sortByPath);
|
|
var outputImports = cacheFileOutput[file].imports.sort(sortByPath);
|
|
|
|
assert.equal(outputImports.length, expectedImports.length);
|
|
|
|
for (var i = 0; i < expectedImports.length; i++) {
|
|
assert.equal(expectedImports[i].path, outputImports[i].path);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
beforeEach(function() {
|
|
// Unfortunately because cache-related items are stored in globals
|
|
// (which they need to be so that they are shared across different
|
|
// middleware invocations), to properly test the cacheFile option we
|
|
// need to re-require the middleware for each of these tests.
|
|
var mpath = path.resolve(__dirname, '../lib/middleware.js');
|
|
delete require.cache[mpath];
|
|
middleware = require('../lib/middleware');
|
|
app = setupExpress(middlewareSrc, {
|
|
dest: dest,
|
|
cacheFile: cacheFile
|
|
});
|
|
});
|
|
|
|
it('should process files correctly and store the right cached imports', function(done){
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/import-exp.css', 'utf8');
|
|
request(app)
|
|
.get('/import.css')
|
|
.expect(200)
|
|
.expect(expected)
|
|
.expect(checkCacheFile(cacheFile, __dirname + '/fixtures/cacheFile-exp.json'))
|
|
.end(done);
|
|
});
|
|
|
|
it('should ignore cached imports if the file has changed and update cached imports', function(done){
|
|
copySync(middlewareSrc + '/importSimple.less', middlewareSrc + '/import.less');
|
|
var expected = fs.readFileSync(__dirname + '/fixtures/importSimple-exp.css', 'utf8');
|
|
request(app)
|
|
.get('/import.css')
|
|
.expect(200)
|
|
.expect(expected)
|
|
.expect(checkCacheFile(cacheFile, __dirname + '/fixtures/cacheFile-exp2.json'))
|
|
.end(done);
|
|
});
|
|
});
|
|
});
|