2014-06-03 12:08:34 +00:00
|
|
|
var boot = require('../');
|
|
|
|
var fs = require('fs');
|
|
|
|
var path = require('path');
|
|
|
|
var expect = require('must');
|
|
|
|
var browserify = require('browserify');
|
|
|
|
var sandbox = require('./helpers/sandbox');
|
|
|
|
var vm = require('vm');
|
|
|
|
|
2014-10-21 06:21:40 +00:00
|
|
|
var compileStrategies = {
|
|
|
|
'default': function(appDir) {
|
|
|
|
var b = browserify({
|
|
|
|
basedir: appDir,
|
|
|
|
debug: true
|
|
|
|
});
|
|
|
|
|
|
|
|
b.require('./app.js', { expose: 'browser-app' });
|
|
|
|
return b;
|
|
|
|
},
|
|
|
|
|
|
|
|
'coffee': function(appDir) {
|
|
|
|
var b = browserify({
|
|
|
|
basedir: appDir,
|
|
|
|
extensions: ['.coffee'],
|
|
|
|
debug: true
|
|
|
|
});
|
|
|
|
|
|
|
|
b.transform('coffeeify');
|
|
|
|
|
|
|
|
b.require('./app.coffee', { expose: 'browser-app' });
|
|
|
|
return b;
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2014-06-03 12:08:34 +00:00
|
|
|
describe('browser support', function() {
|
2014-08-18 12:35:19 +00:00
|
|
|
this.timeout(60000); // 60s to give browserify enough time to finish
|
|
|
|
|
2014-08-19 07:26:57 +00:00
|
|
|
beforeEach(sandbox.reset);
|
|
|
|
|
2014-06-03 12:08:34 +00:00
|
|
|
it('has API for bundling and executing boot instructions', function(done) {
|
|
|
|
var appDir = path.resolve(__dirname, './fixtures/browser-app');
|
|
|
|
|
|
|
|
browserifyTestApp(appDir, function(err, bundlePath) {
|
|
|
|
if (err) return done(err);
|
|
|
|
|
|
|
|
var app = executeBundledApp(bundlePath);
|
|
|
|
|
|
|
|
// configured in fixtures/browser-app/boot/configure.js
|
|
|
|
expect(app.settings).to.have.property('custom-key', 'custom-value');
|
2014-06-13 11:14:43 +00:00
|
|
|
expect(Object.keys(app.models)).to.include('Customer');
|
|
|
|
expect(app.models.Customer.settings)
|
|
|
|
.to.have.property('_customized', 'Customer');
|
2014-06-03 12:08:34 +00:00
|
|
|
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2014-10-21 06:21:40 +00:00
|
|
|
it('supports coffee-script files', function(done) {
|
|
|
|
// add coffee-script to require.extensions
|
|
|
|
require('coffee-script/register');
|
|
|
|
|
|
|
|
var appDir = path.resolve(__dirname, './fixtures/coffee-app');
|
|
|
|
|
|
|
|
browserifyTestApp(appDir, 'coffee', function(err, bundlePath) {
|
|
|
|
if (err) return done(err);
|
|
|
|
|
|
|
|
var app = executeBundledApp(bundlePath);
|
|
|
|
|
|
|
|
// configured in fixtures/browser-app/boot/configure.coffee
|
|
|
|
expect(app.settings).to.have.property('custom-key', 'custom-value');
|
|
|
|
expect(Object.keys(app.models)).to.include('Customer');
|
|
|
|
expect(app.models.Customer.settings)
|
|
|
|
.to.have.property('_customized', 'Customer');
|
|
|
|
done();
|
|
|
|
});
|
2014-06-03 12:08:34 +00:00
|
|
|
});
|
2014-10-21 06:21:40 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
function browserifyTestApp(appDir, strategy, next) {
|
|
|
|
//set default args
|
|
|
|
if (((typeof strategy) === 'function') && !next) {
|
|
|
|
next = strategy;
|
|
|
|
strategy = undefined;
|
|
|
|
}
|
|
|
|
if (!strategy)
|
|
|
|
strategy = 'default';
|
|
|
|
|
|
|
|
var b = compileStrategies[strategy](appDir);
|
2014-06-03 12:08:34 +00:00
|
|
|
|
|
|
|
boot.compileToBrowserify(appDir, b);
|
|
|
|
|
|
|
|
var bundlePath = sandbox.resolve('browser-app-bundle.js');
|
|
|
|
var out = fs.createWriteStream(bundlePath);
|
2014-10-21 07:39:57 +00:00
|
|
|
b.bundle().pipe(out);
|
2014-08-04 08:33:03 +00:00
|
|
|
|
2014-06-03 12:08:34 +00:00
|
|
|
out.on('error', function(err) { return next(err); });
|
|
|
|
out.on('close', function() {
|
|
|
|
next(null, bundlePath);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function executeBundledApp(bundlePath) {
|
|
|
|
var code = fs.readFileSync(bundlePath);
|
|
|
|
var context = createBrowserLikeContext();
|
|
|
|
vm.runInContext(code, context, bundlePath);
|
|
|
|
var app = vm.runInContext('require("browser-app")', context);
|
|
|
|
|
|
|
|
printContextLogs(context);
|
|
|
|
|
|
|
|
return app;
|
|
|
|
}
|
|
|
|
|
|
|
|
function createBrowserLikeContext() {
|
2014-06-13 11:14:43 +00:00
|
|
|
var context = {
|
2014-06-03 12:08:34 +00:00
|
|
|
// required by browserify
|
|
|
|
XMLHttpRequest: function() { throw new Error('not implemented'); },
|
|
|
|
|
2014-06-13 11:14:43 +00:00
|
|
|
localStorage: {
|
|
|
|
// used by `debug` module
|
|
|
|
debug: process.env.DEBUG
|
|
|
|
},
|
|
|
|
|
2014-10-21 07:38:25 +00:00
|
|
|
// used by DataSource.prototype.ready
|
|
|
|
setTimeout: setTimeout,
|
|
|
|
|
2014-06-13 11:14:43 +00:00
|
|
|
// used by `debug` module
|
|
|
|
document: { documentElement: { style: {} } },
|
2014-06-03 12:08:34 +00:00
|
|
|
|
2014-08-18 12:49:02 +00:00
|
|
|
// used by `debug` module
|
|
|
|
navigator: { userAgent: 'sandbox' },
|
|
|
|
|
2014-07-17 08:05:08 +00:00
|
|
|
// used by crypto-browserify & friends
|
|
|
|
Int32Array: Int32Array,
|
|
|
|
DataView: DataView,
|
|
|
|
|
2014-06-03 12:08:34 +00:00
|
|
|
// allow the browserified code to log messages
|
|
|
|
// call `printContextLogs(context)` to print the accumulated messages
|
|
|
|
console: {
|
|
|
|
log: function() {
|
|
|
|
this._logs.log.push(Array.prototype.slice.call(arguments));
|
|
|
|
},
|
|
|
|
warn: function() {
|
|
|
|
this._logs.warn.push(Array.prototype.slice.call(arguments));
|
|
|
|
},
|
|
|
|
error: function() {
|
|
|
|
this._logs.error.push(Array.prototype.slice.call(arguments));
|
|
|
|
},
|
|
|
|
_logs: {
|
|
|
|
log: [],
|
|
|
|
warn: [],
|
|
|
|
error: []
|
|
|
|
},
|
|
|
|
}
|
2014-06-13 11:14:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// `window` is used by loopback to detect browser runtime
|
|
|
|
context.window = context;
|
|
|
|
|
|
|
|
return vm.createContext(context);
|
2014-06-03 12:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function printContextLogs(context) {
|
|
|
|
for (var k in context.console._logs) {
|
|
|
|
var items = context.console._logs[k];
|
|
|
|
for (var ix in items) {
|
|
|
|
console[k].apply(console, items[ix]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|