UNPKG

jcs-middleware

Version:

Jade, CoffeeScript, Stylus middleware for Express.js

568 lines (481 loc) 21.7 kB
#! # jcs-middleware Copyright(c) 2014 Wu Yuntao # https://github.com/WuYuntaoTheGreat/jcs-middleware # Released under the MIT License. # vim: set et ai ts=4 sw=4 cc=100 nu: # logger = require("../lib/logger").logger assert = require "assert" fs = require "fs" path = require "path" mkdirp = require "mkdirp" url = require "url" rmdir = require "rimraf" async = require "async" STATICROOT = path.join __dirname, "public" SOURCEROOT = path.join __dirname, "views" EXAMPLESITE = "http://yourdomain.com" PREFIX = "prefix" # All the test data # # a - testcase 'A' # b - testcase 'B' # x - testcase NOT EXIST # # .src - source file path # .dst - destination file path # .url - plain url # .urlP - url with prefix # R = stylus: _dst: 'css' _srcSuffix: 'styl' a: {} b: {} x: {} coffee: _dst: 'js' a: {} x: {} jade: _dst: 'html' a: {} b: {} x: {} ejs: _dst: 'html' a: {} b: {} x: {} less: _dst: 'css' a: {} x: {} for i, cjh of R for k of cjh when k[0] != '_' cjh[k] = src : path.join SOURCEROOT, i, "#{k}.#{cjh._srcSuffix || i}" dst : path.join STATICROOT, cjh._dst, "#{k}.#{cjh._dst}" url : "#{EXAMPLESITE}/#{cjh._dst}/#{k}.#{cjh._dst}" urlP: "#{EXAMPLESITE}/#{PREFIX}/#{cjh._dst}/#{k}.#{cjh._dst}" logger.info R # Shorthand function to create jcs instance. createJcsObj = (which, extra) -> opt = extra || {} opt.staticRoot = STATICROOT which.split(/[\s\|,;]+/).forEach (w) -> if /^[sS]/.test w opt.stylusSrc= path.join SOURCEROOT, 'stylus' opt.stylusDst= path.join STATICROOT, 'css' if /^[lL]/.test w opt.lessSrc = path.join SOURCEROOT, 'less' opt.lessDst = path.join STATICROOT, 'css' if /^[jJ]/.test w opt.jadeSrc = path.join SOURCEROOT, 'jade' opt.jadeDst = path.join STATICROOT, 'html' if /^[eE]/.test w opt.ejsSrc = path.join SOURCEROOT, 'ejs' opt.ejsDst = path.join STATICROOT, 'html' if /^[cC]/.test w opt.coffeeSrc= path.join SOURCEROOT, 'coffee' opt.coffeeDst= path.join STATICROOT, 'js' require("../index")(opt) createJcs = (which, extra) -> createJcsObj(which, extra).middleware createJcsObj('s|c|j').prepare (err)-> logger.info err # Change the file timestamp. touch = (f, d) -> d = d || new Date fs.utimesSync f, d, d # Create a mockup http request object. mockReq = (url, method) -> { url: url method: method || 'GET' } describe "ALL", -> describe "THE TEST FOR JCS MIDDLEWARE", -> # Before each test case. we need to clear the output folder. # This is done by: # 1) Delete the whole directory, with its contents. # 2) And then create that directory again. # beforeEach (done)-> rmdir STATICROOT, (err)-> if err logger.error err mkdirp STATICROOT, (err)-> if err logger.error err throw err else done() ############################################################ # Test stylus middleware describe "Test stylus middleware", -> jcs = createJcs 's' it "#1 'a.styl' should be compiled to 'a.css'", (done) -> jcs mockReq(R.stylus.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.stylus.a.dst done() it "#2 do twice without touch source, should not compile", (done) -> jcs mockReq(R.stylus.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.stylus.a.dst outTime = fs.statSync(R.stylus.a.dst).mtime jcs mockReq(R.stylus.a.url), null, (err) -> if err logger.error err logger.error err.stack assert.ok !err assert.ok fs.existsSync R.stylus.a.dst assert.notStrictEqual fs.statSync(R.stylus.a.dst).mtime, outTime done() it "#4 do twice with touch source, should compile", (done) -> this.timeout 3000 jcs mockReq(R.stylus.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.stylus.a.dst outTime = fs.statSync(R.stylus.a.dst).mtime setTimeout ()-> touch R.stylus.a.src jcs mockReq(R.stylus.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.stylus.a.dst outTime2 = fs.statSync(R.stylus.a.dst).mtime logger.debug "t1=#{outTime}" logger.debug "t2=#{outTime2}" assert.ok outTime2 > outTime done() , 1234 it "#5 touch included file, should compile", (done) -> this.timeout 3000 jcs mockReq(R.stylus.b.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.stylus.b.dst outTime = fs.statSync(R.stylus.b.dst).mtime setTimeout ()-> touch R.stylus.a.src jcs mockReq(R.stylus.b.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.stylus.b.dst outTime2 = fs.statSync(R.stylus.b.dst).mtime logger.debug "t1=#{outTime}" logger.debug "t2=#{outTime2}" assert.ok outTime2 > outTime done() , 1234 ############################################################ # Test less middleware describe "Test less middleware", -> jcs = createJcs 'l' it "#1 'a.less' should be compiled to 'a.css'", (done) -> jcs mockReq(R.less.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.less.a.dst done() ############################################################ # Test coffee middleware describe "Test coffee middleware", -> jcs = createJcs 'c' it "#1 'a.coffee' should be compiled to 'a.js'", (done) -> jcs mockReq(R.coffee.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.coffee.a.dst done() it "#2 do twice without touch source, should not compile", (done) -> jcs mockReq(R.coffee.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.coffee.a.dst outTime = fs.statSync(R.coffee.a.dst).mtime jcs mockReq(R.coffee.a.url), null, (err) -> if err logger.error err logger.error err.stack assert.ok !err assert.ok fs.existsSync R.coffee.a.dst assert.notStrictEqual fs.statSync(R.coffee.a.dst).mtime, outTime done() it "#3 do twice with touch source, should compile", (done) -> this.timeout 3000 jcs mockReq(R.coffee.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.coffee.a.dst outTime = fs.statSync(R.coffee.a.dst).mtime setTimeout ()-> touch R.coffee.a.src jcs mockReq(R.coffee.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.coffee.a.dst outTime2 = fs.statSync(R.coffee.a.dst).mtime logger.debug "t1=#{outTime}" logger.debug "t2=#{outTime2}" assert.ok outTime2 > outTime done() , 1234 ############################################################ # Test jade middleware describe "Test jade middleware", -> jcs = createJcs 'j' it "#1 'a.jade' should be compiled to 'a.html'", (done) -> jcs mockReq(R.jade.b.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.jade.b.dst done() it "#2 do twice without touch source, should not compile", (done) -> jcs mockReq(R.jade.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.jade.a.dst outTime = fs.statSync(R.jade.a.dst).mtime jcs mockReq(R.jade.a.url), null, (err) -> if err logger.error err logger.error err.stack assert.ok !err assert.ok fs.existsSync R.jade.a.dst assert.notStrictEqual fs.statSync(R.jade.a.dst).mtime, outTime done() it "#3 do twice with touch source, should compile", (done) -> this.timeout 3000 jcs mockReq(R.jade.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.jade.a.dst outTime = fs.statSync(R.jade.a.dst).mtime setTimeout ()-> touch R.jade.a.src jcs mockReq(R.jade.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.jade.a.dst outTime2 = fs.statSync(R.jade.a.dst).mtime logger.debug "t1=#{outTime}" logger.debug "t2=#{outTime2}" assert.ok outTime2 > outTime done() , 1234 it "#4 touch included file, should compile", (done) -> this.timeout 3000 jcs mockReq(R.jade.b.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.jade.b.dst outTime = fs.statSync(R.jade.b.dst).mtime setTimeout ()-> # Touch 'a', which is included by 'b' touch R.jade.a.src jcs mockReq(R.jade.b.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.jade.b.dst outTime2 = fs.statSync(R.jade.b.dst).mtime logger.debug "t1=#{outTime}" logger.debug "t2=#{outTime2}" assert.ok outTime2 > outTime done() , 1234 ############################################################ # Test ejs describe "Test ejs middleware", -> jcs = createJcs 'e' it "#1 'b.ejs' should be compiled to 'b.html'", (done) -> jcs mockReq(R.ejs.b.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.ejs.b.dst assert.ok fs.statSync(R.ejs.b.dst).size == 0 done() it "#2 do twice without touch source, should not compile", (done) -> jcs mockReq(R.ejs.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.ejs.a.dst outTime = fs.statSync(R.ejs.a.dst).mtime jcs mockReq(R.ejs.a.url), null, (err) -> if err logger.error err logger.error err.stack assert.ok !err assert.ok fs.existsSync R.ejs.a.dst assert.notStrictEqual fs.statSync(R.ejs.a.dst).mtime, outTime done() it "#3 do twice with touch source, should compile", (done) -> this.timeout 3000 jcs mockReq(R.ejs.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.ejs.a.dst outTime = fs.statSync(R.ejs.a.dst).mtime setTimeout ()-> touch R.ejs.a.src jcs mockReq(R.ejs.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.ejs.a.dst outTime2 = fs.statSync(R.ejs.a.dst).mtime logger.debug "t1=#{outTime}" logger.debug "t2=#{outTime2}" assert.ok outTime2 > outTime done() , 1234 ############################################################ # Test All middlewares, together describe "Test All middlewares, together", -> jcs = createJcs 's|c|j', urlBase: PREFIX it "#1 'POST' method should return next directly, without error", (done) -> jcs mockReq(R.stylus.x.urlP, 'POST'), null, (err) -> assert.ok !err done() it "#2 Non exist stylus should return next directly, without error", (done) -> jcs mockReq(R.stylus.x.urlP), null, (err) -> assert.ok !err done() it "#3 Non exist coffee should return next directly, without error", (done) -> jcs mockReq(R.coffee.x.urlP), null, (err) -> assert.ok !err done() it "#4 Non exist jade should return next directly, without error", (done) -> jcs mockReq(R.jade.x.urlP), null, (err) -> assert.ok !err done() it "#5 Non exist ejs should return next directly, without error", (done) -> jcs mockReq(R.ejs.x.urlP), null, (err) -> assert.ok !err done() it "#6 'a.styl' should be compiled to 'a.css', with prefix", (done) -> jcs mockReq(R.stylus.a.urlP), null, (err) -> assert.ok !err assert.ok fs.existsSync R.stylus.a.dst done() it "#7 'a.coffee' should be compiled to 'a.js', with prefix", (done) -> jcs mockReq(R.coffee.a.urlP), null, (err) -> assert.ok !err assert.ok fs.existsSync R.coffee.a.dst done() it "#8 'a.jade' should be compiled to 'a.html', with prefix", (done) -> jcs mockReq(R.jade.a.urlP), null, (err) -> assert.ok !err assert.ok fs.existsSync R.jade.a.dst done() it "#9 'a.ejs' should be compiled to 'a.html', with prefix", (done) -> jcs mockReq(R.ejs.a.urlP), null, (err) -> assert.ok !err assert.ok fs.existsSync R.ejs.a.dst done() it "#10 do twice without touch source, but with force, should compile", (done) -> this.timeout 3000 jcs = createJcs 's', force: true urlBase: 'prefix' jcs mockReq(R.stylus.a.urlP), null, (err) -> assert.ok !err assert.ok fs.existsSync R.stylus.a.dst outTime = fs.statSync(R.stylus.a.dst).mtime setTimeout ()-> jcs mockReq(R.stylus.a.urlP), null, (err) -> if err logger.error err logger.error err.stack assert.ok !err assert.ok fs.existsSync R.stylus.a.dst assert.ok fs.statSync(R.stylus.a.dst).mtime > outTime done() , 1158 it "#11 test compress", (done) -> jcs = createJcs 'j', force: true compress: true urlBase: 'prefix' jcs mockReq(R.jade.a.urlP), null, (err) -> assert.ok !err assert.ok fs.existsSync R.jade.a.dst size1 = fs.statSync(R.jade.a.dst).size jcs = createJcs 'j', force: true compress: false urlBase: 'prefix' jcs mockReq(R.jade.a.urlP), null, (err) -> assert.ok !err assert.ok fs.existsSync R.jade.a.dst size2 = fs.statSync(R.jade.a.dst).size assert.ok size2 > size1 done() ############################################################ # Test All middlewares, without prefix describe "Test All middlewares, without prefix", -> jcs = createJcs 's|c|j', urlBase: '/' examplesite = EXAMPLESITE it "#1 Non exist stylus should return next directly, without error", (done) -> jcs mockReq(R.stylus.x.url), null, (err) -> assert.ok !err done() it "#2 Non exist coffee should return next directly, without error", (done) -> jcs mockReq(R.coffee.x.url), null, (err) -> assert.ok !err done() it "#3 Non exist jade should return next directly, without error", (done) -> jcs mockReq(R.jade.x.url), null, (err) -> assert.ok !err done() it "#4 'a.styl' should be compiled to 'a.css', with prefix", (done) -> jcs mockReq(R.stylus.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.stylus.a.dst done() it "#5 'a.coffee' should be compiled to 'a.js', with prefix", (done) -> jcs mockReq(R.coffee.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.coffee.a.dst done() it "#6 'a.jade' should be compiled to 'a.html', with prefix", (done) -> jcs mockReq(R.jade.a.url), null, (err) -> assert.ok !err assert.ok fs.existsSync R.jade.a.dst done() ############################################################ # Test parallel... describe "Test parallel...", -> jcs = createJcs 's|c|j' it "#1 'parallel'", (done) -> this.timeout 2000 async.detect [ R.stylus.a R.stylus.b R.coffee.a R.jade.a R.jade.b ], (item, cb) -> jcs mockReq(item.url), null, (err) -> if err logger.error err cb true else if !fs.existsSync item.dst logger.error "Error: #{item.dst} not generated!" cb true else cb false , (result) -> assert.ok !result done() ############################################################ # Test prepare static resources. describe "Test prepare static resources.", -> it "#1 'prepare'", (done) -> createJcsObj('s|c|j').prepare (err)-> assert.ok !err for item in [ R.stylus.a R.stylus.b R.coffee.a R.jade.a R.jade.b ] assert.ok fs.existsSync item.dst done() ############################################################ # Test both ejs & jade describe "Test ejs overriding jade", -> jcs = createJcs 'e|j' it "#1 do both ejs & jade, should compile jade", (done) -> jcs mockReq(R.ejs.b.url), null, (err)-> assert.ok !err assert.ok fs.existsSync R.ejs.b.dst assert.ok fs.statSync(R.ejs.b.dst).size > 0 done()