Permalink
Browse files

now with 100% more tests

  • Loading branch information...
1 parent 999a2a0 commit 1e77dfd8bf21c7e95c855429c8c055851f5bfae4 @clarkdave committed Dec 17, 2013
View
@@ -1,4 +1,4 @@
test:
- NODE_ENV=test ./node_modules/.bin/mocha
+ NODE_ENV=test ./node_modules/.bin/mocha test/unit test/requests
.PHONY: test
View
@@ -2,13 +2,16 @@
var express = require('express'),
env = process.env.NODE_ENV,
- ConnectMincer = require('../../')
+ ConnectMincer = require('../../'),
+ Mincer = require('mincer')
;
var app = express();
// set up connect-mincer middleware
var mincer = new ConnectMincer({
+ // you can, optionally, pass in your own required Mincer class, so long as it is >= 0.5.0
+ mincer: Mincer,
root: __dirname,
production: env === 'production' || env === 'staging',
// uncomment to have view helpers generate urls of the form: //assets.example.com/assets/...
@@ -1,21 +1,22 @@
'use strict';
-var Mincer = require('mincer'),
- fs = require('fs'),
+var fs = require('fs'),
_ = require('underscore')
;
var ConnectMincer = (function() {
function ConnectMincer(opts) {
- this.Mincer = Mincer;
+ opts = opts || {};
+
+ this._setMincer(opts.mincer);
+
this.production = opts.production === true ? true : false;
this.options = opts;
this._setAssetHost(opts.assetHost);
this._setMountPoint(opts.mountPoint);
this._createEnvironment(opts.root, opts.paths);
- this._setPrecompileList(opts.precompileList);
if (this.options.precompile !== false) {
// if precompile has not explicitly been set to false, default it to true
@@ -37,6 +38,32 @@ var ConnectMincer = (function() {
}
/**
+ * Set the Mincer class we'll use.
+ *
+ * If not provided, the bundled Mincer object will be used. It should be safe to pass in any version of Mincer
+ * unless there has been a major update and the public API has changed.
+ *
+ * Versions < 0.5.x of Mincer are not supported and will generate an error
+ *
+ * @param {[type]} Mincer [description]
+ */
+ ConnectMincer.prototype._setMincer = function(Mincer) {
+
+ // if no Mincer was provided, we'll require our own bundled one
+ this.Mincer = Mincer || require('mincer');
+
+ // check the version of the passed in Mincer. We no longer support versions < 0.5 because of API changes
+ var version = this.Mincer.VERSION;
+
+ if (!version) throw new Error("Mincer class should be a valid Mincer object, e.g. require('mincer')");
+
+ var major = parseInt(version.split('.')[0], 10),
+ minor = parseInt(version.split('.')[1], 10);
+
+ if (major === 0 && minor < 5) throw new Error("provided Mincer class must be >= 0.5.x (you provided " + version + ")");
+ };
+
+ /**
* Sanitize and set the mount point. If no mount point was provided, it will default
* to /assets.
*
@@ -60,26 +87,6 @@ var ConnectMincer = (function() {
};
/**
- * Set the precompile list. If none is provided, default to a deep wildcard which will
- * precompile everything. This is usually OK, but if dependencies like bootstrap are involved
- * they can break because deeper components will fail to compile independently.
- *
- * @param {[type]} precompileList [description]
- */
- ConnectMincer.prototype._setPrecompileList = function(precompileList) {
-
- if (!precompileList) {
- precompileList = ['*', '*/**'];
- } else {
- if (!(precompileList instanceof Array)) {
- throw new Error("Precompile list must be an array");
- }
- }
-
- this.precompileList = precompileList;
- };
-
- /**
* Set the asset host if the provided assetHost is not null or an empty string.
*
* @param {[type]} assetHost [description]
@@ -116,11 +123,20 @@ var ConnectMincer = (function() {
throw new Error("Asset root [" + root + "] does not exist");
}
- var environment = new Mincer.Environment(root);
+ if (!Array.isArray(paths) || !paths.length) {
+ throw new Error("Asset paths are missing, e.g. ['assets/css', 'assets/js']");
+ }
+
+ var environment = new this.Mincer.Environment(root);
paths.forEach(function(path) {
environment.appendPath(path);
});
+ // implement the `asset_path` helper for assets. this is not set by default because Mincer doesn't
+ // know what the final path should be, but we do so we're implementing it here
+ //
+ // this can then be used in assets thusly: <%= asset_path('logo.png') %>
+
environment.registerHelper('asset_path', function(name, opts) {
var asset = environment.findAsset(name, opts);
if (!asset) throw new Error("File [" + name + "] not found");
@@ -358,7 +374,7 @@ var ConnectMincer = (function() {
}
// otherwise a normal dev server is used, which will recompile files on a request if necessary
- var server = new Mincer.Server(this.environment, this.manifest);
+ var server = new this.Mincer.Server(this.environment, this.manifest);
return function(req, res) {
return server.handle(req, res);
View
@@ -16,7 +16,7 @@
"type": "git",
"url": "git://github.com/clarkdave/connect-mincer"
},
- "main": "./lib/connect-mincer.js",
+ "main": "./lib/connect_mincer.js",
"dependencies": {
"mincer": "0.5.12",
"underscore": "1.4.x"
@@ -35,7 +35,9 @@
"mocha": "1.8.x",
"chai": "*",
"should": "*",
- "sinon": "1.6.x"
+ "sinon": "1.6.x",
+ "supertest": "*",
+ "cheerio": "*"
},
"engines": {
"node": ">= 0.6.0"
@@ -0,0 +1,6 @@
+body {
+ font-family: helvetica, arial;
+ margin: 30px;
+ padding: 30px;
+ background: url(<%= asset_path('background.png') %>) no-repeat 0 0;
+}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1 @@
+console.log('Hello');
@@ -0,0 +1,2 @@
+//= require underscore
+//= require jquery
View
@@ -0,0 +1,36 @@
+'use strict';
+
+var express = require('express'),
+ ConnectMincer = require('../../../')
+;
+
+var app = express();
+
+var mincer = new ConnectMincer({
+ root: __dirname,
+ paths: [
+ 'assets/img',
+ 'assets/css',
+ 'assets/js',
+ 'vendor/css',
+ 'vendor/js'
+ ],
+});
+
+app.use(mincer.assets());
+app.use('/assets', mincer.createServer());
+
+app.set('view engine', 'ejs');
+app.set('views', __dirname + '/views');
+
+app.get('/', function(req, res) {
+ res.render('index.ejs');
+});
+
+app.use(function(err, req, res, next) {
+ console.error(err);
+ next();
+});
+
+
+module.exports = app;
@@ -0,0 +1 @@
+window.jquery = {};
@@ -0,0 +1 @@
+window.underscore = {};
@@ -0,0 +1,13 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset='utf-8'>
+ <%- css('layout.css') %>
+</head>
+<body>
+ <h1>Testing</h1>
+ <p>Hello</p>
+ <%- js('libs.js') %>
+ <%- js('app.js') %>
+</body>
+</html>
View
@@ -0,0 +1,65 @@
+var async = require('async'),
+ should = require('should'),
+ sinon = require('sinon'),
+ cheerio = require('cheerio'),
+ supertest = require('supertest'),
+ ConnectMincer = require('../../lib/connect_mincer')
+;
+
+describe('Basic app', function() {
+
+ var app = require('../apps/basic'), request;
+
+ describe('with default ConnectMincer options', function() {
+
+ before(function() {
+
+
+ request = supertest(app);
+ });
+
+ it('should have correct tags in output', function(done) {
+
+ request
+ .get('/')
+ .expect(200)
+ .end(function(err, res) {
+ should.not.exist(err);
+
+ var $ = cheerio.load(res.text);
+
+ var link = $('link').first();
+ link.attr('type').should.eql('text/css');
+ link.attr('href').should.eql('/assets/layout.css?body=1');
+ link.attr('rel').should.eql('stylesheet');
+ link.attr('media').should.eql('screen');
+
+ var scripts = $('script');
+ scripts.length.should.eql(4);
+
+ scripts.eq(0).attr('src').should.eql('/assets/underscore.js?body=1');
+ scripts.eq(1).attr('src').should.eql('/assets/jquery.js?body=1');
+ scripts.eq(2).attr('src').should.eql('/assets/libs.js?body=1');
+ scripts.eq(3).attr('src').should.eql('/assets/app.js?body=1');
+
+ done();
+ });
+ });
+
+ it('should render assets', function(done) {
+
+ request
+ .get('/assets/layout.css?body=1')
+ .expect(200)
+ .end(function(err, res) {
+ should.not.exist(err);
+
+ // verify type is OK and the asset_path helper is working as it should
+ res.type.should.equal('text/css');
+ res.text.should.match(/url\(\/assets\/background\.png\)/);
+
+ done();
+ });
+ });
+ });
+});
@@ -1,5 +0,0 @@
-var async = require('async'),
- should = require('should'),
- sinon = require('sinon')
-;
-
@@ -0,0 +1,79 @@
+var async = require('async'),
+ should = require('should'),
+ sinon = require('sinon'),
+ ConnectMincer = require('../../lib/connect_mincer')
+;
+
+describe('ConnectMincer', function() {
+
+ describe('instantiating', function() {
+
+ it('should allow passing a custom Mincer object', function() {
+ var Mincer = require('Mincer');
+
+ var cm = new ConnectMincer({
+ mincer: Mincer,
+ root: __dirname,
+ paths: ['assets/css']
+ });
+
+ // verify that our Mincer is the one being used ...
+ should.exist(cm.Mincer);
+ cm.Mincer.should.equal(Mincer);
+ });
+
+ it('should error if required properties are missing', function() {
+ (function() {
+ new ConnectMincer({});
+ }).should.throwError(/root/);
+
+ (function() {
+ new ConnectMincer({
+ root: __dirname,
+ });
+ }).should.throwError(/paths/);
+ });
+
+ it('should set the asset host', function() {
+ new ConnectMincer({
+ root: __dirname,
+ paths: ['assets/css'],
+ assetHost: '//cdn.example.com'
+ }).assetHost.should.eql('//cdn.example.com');
+ });
+
+ it('should set the mount point', function() {
+ new ConnectMincer({
+ root: __dirname,
+ paths: ['assets/css']
+ }).mountPoint.should.eql('/assets');
+
+ new ConnectMincer({
+ root: __dirname,
+ paths: ['assets/css'],
+ mountPoint: '/static'
+ }).mountPoint.should.eql('/static');
+
+ new ConnectMincer({
+ root: __dirname,
+ paths: ['assets/css'],
+ mountPoint: 'static'
+ }).mountPoint.should.eql('/static');
+
+ new ConnectMincer({
+ root: __dirname,
+ paths: ['assets/css'],
+ mountPoint: '/assets/'
+ }).mountPoint.should.eql('/assets');
+ });
+ });
+
+ it('should make the environment accessible', function() {
+ var cm = new ConnectMincer({
+ root: __dirname,
+ paths: ['assets/css']
+ });
+
+ should.exist(cm.environment);
+ });
+});

0 comments on commit 1e77dfd

Please sign in to comment.