Skip to content

Commit a6b82c1

Browse files
committed
Merge branch 'browser-tests'
2 parents 2ab20b0 + ad403ae commit a6b82c1

88 files changed

Lines changed: 1404106 additions & 9 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ matter-doc-theme
66
build/matter-dev.js
77
build/matter-dev.min.js
88
demo/js/lib/matter-dev.js
9+
tests/browser/diffs

.jshintrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
"undef": true,
3232
"-W079": true, // Silence redefinition errors (they are false positives).
3333
"predef": [
34-
"Matter", "window", "document", "Element", "MatterTools", "PIXI",
35-
"$", "Image", "navigator", "setTimeout", "decomp", "HTMLElement",
34+
"Matter", "window", "document", "Element", "MatterTools", "PIXI", "phantom",
35+
"$", "Image", "navigator", "setTimeout", "decomp", "HTMLElement", "require",
3636
"Body", "Composite", "World", "Contact", "Detector", "Grid",
3737
"Pairs", "Pair", "Resolver", "SAT", "Constraint", "MouseConstraint",
3838
"Common", "Engine", "Mouse", "Sleeping", "Bodies", "Composites",

.travis.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
language: node_js
2+
sudo: false
23
node_js:
34
- "0.10"
4-
before_install: npm install -g grunt-cli
5-
install: npm install
6-
before_script: grunt
5+
before_install:
6+
- npm install -g grunt-cli
7+
- mkdir travis-phantomjs
8+
- 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
9+
- tar -xvf $PWD/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2 -C $PWD/travis-phantomjs
10+
- export PATH=$PWD/travis-phantomjs:$PATH
11+
install: npm install

Gruntfile.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ module.exports = function(grunt) {
5757
options: {
5858
jshintrc: '.jshintrc'
5959
},
60-
all: ['src/**/*.js', 'demo/js/*.js', '!src/module/*']
60+
all: ['src/**/*.js', 'demo/js/*.js', 'test/browser/TestDemo.js', '!src/module/*']
6161
},
6262
connect: {
6363
watch: {
@@ -66,6 +66,11 @@ module.exports = function(grunt) {
6666
open: 'http://localhost:9000/demo/dev.html',
6767
livereload: 9001
6868
}
69+
},
70+
serve: {
71+
options: {
72+
port: 9000
73+
}
6974
}
7075
},
7176
watch: {
@@ -107,6 +112,19 @@ module.exports = function(grunt) {
107112
src: 'build/<%= buildName %>.js',
108113
dest: 'build/<%= buildName %>.js'
109114
}
115+
},
116+
shell: {
117+
testDemo: {
118+
command: function(arg) {
119+
arg = arg ? ' --' + arg : '';
120+
return 'phantomjs test/browser/TestDemo.js' + arg;
121+
},
122+
options: {
123+
execOptions: {
124+
timeout: 1000 * 60
125+
}
126+
}
127+
}
110128
}
111129
});
112130

@@ -118,11 +136,26 @@ module.exports = function(grunt) {
118136
grunt.loadNpmTasks('grunt-contrib-copy');
119137
grunt.loadNpmTasks('grunt-contrib-yuidoc');
120138
grunt.loadNpmTasks('grunt-preprocess');
139+
grunt.loadNpmTasks('grunt-shell');
121140

122141
grunt.registerTask('default', ['test', 'build']);
123-
grunt.registerTask('test', ['jshint']);
142+
grunt.registerTask('test', ['jshint', 'test:demo']);
143+
grunt.registerTask('test:all', ['build:dev', 'connect:serve', 'test']);
124144
grunt.registerTask('dev', ['build:dev', 'connect:watch', 'watch']);
125145

146+
grunt.registerTask('test:demo', function() {
147+
var updateAll = grunt.option('updateAll'),
148+
diff = grunt.option('diff');
149+
150+
if (updateAll) {
151+
grunt.task.run('shell:testDemo:updateAll');
152+
} else if (diff) {
153+
grunt.task.run('shell:testDemo:diff');
154+
} else {
155+
grunt.task.run('shell:testDemo');
156+
}
157+
});
158+
126159
grunt.registerTask('build', function(mode) {
127160
var isDev = (mode === 'dev'),
128161
isRelease = (mode === 'release'),

demo/js/Demo.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
}
2626

2727
var Demo = {};
28+
Matter.Demo = Demo;
2829

2930
var _engine,
3031
_gui,
@@ -1608,6 +1609,9 @@
16081609
var demoSelect = document.getElementById('demo-select'),
16091610
demoReset = document.getElementById('demo-reset');
16101611

1612+
// engine reference for external use
1613+
Matter.Demo._engine = _engine;
1614+
16111615
// create a Matter.Gui
16121616
if (!_isMobile && Gui) {
16131617
_gui = Gui.create(_engine);

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"rigid body physics"
2121
],
2222
"devDependencies": {
23+
"fast-json-patch": "^0.5.4",
2324
"grunt": "~0.4.2",
2425
"grunt-contrib-concat": "~0.3.0",
2526
"grunt-contrib-connect": "~0.6.0",
@@ -28,11 +29,12 @@
2829
"grunt-contrib-uglify": "~0.2.7",
2930
"grunt-contrib-watch": "~0.5.3",
3031
"grunt-contrib-yuidoc": "~0.5.1",
31-
"grunt-preprocess": "^4.1.0"
32+
"grunt-preprocess": "^4.1.0",
33+
"grunt-shell": "^1.1.2"
3234
},
3335
"scripts": {
3436
"dev": "npm install && grunt dev",
35-
"test": "grunt test"
37+
"test": "grunt test:all"
3638
},
3739
"dependencies": {}
3840
}

test/browser/TestDemo.js

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
var page = require('webpage').create();
2+
var fs = require('fs');
3+
var Resurrect = require('./lib/resurrect');
4+
var compare = require('fast-json-patch').compare;
5+
var system = require('system');
6+
7+
var demo,
8+
frames = 10,
9+
testUrl = 'http://localhost:9000/demo/dev.html',
10+
refsPath = 'test/browser/refs',
11+
diffsPath = 'test/browser/diffs';
12+
13+
var update = arg('--update'),
14+
updateAll = typeof arg('--updateAll') !== 'undefined',
15+
diff = arg('--diff');
16+
17+
var resurrect = new Resurrect({ cleanup: true }),
18+
created = [],
19+
changed = [];
20+
21+
var test = function(status) {
22+
if (status === 'fail') {
23+
console.log('failed to load', testUrl);
24+
console.log('check dev server is running!');
25+
console.log('use `grunt dev`');
26+
phantom.exit(1);
27+
return;
28+
}
29+
30+
var demos = page.evaluate(function() {
31+
var demoSelect = document.getElementById('demo-select'),
32+
options = Array.prototype.slice.call(demoSelect);
33+
return options.map(function(o) { return o.value; });
34+
});
35+
36+
fs.removeTree(diffsPath);
37+
38+
if (diff) {
39+
fs.makeDirectory(diffsPath);
40+
}
41+
42+
for (var i = 0; i < demos.length; i += 1) {
43+
demo = demos[i];
44+
45+
var hasChanged = false,
46+
hasCreated = false,
47+
forceUpdate = update === demo || updateAll,
48+
worldStartPath = refsPath + '/' + demo + '/' + demo + '-0.json',
49+
worldEndPath = refsPath + '/' + demo + '/' + demo + '-' + frames + '.json',
50+
worldStartDiffPath = diffsPath + '/' + demo + '/' + demo + '-0.json',
51+
worldEndDiffPath = diffsPath + '/' + demo + '/' + demo + '-' + frames + '.json';
52+
53+
var worldStart = page.evaluate(function(demo) {
54+
var engine = Matter.Demo._engine;
55+
Matter.Runner.stop(engine);
56+
if (!(demo in Matter.Demo)) {
57+
throw '\'' + demo + '\' is not defined in Matter.Demo';
58+
}
59+
Matter.Demo[demo]();
60+
return engine.world;
61+
}, demo);
62+
63+
var worldEnd = page.evaluate(function(demo, frames) {
64+
var engine = Matter.Demo._engine;
65+
66+
for (var j = 0; j <= frames; j += 1) {
67+
Matter.Events.trigger(engine, 'tick', { timestamp: engine.timing.timestamp });
68+
Matter.Engine.update(engine, engine.timing.delta);
69+
Matter.Events.trigger(engine, 'afterTick', { timestamp: engine.timing.timestamp });
70+
}
71+
72+
return engine.world;
73+
}, demo, frames);
74+
75+
if (fs.exists(worldStartPath)) {
76+
var worldStartRef = resurrect.resurrect(fs.read(worldStartPath));
77+
var worldStartDiff = compare(worldStartRef, worldStart);
78+
79+
if (worldStartDiff.length !== 0) {
80+
if (diff) {
81+
fs.write(worldStartDiffPath, JSON.stringify(worldStartDiff, null, 2), 'w');
82+
}
83+
84+
if (forceUpdate) {
85+
hasCreated = true;
86+
fs.write(worldStartPath, resurrect.stringify(worldStart, null, 2), 'w');
87+
} else {
88+
hasChanged = true;
89+
}
90+
}
91+
} else {
92+
hasCreated = true;
93+
fs.write(worldStartPath, resurrect.stringify(worldStart, null, 2), 'w');
94+
}
95+
96+
if (fs.exists(worldEndPath)) {
97+
var worldEndRef = resurrect.resurrect(fs.read(worldEndPath));
98+
var worldEndDiff = compare(worldEndRef, worldEnd);
99+
100+
if (worldEndDiff.length !== 0) {
101+
if (diff) {
102+
fs.write(worldEndDiffPath, JSON.stringify(worldEndDiff, null, 2), 'w');
103+
}
104+
105+
if (forceUpdate) {
106+
hasCreated = true;
107+
fs.write(worldEndPath, resurrect.stringify(worldEnd, null, 2), 'w');
108+
} else {
109+
hasChanged = true;
110+
}
111+
}
112+
} else {
113+
hasCreated = true;
114+
fs.write(worldEndPath, resurrect.stringify(worldEnd, null, 2), 'w');
115+
}
116+
117+
if (hasChanged) {
118+
changed.push("'" + demo + "'");
119+
system.stdout.write('x');
120+
} else if (hasCreated) {
121+
created.push("'" + demo + "'");
122+
system.stdout.write('+');
123+
} else {
124+
system.stdout.write('.');
125+
}
126+
}
127+
128+
if (created.length > 0) {
129+
console.log('\nupdated', created.join(', '));
130+
}
131+
132+
var isOk = changed.length === 0 ? 1 : 0;
133+
134+
console.log('');
135+
136+
if (isOk) {
137+
console.log('ok');
138+
} else {
139+
console.log('\nchanges detected on:');
140+
console.log(changed.join(', '));
141+
console.log('\nreview, then --update [name] or --updateAll');
142+
console.log('use --diff for diff log');
143+
}
144+
145+
phantom.exit(!isOk);
146+
};
147+
148+
function arg(name) {
149+
var index = system.args.indexOf(name);
150+
if (index >= 0) {
151+
return system.args[index + 1] || true;
152+
}
153+
return undefined;
154+
}
155+
156+
page.onError = function(msg, trace) {
157+
setTimeout(function() {
158+
var msgStack = ['testing \'' + demo + '\'', msg];
159+
160+
if (trace && trace.length) {
161+
trace.forEach(function(t) {
162+
msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (fn: ' + t.function +')' : ''));
163+
});
164+
}
165+
166+
console.log(msgStack.join('\n'));
167+
phantom.exit(1);
168+
}, 0);
169+
};
170+
171+
172+
page.onResourceReceived = function(res) {
173+
setTimeout(function() {
174+
if (res.stage === 'end'
175+
&& (res.status !== 304 && res.status !== 200 && res.status !== null)) {
176+
console.log('error', res.status, res.url);
177+
phantom.exit(1);
178+
}
179+
}, 0);
180+
};
181+
182+
phantom.onError = page.onError;
183+
184+
page.open(testUrl, test);

0 commit comments

Comments
 (0)