Browse Source

Cleanup browser testing

- Remove pug in favour of simple html file
- Stop sending code over the wire to eval on the server
- Remove jpeg view since it doesn't make sense to have it here
master
Linus Unnebäck 8 years ago
parent
commit
47a069e8d1
No known key found for this signature in database GPG Key ID: F23BD23774478D34
  1. 4
      package.json
  2. 0
      test/fixtures/face.jpeg
  3. 0
      test/fixtures/star.png
  4. 0
      test/fixtures/state.png
  5. 19
      test/public/app.html
  6. 166
      test/public/app.js
  7. 16
      test/public/style.css
  8. 3774
      test/public/tests.js
  9. 126
      test/server.js
  10. 9
      test/views/layout.pug
  11. 24
      test/views/tests.pug

4
package.json

@ -24,7 +24,7 @@
"prebenchmark": "node-gyp build",
"benchmark": "node benchmarks/run.js",
"pretest": "node-gyp build",
"test": "standard examples/*.js && mocha test/*.test.js",
"test": "standard examples/*.js test/server.js test/public/*.js && mocha test/*.test.js",
"pretest-server": "node-gyp build",
"test-server": "node test/server.js"
},
@ -32,9 +32,7 @@
"nan": "^2.3.2"
},
"devDependencies": {
"body-parser": "^1.13.3",
"express": "^4.13.2",
"pug": "^2.0.0-beta3",
"mocha": "*",
"standard": "^7.1.1"
},

0
test/public/face.jpeg → test/fixtures/face.jpeg

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 151 KiB

0
test/public/star.png → test/fixtures/star.png

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

0
test/public/state.png → test/fixtures/state.png

Before

Width:  |  Height:  |  Size: 566 B

After

Width:  |  Height:  |  Size: 566 B

19
test/public/app.html

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>node-canvas</title>
<link href="/style.css" rel="stylesheet">
</head>
<body>
<h1>node-canvas</h1>
<p class="msg">
The tests below assert visual and api integrity by running the <em>exact</em> same code utilizing the client canvas api, as well as node-canvas.
</p>
<script src="/tests.js"></script>
<script src="/app.js"></script>
</body>
</html>

166
test/public/app.js

@ -1,145 +1,55 @@
window.addEventListener('load', runTests)
function log() {
if (window.console) console.log.apply(this, arguments);
}
window.onload = function(){
runTests();
get('run').addEventListener('click', runTests, false);
};
document.addEventListener('keypress', function(event){
if (114 == event.charCode) runTests();
}, false);
function create (type, attrs, children) {
const element = Object.assign(document.createElement(type), attrs)
function get(id) {
return document.getElementById(id);
}
if (children) {
children.forEach(function (child) { element.appendChild(child) })
}
function create(type, str) {
var el = document.createElement(type);
if (str) el.appendChild(text(str));
return el;
return element
}
function text(str) {
return document.createTextNode(str);
function pdfLink (name) {
return create('a', {
href: '/pdf?name=' + encodeURIComponent(name),
target: '_blank',
textContent: 'PDF'
})
}
function pdfForm(fn, canvas) {
var form = create('form')
, input = create('input')
, submit = create('input');
function localRendering (name) {
var canvas = create('canvas', { width: 200, height: 200, title: name })
form.setAttribute('action', '/pdf');
form.setAttribute('method', 'post');
form.setAttribute('target', '_blank');
window.tests[name](canvas.getContext('2d'), function () {})
input.setAttribute('type', 'hidden');
input.setAttribute('name', 'json');
input.setAttribute('value', JSON.stringify({
fn: fn.toString()
, width: canvas.width
, height: canvas.height
}));
submit.setAttribute('type', 'submit');
submit.setAttribute('value', 'PDF');
form.appendChild(input);
form.appendChild(submit);
return form;
return canvas
}
function clearTests() {
var table = get('tests');
table.removeChild(table.children[1]);
function clearTests () {
var table = document.getElementById('tests')
if (table) document.body.removeChild(table)
}
function runTests() {
clearTests();
var table = get('tests')
, tbody = create('tbody');
for (var name in tests) {
var fn = tests[name]
, canvas = create('canvas')
, tr = create('tr')
, tds = [create('td'), create('td'), create('td'), create('td')];
function runTests () {
clearTests()
canvas.width = 200;
canvas.height = 200;
canvas.title = name;
var testNames = Object.keys(window.tests)
tds[2].appendChild(canvas);
tds[3].appendChild(create('h3', name));
tds[3].appendChild(pdfForm(fn, canvas));
var table = create('table', { id: 'tests' }, [
create('thead', {}, [
create('th', { textContent: 'node-canvas' }),
create('th', { textContent: 'browser canvas' }),
create('th', { textContent: '' })
]),
create('tbody', {}, testNames.map(function (name) {
return create('tr', {}, [
create('td', {}, [create('img', { src: '/render?name=' + encodeURIComponent(name) })]),
create('td', {}, [localRendering(name)]),
create('td', {}, [create('h3', { textContent: name }), pdfLink(name)])
])
}))
])
tr.appendChild(tds[0]);
tr.appendChild(tds[1]);
tr.appendChild(tds[2]);
tr.appendChild(tds[3]);
tbody.appendChild(tr);
table.appendChild(tbody);
runTest(name, canvas, tds[0], tds[1], tds[3]);
}
}
function runTest(name, canvas, dest, jpegDest, stats) {
var fn = tests[name]
, start = new Date;
try {
fn(canvas.getContext('2d'), function(){});
} catch (err) {
log(err);
}
var duration = new Date - start;
stats.appendChild(create('p', 'browser: ' + duration + 'ms'));
stats.appendChild(create('p', 'fps: ' + (1000 / duration).toFixed(0)));
renderOnServer('/render', name, canvas, function(res){
if (res.error) {
var p = create('p');
p.innerText = res.error;
dest.appendChild(p);
} else if (res.data) {
var img = create('img');
img.src = res.data;
stats.appendChild(create('p', 'node: ' + res.duration + 'ms'));
stats.appendChild(create('p', 'fps: ' + (1000 / res.duration).toFixed(0)));
dest.appendChild(img);
}
});
renderOnServer('/jpeg', name, canvas, function(res){
if (res.error) {
var p = create('p');
p.innerText = res.error;
jpegDest.appendChild(p);
} else if (res.data) {
var img = create('img');
img.src = res.data;
jpegDest.appendChild(img);
}
});
}
function renderOnServer(url, name, canvas, fn) {
var req = new XMLHttpRequest
, json = JSON.stringify({
fn: tests[name].toString()
, width: canvas.width
, height: canvas.height
});
req.open('POST', url);
req.setRequestHeader('Content-Type', 'application/json');
req.onreadystatechange = function(){
if (4 == req.readyState) {
try {
fn(JSON.parse(req.responseText));
} catch (err) {
fn({ error: err });
}
}
};
req.send(json);
document.body.appendChild(table)
}

16
test/public/style.css

@ -2,38 +2,38 @@ body {
padding: 40px 50px;
font: 13px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif;
}
p {
margin: 15px 5px;
}
em {
color: #00C5F7;
}
a {
color: #00C5F7;
}
canvas, img {
padding: 5px;
border: 1px solid #eee;
}
pre {
height: 200px;
font-size: 12px;
overflow: auto;
}
p.msg {
width: 400px;
}
#tests {
width: 100%;
margin-top: 35px;
}
table tr td:nth-child(1),
table tr td:nth-child(2) {
width: 200px;
}
table tr td:nth-child(3) {
padding: 0 45px;
}
table tr td p {
margin: 5px 0;
}

3774
test/public/tests.js

File diff suppressed because it is too large

126
test/server.js

@ -1,106 +1,54 @@
/**
* Module dependencies.
*/
var path = require('path')
var express = require('express')
, Canvas = require('../lib/canvas')
, Image = Canvas.Image
, bodyParser = require('body-parser')
, app = express();
// Config
app.set('views', __dirname + '/views');
app.set('view engine', 'pug');
// Middleware
var Canvas = require('../')
var tests = require('./public/tests')
app.use(bodyParser.json());
app.use(express.static(__dirname + '/public'));
var app = express()
var port = parseInt(process.argv[2] || '4000', 10)
// Routes
app.get('/', function(req, res){
res.render('tests');
});
function testFn(req){
// Normalize state.png as ./public/state.png
// no good way around this at the moment
req.body.fn = req.body.fn
.replace("'state.png'", "'" + __dirname + "/public/state.png'")
.replace("'face.jpeg'", "'" + __dirname + "/public/face.jpeg'")
.replace("'star.png'", "'" + __dirname + "/public/star.png'");
// Do not try this at home :)
return eval('(' + req.body.fn + ')');
}
function renderTest (canvas, name, cb) {
if (!tests[name]) {
throw new Error('Unknown test: ' + name)
}
function executeTestFn(ctx, fn, done) {
if(2 === fn.length) {
fn(ctx, done);
if (tests[name].length === 2) {
tests[name](canvas.getContext('2d'), cb)
} else {
fn(ctx);
done();
tests[name](canvas.getContext('2d'))
cb(null)
}
}
function createCanvas(req, type){
var width = req.body.width
, height = req.body.height;
return new Canvas(width, height, type);
}
app.use(express.static(path.join(__dirname, 'fixtures')))
app.use(express.static(path.join(__dirname, 'public')))
app.post('/render', function(req, res, next){
var fn = testFn(req)
, canvas = createCanvas(req)
, ctx = canvas.getContext('2d')
, start = new Date;
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'public', 'app.html'))
})
function done(){
var duration = new Date - start;
canvas.toDataURL(function(err, str){
if (err) throw err;
res.send({ data: str, duration: duration });
});
}
app.get('/render', function (req, res, next) {
var canvas = new Canvas(200, 200)
executeTestFn(ctx, fn, done);
});
renderTest(canvas, req.query.name, function (err) {
if (err) return next(err)
app.post('/pdf', function(req, res, next){
req.body = JSON.parse(req.body.json);
var fn = testFn(req)
, canvas = createCanvas(req, 'pdf')
, ctx = canvas.getContext('2d');
res.writeHead(200, { 'Content-Type': 'image/png' })
canvas.pngStream().pipe(res)
})
})
function done(){
res.writeHead(200, {'Content-Type' : 'application/pdf'});
res.write(canvas.toBuffer());
res.end();
}
app.get('/pdf', function (req, res, next) {
var canvas = new Canvas(200, 200, 'pdf')
executeTestFn(ctx, fn, done);
});
app.post('/jpeg', function(req, res, next){
// Send nothing if jpeg isn't available.
if (!Canvas.jpegVersion) { return res.send({}).end(); }
var fn = testFn(req)
, canvas = createCanvas(req)
, ctx = canvas.getContext('2d');
function done(){
canvas.toDataURL('image/jpeg', function (err, str){
if (err) throw err;
res.send({data: str});
});
}
renderTest(canvas, req.query.name, function (err) {
if (err) return next(err)
executeTestFn(ctx, fn, done);
});
res.writeHead(200, { 'Content-Type': 'application/pdf' })
canvas.pdfStream().pipe(res)
})
})
var port = parseInt(process.argv[2] || '4000', 10);
app.listen(port);
console.log('Test server listening on port %d', port);
app.listen(port, function () {
console.log('👉 http://localhost:%d/', port)
})

9
test/views/layout.pug

@ -1,9 +0,0 @@
doctype
html
head
title node-canvas
link(href='/style.css', rel='stylesheet')
script(src='/tests.js')
script(src='/app.js')
body
block content

24
test/views/tests.pug

@ -1,24 +0,0 @@
extend layout
block content
h1 node-canvas
p.msg
| The tests below assert visual and api integrity by running the
em &nbsp;exact&nbsp;
| same code utilizing the client canvas api, as well as node-canvas.
p
| Click to
a#run(href='#') &nbsp;re-run&nbsp;
| the test suite or "r".
table#tests
thead
tr
th node-canvas
th node-canvas (JPEG)
th target
th
tbody
Loading…
Cancel
Save