Skip to content
This repository has been archived by the owner on Apr 20, 2018. It is now read-only.

[dev] Fix some flow issues #543

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion lib/flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ Flow.prototype.setSteps = function (steps) {
this._steps = steps;
};

Flow.prototype.mergeSteps = function (steps) {
// better to use _.defaults than _.merge to not modify existing steps
// using _.merge would result in adding steps to an existing step array.
this._steps = _.defaults(steps || {}, this._steps);
};

//
// Returns the postprocessors for the furnished block type
//
Expand All @@ -45,7 +51,7 @@ Flow.prototype.post = function (blockType) {
//
Flow.prototype.setPost = function (post) {
// FIXME: Check format !!!
this._post = post;
this._post = post || {};
};


Expand All @@ -56,3 +62,28 @@ Flow.prototype.setPost = function (post) {
Flow.prototype.blockTypes = function () {
return _.union(_.keys(this._steps), _.keys(this._post));
};

// Default flow configuration for a target
Flow.defaultConfig = {
steps: {
js: ['concat', 'uglify'],
css: ['concat', 'cssmin']
},
post: {}
};

// Retrieve the flow config from the furnished configuration. It can be:
// - a dedicated one for the furnished target
// - a general one
// - the default one
Flow.getFlowFromConfig = function (config, target) {
var flow = new Flow(Flow.defaultConfig);

if (config.options && config.options.flow) {
var flowConfig = config.options.flow[target] ? config.options.flow[target] : config.options.flow;
flow.mergeSteps(flowConfig.steps);
flow.setPost(flowConfig.post);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newline after this


return flow;
};
27 changes: 2 additions & 25 deletions tasks/usemin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,7 @@
var util = require('util');
var chalk = require('chalk');

// Retrieve the flow config from the furnished configuration. It can be:
// - a dedicated one for the furnished target
// - a general one
// - the default one
var getFlowFromConfig = function (config, target) {
var Flow = require('../lib/flow');
var flow = new Flow({
steps: {
js: ['concat', 'uglify'],
css: ['concat', 'cssmin']
},
post: {}
});
if (config.options && config.options.flow) {
if (config.options.flow[target]) {
flow.setSteps(config.options.flow[target].steps);
flow.setPost(config.options.flow[target].post);
} else {
flow.setSteps(config.options.flow.steps);
flow.setPost(config.options.flow.post);
}
}
return flow;
};
var Flow = require('../lib/flow');

//
// Return which locator to use to get the revisioned version (revved) of the files, with, by order of
Expand Down Expand Up @@ -172,7 +149,7 @@ module.exports = function (grunt) {
.writeln('Going through ' + grunt.log.wordlist(this.filesSrc) + ' to update the config')
.writeln('Looking for build script HTML comment blocks');

var flow = getFlowFromConfig(grunt.config('useminPrepare'), this.target);
var flow = Flow.getFlowFromConfig(grunt.config('useminPrepare'), this.target);

var c = new ConfigWriter(flow, {
root: root,
Expand Down
154 changes: 154 additions & 0 deletions test/test-flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,158 @@ describe('ConfigWriter', function () {
assert.deepEqual(flow.post('js'), ['foo', 'bar']);
});

it('should default to empty post', function () {
// default flow
var flow = new Flow({
steps: {
js: ['concat', 'uglify'],
css: ['concat', 'cssmin']
},
post: {}
});
// this might be called if someone define a flow without adding a `post` entry
flow.setPost();
assert.deepEqual(flow._post, {});
});

it('should be able to merge steps', function () {
// default flow
var flow = new Flow({
steps: {
js: ['concat', 'uglify'],
css: ['concat', 'cssmin']
},
post: {}
});
// this might be called if someone define a flow without adding a `post` entry
flow.mergeSteps({
js: ['foo', 'bar']
});
assert.deepEqual(flow.steps('js'), ['foo', 'bar']);
assert.deepEqual(flow.steps('css'), ['concat', 'cssmin']);
});

it('should be able to merge steps', function () {
// default flow
var flow = new Flow({
steps: {
js: ['concat', 'uglify'],
css: ['concat', 'cssmin']
},
post: {}
});
// this might be called if someone define a flow without adding a `post` entry
flow.mergeSteps({
js: ['uglify']
});
assert.deepEqual(flow.steps('js'), ['uglify']);
assert.deepEqual(flow.steps('css'), ['concat', 'cssmin']);
});

});

describe('Flow builder from configuration', function () {
describe('global flow', function () {
it('should enable removing a step for a type', function () {
var flow = Flow.getFlowFromConfig({
html: 'index.html',
options: {
flow: {
steps: {
js: ['uglify']
}
}
}
});

assert.deepEqual(flow.steps('js'), ['uglify']);
assert.deepEqual(flow.steps('css'), Flow.defaultConfig.steps.css);
});

it('should enable clearing all steps for a type', function () {
var flow = Flow.getFlowFromConfig({
html: 'index.html',
options: {
flow: {
steps: {
css: []
}
}
}
});

assert.deepEqual(flow.steps('js'), Flow.defaultConfig.steps.js);
assert.deepEqual(flow.steps('css'), []);
});
});

describe('flow per target', function () {
it('should enable removing a step for a type', function () {
var flow = Flow.getFlowFromConfig({
html: 'index.html',
options: {
flow: {
html: {
steps: {
js: ['uglify']
}
}
}
}
}, 'html');

assert.deepEqual(flow.steps('js'), ['uglify']);
assert.deepEqual(flow.steps('css'), Flow.defaultConfig.steps.css);
});

it('should enable clearing all steps for a type', function () {
var flow = Flow.getFlowFromConfig({
html: 'index.html',
options: {
flow: {
html: {
steps: {
js: ['uglify'],
css: []
}
}
}
}
}, 'html');

assert.deepEqual(flow.steps('js'), ['uglify']);
assert.deepEqual(flow.steps('css'), []);
});
});

describe('Support multiple targets', function () {
it('should enable clearing all steps for a type', function () {
var config = {
foo: 'foo.html',
bar: 'bar.html',
options: {
flow: {
foo: {
steps: {}
},
bar: {
steps: {
js: ['concat'],
css: ['concat']
}
}
}
}
};

var fooFlow = Flow.getFlowFromConfig(config, 'foo');
var barFlow = Flow.getFlowFromConfig(config, 'bar');

assert.deepEqual(fooFlow.steps('js'), Flow.defaultConfig.steps.js);
assert.deepEqual(fooFlow.steps('css'), Flow.defaultConfig.steps.css);

assert.deepEqual(barFlow.steps('js'), ['concat']);
assert.deepEqual(barFlow.steps('css'), ['concat']);
});
});
});
66 changes: 54 additions & 12 deletions test/test-usemin-prepare.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,7 @@ describe('useminPrepare', function () {
flow: {
steps: {
js: ['uglify']
},
post: {}
}
}
}
});
Expand All @@ -236,14 +235,19 @@ describe('useminPrepare', function () {

var uglify = grunt.config('uglify');
var concat = grunt.config('concat');
var cssmin = grunt.config('cssmin');

assert.equal(concat, null);
assert.ok(uglify);
assert.ok(concat);
assert.equal(concat.generated.files.length, 1);
assert.equal(concat.generated.files[0].dest, path.normalize('.tmp/concat/styles/main.min.css'));

assert.ok(uglify);
assert.equal(uglify.generated.files.length, 1);
var files = uglify.generated.files[0];
assert.equal(uglify.generated.files[0].dest, path.normalize('dist/scripts/plugins.js'));

assert.equal(files.dest, path.normalize('dist/scripts/plugins.js'));
assert.ok(cssmin);
assert.equal(cssmin.generated.files.length, 1);
assert.equal(cssmin.generated.files[0].dest, path.normalize('dist/styles/main.min.css'));

});

Expand All @@ -257,8 +261,7 @@ describe('useminPrepare', function () {
html: {
steps: {
js: ['uglify']
},
post: {}
}
}
}
}
Expand All @@ -269,13 +272,53 @@ describe('useminPrepare', function () {

var uglify = grunt.config('uglify');
var concat = grunt.config('concat');
var cssmin = grunt.config('cssmin');

assert.ok(concat);
assert.equal(concat.generated.files.length, 1);
assert.equal(concat.generated.files[0].dest, path.normalize('.tmp/concat/styles/main.min.css'));

assert.ok(uglify);
assert.equal(uglify.generated.files.length, 1);
assert.equal(uglify.generated.files[0].dest, path.normalize('dist/scripts/plugins.js'));

assert.ok(cssmin);
assert.equal(cssmin.generated.files.length, 1);
assert.equal(cssmin.generated.files[0].dest, path.normalize('dist/styles/main.min.css'));

});

it('should allow to suppress a step', function () {
grunt.log.muted = true;
grunt.config.init();
grunt.config('useminPrepare', {
html: 'index.html',
options: {
flow: {
html: {
steps: {
js: ['uglify'],
css: []
}
}
}
}
});
grunt.file.copy(path.join(__dirname, 'fixtures/usemin.html'), 'index.html');
grunt.task.run('useminPrepare');
grunt.task.start();

var uglify = grunt.config('uglify');
var concat = grunt.config('concat');
var cssmin = grunt.config('cssmin');

assert.equal(concat, null);

assert.ok(uglify);
assert.equal(uglify.generated.files.length, 1);
var files = uglify.generated.files[0];
assert.equal(files.dest, path.normalize('dist/scripts/plugins.js'));
assert.equal(uglify.generated.files[0].dest, path.normalize('dist/scripts/plugins.js'));

assert.equal(cssmin, null);
});

it('should allow use to furnish new steps of the flow', function () {
Expand All @@ -302,8 +345,7 @@ describe('useminPrepare', function () {
flow: {
steps: {
js: [copy]
},
post: {}
}
}
}
});
Expand Down