Skip to content

Commit

Permalink
Merge branch 'master' into runner-improve
Browse files Browse the repository at this point in the history
  • Loading branch information
liabru committed Aug 4, 2015
2 parents 4ecad0f + c1f71b9 commit a48d219
Show file tree
Hide file tree
Showing 89 changed files with 1,404,126 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -6,3 +6,4 @@ matter-doc-theme
build/matter-dev.js
build/matter-dev.min.js
demo/js/lib/matter-dev.js
test/browser/diffs
4 changes: 2 additions & 2 deletions .jshintrc
Expand Up @@ -31,8 +31,8 @@
"undef": true,
"-W079": true, // Silence redefinition errors (they are false positives).
"predef": [
"Matter", "window", "document", "Element", "MatterTools", "PIXI",
"$", "Image", "navigator", "setTimeout", "decomp", "HTMLElement",
"Matter", "window", "document", "Element", "MatterTools", "PIXI", "phantom",
"$", "Image", "navigator", "setTimeout", "decomp", "HTMLElement", "require",
"Body", "Composite", "World", "Contact", "Detector", "Grid",
"Pairs", "Pair", "Resolver", "SAT", "Constraint", "MouseConstraint",
"Common", "Engine", "Mouse", "Sleeping", "Bodies", "Composites",
Expand Down
4 changes: 3 additions & 1 deletion .npmignore
@@ -1,7 +1,9 @@
.idea
node_modules
npm-debug.log
doc
matter-doc-theme
build/matter-dev.js
build/matter-dev.min.js
demo/js/lib/matter-dev.js
demo/js/lib/matter-dev.js
test/browser/diffs
11 changes: 8 additions & 3 deletions .travis.yml
@@ -1,6 +1,11 @@
language: node_js
sudo: false
node_js:
- "0.10"
before_install: npm install -g grunt-cli
install: npm install
before_script: grunt
before_install:
- npm install -g grunt-cli
- mkdir travis-phantomjs
- wget https://s3.amazonaws.com/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2 -O $PWD/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2
- tar -xvf $PWD/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2 -C $PWD/travis-phantomjs
- export PATH=$PWD/travis-phantomjs:$PATH
install: npm install
36 changes: 34 additions & 2 deletions Gruntfile.js
Expand Up @@ -57,7 +57,7 @@ module.exports = function(grunt) {
options: {
jshintrc: '.jshintrc'
},
all: ['src/**/*.js', 'demo/js/*.js', '!src/module/*']
all: ['src/**/*.js', 'demo/js/*.js', 'test/browser/TestDemo.js', '!src/module/*']
},
connect: {
watch: {
Expand All @@ -66,6 +66,11 @@ module.exports = function(grunt) {
open: 'http://localhost:9000/demo/dev.html',
livereload: 9001
}
},
serve: {
options: {
port: 8000
}
}
},
watch: {
Expand Down Expand Up @@ -107,6 +112,19 @@ module.exports = function(grunt) {
src: 'build/<%= buildName %>.js',
dest: 'build/<%= buildName %>.js'
}
},
shell: {
testDemo: {
command: function(arg) {
arg = arg ? ' --' + arg : '';
return 'phantomjs test/browser/TestDemo.js' + arg;
},
options: {
execOptions: {
timeout: 1000 * 60
}
}
}
}
});

Expand All @@ -118,11 +136,25 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-yuidoc');
grunt.loadNpmTasks('grunt-preprocess');
grunt.loadNpmTasks('grunt-shell');

grunt.registerTask('default', ['test', 'build']);
grunt.registerTask('test', ['jshint']);
grunt.registerTask('test', ['build:dev', 'connect:serve', 'jshint', 'test:demo']);
grunt.registerTask('dev', ['build:dev', 'connect:watch', 'watch']);

grunt.registerTask('test:demo', function() {
var updateAll = grunt.option('updateAll'),
diff = grunt.option('diff');

if (updateAll) {
grunt.task.run('shell:testDemo:updateAll');
} else if (diff) {
grunt.task.run('shell:testDemo:diff');
} else {
grunt.task.run('shell:testDemo');
}
});

grunt.registerTask('build', function(mode) {
var isDev = (mode === 'dev'),
isRelease = (mode === 'release'),
Expand Down
10 changes: 9 additions & 1 deletion demo/js/Demo.js
Expand Up @@ -25,6 +25,7 @@
}

var Demo = {};
Matter.Demo = Demo;

var _engine,
_runner,
Expand All @@ -34,7 +35,8 @@
_mouseConstraint,
_sceneEvents = [],
_useInspector = window.location.hash.indexOf('-inspect') !== -1,
_isMobile = /(ipad|iphone|ipod|android)/gi.test(navigator.userAgent);
_isMobile = /(ipad|iphone|ipod|android)/gi.test(navigator.userAgent),
_isAutomatedTest = window._phantom ? true : false;

// initialise the demo

Expand All @@ -57,6 +59,12 @@
_mouseConstraint = MouseConstraint.create(_engine);
World.add(_engine.world, _mouseConstraint);

// engine reference for external use
Matter.Demo._engine = _engine;

// skip runner when performing automated tests
if (_isAutomatedTest) return;

// run the engine
_runner = Engine.run(_engine);

Expand Down
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -20,6 +20,7 @@
"rigid body physics"
],
"devDependencies": {
"fast-json-patch": "^0.5.4",
"grunt": "~0.4.2",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-connect": "~0.6.0",
Expand All @@ -28,7 +29,8 @@
"grunt-contrib-uglify": "~0.2.7",
"grunt-contrib-watch": "~0.5.3",
"grunt-contrib-yuidoc": "~0.5.1",
"grunt-preprocess": "^4.1.0"
"grunt-preprocess": "^4.1.0",
"grunt-shell": "^1.1.2"
},
"scripts": {
"dev": "npm install && grunt dev",
Expand Down
193 changes: 193 additions & 0 deletions test/browser/TestDemo.js
@@ -0,0 +1,193 @@
var page = require('webpage').create();
var fs = require('fs');
var Resurrect = require('./lib/resurrect');
var compare = require('fast-json-patch').compare;
var system = require('system');

var demo,
frames = 10,
testUrl = 'http://localhost:8000/demo/dev.html',
refsPath = 'test/browser/refs',
diffsPath = 'test/browser/diffs';

var update = arg('--update'),
updateAll = typeof arg('--updateAll') !== 'undefined',
diff = arg('--diff');

var resurrect = new Resurrect({ cleanup: true }),
created = [],
changed = [];

var test = function(status) {
if (status === 'fail') {
console.log('failed to load', testUrl);
console.log('check dev server is running!');
console.log('use `grunt dev`');
phantom.exit(1);
return;
}

var demos = page.evaluate(function() {
var demoSelect = document.getElementById('demo-select'),
options = Array.prototype.slice.call(demoSelect);
return options.map(function(o) { return o.value; });
});

fs.removeTree(diffsPath);

if (diff) {
fs.makeDirectory(diffsPath);
}

for (var i = 0; i < demos.length; i += 1) {
demo = demos[i];

var hasChanged = false,
hasCreated = false,
forceUpdate = update === demo || updateAll,
worldStartPath = refsPath + '/' + demo + '/' + demo + '-0.json',
worldEndPath = refsPath + '/' + demo + '/' + demo + '-' + frames + '.json',
worldStartDiffPath = diffsPath + '/' + demo + '/' + demo + '-0.json',
worldEndDiffPath = diffsPath + '/' + demo + '/' + demo + '-' + frames + '.json';

var worldStart = page.evaluate(function(demo) {
var engine = Matter.Demo._engine;
if (!(demo in Matter.Demo)) {
throw '\'' + demo + '\' is not defined in Matter.Demo';
}
Matter.Demo[demo]();
return engine.world;
}, demo);

var worldEnd = page.evaluate(function(demo, frames) {
var engine = Matter.Demo._engine;

for (var j = 0; j <= frames; j += 1) {
Matter.Events.trigger(engine, 'tick', { timestamp: engine.timing.timestamp });
Matter.Engine.update(engine, engine.timing.delta);
Matter.Events.trigger(engine, 'afterTick', { timestamp: engine.timing.timestamp });
}

return engine.world;
}, demo, frames);

worldEnd = resurrect.resurrect(resurrect.stringify(worldEnd, precisionLimiter));
worldStart = resurrect.resurrect(resurrect.stringify(worldStart, precisionLimiter));

if (fs.exists(worldStartPath)) {
var worldStartRef = resurrect.resurrect(fs.read(worldStartPath));
var worldStartDiff = compare(worldStartRef, worldStart);

if (worldStartDiff.length !== 0) {
if (diff) {
fs.write(worldStartDiffPath, JSON.stringify(worldStartDiff, precisionLimiter, 2), 'w');
}

if (forceUpdate) {
hasCreated = true;
fs.write(worldStartPath, resurrect.stringify(worldStart, precisionLimiter, 2), 'w');
} else {
hasChanged = true;
}
}
} else {
hasCreated = true;
fs.write(worldStartPath, resurrect.stringify(worldStart, precisionLimiter, 2), 'w');
}

if (fs.exists(worldEndPath)) {
var worldEndRef = resurrect.resurrect(fs.read(worldEndPath));
var worldEndDiff = compare(worldEndRef, worldEnd);

if (worldEndDiff.length !== 0) {
if (diff) {
fs.write(worldEndDiffPath, JSON.stringify(worldEndDiff, precisionLimiter, 2), 'w');
}

if (forceUpdate) {
hasCreated = true;
fs.write(worldEndPath, resurrect.stringify(worldEnd, precisionLimiter, 2), 'w');
} else {
hasChanged = true;
}
}
} else {
hasCreated = true;
fs.write(worldEndPath, resurrect.stringify(worldEnd, precisionLimiter, 2), 'w');
}

if (hasChanged) {
changed.push("'" + demo + "'");
system.stdout.write('x');
} else if (hasCreated) {
created.push("'" + demo + "'");
system.stdout.write('+');
} else {
system.stdout.write('.');
}
}

if (created.length > 0) {
console.log('\nupdated', created.join(', '));
}

var isOk = changed.length === 0 ? 1 : 0;

console.log('');

if (isOk) {
console.log('ok');
} else {
console.log('\nchanges detected on:');
console.log(changed.join(', '));
console.log('\nreview, then --update [name] or --updateAll');
console.log('use --diff for diff log');
}

phantom.exit(!isOk);
};

var precisionLimiter = function(key, value) {
if (typeof value === 'number') {
return parseFloat(value.toFixed(5));
}
return value;
};

function arg(name) {
var index = system.args.indexOf(name);
if (index >= 0) {
return system.args[index + 1] || true;
}
return undefined;
}

page.onError = function(msg, trace) {
setTimeout(function() {
var msgStack = ['testing \'' + demo + '\'', msg];

if (trace && trace.length) {
trace.forEach(function(t) {
msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (fn: ' + t.function +')' : ''));
});
}

console.log(msgStack.join('\n'));
phantom.exit(1);
}, 0);
};


page.onResourceReceived = function(res) {
setTimeout(function() {
if (res.stage === 'end'
&& (res.status !== 304 && res.status !== 200 && res.status !== null)) {
console.log('error', res.status, res.url);
phantom.exit(1);
}
}, 0);
};

phantom.onError = page.onError;

page.open(testUrl, test);

0 comments on commit a48d219

Please sign in to comment.