Working Skelleton
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"{$}/import.less": {
|
||||
"imports": [
|
||||
{
|
||||
"path": "{$}/import-header.less",
|
||||
"mtime": null
|
||||
},
|
||||
{
|
||||
"path": "{$}/import-widget.less",
|
||||
"mtime": null
|
||||
},
|
||||
{
|
||||
"path": "{$}/import-color.less",
|
||||
"mtime": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"{$}/import.less": {
|
||||
"imports": [
|
||||
{
|
||||
"path": "{$}/import-color.less",
|
||||
"mtime": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Generated
Vendored
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
@externalColor: #f03;
|
||||
Generated
Vendored
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
@paddingBox: 20px;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
@titleColor: #f00;
|
||||
@linkColor: #00f;
|
||||
+1
@@ -0,0 +1 @@
|
||||
#header{color:#f00}.widget{color:#f00;background:#00f}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
#header {
|
||||
color: #ff0000;
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
@import "import-color";
|
||||
|
||||
#header {
|
||||
color: @titleColor;
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
.widget {
|
||||
color: #ff0000;
|
||||
background: #0000ff;
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@import "import-color";
|
||||
|
||||
.widget {
|
||||
color: @titleColor;
|
||||
background: @linkColor;
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
#header {
|
||||
color: #ff0000;
|
||||
}
|
||||
.widget {
|
||||
color: #ff0000;
|
||||
background: #0000ff;
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
@import "import-header";
|
||||
@import "import-widget";
|
||||
+1
@@ -0,0 +1 @@
|
||||
a{color:#00f}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
a {
|
||||
color: #0000ff;
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
@import "import-color";
|
||||
|
||||
a {
|
||||
color: @linkColor;
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
body{color:#d3d3d3}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
color: #d3d3d3;
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
@color1: #d3d3d3;
|
||||
|
||||
body {
|
||||
color: @color1;
|
||||
}
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
/* Prepended Comment */
|
||||
.widget{color:#f00}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
.widget {
|
||||
color: #f00;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
.widget {
|
||||
color: #f00;
|
||||
}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
h1 .widget{color:#00f}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
.widget{color:#00f}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
.widget {
|
||||
color: #00f;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
.widget {
|
||||
color: #00f;
|
||||
}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
.widget{color:#f03;padding:20px}
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
@import "externalvariables.less";
|
||||
@import "ui.less";
|
||||
.widget {
|
||||
color: @externalColor;
|
||||
padding: @paddingBox;
|
||||
}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
.widget{color:#0f0}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
.widget {
|
||||
color: #0f0;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
.widget {
|
||||
color: #0f0;
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
body{color:#d3d3d3}
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["simple.less"],"names":[],"mappings":"AAEA,KACI"}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
color: #d3d3d3;
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
@color1: #d3d3d3;
|
||||
|
||||
body {
|
||||
color: @color1;
|
||||
}
|
||||
+299
@@ -0,0 +1,299 @@
|
||||
"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);
|
||||
});
|
||||
});
|
||||
});
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
"use strict";
|
||||
|
||||
var utilities = require('../lib/utilities');
|
||||
var assert = require('assert');
|
||||
|
||||
describe('utilities', function(){
|
||||
describe('#isCompressedPath()', function(){
|
||||
it('should match path when valid path found', function(){
|
||||
assert.equal(true, utilities.isCompressedPath('styles-min.css'));
|
||||
assert.equal(true, utilities.isCompressedPath('styles.min.css'));
|
||||
});
|
||||
|
||||
it('should not match path when invalid path found', function(){
|
||||
assert.equal(false, utilities.isCompressedPath('styles.css'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#isValidPath()', function(){
|
||||
it('should match path when valid path found', function(){
|
||||
assert.equal(true, utilities.isValidPath('styles.css'));
|
||||
});
|
||||
|
||||
it('should not match path when invalid path found', function(){
|
||||
assert.equal(false, utilities.isValidPath('styles.less'));
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user