chore(testsuite): organize tests into node/browser

This commit introduces a clean separation of node and browser tests.

ALL tests should be organized according to where they are run

non browser (áka node tests): `test/spec/node`
browser tests: `test/spec/browser`
This commit is contained in:
Nico Rehwaldt 2014-03-13 11:21:03 +01:00
parent d7ccd35e9f
commit 423c757f1d
14 changed files with 217 additions and 175 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
node_modules/ node_modules/
bower_components/
tmp/ tmp/
docs/ docs/
dist/ dist/

View File

@ -26,7 +26,7 @@ module.exports = function(grunt) {
}, },
jasmine_node: { jasmine_node: {
specNameMatcher: '.*Spec', specNameMatcher: '.*Spec',
projectRoot: 'test/spec/model', projectRoot: 'test/spec/node',
jUnit: { jUnit: {
report: true, report: true,
savePath : 'tmp/reports/jasmine', savePath : 'tmp/reports/jasmine',
@ -56,16 +56,17 @@ module.exports = function(grunt) {
browserify: { browserify: {
options: { options: {
alias: [ alias: [
'<%= config.sources %>/main.js:Bpmn', '<%= config.sources %>/main.js:bpmn',
'<%= config.sources %>/model/BpmnModel.js:BpmnModel' '<%= config.sources %>/Model.js:bpmn/Model'
] ]
}, },
src: { sources: {
files: { files: {
'<%= config.dist %>/bpmn.js': [ '<%= config.sources %>/**/*.js' ] '<%= config.dist %>/bpmn.js': [ '<%= config.sources %>/**/*.js' ]
}, },
options: { options: {
debug: true debug: true,
transform: [ 'debowerify' ]
} }
}, },
dist: { dist: {
@ -74,7 +75,7 @@ module.exports = function(grunt) {
}, },
options: { options: {
debug: false, debug: false,
transform: [ 'uglifyify' ] transform: [ 'debowerify', 'uglifyify' ]
} }
} }
}, },
@ -93,12 +94,16 @@ module.exports = function(grunt) {
}, },
watch: { watch: {
sources: { sources: {
files: [ '<%= config.sources %>/**/*.js'], files: [ '<%= config.sources %>/**/*.js', '<%= config.samples %>/**/*.*' ],
tasks: [ 'browserify:src'] tasks: [ 'browserify:sources', 'copy:samples' ]
},
samples: {
files: [ '<%= config.samples %>/**/*.*' ],
tasks: [ 'copy:samples' ]
}, },
jasmine_node: { jasmine_node: {
files: [ '<%= config.sources %>/**/*.js', '<%= config.tests %>/spec/model/**/*.js'], files: [ '<%= config.sources %>/**/*.js', '<%= config.tests %>/spec/node/**/*.js' ],
tasks: [ 'jasmine_node'] tasks: [ 'jasmine_node' ]
} }
}, },
jsdoc: { jsdoc: {
@ -111,7 +116,7 @@ module.exports = function(grunt) {
} }
}, },
concurrent: { concurrent: {
'sources': [ 'browserify:src', 'jshint' ], 'sources': [ 'browserify:sources', 'jshint' ],
'build': [ 'jshint', 'build', 'jsdoc' ] 'build': [ 'jshint', 'build', 'jsdoc' ]
}, },
connect: { connect: {
@ -128,20 +133,21 @@ module.exports = function(grunt) {
] ]
} }
} }
}, }
}); });
// tasks // tasks
grunt.registerTask('test', [ 'jasmine_node', 'karma:single' ]); grunt.registerTask('test', [ 'jasmine_node', 'karma:single' ]);
grunt.registerTask('build', [ 'browserify', 'copy:samples' ]); grunt.registerTask('build', [ 'browserify:dist', 'copy:samples' ]);
grunt.registerTask('auto-build', [ grunt.registerTask('auto-build', [
'concurrent:build', 'concurrent:sources',
'connect:livereload', 'connect:livereload',
'watch' 'watch'
]); ]);
grunt.registerTask('auto-test', [ 'jasmine_node', 'watch:test' ]); grunt.registerTask('auto-test', [ 'jasmine_node', 'watch:jasmine_node' ]);
grunt.registerTask('default', [ 'jshint', 'test', 'build', 'jsdoc' ]); grunt.registerTask('default', [ 'jshint', 'test', 'build', 'jsdoc' ]);
}; };

View File

@ -6,11 +6,16 @@
<div id="drop-zone">Drop files here</div> <div id="drop-zone">Drop files here</div>
<output id="list"></output> <output id="list"></output>
<div class="canvas"></div>
<script src="../bpmn.js"></script> <script src="../bpmn.js"></script>
<script> <script>
var BpmnModel = require('BpmnModel'); var bpmn = require('bpmn');
var Model = require('bpmn/Model');
</script> </script>
<script> <script>
function handleFileSelect(evt) { function handleFileSelect(evt) {
evt.stopPropagation(); evt.stopPropagation();
@ -19,7 +24,6 @@
var files = evt.dataTransfer.files; // FileList object. var files = evt.dataTransfer.files; // FileList object.
// files is a FileList of File objects. List some properties. // files is a FileList of File objects. List some properties.
var output = [];
for (var i = 0, f; f = files[i]; i++) { for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader(); var reader = new FileReader();
@ -28,11 +32,17 @@
var xml = e.target.result; var xml = e.target.result;
BpmnModel.fromXML(xml, 'bpmn:Definitions', function(err, result) { Model.fromXML(xml, 'bpmn:Definitions', function(err, definitions) {
if (err) {
var resultAsJson = JSON.stringify(result, null, ' '); console.error(err);
document.getElementById('list').innerHTML = resultAsJson; } else {
console.log(definitions);
}
}); });
/*renderer.renderXML(xml, function(err) {
console.log('diagram rendererd');
});*/
}; };
reader.readAsText(f); reader.readAsText(f);

View File

@ -4,10 +4,10 @@ var Model = require('moddle'),
xml = require('moddle-xml'); xml = require('moddle-xml');
var PACKAGES = { var PACKAGES = {
bpmn: require('../../resources/bpmn/json/bpmn.json'), bpmn: require('../resources/bpmn/json/bpmn.json'),
bpmndi: require('../../resources/bpmn/json/bpmndi.json'), bpmndi: require('../resources/bpmn/json/bpmndi.json'),
dc: require('../../resources/bpmn/json/dc.json'), dc: require('../resources/bpmn/json/dc.json'),
di: require('../../resources/bpmn/json/di.json') di: require('../resources/bpmn/json/di.json')
}; };
var INSTANCE = null; var INSTANCE = null;

View File

@ -33,31 +33,31 @@
"grunt-contrib-watch": "~0.5.0", "grunt-contrib-watch": "~0.5.0",
"grunt-contrib-connect": "~0.6.0", "grunt-contrib-connect": "~0.6.0",
"grunt-contrib-jshint": "~0.7.2", "grunt-contrib-jshint": "~0.7.2",
"grunt-contrib-copy": "~0.5.0",
"grunt-browserify": "~1.3.0", "grunt-browserify": "~1.3.0",
"grunt-jsdoc": "~0.5.1", "grunt-jsdoc": "~0.5.1",
"grunt-concurrent": "~0.4.0",
"grunt-karma": "~0.8.0",
"grunt-jasmine-node": "~0.1.0", "grunt-jasmine-node": "~0.1.0",
"load-grunt-tasks": "~0.3.0", "load-grunt-tasks": "~0.3.0",
"uglifyify": "~1.1.0", "uglifyify": "~1.1.0",
"debowerify": "0.6.0", "debowerify": "0.6.0",
"jsondiffpatch": "~0.1.4",
"xsd-schema-validator": "0.0.3",
"sax": "~0.6.0",
"karma": "~0.12.0",
"grunt-karma": "~0.8.0",
"browserify": "~3.32.1", "browserify": "~3.32.1",
"karma": "~0.12.0",
"karma-browserify": "~0.0.6", "karma-browserify": "~0.0.6",
"karma-jasmine": "~0.2.0", "karma-jasmine": "~0.2.0",
"karma-chrome-launcher": "~0.1.2", "karma-chrome-launcher": "~0.1.2",
"karma-phantomjs-launcher": "~0.1.2", "karma-phantomjs-launcher": "~0.1.2",
"grunt-contrib-copy": "~0.5.0", "jsondiffpatch": "~0.1.4",
"moddle": "~0.0.1", "xsd-schema-validator": "0.0.3",
"moddle-xml": "~0.0.1", "sax": "~0.6.0",
"grunt-concurrent": "~0.4.0", "lodash": "~2.4.0",
"lodash": "~2.4.0" "eve": "0.4.1"
}, },
"dependencies": { "dependencies": {
"moddle": "~0.0.1", "moddle": "~0.0.1",
"moddle-xml": "~0.0.1", "moddle-xml": "~0.0.1",
"diagram-js": "~0.0.1",
"lodash": "~2.4.0" "lodash": "~2.4.0"
} }
} }

View File

@ -1,100 +0,0 @@
var fs = require('fs');
var util = require('util');
var _ = require('lodash');
var Model = require('moddle');
var logger = require('moddle/lib/util/Logger');
var jsondiffpatch = require('jsondiffpatch').create({
objectHash: function (obj) {
return JSON.stringify(obj);
}
});
function ensureDirExists(dir) {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
}
function readFile(filename) {
return fs.readFileSync(filename, { encoding: 'UTF-8' });
}
function initAdditionalMatchers() {
// this == jasmine
this.addMatchers({
toDeepEqual: function(expected) {
// jasmine 1.3.x
var actual = this.actual;
var actualClone = _.cloneDeep(actual);
var expectedClone = _.cloneDeep(expected);
var result = {
pass: _.isEqual(actualClone, expectedClone)
};
if (!result.pass) {
logger.error('[to-deep-equal] elements do not equal. diff: ', util.inspect(jsondiffpatch.diff(actualClone, expectedClone), false, 4));
}
// jasmine 1.3.x
return result.pass;
}
});
}
function createModelBuilder(base) {
var cache = {};
if (!base) {
throw new Error("[test-util] must specify a base directory");
}
function createModel(packageNames) {
var packages = _.collect(packageNames, function(f) {
var pkg = cache[f];
var file = base + f + '.json';
if (!pkg) {
try {
pkg = cache[f] = JSON.parse(readFile(base + f + '.json'));
} catch (e) {
throw new Error('[Helper] failed to parse <' + file + '> as JSON: ' + e.message);
}
}
return pkg;
});
return new Model(packages);
}
return createModel;
}
/** log during execution of a test callback */
function log(level, fn) {
logger.setLevel(level);
return function(done) {
fn(function() {
logger.setLevel(null);
done();
});
};
}
module.exports.log = log;
module.exports.readFile = readFile;
module.exports.ensureDirExists = ensureDirExists;
module.exports.initAdditionalMatchers = initAdditionalMatchers;
module.exports.createModelBuilder = createModelBuilder;

53
test/spec/Matchers.js Normal file
View File

@ -0,0 +1,53 @@
var logger = require('moddle').util.Logger;
var jsondiffpatch = require('jsondiffpatch'),
_ = require('lodash');
var compare = jsondiffpatch.create({
objectHash: function (obj) {
return JSON.stringify(obj);
}
});
function deepEquals(actual, expected) {
var actualClone = _.cloneDeep(actual);
var expectedClone = _.cloneDeep(expected);
var result = {
pass: _.isEqual(actualClone, expectedClone)
};
if (!result.pass) {
logger.error('[to-deep-equal] elements do not equal. diff: ', compare.diff(actualClone, expectedClone), false, 4);
}
return result;
}
function wrap(isOld, callback) {
if (isOld) {
return function(expected) {
return callback(expected, this.actual).pass;
};
} else {
return callback;
}
}
function addMatchers() {
// DIRTY HACK DDDSZZZ
// Remove when we got jasmin 2.x in browser AND node env
var old = !jasmine.addMatchers;
(old ? this : jasmine).addMatchers({
toDeepEqual: wrap(old, function(actual, expected) {
return deepEquals(actual, expected);
})
});
}
module.exports.add = addMatchers;

View File

@ -1,6 +1,6 @@
var BpmnModel = require('../../../lib/model/BpmnModel'); var BpmnModel = require('../../../lib/Model');
describe('BpmnModel - browser support', function() { describe('Model - browser support', function() {
function read(xml, callback, done) { function read(xml, callback, done) {

51
test/spec/node/Helper.js Normal file
View File

@ -0,0 +1,51 @@
var fs = require('fs'),
util = require('util'),
_ = require('lodash');
var Model = require('moddle');
function ensureDirExists(dir) {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
}
function readFile(filename) {
return fs.readFileSync(filename, { encoding: 'UTF-8' });
}
function createModelBuilder(base) {
var cache = {};
if (!base) {
throw new Error("[test-util] must specify a base directory");
}
function createModel(packageNames) {
var packages = _.collect(packageNames, function(f) {
var pkg = cache[f];
var file = base + f + '.json';
if (!pkg) {
try {
pkg = cache[f] = JSON.parse(readFile(base + f + '.json'));
} catch (e) {
throw new Error('[Helper] failed to parse <' + file + '> as JSON: ' + e.message);
}
}
return pkg;
});
return new Model(packages);
}
return createModel;
}
module.exports.readFile = readFile;
module.exports.ensureDirExists = ensureDirExists;
module.exports.createModelBuilder = createModelBuilder;

View File

@ -1,12 +1,14 @@
var _ = require('lodash'); var _ = require('lodash');
var BpmnModel = require('../../../lib/model/BpmnModel'); var BpmnModel = require('../../../lib/Model');
var Helper = require('../Helper'); var Helper = require('./Helper'),
Matchers = require('../Matchers');
describe('BpmnModel', function() {
beforeEach(Helper.initAdditionalMatchers); describe('Model', function() {
beforeEach(Matchers.add);
describe('parsing', function() { describe('parsing', function() {
@ -37,6 +39,7 @@ describe('BpmnModel', function() {
expect(descriptor).toBeDefined(); expect(descriptor).toBeDefined();
expect(descriptor.propertiesByName['di:modelElement']).toEqual(descriptor.propertiesByName['bpmndi:bpmnElement']); expect(descriptor.propertiesByName['di:modelElement']).toEqual(descriptor.propertiesByName['bpmndi:bpmnElement']);
}); });
}); });
describe('creation', function() { describe('creation', function() {
@ -58,6 +61,7 @@ describe('BpmnModel', function() {
expect(definitions.$type).toEqual('bpmn:Definitions'); expect(definitions.$type).toEqual('bpmn:Definitions');
}); });
}); });
describe('property access', function() { describe('property access', function() {
@ -146,6 +150,7 @@ describe('BpmnModel', function() {
] ]
}); });
}); });
}); });
}); });
}); });

View File

@ -1,17 +1,19 @@
var fs = require('fs'); var fs = require('fs'),
var _ = require('lodash'); _ = require('lodash');
var Helper = require('../../../Helper'); var CmofParser = require('moddle/lib/adapter/cmof/Parser');
var Parser = require('moddle/lib/adapter/cmof/Parser');
var Helper = require('../../Helper');
Helper.ensureDirExists('resources/bpmn/json'); Helper.ensureDirExists('resources/bpmn/json');
describe('generate JSON meta model', function() { describe('generate JSON meta model', function() {
function parsed(file, callback, options) { function parsed(file, callback, options) {
return function(done) { return function(done) {
new Parser({ clean: true }).parseFile(file, function(err, results) { new CmofParser({ clean: true }).parseFile(file, function(err, results) {
if (err) { if (err) {
done(err); done(err);
} else { } else {

View File

@ -1,10 +1,11 @@
var os = require('os'); var os = require('os');
var BpmnModel = require('../../../../lib/model/BpmnModel'); var BpmnModel = require('../../../../lib/Model'),
Helper = require('../Helper'),
Matchers = require('../../Matchers');
var Helper = require('../../Helper');
describe('BpmnModel - read', function() { describe('Model', function() {
var bpmnModel = BpmnModel.instance(); var bpmnModel = BpmnModel.instance();
@ -20,7 +21,7 @@ describe('BpmnModel - read', function() {
return read(readBpmnDiagram(file), root, opts, callback); return read(readBpmnDiagram(file), root, opts, callback);
} }
beforeEach(Helper.initAdditionalMatchers); beforeEach(Matchers.add);
describe('fromXML', function() { describe('fromXML', function() {

View File

@ -1,12 +1,13 @@
var BpmnModel = require('../../../../lib/model/BpmnModel'), var SchemaValidator = require('xsd-schema-validator');
SchemaValidator = require('xsd-schema-validator');
var Helper = require('../../Helper'); var BpmnModel = require('../../../../lib/Model'),
Helper = require('../Helper'),
Matchers = require('../../Matchers');
var BPMN_XSD = 'resources/bpmn/xsd/BPMN20.xsd'; var BPMN_XSD = 'resources/bpmn/xsd/BPMN20.xsd';
xdescribe('BpmnModel - roundtrip', function() { describe('Model - roundtrip', function() {
var bpmnModel = BpmnModel.instance(); var bpmnModel = BpmnModel.instance();
@ -19,23 +20,19 @@ xdescribe('BpmnModel - roundtrip', function() {
} }
function writeBpmn(element, opts, callback) { function writeBpmn(element, opts, callback) {
var result, err; BpmnModel.toXML(element, opts, callback);
try {
result = BpmnModel.toXML(element, callback, opts);
} catch (e) {
err = e;
}
callback(err, result);
} }
function validate(err, xml, done) { function validate(err, xml, done) {
console.log('validate');
if (err) { if (err) {
done(err); done(err);
} else { } else {
if (!xml) {
done(new Error('XML is not defined'));
}
SchemaValidator.validateXML(xml, BPMN_XSD, function(err, result) { SchemaValidator.validateXML(xml, BPMN_XSD, function(err, result) {
if (err) { if (err) {
@ -48,15 +45,16 @@ xdescribe('BpmnModel - roundtrip', function() {
} }
} }
beforeEach(Helper.initAdditionalMatchers); beforeEach(Matchers.add);
describe('Roundtrip', function() { describe('Roundtrip', function() {
it('should serialize home-made bpmn model', function(done) { it('should serialize home-made bpmn model', function(done) {
// given
var model = bpmnModel; var model = bpmnModel;
var definitions = model.create('bpmn:Definitions'); var definitions = model.create('bpmn:Definitions', { targetNamespace: 'http://foo' });
var ServiceTask = model.getType('bpmn:ServiceTask'); var ServiceTask = model.getType('bpmn:ServiceTask');
@ -68,6 +66,8 @@ xdescribe('BpmnModel - roundtrip', function() {
// when // when
writeBpmn(definitions, { format: true }, function(err, xml) { writeBpmn(definitions, { format: true }, function(err, xml) {
// then
validate(err, xml, done); validate(err, xml, done);
}); });
}); });
@ -77,6 +77,11 @@ xdescribe('BpmnModel - roundtrip', function() {
// given // given
readBpmn('complex.bpmn', function(err, result) { readBpmn('complex.bpmn', function(err, result) {
if (err) {
done(err);
return;
}
// when // when
writeBpmn(result, { format: true }, function(err, xml) { writeBpmn(result, { format: true }, function(err, xml) {
validate(err, xml, done); validate(err, xml, done);
@ -89,6 +94,11 @@ xdescribe('BpmnModel - roundtrip', function() {
// given // given
readBpmn('complex-no-extensions.bpmn', function(err, result) { readBpmn('complex-no-extensions.bpmn', function(err, result) {
if (err) {
done(err);
return;
}
// when // when
writeBpmn(result, { format: true }, function(err, xml) { writeBpmn(result, { format: true }, function(err, xml) {
validate(err, xml, done); validate(err, xml, done);
@ -101,6 +111,11 @@ xdescribe('BpmnModel - roundtrip', function() {
// given // given
readBpmn('simple.bpmn', function(err, result) { readBpmn('simple.bpmn', function(err, result) {
if (err) {
done(err);
return;
}
// when // when
writeBpmn(result, { format: true }, function(err, xml) { writeBpmn(result, { format: true }, function(err, xml) {
validate(err, xml, done); validate(err, xml, done);

View File

@ -1,13 +1,11 @@
var _ = require('lodash'); var _ = require('lodash');
var BpmnModel = require('../../../../lib/model/BpmnModel'); var BpmnModel = require('../../../../lib/Model'),
logger = require('moddle').util.Logger; Helper = require('../Helper'),
Matchers = require('../../Matchers');
var Helper = require('../../Helper'),
log = Helper.log;
describe('BpmnModel - write', function() { describe('Model', function() {
var createModel = Helper.createModelBuilder('resources/bpmn/json/'); var createModel = Helper.createModelBuilder('resources/bpmn/json/');
@ -25,7 +23,7 @@ describe('BpmnModel - write', function() {
BpmnModel.toXML(element, options, callback); BpmnModel.toXML(element, options, callback);
} }
beforeEach(Helper.initAdditionalMatchers); beforeEach(Matchers.add);
describe('toXML', function() { describe('toXML', function() {