Skip to content

Commit

Permalink
Make slim build code path testable; Adds tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rwaldron committed Oct 26, 2015
1 parent 1941016 commit c976c80
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 8 deletions.
32 changes: 24 additions & 8 deletions lib/tessel/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,12 +302,13 @@ actions.tarBundle = function(opts) {
if (opts.slim) {
logs.info('Generating slim build.');
return new Promise(function(resolve, reject) {
glob(process.cwd() + '/**/*.tesselignore', {
actions.glob(target + '/**/*.tesselignore', {
dot: true
}, function(error, ignoreFiles) {
if (error) {
return reject(error);
}

var rules = ignoreFiles.reduce(function(rules, ignoreFile) {
var dirname = path.dirname(ignoreFile);
var patterns = fs.readFileSync(ignoreFile, 'utf8').trim().split('\n').map(function(pattern) {
Expand All @@ -330,27 +331,23 @@ actions.tarBundle = function(opts) {

var exclusions = '{' + rules.join(',') + '}';

var b = browserify(opts.resolvedEntryPoint, {
var b = actions.browserify(opts.resolvedEntryPoint, {
builtins: false,
commondir: false,
browserField: false,
detectGlobals: false,
ignoreMissing: true
});

glob.sync(exclusions).forEach(function(file) {
actions.glob.sync(exclusions).forEach(function(file) {
b.exclude(file);
});

b.bundle(function(error, results) {
if (error) {
return reject(error);
} else {
var bundled = uglify.minify(results.toString(), {
fromString: true
});

fs.writeFileSync(opts.slimPath, bundled.code);
fs.writeFileSync(opts.slimPath, actions.compress(results));

var fstream = new Ignore({
path: target,
Expand Down Expand Up @@ -493,6 +490,25 @@ actions.startPushedScript = function(tessel, entryPoint) {
});
};

// To make these operations testable, we must wrap them
// in our own exported `actions`.
actions.glob = function(pattern, options, callback) {
glob(pattern, options, callback);
};

actions.glob.sync = function(pattern, options) {
return glob.sync(pattern, options);
};

actions.browserify = function(entry, options) {
return browserify(entry, options);
};

actions.compress = function(source) {
return uglify.minify(source.toString(), {
fromString: true
}).code;
};

if (global.IS_TEST_ENV) {
module.exports = actions;
Expand Down
92 changes: 92 additions & 0 deletions test/unit/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ var mkdirp = require('mkdirp');
var path = require('path');
var rimraf = require('rimraf');
var Ignore = require('fstream-ignore');
var browserify = require('browserify');
var uglify = require('uglify-js');
var meminfo = fs.readFileSync('test/unit/fixtures/proc-meminfo', 'utf8');

var deployFolder = path.join(__dirname, 'tmp');
var deployFile = path.join(deployFolder, 'app.js');
var codeContents = 'console.log("testing deploy");';
Expand Down Expand Up @@ -325,6 +328,9 @@ exports['Tessel.prototype.deployScript'] = {
exports['tarBundle'] = {
setUp: function(done) {
this.addIgnoreRules = sandbox.spy(Ignore.prototype, 'addIgnoreRules');
this.logsWarn = sandbox.stub(logs, 'warn', function() {});
this.logsInfo = sandbox.stub(logs, 'info', function() {});

done();
},

Expand All @@ -347,6 +353,92 @@ exports['tarBundle'] = {
}.bind(this));
},

slim: function(test) {
test.expect(21);

var target = 'test/unit/fixtures/slim';
var entryPoint = 'index.js';
var tesselignore = path.join(target, '.tesselignore');
var fileToIgnore = path.join(target, 'mock-foo.js');
var slimPath = path.join(target, 'bundle.js');

this.glob = sandbox.stub(deploy, 'glob', function(pattern, options, callback) {
test.equal(options.dot, true);
process.nextTick(function() {
callback(null, [tesselignore]);
});
});

// This is necessary because the path in which the tests are being run might
// not be the same path that this operation occurs within.
this.globSync = sandbox.stub(deploy.glob, 'sync', function() {
return [fileToIgnore];
});

this.exclude = sandbox.spy(browserify.prototype, 'exclude');
this.browserify = sandbox.spy(deploy, 'browserify');

this.minify = sandbox.spy(uglify, 'minify');
this.compress = sandbox.spy(deploy, 'compress');

this.writeFileSync = sandbox.spy(fs, 'writeFileSync');
this.unlinkSync = sandbox.spy(fs, 'unlinkSync');

deploy.tarBundle({
target: target,
resolvedEntryPoint: path.join(target, entryPoint),
slimPath: slimPath,
slim: true,
}).then(function() {
test.equal(this.glob.callCount, 1);
test.equal(this.globSync.callCount, 1);

test.equal(this.browserify.callCount, 1);
test.equal(this.browserify.lastCall.args[0], path.join(target, entryPoint));

// These options are extrememly important. Without them,
// the bundles will have node.js built-ins shimmed!!
test.deepEqual(this.browserify.lastCall.args[1], {
builtins: false,
commondir: false,
browserField: false,
detectGlobals: false,
ignoreMissing: true
});

test.equal(this.exclude.callCount, 1);
test.equal(this.exclude.lastCall.args[0], 'test/unit/fixtures/slim/mock-foo.js');

test.equal(this.compress.callCount, 1);
test.equal(Buffer.isBuffer(this.compress.lastCall.args[0]), true);

var minified = this.compress.lastCall.returnValue;

test.equal(minified.indexOf('!!mock foo!!'), -1);

test.equal(this.minify.callCount, 1);
test.equal(typeof this.minify.lastCall.args[0], 'string');

// Cannot deepEqual because uglify.minify(..., options) will
// mutate the options reference. No need to keep track of that.
test.equal(this.minify.lastCall.args[1].fromString, true);

// Creates up bundle.js
test.equal(this.writeFileSync.callCount, 1);
test.equal(this.writeFileSync.lastCall.args[0], slimPath);
test.equal(this.writeFileSync.lastCall.args[1], minified);

test.equal(this.addIgnoreRules.callCount, 1);
test.deepEqual(this.addIgnoreRules.lastCall.args[0], ['*', '!' + slimPath]);

// Cleaned up bundle.js
test.equal(this.unlinkSync.callCount, 1);
test.equal(this.unlinkSync.lastCall.args[0], slimPath);

test.done();
}.bind(this));
},

single: function(test) {
test.expect(3);

Expand Down
1 change: 1 addition & 0 deletions test/unit/fixtures/slim/.tesselignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mock-foo.js
3 changes: 3 additions & 0 deletions test/unit/fixtures/slim/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
var foo = true ? require('foo') : require('./mock-foo');

console.log(foo());
3 changes: 3 additions & 0 deletions test/unit/fixtures/slim/mock-foo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = function() {
return '!!mock foo!! <-- this string must not appear in bundle.js';
};
6 changes: 6 additions & 0 deletions test/unit/fixtures/slim/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "slim",
"version": "0.0.1",
"description": "slim",
"main": "./index.js"
}

0 comments on commit c976c80

Please sign in to comment.