Merge pull request #3441 from cpojer/rm-perf

Remove perf folder
This commit is contained in:
Christoph Pojer
2015-03-18 12:28:55 -07:00
24 changed files with 0 additions and 1484 deletions
-1
View File
@@ -49,7 +49,6 @@ matrix:
fast_finish: true
allow_failures:
- env: TEST_TYPE=test:coverage
- env: TEST_TYPE=perf:full
- env: TEST_TYPE=test:webdriver:saucelabs:modern
- env: TEST_TYPE=test:webdriver:saucelabs BROWSER_NAME=ie11
- env: TEST_TYPE=test:webdriver:saucelabs BROWSER_NAME=ie10
-32
View File
@@ -24,7 +24,6 @@ module.exports = function(grunt) {
populist: require('./grunt/config/populist')(grunt),
connect: require('./grunt/config/server')(grunt),
'webdriver-jasmine': require('./grunt/config/webdriver-jasmine'),
'webdriver-perf': require('./grunt/config/webdriver-perf'),
npm: require('./grunt/config/npm'),
clean: [
'./build',
@@ -79,8 +78,6 @@ module.exports = function(grunt) {
grunt.registerMultiTask('webdriver-jasmine', webdriverJasmineTasks);
grunt.registerMultiTask('webdriver-perf', require('./grunt/tasks/webdriver-perf'));
grunt.registerMultiTask('npm', npmTask);
grunt.registerTask('npm-react:release', npmReactTasks.buildRelease);
@@ -119,14 +116,6 @@ module.exports = function(grunt) {
'version-check',
'browserify:withCodeCoverageLogging'
]);
grunt.registerTask('build:perf', [
'jsx:normal',
'version-check',
'browserify:transformer',
'browserify:basic',
'browserify:min',
'download-previous-version'
]);
grunt.registerTask('build:test', [
'delete-build-modules',
'jsx:test',
@@ -153,12 +142,6 @@ module.exports = function(grunt) {
'webdriver-jasmine:local'
]);
grunt.registerTask('perf:webdriver:phantomjs', [
'connect',
'webdriver-phantomjs',
'webdriver-perf:local'
]);
grunt.registerTask('test:full', [
'build:test',
'build:basic',
@@ -173,20 +156,6 @@ module.exports = function(grunt) {
'webdriver-jasmine:saucelabs_chrome'
]);
grunt.registerTask('perf:full', [
'build:perf',
'connect',
'webdriver-phantomjs',
'webdriver-perf:local',
'sauce-tunnel',
'webdriver-perf:saucelabs_firefox',
'webdriver-perf:saucelabs_chrome',
'webdriver-perf:saucelabs_ie11',
'webdriver-perf:saucelabs_ie8'
]);
grunt.registerTask('test:webdriver:saucelabs', [
'build:test',
'build:basic',
@@ -251,7 +220,6 @@ module.exports = function(grunt) {
grunt.task.run('build:test', 'build:basic', 'test:webdriver:phantomjs');
}
});
grunt.registerTask('perf', ['build:perf', 'perf:webdriver:phantomjs']);
grunt.registerTask('npm:test', ['build', 'npm:pack']);
// Optimized build task that does all of our builds. The subtasks will be run
-55
View File
@@ -1,55 +0,0 @@
'use strict';
var grunt = require('grunt');
var path = require('path');
var tests = grunt.file.expand(path.join(__dirname, '/../../perf/tests/*'));
var maxTime = 5;
var reactVersions = [
'edge',
'previous'
];
var params = []
.concat('headless=false')
.concat('maxTime=' + maxTime)
.concat(tests
.map(function(testPath) {
return testPath.split(/tests./i).reverse()[0];
})
.map(encodeURIComponent)
.map(function(filename) {
return 'test=' + filename;
})
)
.concat(reactVersions
.map(encodeURIComponent)
.map(function(version) {
return 'react=' + version;
}
)
);
module.exports = require('./webdriver-all')({
url: 'http://127.0.0.1:9999/perf/index.html?' + params.join('&'),
isDoneTimeout: 15 * 60 * 1000,
onStart: function() {
grunt.event.on('perf results', function(results) {
console.log(results);
});
},
onComplete: function(completedTestKeys) {
grunt.verbose.writeln('onComplete ' + JSON.stringify(completedTestKeys));
},
onError: function(error) {
grunt.fatal(error);
}
});
-20
View File
@@ -1,20 +0,0 @@
'use strict';
var grunt = require('grunt');
module.exports = function() {
return require('./webdriver-all').call(this, function(config, wd, browser) {
if (!config.isDoneTimeout) {
grunt.verbose.writeln('Expected isDoneTimeout config, using default value');
}
grunt.verbose.writeln('isDoneTimeout:' + config.isDoneTimeout);
return browser
.waitFor(wd.asserters.jsCondition('window.isDone === false'), 5e3, 50)
.fail(function(error) {
throw Error('The test page didn\'t load properly. ' + error);
})
.waitFor(wd.asserters.jsCondition('window.isDone === true'), config.isDoneTimeout || 30e3, 1e3)
.waitFor(wd.asserters.jsCondition('window.postDataToURL.running <= 0'), 30e3, 500)
.eval('window.completedTestKeys || window._unhandledError');
});
};
-21
View File
@@ -1,21 +0,0 @@
globals:
document: true
window: true
Benchmark: true
React: true
_rootNode: true
todolist: true
_app: true
_todo1: true
_todo2: true
_todo3: true
_timesToRun: true
setState: true
rules:
strict: false
no-undef: false
no-unused-vars: false
block-scoped-var: false
consistent-return: false
no-shadow: false
-67
View File
@@ -1,67 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>Perf Tests</title>
<script>
window.onerror = function(error){
window._unhandledError = error;
window.isDone = true;
}
</script>
<script src="./lib/perf-test-runner.browser.js"></script>
<script> perfRunner.Polyfill(); </script>
<script src="../build/react.js"></script>
<script src="../build/JSXTransformer.js"></script>
<script src="../test/lib/postDataToURL.browser.js"></script>
<script src="./lib/BrowserPerfRunnerContext.react.js"></script>
<script src="./lib/BrowserPerfRunnerApp.react.js"></script>
<script>
var tests = [
"sanity.js",
"todolist-mount.js",
"todolist-edit.js",
"todolist-add.js",
"todolist-do-stuff.js",
"setState-callback-5.js",
"setState-callback.js",
"basic-div.js",
"basic-unmount.js",
"propTypes.js",
"renderComponent-basic.js",
"shouldComponentUpdate.js",
];
var reactVersions = [
'edge',
'builds/master/latest'
];
window.onload = function(){
window.isDone = false;
React.render(
BrowserPerfRunnerApp({
headless: perfRunner.getQueryParamArrayOrDefault('headless', [false])[0],
react: perfRunner.getQueryParamArrayOrDefault('react', reactVersions),
tests: perfRunner.getQueryParamArrayOrDefault('test', tests),
maxTime: perfRunner.getQueryParamArrayOrDefault('maxTime', [5])[0],
onCompleteEach: function(results){
console.log('onCompleteEach', results);
postDataToURL({type:'perf', message:results}, '/reportTestResults');
},
onError: function(error){
window._unhandledError = error;
},
onComplete: function(results){
window.completedTestKeys = Object.keys(results);
window.isDone = true;
}
}),
document.body
);
}
</script>
-219
View File
@@ -1,219 +0,0 @@
var BrowserPerfRunnerApp = React.createClass({
propTypes: {
tests: React.PropTypes.array.isRequired,
react: React.PropTypes.array.isRequired,
maxTime: React.PropTypes.number,
onCompleteEach: React.PropTypes.func,
onComplete: React.PropTypes.func,
onError: React.PropTypes.func,
headless: React.PropTypes.bool
},
getInitialState: function() {
var queue = [];
this.props.tests.forEach(function(testName) {
this.props.react.forEach(function(version) {
queue.push({
test: testName,
react: version
});
}, this);
}, this);
return {
queue: queue,
results: {}
};
},
handleResults: function(results) {
this.state.results[results.test + '@' + results.react] = results;
this.replaceState(this.state);
},
handleComplete: function(queueItem) {
queueItem.completed = true;
if (!this.props.onCompleteEach) {
return;
}
// Can't get the resultsForAllVersions if there are still some queued
var incompleteCount = 0;
for (var index = this.state.queue.length; --index >= 0;) {
if (this.state.queue[index].completed) {
continue;
}
if (this.state.queue[index].test === queueItem.test) {
return;
}
incompleteCount++;
}
var resultsForAllVersions = Object.keys(this.state.results)
.filter(function(key) {
return key.indexOf(queueItem.test) === 0;
})
.map(function(key) {
return this.state.results[key];
}, this);
this.props.onCompleteEach(resultsForAllVersions);
if (this.props.onComplete && incompleteCount === 0) {
this.props.onComplete(this.state.results);
}
},
render: function() {
var grid = null;
if (!this.props.headless) {
grid = GridViewTable({
rows: this.props.tests,
cols: this.props.react,
renderCell: BrowserPerfRunnerApp.renderBenchmarkCell,
value: this.state.results
});
}
return React.DOM.div(null,
BenchmarkQueue({
initialQueue: this.state.queue,
onChange: this.handleResults,
maxTime: this.props.maxTime,
onCompleteEach: this.handleComplete,
onError: this.props.onError
}),
grid
);
}
});
BrowserPerfRunnerApp.renderBenchmarkCell = function(props, row, col) {
if (col == null && row == null) {
return React.DOM.th(null);
}
if (row == null) {
return React.DOM.th({style:{verticalAlign:'top', textAlign:'center'}}, col);
}
var benchmarks = Object.keys(props.value)
.filter(function(key) {
return key.indexOf(row) === 0;
})
.map(function(key) {
return props.value[key];
})
.filter(function(benchmark) {
return benchmark && !benchmark.isRunning && benchmark.stats;
});
if (col == null) {
return React.DOM.th({style:{verticalAlign:'top', textAlign:'right'}},
React.DOM.a({href:'?test=' + row}, benchmarks[0] && benchmarks[0].name || row)
);
}
var key = row + '@' + col;
var benchmark = props.value[key];
if (!(benchmark && benchmark.stats)) {
return React.DOM.td({key:key});
}
var colors = [
'000000',
'AA0000',
'00AA00',
'AA5500',
'0000AA',
'AA00AA',
'00AAAA',
'AAAAAA',
'555555',
'FF5555',
'55FF55',
'FFFF55',
'5555FF',
'FF55FF',
'55FFFF',
'FFFFFF'
];
function chartValue(value) {
return Math.round(valueFromRangeToRange(value, chartValue.min, chartValue.max, 0, 100));
}
chartValue.min = Math.min.apply(Math, benchmarks.map(function(benchmark) {
return Math.min.apply(Math, benchmark.stats.sample);
}));
chartValue.max = Math.max.apply(Math, benchmarks.map(function(benchmark) {
return Math.max.apply(Math, benchmark.stats.sample);
}));
var means = benchmarks.map(function(benchmark) {
return benchmark.stats.mean;
});
benchmarks.forEach(function(benchmark) {
benchmark.isTheWinner = benchmark.stats.mean <= Math.min.apply(Math, means);
});
var chartValues = benchmarks.map(function(benchmark) {
// benchmark.stats.sample.sort(function(a,b) {return b - a;});
return benchmark.stats.sample.map(chartValue).join(',');
}).join('|');
return (
React.DOM.td({key:key, style:{textAlign:'center', width:234, verticalAlign:'top'}},
benchmark.error && benchmark.error.message || '',
React.DOM.div({style: benchmark.isTheWinner ? {backgroundColor:'#0A5', color:'#AFA'} : {backgroundColor:'transparent', color:'inherit'}},
Math.round(1 / benchmark.stats.mean * 100) / 100, ' op/s ',
React.DOM.strong(null, Math.round(benchmark.stats.mean * 1000 * 100) / 100, ' ms/op '),
React.DOM.small(null, '(±' + (Math.round(benchmark.stats.rme * 10) / 10) + '%)')
),
benchmark.isRunning && 'Running' || React.DOM.img({
style: {
borderWidth: 2,
borderStyle: 'solid',
color: '#' + colors[benchmarks.indexOf(benchmark)]
},
width: 230,
height: 50,
src: 'https://chart.googleapis.com/chart?cht=ls&chs=460x100&chd=t:' + chartValues + '&chco=' + colors.join(',')
})
)
);
};
function valueFromRangeToRange(value, fromMin, fromMax, toMin, toMax) {
var fromRange = fromMax - fromMin;
var toRange = toMax - toMin;
return (((value - fromMin) * toRange) / fromRange) + toMin;
}
var GridViewTable = React.createClass({
propTypes: {
rows: React.PropTypes.array.isRequired,
cols: React.PropTypes.array.isRequired,
renderCell: React.PropTypes.func.isRequired
},
_renderCell: function(col) {
return this.props.renderCell({value:this.props.value}, this._row, col);
},
_renderRow: function(row) {
this._row = row;
return React.DOM.tr({key:row},
this._renderCell(null, 0),
this.props.cols.map(this._renderCell, this)
);
},
render: function() {
return React.DOM.table(null,
this._renderRow(null, 0),
this.props.rows.map(this._renderRow, this)
);
}
});
-201
View File
@@ -1,201 +0,0 @@
var BenchmarkQueue = React.createClass({
propTypes: {
debug: React.PropTypes.bool,
onChange: React.PropTypes.func.isRequired,
initialQueue: React.PropTypes.array.isRequired,
maxTime: React.PropTypes.number,
onCompleteEach: React.PropTypes.func,
onError: React.PropTypes.func
},
getDefaultProps: function() {
return {
maxTime: 5
};
},
getInitialState: function() {
return {
queue: this.props.initialQueue.slice()
};
},
setItemState: function(state) {
state.test = this.state.queue[0].test;
state.react = this.state.queue[0].react;
this.props.onChange(state);
},
handleContextReady: function(window) {
var benchmark = window.Benchmark(window.exports);
benchmark.options.maxTime = this.props.maxTime; //DEBUG
var itemState = {
testRunnerURL: window.location.href,
name: window.exports.name,
platform: window.Benchmark.platform.description,
reactVersion: window.React.version,
isMinified: (function() {
var code = window.React.render.toString();
return code.indexOf(',') - code.indexOf('(') <= 2;
}())
};
this.setItemState(itemState);
var self = this;
benchmark.on('start error cycle complete', function() {
var stats = JSON.parse(JSON.stringify(benchmark.stats));
itemState.stats = stats;
itemState.isRunning = benchmark.running;
itemState.error = benchmark.error;
self.setItemState(itemState);
});
if (this.props.onError) {
benchmark.on('error', this.props.onError);
}
benchmark.on('complete', function() {
var queue = self.state.queue.slice();
var queueItem = queue.shift();
if (self.props.onCompleteEach) {
self.props.onCompleteEach(queueItem);
}
self.setState({queue:queue});
});
benchmark.run({async:true});
},
shouldComponentUpdate: function(nextProps, nextState) {
return nextState.queue.length < this.state.queue.length;
},
render: function() {
if (!(this.state.queue && this.state.queue.length > 0)) {
return React.DOM.div({style:{display:'none'}});
}
return BrowserPerfRunnerContext({
debug: this.props.debug,
test: this.state.queue[0].test,
react: this.state.queue[0].react,
onReady: this.handleContextReady
});
}
});
var BrowserPerfRunnerContext = React.createClass({
propTypes: {
debug: React.PropTypes.bool,
test: function(object, key) {
React.PropTypes.string.isRequired(object, key);
if (/\.jsx?$/i.test(object[key])) {
return;
}
throw Error('Expected `' + key + '` to be a test file name with extension `.js` or `.jsx`');
},
react: function(object, key) {
React.PropTypes.string.isRequired(object, key);
if (/^(?:builds\/.+|edge|previous|(?:\d+\.){2}\d+)$/.test(object[key])) {
return;
}
throw Error('Expected `' + key + '` prop to be a valid react version string, build string or \'edge\' or \'previous\'');
},
onReady: React.PropTypes.func.isRequired
},
getInitialState: function() {
return {
testRunnerURL:'about:blank'
};
},
// _handleFrameError: function(error) {
// console.error('BrowserPerfRunnerContext', error);
// },
//
// _handleFrameLoad: function(event) {
// console.log('BrowserPerfRunnerContext', event);
// },
//
_handleMessage: function(event) {
if (location.href.indexOf(event.origin) !== 0) {
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message from ' + event.origin);
}
if (event.source.location.href.indexOf(this.state.testRunnerURL) === -1) {
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message from ' + event.source.location.href);
}
if (event.data !== 'Ready!') {
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message ' + JSON.stringify(event.data));
}
this.props.onReady(event.source);
},
_getTestRunnerURL: function(props) {
return 'runner.html' +
'?' +
'debug=' + (props.debug ? 1 : 0) +
'&' +
'react=' + encodeURIComponent(props.react) +
'&' +
'test=' + encodeURIComponent(props.test);
},
_renderState: function(props) {
return {
testRunnerURL: this._getTestRunnerURL(props)
};
},
componentDidMount: function() {
var node = this.refs.iframe.getDOMNode();
// node.onload = this._handleFrameLoad;
// node.onerror = this._handleFrameError;
if (window.addEventListener) {
window.addEventListener('message', this._handleMessage, false);
} else if (window.attachEvent) {
window.attachEvent('onmessage', this._handleMessage);
} else {
throw Error('cannot attach onmessage listener');
}
this.setState(this._renderState(this.props));
},
componentWillUnmount: function() {
if (window.removeEventListener) {
window.removeEventListener('message', this._handleMessage);
} else if (window.detachEvent) {
window.detachEvent('onmessage', this._handleMessage);
} else {
throw Error('cannot detach onmessage listener');
}
this.refs.iframe.getDOMNode().src = '';
},
componentWillReceiveProps: function(nextProps) {
this.setState(this._renderState(nextProps));
},
shouldComponentUpdate: function(nextProps, nextState) {
return nextState.testRunnerURL !== this.state.testRunnerURL;
},
render: function() {
return (
React.DOM.iframe({
ref: 'iframe',
name: 'BrowserPerfRunnerContextFrame',
style: this.style,
src: this.state.testRunnerURL
})
);
},
style: {
position: 'absolute',
right: '100%',
bottom: '100%'
}
});
-224
View File
@@ -1,224 +0,0 @@
if (typeof console === 'undefined') {
console = {
log: function() {},
warn: function() {},
error: function() {},
debug: function() {}
};
}
var perfRunner;
if (typeof exports === 'object') {
perfRunner = exports;
} else {
perfRunner = {};
}
perfRunner.assert = function(test, message) {
if (typeof test === 'function') {
test = test();
}
if (test) {
return;
}
throw Error(message);
};
perfRunner.WriteScript = function(props) {
var type = '';
if (props.jsx) {
type = ' type=\'text/jsx\'';
}
var src = props.src;
if (!props.cache) {
src += src.indexOf('?') === -1 ? '?_' : '&_';
src += perfRunner.WriteScript.cacheBust;
}
document.write('<script' + type + ' src=\'' + src + '\'><\/script>');
};
perfRunner.WriteScript.cacheBust = (+new Date()).toString(36);
perfRunner.WriteReactLibScript = function(params) {
var src;
var minSuffix;
if (params.debug) {
minSuffix = '';
} else {
minSuffix = '.min';
}
if (params.version && typeof params.version !== 'string') {
throw TypeError('Expected \'version\' to be a string');
}
if (params.version === 'edge' || !params.version) {
console.log('React edge (local)');
perfRunner.WriteScript({src:'../build/react' + minSuffix + '.js'});
perfRunner.WriteScript({src:'../build/JSXTransformer.js'});
} else if (params.version === 'previous') {
console.log('React previous (local)');
perfRunner.WriteScript({cache:true, src:'../build/react-previous' + minSuffix + '.js'});
perfRunner.WriteScript({cache:true, src:'../build/JSXTransformer-previous.js'});
} else if (params.version.indexOf('builds/') === 0) {
perfRunner.WriteScript({cache:true, src:'http://react.zpao.com/' + params.version + '/react' + minSuffix + '.js'});
perfRunner.WriteScript({cache:true, src:'http://react.zpao.com/' + params.version + '/JSXTransformer.js'});
} else {
console.log('React ' + params.version);
perfRunner.WriteScript({cache:true, src:'http://fb.me/react-' + params.version + minSuffix + '.js'});
perfRunner.WriteScript({cache:true, src:'http://fb.me/JSXTransformer-' + params.version + '.js'});
}
if (params.debug) {
console.warn('Loading the unminified build of React, performance may suffer.');
console.warn('Load \'' + location.href.replace(/\bdebug=\w+&?|&\bdebug=\w+/ig, '') + '\' for better perf.');
} else {
console.warn('Loading the minified build of React, debugging may be harder.');
console.warn('Load \'' + location.href.replace(/\bdebug=\w+&?|&\bdebug=\w+/ig, '') + '&debug=1' + '\' for easier debugging.');
}
};
perfRunner.WriteTestScript = function(params) {
if (Array.isArray(params.test)) {
return params.test
.map(function(test) {
return {
test:test
};
})
.map(perfRunner.WriteTestScript);
}
perfRunner.assert(params.test.indexOf('..') === -1, 'no relative paths allowed');
return perfRunner.WriteScript({jsx:true, src: './tests/' + params.test});
};
perfRunner.getQueryParamArray = function(key) {
var values;
var queryString = location.search.substr(1);
var _key = encodeURIComponent(key) + '=';
if (queryString.indexOf(_key) > -1) {
values = queryString
.split(_key)
.slice(1)
.map(function(part) {
return part.split('&')[0];
})
.map(decodeURIComponent)
.map(function(string) {
try {
return JSON.parse(string);
} catch(e) {}
return string;
});
}
perfRunner.assert(values && values.length && values[0], 'expected ' + key + ' query param');
return values;
};
perfRunner.getQueryParamArrayOrDefault = function(key, defaultValue) {
try {
return perfRunner.getQueryParamArray(key);
} catch (e) {}
return defaultValue;
};
perfRunner.Polyfill = function() {
if (typeof Function.prototype.bind !== 'undefined') {
return;
}
perfRunner.WriteScript({src:'/node_modules/es5-shim/es5-shim.js', cache:true});
perfRunner.WriteScript({src:'/node_modules/es5-shim/es5-sham.js', cache:true});
};
perfRunner.BenchmarkResults = function(props) {
return perfRunner.roundNumberWithPrecision(props.stats.mean * 1000) + 'ms/op';
};
perfRunner.roundNumberWithPrecision = function(number, precision) {
if (!precision) {
precision = 1000;
}
return Math.round(number * precision) / precision;
};
perfRunner.quickBench = function(benchmarkOptions, onComplete, onBeforeStart) {
var bench = new Benchmark(benchmarkOptions);
if (onBeforeStart) {
onBeforeStart(null, bench);
}
bench.on('error', function(event) {
console.error(event.message);
console.log(event.target.compiled.toString());
onComplete(Error(event.error));
});
bench.on('start', function() {
console.log('starting', bench.name);
});
bench.on('cycle', function() {
var benchmark = this,
size = benchmark.stats.size;
if (!benchmark.aborted) {
console.warn(benchmark.name + ' × ' + benchmark.count +
' (' + benchmark.stats.sample.length + ' samples)' +
' (' + Math.round(1 / benchmark.stats.mean) + ' ops/sec' + ')' +
' (' + (benchmark.stats.mean * 1000) + ' ms/op' + ')' +
' (±' + benchmark.stats.rme.toFixed(2) + '%)' +
' with ' + React.version
);
}
});
bench.on('complete', function() {
var results = {
platform: Benchmark.platform.description,
react: React.version,
name: bench.name
// times: bench.times,
// stats: bench.stats
};
results['s/op'] = bench.stats.mean;
results['ms/op'] = results['s/op'] * 1000;
results['op/s'] = 1 / results['s/op'];
results['% frame 60'] = results['ms/op'] / (1000 / 60) * 100;
console.log(results);
onComplete(null, results);
});
bench.run();
};
perfRunner.singleTest = function(benchmarkOptions, onComplete) {
var bench = Benchmark(exports);
bench.on('complete', function() {
var results = {
platform: Benchmark.platform.description,
react: React.version,
name: bench.name,
stats: bench.stats
};
onComplete(results);
});
bench.run();
};
perfRunner.ViewObject = function(props) {
var value = props.value;
delete props.value;
if (typeof value !== 'object') {
return React.DOM.span(props, [JSON.stringify(value), ' ', typeof value]);
}
return React.DOM.table(props, Object.keys(value).map(function(key) {
return React.DOM.tr(null,
React.DOM.th(null, key),
React.DOM.td(null, perfRunner.ViewObject({key:key, value:value[key]}))
);
}));
};
-145
View File
@@ -1,145 +0,0 @@
todolist = {};
todolist.ID = Date.now();
todolist.now = window.performance && window.performance.now && window.performance.now.bind(window.performance) || Date.now.bind(Date);
todolist.App = React.createClass({
propTypes: {
fakeDataCount: React.PropTypes.number
},
getInitialState: function() {
var todos;
if (this.props.fakeDataCount) {
todos = Array(this.props.fakeDataCount + 1).join(',').split(',').map(function(ignore, index) {
return {
id: index,
title: 'Title ' + index + ' ' + Math.random().toString(36).substring(2, 16),
completed: !!(index % 2)
};
});
}
return {
timerStart: todolist.now(),
timerEnd: null,
timerEvent: 'getInitialState',
todos: todos || this.props.initialData || []
};
},
componentWillUpdate: function(props, state) {
state.todos = state.todos.filter(function(todo) {
return !todo.deleted;
});
},
addItem: function(title, callback) {
if (title == null || title === '') {
var error = Error('invalid title');
if (!callback) {
throw error;
}
return callback(error);
}
var todos = this.state.todos.slice();
var todo = {
id: ++todolist.ID,
title: title,
completed: false
};
todos.push(todo);
if (callback) {
callback = callback.bind(this, todo);
}
this.setState({timerEvent:'addItem', timerStart:todolist.now(), timerEnd:null, todos:todos}, callback);
return todo;
},
deleteItemById: function(id, callback) {
var todo = this._getById(id);
if (!todo) {
return callback && callback(Error('todo with id ' + id + ' not found'));
}
todo.deleted = true;
this.setState({timerEvent:'deleteItemById', timerStart:todolist.now(), timerEnd:null, todos:this.state.todos}, callback);
},
setItemCompleted: function(id, completed, callback) {
var todo = this._getById(id);
if (!todo) {
return callback && callback(Error('todo with id ' + id + ' not found'));
}
todo.completed = completed;
this.setState({timerEvent:'setItemCompleted', timerStart:todolist.now(), timerEnd:null, todos:this.state.todos}, callback);
},
_getById: function(id) {
id = +id;
var todos = this.state.todos;
for (var index = todos.length; --index >= 0;) {
if (todos[index].id === id) {
return todos[index];
}
}
return null;
},
_handleItemCompletedCheckboxChange: function(event) {
var node = event.target;
this.setItemCompleted(node.value, node.checked);
},
_handleItemDeletedButton: function(event) {
var node = event.target;
this.deleteItemById(node.value);
},
_renderTodoItem: function(todo, index) {
return (
React.DOM.li({key:todo.id},
React.DOM.button({value:todo.id, onClick:this._handleItemDeletedButton}, 'x'),
React.DOM.input({type:'checkbox', value:todo.id, checked:todo.completed, onChange:this._handleItemCompletedCheckboxChange}),
' ',
React.DOM.span({style:{'text-decoration':todo.completed ? 'line-through' : ''}}, todo.title)
)
);
},
render: function() {
if (!this.state.timerEnd) {
this.state.timerEnd = todolist.now();
}
if (this.props.onRender) {
this.props.onRender();
}
return (
React.DOM.div(null,
React.DOM.h1(null, 'TODO'),
React.DOM.h3(null, this.state.timerEvent, ' ', this.state.timerEnd - this.state.timerStart, 'ms'),
todolist.NewItemForm({onEnter:this.addItem, autoFocus:true}),
React.DOM.ol(null, this.state.todos.map(this._renderTodoItem))
)
);
},
componentDidMount: function(rootNode) {
if (this.props.onDidMount) {
this.props.onDidMount(rootNode);
}
}
});
todolist.NewItemForm = React.createClass({
_handleNewItemKeyDown: function(event) {
if (event.which !== 13/*enter key*/) {
return;
}
var node = this.refs.text.getDOMNode();
var value = node.value;
node.value = '';
this.props.onEnter(value);
return false;
},
render: function() {
var props = {};
for (var key in this.props) {
if (key !== 'onEnter') {
props[key] = this.props[key];
}
}
props.ref = 'text';
props.onKeyDown = this.props.onEnter && this._handleNewItemKeyDown;
return React.DOM.input(props);
}
});
-16
View File
@@ -1,16 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>todolist</title>
<script src="perf-test-runner.browser.js"></script>
<script> perfRunner.Polyfill(); </script>
<script src="../../build/react.min.js"></script>
<script src="todolist.browser.js"></script>
<script>
function main(){
var app = todolist.App({ fakeDataCount:333 });
React.render(app, document.body);
}
window.onload = main;
</script>
-59
View File
@@ -1,59 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>Perf Test Runner</title>
<script src="../node_modules/platform/platform.js"></script>
<script src="../node_modules/benchmark/benchmark.js"></script>
<script src="lib/perf-test-runner.browser.js"></script>
<script> perfRunner.Polyfill(); </script>
<script>
perfRunner.WriteReactLibScript({
version: perfRunner.getQueryParamArrayOrDefault('react', [null])[0],
debug: perfRunner.getQueryParamArrayOrDefault('debug', [false])[0]
});
perfRunner.WriteScript({src:"lib/todolist.browser.js"});
perfRunner.WriteTestScript({ test:perfRunner.getQueryParamArray('test') });
</script>
<script>
function checkIfReady(){
if (!window.exports) return setTimeout(checkIfReady, 50);
console.timeStamp && console.timeStamp(perfRunner.getQueryParamArray('test'));
if (typeof gc == 'function') gc();
window.parent.postMessage(perfRunner.getQueryParamArrayOrDefault('callback', ['Ready!'])[0], '*');
}
checkIfReady();
function main(callback){
perfRunner.singleTest(exports, function(results){
document.getElementById('results').textContent = JSON.stringify(results, null, 2);
callback();
});
}
function runOnce(callback){
setTimeout(function(){
exports.fn({resolve: function(){
setTimeout(callback, 0);
}});
},0);
}
</script>
<button autofocus onclick="if (disabled) return false; main(function(){ disabled=false; textContent='Run again!'; }); textContent='Running!'; disabled=true">Run!</button>
<div>
<button onclick="exports.setup();">Setup!</button>
<button onclick="if (disabled) return false; runOnce(function(){ disabled=false; textContent='Run again!'; }); textContent='Running!'; disabled=true">Run once!</button>
<button onclick="exports.teardown();">Teardown!</button>
</div>
<pre id=results style="font-size:9px"></pre>
-11
View File
@@ -1,11 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
exports.name = 'React.DOM.div, no props';
exports.fn = function() {
React.DOM.div(null, 'lol, perf testing ', this.count);
};
-21
View File
@@ -1,21 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
exports.name = 'unmountComponentAtNode';
exports.setup = function() {
_rootNode = document.createElement('div');
document.body.appendChild(_rootNode);
var _firstChild = React.DOM.div(null, 'lol, perf testing ', this.count);
React.render(_firstChild, _rootNode);
};
exports.fn = function() {
if (React.unmountAndReleaseReactRootNode) {
React.unmountAndReleaseReactRootNode(_rootNode);
} else {
React.unmountComponentAtNode(_rootNode);
}
};
-91
View File
@@ -1,91 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
exports.name = 'propTypes';
var Thing = function() {};
var List;
var ListItem;
var MyReactComponent;
var _rootNode;
function func() {
return 'this is a function';
}
exports.setup = function() {
List = React.createClass({
propTypes: {
array: React.PropTypes.array,
bool: React.PropTypes.bool.isRequired,
number: React.PropTypes.number,
string: React.PropTypes.string.isRequired,
func: React.PropTypes.func.isRequired,
node: React.PropTypes.node.isRequired,
instanceOf: React.PropTypes.instanceOf(Thing).isRequired
},
render: function() {
return React.DOM.ul(null, this.props.children);
}
});
ListItem = React.createClass({
propTypes: {
array: React.PropTypes.array,
bool: React.PropTypes.bool.isRequired,
number: React.PropTypes.number,
string: React.PropTypes.string.isRequired,
func: React.PropTypes.func.isRequired,
node: React.PropTypes.node.isRequired,
node2: React.PropTypes.node.isRequired,
instanceOf: React.PropTypes.instanceOf(Thing).isRequired,
element: React.PropTypes.element.isRequired
},
render: function() {
return React.DOM.li(null,
this.props.number + this.props.string + this.props.node
);
}
});
MyReactComponent = React.createClass({
render: function() {
return React.DOM.span();
}
});
_rootNode = document.createElement('div');
document.body.appendChild(_rootNode);
};
exports.fn = function() {
var items = [];
for (var i = 0; i < 1000; i++) {
items.push(ListItem({
array: [11, 12, 13, 14, 15, 16, 17, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
bool: false,
number: Math.random(),
string: 'banana banana banana',
func: func,
node: 'renderable string',
node2: [MyReactComponent(), 'a string'],
instanceOf: new Thing(),
element: MyReactComponent()
}));
}
React.render(List({
array: [11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
bool: false,
number: Math.random(),
string: 'banana banana banana',
func: func,
renderable: 'renderable string',
instanceOf: new Thing()
}, items), _rootNode);
};
exports.teardown = function() {
React.unmountComponentAtNode(_rootNode);
};
-22
View File
@@ -1,22 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
exports.name = 'React.render single div';
exports.setup = function() {
_rootNode = document.createElement('div');
document.body.appendChild(_rootNode);
};
exports.fn = function() {
React.render(React.DOM.div(null, 'lol, perf testing ', this.count), _rootNode);
};
exports.teardown = function() {
if (React.unmountAndReleaseReactRootNode) {
React.unmountAndReleaseReactRootNode(_rootNode);
} else {
React.unmountComponentAtNode(_rootNode);
}
};
-17
View File
@@ -1,17 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
exports.name = 'Trivial benchmark to verify that everything works';
exports.setup = function() {
var foo;
};
exports.fn = function() {
foo = Array(999).join('Howdy!\n');
};
exports.teardown = function() {
foo = null;
};
-45
View File
@@ -1,45 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
exports.name = 'From setState to callback (x5)';
exports.defer = true;
exports.setup = function() {
_rootNode = document.createElement('div');
document.body.appendChild(_rootNode);
setState = null;
var AwesomeComponent = React.createClass({
getInitialState: function() {
return {random:null};
},
render: function() {
if (!setState) {
setState = this.setState.bind(this);
}
return React.DOM.div(null, this.state.random);
}
});
React.render(AwesomeComponent(null), _rootNode);
};
exports.fn = function(deferred) {
setState({random: Date.now() + Math.random()}, function() {
setState({random: Date.now() + Math.random()}, function() {
setState({random: Date.now() + Math.random()}, function() {
setState({random: Date.now() + Math.random()}, function() {
setState({random: Date.now() + Math.random()}, function() {
deferred.resolve();
});
});
});
});
});
};
exports.teardown = function() {
React.unmountComponentAtNode(_rootNode);
};
-37
View File
@@ -1,37 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
exports.name = 'From setState to callback';
exports.defer = true;
exports.setup = function() {
_rootNode = document.createElement('div');
document.body.appendChild(_rootNode);
setState = null;
var AwesomeComponent = React.createClass({
getInitialState: function() {
return {random:null};
},
render: function() {
if (!setState) {
setState = this.setState.bind(this);
}
return React.DOM.div(null, this.state.random);
}
});
React.render(AwesomeComponent(null), _rootNode);
};
exports.fn = function(deferred) {
setState({random: Date.now() + Math.random()}, function() {
deferred.resolve();
});
};
exports.teardown = function() {
React.unmountComponentAtNode(_rootNode);
};
-27
View File
@@ -1,27 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
exports.name = 'shouldComponentUpdate';
exports.setup = function() {
var AwesomeComponent = React.createClass({
shouldComponentUpdate: function() {
return false;
},
render: function() {
return React.DOM.div({});
}
});
var _rootNode = document.createElement('div');
document.body.appendChild(_rootNode);
};
exports.fn = function() {
React.render(AwesomeComponent(null), _rootNode);
};
exports.teardown = function() {
React.unmountComponentAtNode(_rootNode);
};
-31
View File
@@ -1,31 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
exports.name = 'todolist from addItem to callback';
exports.defer = true;
exports.setup = function() {
_rootNode = document.createElement('div');
document.body.appendChild(_rootNode);
var appDescriptor = todolist.App({fakeDataCount: 333});
_app = React.render(appDescriptor, _rootNode);
};
exports.fn = function(deferred) {
var liCount = document.getElementsByTagName('li').length;
_app.addItem(Math.random(), function() {
if (document.getElementsByTagName('li').length <= liCount) {
throw Error('expected a list item to be added to the dom');
}
deferred.resolve();
});
};
exports.teardown = function() {
React.unmountComponentAtNode(_rootNode);
_rootNode.parentNode.removeChild(_rootNode);
_rootNode = null;
_app = null;
};
-58
View File
@@ -1,58 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
_timesToRun = 2;
exports.name = 'todolist add, complete, remove (x' + _timesToRun + ')';
exports.defer = true;
exports.setup = function() {
_rootNode = document.createElement('div');
document.body.appendChild(_rootNode);
var appDescriptor = todolist.App({fakeDataCount: 333});
_app = React.render(appDescriptor, _rootNode);
};
exports.fn = function(deferred) {
var originalLiCount = document.getElementsByTagName('li').length;
var todos = [];
var times = _timesToRun;
while (times-- >= 0) {
todos.push(_app.addItem(times + 1));
}
todos.forEach(function(todo) {
_app.setItemCompleted(todo.id);
});
todos.forEach(function(todo) {
_app.deleteItemById(todo.id);
});
todos = null;
_app.addItem(Math.random(), function(todo) {
if (document.getElementsByTagName('li').length <= originalLiCount) {
throw Error('expected a list item to be added to the dom');
}
_app.deleteItemById(todo.id, function() {
if (document.getElementsByTagName('li').length !== originalLiCount) {
throw Error('expected everything to be done by now');
}
deferred.resolve();
});
});
};
exports.teardown = function() {
React.unmountComponentAtNode(_rootNode);
_rootNode.parentNode.removeChild(_rootNode);
_rootNode = null;
_app = null;
};
-34
View File
@@ -1,34 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
exports.name = 'todolist setItemCompleted';
exports.defer = true;
exports.setup = function() {
_rootNode = document.createElement('div');
document.body.appendChild(_rootNode);
var appDescriptor = todolist.App({fakeDataCount: 333});
_app = React.render(appDescriptor, _rootNode);
_todo1 = _app.addItem('Howdy 1!');
_todo2 = _app.addItem('Howdy 2!');
_todo3 = _app.addItem('Howdy 3!');
};
exports.fn = function(deferred) {
_app.setItemCompleted(_todo1.id, !_todo1.completed);
_app.setItemCompleted(_todo2.id, !_todo2.completed);
_app.setItemCompleted(_todo3.id, !_todo3.completed, function() {
deferred.resolve();
});
};
exports.teardown = function() {
React.unmountComponentAtNode(_rootNode);
_rootNode.parentNode.removeChild(_rootNode);
_rootNode = null;
_app = null;
};
-30
View File
@@ -1,30 +0,0 @@
if (typeof exports === 'undefined') {
exports = {};
}
/*http://benchmarkjs.com/docs#options*/
exports.name =
'todolist from renderComponent to renderComponent callback (333 rows)';
exports.defer = true;
exports.setup = function() {
if (typeof _rootNode !== 'undefined') {
throw Error('should teardown before running setup again');
}
_rootNode = document.createElement('div');
document.body.appendChild(_rootNode);
};
exports.fn = function(deferred) {
React.render(todolist.App({fakeDataCount: 333}), _rootNode, function() {
deferred.resolve();
});
};
exports.teardown = function() {
React.unmountComponentAtNode(_rootNode);
_rootNode.parentNode.removeChild(_rootNode);
_rootNode = undefined;
};