0
0
Fork 0
mirror of https://github.com/liabru/matter-js.git synced 2024-12-26 13:49:01 -05:00

Merge branch 'node-tests' into browserify

Conflicts:
	.jshintrc
This commit is contained in:
liabru 2015-08-17 20:55:13 +01:00
commit 6e0e7e47f8
72 changed files with 1422143 additions and 76 deletions

1
.gitignore vendored
View file

@ -7,3 +7,4 @@ build/matter-dev.js
build/matter-dev.min.js
demo/js/lib/matter-dev.js
test/browser/diffs
test/node/diffs

View file

@ -30,9 +30,11 @@
// variables
"undef": true,
"-W079": true, // Silence redefinition errors (they are false positives).
"-W020": true, // Silence readonly error (needed to simplify support for node).
"predef": [
"Matter", "window", "document", "Element", "MatterTools", "PIXI", "phantom", "module",
"$", "Image", "navigator", "setTimeout", "decomp", "HTMLElement", "require",
"Matter", "window", "document", "Element", "MatterTools",
"phantom", "process", "HTMLElement", "require", "PIXI",
"$", "Image", "navigator", "setTimeout", "decomp", "module",
"Body", "Composite", "World", "Contact", "Detector", "Grid",
"Pairs", "Pair", "Resolver", "SAT", "Constraint", "MouseConstraint",
"Common", "Engine", "Mouse", "Sleeping", "Bodies", "Composites",

View file

@ -7,6 +7,9 @@ module.exports = function(grunt) {
browserify: {
options: {
banner: '/**\n* <%= buildName %>.js <%= buildVersion %> <%= grunt.template.today("yyyy-mm-dd") %>\n* <%= pkg.homepage %>\n* License: <%= pkg.license %>\n*/\n\n',
browserifyOptions: {
standalone: '<%= pkg.name %>'
}
},
'build/<%= buildName %>.js': ['src/module/main.js']
},
@ -45,7 +48,7 @@ module.exports = function(grunt) {
options: {
jshintrc: '.jshintrc'
},
all: ['src/**/*.js', 'demo/js/*.js', 'test/browser/TestDemo.js', '!src/module/*']
all: ['src/**/*.js', 'demo/js/*.js', 'test/browser/TestDemo.js', 'test/node/TestDemo.js', '!src/module/*']
},
connect: {
watch: {
@ -102,7 +105,7 @@ module.exports = function(grunt) {
}
},
shell: {
testDemo: {
testDemoBrowser: {
command: function(arg) {
arg = arg ? ' --' + arg : '';
return 'phantomjs test/browser/TestDemo.js' + arg;
@ -112,6 +115,17 @@ module.exports = function(grunt) {
timeout: 1000 * 60
}
}
},
testDemoNode: {
command: function(arg) {
arg = arg ? ' --' + arg : '';
return 'node test/node/TestDemo.js' + arg;
},
options: {
execOptions: {
timeout: 1000 * 60
}
}
}
}
});
@ -127,7 +141,7 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-shell');
grunt.registerTask('default', ['test', 'build']);
grunt.registerTask('test', ['build:dev', 'connect:serve', 'jshint', 'test:demo']);
grunt.registerTask('test', ['build:dev', 'connect:serve', 'jshint', 'test:demo', 'test:demoNode']);
grunt.registerTask('dev', ['build:dev', 'connect:watch', 'watch']);
grunt.registerTask('test:demo', function() {
@ -135,11 +149,24 @@ module.exports = function(grunt) {
diff = grunt.option('diff');
if (updateAll) {
grunt.task.run('shell:testDemo:updateAll');
grunt.task.run('shell:testDemoBrowser:updateAll');
} else if (diff) {
grunt.task.run('shell:testDemo:diff');
grunt.task.run('shell:testDemoBrowser:diff');
} else {
grunt.task.run('shell:testDemo');
grunt.task.run('shell:testDemoBrowser');
}
});
grunt.registerTask('test:demoNode', function() {
var updateAll = grunt.option('updateAll'),
diff = grunt.option('diff');
if (updateAll) {
grunt.task.run('shell:testDemoNode:updateAll');
} else if (diff) {
grunt.task.run('shell:testDemoNode:diff');
} else {
grunt.task.run('shell:testDemoNode');
}
});

View file

@ -1,5 +1,16 @@
(function() {
var _isBrowser = typeof window !== 'undefined',
Matter = _isBrowser ? window.Matter : require('../../build/matter-dev.js');
var Demo = {};
Matter.Demo = Demo;
if (!_isBrowser) {
module.exports = Demo;
window = {};
}
// Matter aliases
var Engine = Matter.Engine,
World = Matter.World,
@ -24,9 +35,6 @@
Inspector = MatterTools.Inspector;
}
var Demo = {};
Matter.Demo = Demo;
var _engine,
_runner,
_gui,
@ -34,15 +42,13 @@
_sceneName,
_mouseConstraint,
_sceneEvents = [],
_useInspector = window.location.hash.indexOf('-inspect') !== -1,
_isMobile = /(ipad|iphone|ipod|android)/gi.test(navigator.userAgent),
_isAutomatedTest = window._phantom ? true : false;
_useInspector = _isBrowser && window.location.hash.indexOf('-inspect') !== -1,
_isMobile = _isBrowser && /(ipad|iphone|ipod|android)/gi.test(navigator.userAgent),
_isAutomatedTest = !_isBrowser || window._phantom;
// initialise the demo
Demo.init = function() {
var container = document.getElementById('canvas-container');
// some example engine options
var options = {
positionIterations: 6,
@ -53,11 +59,18 @@
// create a Matter engine
// NOTE: this is actually Matter.Engine.create(), see the aliases at top of this file
_engine = Engine.create(container, options);
if (_isBrowser) {
var container = document.getElementById('canvas-container');
_engine = Engine.create(container, options);
// add a mouse controlled constraint
_mouseConstraint = MouseConstraint.create(_engine);
World.add(_engine.world, _mouseConstraint);
// add a mouse controlled constraint
_mouseConstraint = MouseConstraint.create(_engine);
World.add(_engine.world, _mouseConstraint);
} else {
_engine = Engine.create(options);
_engine.render = {};
_engine.render.options = {};
}
// engine reference for external use
Matter.Demo._engine = _engine;
@ -676,9 +689,6 @@
var renderOptions = _engine.render.options;
renderOptions.wireframes = false;
renderOptions.showAngleIndicator = false;
if (window.chrome)
renderOptions.showShadows = true;
};
Demo.chains = function() {
@ -1714,21 +1724,26 @@
};
Demo.reset = function() {
var _world = _engine.world;
var _world = _engine.world,
i;
World.clear(_world);
Engine.clear(_engine);
// clear scene graph (if defined in controller)
var renderController = _engine.render.controller;
if (renderController.clear)
renderController.clear(_engine.render);
if (_engine.render) {
var renderController = _engine.render.controller;
if (renderController && renderController.clear)
renderController.clear(_engine.render);
}
// clear all scene events
for (var i = 0; i < _sceneEvents.length; i++)
Events.off(_engine, _sceneEvents[i]);
if (_engine.events) {
for (i = 0; i < _sceneEvents.length; i++)
Events.off(_engine, _sceneEvents[i]);
}
if (_mouseConstraint.events) {
if (_mouseConstraint && _mouseConstraint.events) {
for (i = 0; i < _sceneEvents.length; i++)
Events.off(_mouseConstraint, _sceneEvents[i]);
}
@ -1743,7 +1758,7 @@
Events.off(_runner, _sceneEvents[i]);
}
if (_engine.render.events) {
if (_engine.render && _engine.render.events) {
for (i = 0; i < _sceneEvents.length; i++)
Events.off(_engine.render, _sceneEvents[i]);
}
@ -1757,8 +1772,10 @@
Common._seed = 0;
// reset mouse offset and scale (only required for Demo.views)
Mouse.setScale(_mouseConstraint.mouse, { x: 1, y: 1 });
Mouse.setOffset(_mouseConstraint.mouse, { x: 0, y: 0 });
if (_mouseConstraint) {
Mouse.setScale(_mouseConstraint.mouse, { x: 1, y: 1 });
Mouse.setOffset(_mouseConstraint.mouse, { x: 0, y: 0 });
}
_engine.enableSleeping = false;
_engine.world.gravity.y = 1;
@ -1773,29 +1790,34 @@
Bodies.rectangle(-offset, 300, 50.5, 600.5 + 2 * offset, { isStatic: true })
]);
World.add(_world, _mouseConstraint);
if (_mouseConstraint) {
World.add(_world, _mouseConstraint);
}
var renderOptions = _engine.render.options;
renderOptions.wireframes = true;
renderOptions.hasBounds = false;
renderOptions.showDebug = false;
renderOptions.showBroadphase = false;
renderOptions.showBounds = false;
renderOptions.showVelocity = false;
renderOptions.showCollisions = false;
renderOptions.showAxes = false;
renderOptions.showPositions = false;
renderOptions.showAngleIndicator = true;
renderOptions.showIds = false;
renderOptions.showShadows = false;
renderOptions.showVertexNumbers = false;
renderOptions.showConvexHulls = false;
renderOptions.showInternalEdges = false;
renderOptions.showSeparations = false;
renderOptions.background = '#fff';
if (_engine.render) {
var renderOptions = _engine.render.options;
renderOptions.wireframes = true;
renderOptions.hasBounds = false;
renderOptions.showDebug = false;
renderOptions.showBroadphase = false;
renderOptions.showBounds = false;
renderOptions.showVelocity = false;
renderOptions.showCollisions = false;
renderOptions.showAxes = false;
renderOptions.showPositions = false;
renderOptions.showAngleIndicator = true;
renderOptions.showIds = false;
renderOptions.showShadows = false;
renderOptions.showVertexNumbers = false;
renderOptions.showConvexHulls = false;
renderOptions.showInternalEdges = false;
renderOptions.showSeparations = false;
renderOptions.background = '#fff';
if (_isMobile)
renderOptions.showDebug = true;
if (_isMobile) {
renderOptions.showDebug = true;
}
}
};
})();

View file

@ -5,7 +5,7 @@
"homepage": "http://brm.io/matter-js/",
"author": "Liam Brummitt <liam@brm.io> (http://brm.io/)",
"description": "a 2D rigid body physics engine for the web",
"main": "build/matter-0.8.0.min.js",
"main": "build/matter-dev.js",
"repository": {
"type": "git",
"url": "https://github.com/liabru/matter-js.git"
@ -20,6 +20,7 @@
"rigid body physics"
],
"devDependencies": {
"cheerio": "^0.19.0",
"fast-json-patch": "^0.5.4",
"grunt": "~0.4.2",
"grunt-browserify": "~3.7.0",
@ -30,7 +31,9 @@
"grunt-contrib-watch": "~0.5.3",
"grunt-contrib-yuidoc": "~0.5.1",
"grunt-preprocess": "^4.1.0",
"grunt-shell": "^1.1.2"
"grunt-shell": "^1.1.2",
"mkdirp": "^0.5.1",
"rimraf": "^2.4.2"
},
"scripts": {
"dev": "npm install && grunt dev",

View file

@ -59,7 +59,7 @@ var Common = require('./Common');
var callbacks = object.events[names[i]],
newCallbacks = [];
if (callback) {
if (callback && callbacks) {
for (var j = 0; j < callbacks.length; j++) {
if (callbacks[j] !== callback)
newCallbacks.push(callbacks[j]);

View file

@ -22,17 +22,17 @@ var Common = require('./Common');
(function() {
if (typeof window === 'undefined') {
// TODO: support Runner on non-browser environments.
return;
}
var _requestAnimationFrame,
_cancelAnimationFrame;
var _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
if (typeof window !== 'undefined') {
_requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame || window.msRequestAnimationFrame
|| function(callback){ window.setTimeout(function() { callback(Common.now()); }, 1000 / 60); };
var _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
_cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
|| window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
}
/**
* Creates a new Runner. The options parameter is an object that specifies any properties you wish to override the defaults.
@ -169,7 +169,7 @@ var Common = require('./Common');
Events.trigger(runner, 'afterUpdate', event);
// render
if (engine.render) {
if (engine.render && engine.render.controller) {
Events.trigger(runner, 'beforeRender', event);
Events.trigger(engine, 'beforeRender', event); // @deprecated

View file

@ -1,6 +1,6 @@
var page = require('webpage').create();
var fs = require('fs');
var Resurrect = require('./lib/resurrect');
var Resurrect = require('../lib/resurrect');
var compare = require('fast-json-patch').compare;
var system = require('system');
@ -70,11 +70,11 @@ var test = function(status) {
return engine.world;
}, demo, frames);
worldEnd = resurrect.resurrect(resurrect.stringify(worldEnd, precisionLimiter));
worldStart = resurrect.resurrect(resurrect.stringify(worldStart, precisionLimiter));
worldEnd = JSON.parse(resurrect.stringify(worldEnd, precisionLimiter));
worldStart = JSON.parse(resurrect.stringify(worldStart, precisionLimiter));
if (fs.exists(worldStartPath)) {
var worldStartRef = resurrect.resurrect(fs.read(worldStartPath));
var worldStartRef = JSON.parse(fs.read(worldStartPath));
var worldStartDiff = compare(worldStartRef, worldStart);
if (worldStartDiff.length !== 0) {
@ -84,18 +84,18 @@ var test = function(status) {
if (forceUpdate) {
hasCreated = true;
fs.write(worldStartPath, resurrect.stringify(worldStart, precisionLimiter, 2), 'w');
fs.write(worldStartPath, JSON.stringify(worldStart, precisionLimiter, 2), 'w');
} else {
hasChanged = true;
}
}
} else {
hasCreated = true;
fs.write(worldStartPath, resurrect.stringify(worldStart, precisionLimiter, 2), 'w');
fs.write(worldStartPath, JSON.stringify(worldStart, precisionLimiter, 2), 'w');
}
if (fs.exists(worldEndPath)) {
var worldEndRef = resurrect.resurrect(fs.read(worldEndPath));
var worldEndRef = JSON.parse(fs.read(worldEndPath));
var worldEndDiff = compare(worldEndRef, worldEnd);
if (worldEndDiff.length !== 0) {
@ -105,14 +105,14 @@ var test = function(status) {
if (forceUpdate) {
hasCreated = true;
fs.write(worldEndPath, resurrect.stringify(worldEnd, precisionLimiter, 2), 'w');
fs.write(worldEndPath, JSON.stringify(worldEnd, precisionLimiter, 2), 'w');
} else {
hasChanged = true;
}
}
} else {
hasCreated = true;
fs.write(worldEndPath, resurrect.stringify(worldEnd, precisionLimiter, 2), 'w');
fs.write(worldEndPath, JSON.stringify(worldEnd, precisionLimiter, 2), 'w');
}
if (hasChanged) {
@ -167,7 +167,7 @@ page.onError = function(msg, trace) {
if (trace && trace.length) {
trace.forEach(function(t) {
msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (fn: ' + t.function +')' : ''));
msgStack.push(' at ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (fn: ' + t.function +')' : ''));
});
}

177
test/node/TestDemo.js Normal file
View file

@ -0,0 +1,177 @@
var fs = require('fs');
var mkdirp = require('mkdirp').sync;
var removeDir = require('rimraf').sync;
var Resurrect = require('../lib/resurrect');
var compare = require('fast-json-patch').compare;
var path = require('path');
var $ = require('cheerio');
var Matter = require('../../build/matter-dev.js');
Matter.Demo = require('../../demo/js/Demo.js');
var demo,
frames = 10,
refsPath = 'test/node/refs',
diffsPath = 'test/node/diffs';
var update = arg('--update'),
updateAll = typeof arg('--updateAll') !== 'undefined',
diff = arg('--diff');
var resurrect = new Resurrect({ cleanup: true, revive: false }),
created = [],
changed = [];
var test = function(status) {
var demos = getDemoNames();
removeDir(diffsPath);
if (diff) {
mkdirp(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';
Matter.Demo.init();
var engine = Matter.Demo._engine,
runner = Matter.Runner.create();
if (!(demo in Matter.Demo)) {
throw '\'' + demo + '\' is not defined in Matter.Demo';
}
Matter.Demo[demo]();
var worldStart = JSON.parse(resurrect.stringify(engine.world, precisionLimiter));
for (var j = 0; j <= frames; j += 1) {
Matter.Runner.tick(runner, engine, j * runner.delta);
}
var worldEnd = JSON.parse(resurrect.stringify(engine.world, precisionLimiter));
if (fs.existsSync(worldStartPath)) {
var worldStartRef = JSON.parse(fs.readFileSync(worldStartPath));
var worldStartDiff = compare(worldStartRef, worldStart);
if (worldStartDiff.length !== 0) {
if (diff) {
writeFile(worldStartDiffPath, JSON.stringify(worldStartDiff, precisionLimiter, 2));
}
if (forceUpdate) {
hasCreated = true;
writeFile(worldStartPath, JSON.stringify(worldStart, precisionLimiter, 2));
} else {
hasChanged = true;
}
}
} else {
hasCreated = true;
writeFile(worldStartPath, JSON.stringify(worldStart, precisionLimiter, 2));
}
if (fs.existsSync(worldEndPath)) {
var worldEndRef = JSON.parse(fs.readFileSync(worldEndPath));
var worldEndDiff = compare(worldEndRef, worldEnd);
if (worldEndDiff.length !== 0) {
if (diff) {
writeFile(worldEndDiffPath, JSON.stringify(worldEndDiff, precisionLimiter, 2));
}
if (forceUpdate) {
hasCreated = true;
writeFile(worldEndPath, JSON.stringify(worldEnd, precisionLimiter, 2));
} else {
hasChanged = true;
}
}
} else {
hasCreated = true;
writeFile(worldEndPath, JSON.stringify(worldEnd, precisionLimiter, 2));
}
if (hasChanged) {
changed.push("'" + demo + "'");
process.stdout.write('x');
} else if (hasCreated) {
created.push("'" + demo + "'");
process.stdout.write('+');
} else {
process.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');
}
setTimeout(function() {
process.exit(!isOk);
}, 100);
};
var precisionLimiter = function(key, value) {
if (typeof value === 'number') {
return parseFloat(value.toFixed(5));
}
return value;
};
function arg(name) {
var index = process.argv.indexOf(name);
if (index >= 0) {
return process.argv[index + 1] || true;
}
return undefined;
}
var getDemoNames = function() {
var demos = [],
skip = [
'terrain', 'svg', 'concave',
'slingshot', 'views', 'raycasting',
'events', 'collisionFiltering', 'sleeping'
];
$('#demo-select option', fs.readFileSync('demo/dev.html').toString())
.each(function() {
var name = $(this).val();
if (skip.indexOf(name) === -1) {
demos.push(name);
}
});
return demos;
};
var writeFile = function(filePath, string) {
mkdirp(path.dirname(filePath));
fs.writeFileSync(filePath, string);
};
test();

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff