eslint
chico committed
Feb 12, 2015 at 23:48 UTC
1511fff5982cb3a0557a59b5840ac295de3402a5
51 files changed
+878
-642
.eslintignore
+1
@@ -7,3 +7,4 @@ src/vendor_deprecated
7
src/**/__tests__/**
8
# This should be enabled but that folder has too much in it that doesn't belong
9
src/test
10
+test/the-files-to-test.generated.js
\ No newline at end of file
.eslintrc
new
+50
@@ -0,0 +1,50 @@
1
+---
2
+parser: esprima-fb
3
+
4
+env:
5
+ browser: true
6
+ node: true
7
+
8
+globals:
9
+ __DEV__: true
10
+
11
+rules:
12
+ # ERRORS
13
+ space-before-blocks: [2, 'always']
14
+ brace-style: 2
15
+ space-after-keywords: 2
16
+ strict: 2
17
+ # We actually have a transform to support this and we fix this for bundled
18
+ # releases but not for the npm package, so enforce it strictly
19
+ no-comma-dangle: 2
20
+ # Make this a warning for now. We do this in a few places so we might need to
21
+ # disable
22
+ no-unused-expressions: 2
23
+ block-scoped-var: 2
24
+ eol-last: 2
25
+ dot-notation: 2
26
+ consistent-return: 2
27
+ no-unused-vars: [2, args: none]
28
+ quotes: [2, 'single']
29
+
30
+ # WARNINGS
31
+ # This is the only one that's hard to track since we don't lint just changes.
32
+ max-len: [1, 80]
33
+
34
+ # WISHLIST. One day...
35
+ # We'll need a custom version of this that does a subset of the whole rule.
36
+ # Otherwise this is just too noisy.
37
+ # valid-jsdoc: 1
38
+
39
+ # DISABLED. These aren't compatible with our style
40
+ # We use this for private/internal variables
41
+ no-underscore-dangle: 0
42
+ # We pass constructors around / access them from members
43
+ new-cap: 0
44
+ # We do this a lot.
45
+ no-use-before-define: 0
46
+ # We do this in a few places to align values
47
+ key-spacing: 0
48
+
49
+ # DISABLED. These currently cause errors when running.
50
+ no-multi-spaces: 0
.jshintrc
deleted
-18
@@ -1,18 +0,0 @@
1
-{
2
- "node": true,
3
-
4
- "boss": true,
5
- "curly": true,
6
- "devel": true,
7
- "eqnull": true,
8
- "expr": true,
9
- "funcscope": true,
10
- "globalstrict": true,
11
- "loopfunc": true,
12
- "newcap": false,
13
- "noempty": true,
14
- "nonstandard": true,
15
- "sub": true,
16
- "undef": true,
17
- "unused": "vars"
18
-}
Gruntfile.js
+58
-35
@@ -12,6 +12,7 @@ var npmReactTasks = require('./grunt/tasks/npm-react');
12
var npmReactToolsTasks = require('./grunt/tasks/npm-react-tools');
13
var versionCheckTask = require('./grunt/tasks/version-check');
14
var gemReactSourceTasks = require('./grunt/tasks/gem-react-source');
15
+var eslintTask = require('./grunt/tasks/eslint');
16
17
module.exports = function(grunt) {
18
@@ -22,45 +23,43 @@ module.exports = function(grunt) {
23
browserify: require('./grunt/config/browserify'),
24
populist: require('./grunt/config/populist')(grunt),
25
connect: require('./grunt/config/server')(grunt),
25
- "webdriver-jasmine": require('./grunt/config/webdriver-jasmine'),
26
- "webdriver-perf": require('./grunt/config/webdriver-perf'),
26
+ 'webdriver-jasmine': require('./grunt/config/webdriver-jasmine'),
27
+ 'webdriver-perf': require('./grunt/config/webdriver-perf'),
28
npm: require('./grunt/config/npm'),
28
- clean: ['./build', './*.gem', './docs/_site', './examples/shared/*.js', '.module-cache'],
29
+ clean: [
30
+ './build',
31
+ './*.gem',
32
+ './docs/_site',
33
+ './examples/shared/*.js',
34
+ '.module-cache'
35
+ ],
36
jshint: require('./grunt/config/jshint'),
37
+ /*eslint-disable camelcase */
38
compare_size: require('./grunt/config/compare_size')
39
+ /*eslint-enable camelcase */
40
});
41
42
grunt.config.set('compress', require('./grunt/config/compress'));
43
44
Object.keys(grunt.file.readJSON('package.json').devDependencies)
36
- .filter(function(npmTaskName) { return npmTaskName.indexOf('grunt-') === 0; })
37
- .filter(function(npmTaskName) { return npmTaskName != 'grunt-cli'; })
38
- .forEach(function(npmTaskName) { grunt.loadNpmTasks(npmTaskName); });
39
-
40
- // Super simplified eslint task that we can use to replace linting. This just
41
- // shells out to eslint.
42
- grunt.registerTask('eslint', function() {
43
- var done = this.async();
44
- grunt.util.spawn({
45
- cmd: 'node_modules/.bin/eslint',
46
- args: ['src']
47
- }, function(err, result, code) {
48
- if (code === 0) {
49
- grunt.log.ok('Lint passed (but may contain warnings)');
50
- } else {
51
- grunt.log.error('Lint failed');
52
- }
53
- if (result.stdout.length) {
54
- grunt.log.writeln(result.stdout);
55
- }
56
-
57
- done(code === 0);
45
+ .filter(function(npmTaskName) {
46
+ return npmTaskName.indexOf('grunt-') === 0;
47
+ })
48
+ .filter(function(npmTaskName) {
49
+ return npmTaskName !== 'grunt-cli';
50
+ })
51
+ .forEach(function(npmTaskName) {
52
+ grunt.loadNpmTasks(npmTaskName);
53
});
59
- });
54
+
55
+ grunt.registerTask('eslint', eslintTask);
56
57
grunt.registerTask('lint', ['eslint']);
58
63
- grunt.registerTask('download-previous-version', require('./grunt/tasks/download-previous-version.js'));
59
+ grunt.registerTask(
60
+ 'download-previous-version',
61
+ require('./grunt/tasks/download-previous-version.js')
62
+ );
63
64
grunt.registerTask('delete-build-modules', function() {
65
if (grunt.file.exists('build/modules')) {
@@ -93,11 +92,28 @@ module.exports = function(grunt) {
92
93
grunt.registerTask('version-check', versionCheckTask);
94
96
- grunt.registerTask('build:basic', ['jsx:normal', 'version-check', 'browserify:basic']);
97
- grunt.registerTask('build:addons', ['jsx:normal', 'browserify:addons']);
98
- grunt.registerTask('build:transformer', ['jsx:normal', 'browserify:transformer']);
99
- grunt.registerTask('build:min', ['jsx:normal', 'version-check', 'browserify:min']);
100
- grunt.registerTask('build:addons-min', ['jsx:normal', 'browserify:addonsMin']);
95
+ grunt.registerTask('build:basic', [
96
+ 'jsx:normal',
97
+ 'version-check',
98
+ 'browserify:basic'
99
+ ]);
100
+ grunt.registerTask('build:addons', [
101
+ 'jsx:normal',
102
+ 'browserify:addons'
103
+ ]);
104
+ grunt.registerTask('build:transformer', [
105
+ 'jsx:normal',
106
+ 'browserify:transformer'
107
+ ]);
108
+ grunt.registerTask('build:min', [
109
+ 'jsx:normal',
110
+ 'version-check',
111
+ 'browserify:min'
112
+ ]);
113
+ grunt.registerTask('build:addons-min', [
114
+ 'jsx:normal',
115
+ 'browserify:addonsMin'
116
+ ]);
117
grunt.registerTask('build:withCodeCoverageLogging', [
118
'jsx:normal',
119
'version-check',
@@ -117,8 +133,15 @@ module.exports = function(grunt) {
133
'version-check',
134
'populist:test'
135
]);
120
- grunt.registerTask('build:npm-react', ['version-check', 'jsx:normal', 'npm-react:release']);
121
- grunt.registerTask('build:gem-react-source', ['build', 'gem-react-source:release']);
136
+ grunt.registerTask('build:npm-react', [
137
+ 'version-check',
138
+ 'jsx:normal',
139
+ 'npm-react:release'
140
+ ]);
141
+ grunt.registerTask('build:gem-react-source', [
142
+ 'build',
143
+ 'gem-react-source:release'
144
+ ]);
145
146
grunt.registerTask('webdriver-phantomjs', webdriverPhantomJSTask);
147
@@ -161,7 +184,7 @@ module.exports = function(grunt) {
184
'webdriver-perf:saucelabs_firefox',
185
'webdriver-perf:saucelabs_chrome',
186
'webdriver-perf:saucelabs_ie11',
164
- 'webdriver-perf:saucelabs_ie8',
187
+ 'webdriver-perf:saucelabs_ie8'
188
]);
189
190
grunt.registerTask('test:webdriver:saucelabs', [
README.md
+1
-1
@@ -86,7 +86,7 @@ grunt test
86
grunt test --debug
87
# For speed, you can use fasttest and add --filter to only run one test
88
grunt fasttest --filter=ReactIdentity
89
-# Lint the code with JSHint
89
+# Lint the code with ESLint
90
grunt lint
91
# Wipe out build directory
92
grunt clean
grunt/config/browserify.js
+1
-2
@@ -1,5 +1,4 @@
1
-/* jshint multistr:true */
2
-/* jshint -W040 */
1
+/*eslint-disable no-multi-str */
2
3
'use strict';
4
grunt/config/compare_size.js
+1
-1
@@ -12,6 +12,6 @@ module.exports = {
12
return gzip.zip(contents, {}).length;
13
}
14
},
15
- cache: ".grunt/sizecache.json"
15
+ cache: '.grunt/sizecache.json'
16
}
17
};
grunt/config/copy.js
+1
-1
@@ -1,5 +1,5 @@
1
'use strict';
2
-
2
+/*eslint-disable camelcase*/
3
module.exports = {
4
5
react_docs: {
grunt/config/jsx.js
+11
-11
@@ -4,15 +4,15 @@ var grunt = require('grunt');
4
var _ = require('lodash');
5
6
var rootIDs = [
7
- "React",
8
- "ReactWithAddons"
7
+ 'React',
8
+ 'ReactWithAddons'
9
];
10
11
// TODO: stop packaging these libraries
12
rootIDs = rootIDs.concat([
13
- "merge",
14
- "mergeInto",
15
- "copyProperties"
13
+ 'merge',
14
+ 'mergeInto',
15
+ 'copyProperties'
16
]);
17
18
var normal = {
@@ -23,23 +23,23 @@ var normal = {
23
constants: {}
24
};
25
},
26
- sourceDir: "src",
27
- outputDir: "build/modules"
26
+ sourceDir: 'src',
27
+ outputDir: 'build/modules'
28
};
29
30
31
var test = {
32
rootIDs: rootIDs.concat([
33
- "test/all.js",
34
- "**/__tests__/*.js"
33
+ 'test/all.js',
34
+ '**/__tests__/*.js'
35
]),
36
getConfig: function() {
37
return _.merge({}, normal.getConfig(), {
38
mocking: true
39
});
40
},
41
- sourceDir: "src",
42
- outputDir: "build/modules"
41
+ sourceDir: 'src',
42
+ outputDir: 'build/modules'
43
};
44
45
grunt/config/populist.js
+7
-7
@@ -2,12 +2,12 @@
2
3
module.exports = function(grunt) {
4
var jasmine = {
5
- rootDirectory: "build/jasmine",
6
- // This syntax means to require and expose the "jasmine" module
5
+ rootDirectory: 'build/jasmine',
6
+ // This syntax means to require and expose the 'jasmine' module
7
// (build/jasmine/jasmine.js) as global.jasmine, and to require the
8
- // "all" module (build/jasmine/all.js) but not expose it globally.
9
- args: ["jasmine:jasmine", "all:"],
10
- outfile: "./build/jasmine.js"
8
+ // 'all' module (build/jasmine/all.js) but not expose it globally.
9
+ args: ['jasmine:jasmine', 'all:'],
10
+ outfile: './build/jasmine.js'
11
};
12
13
var filterExpr = grunt.option('filter');
@@ -19,8 +19,8 @@ module.exports = function(grunt) {
19
}
20
21
var test = {
22
- rootDirectory: "build/modules",
23
- args: ["test/all:harness"],
22
+ rootDirectory: 'build/modules',
23
+ args: ['test/all:harness'],
24
requires: [filterExpr],
25
outfile: './build/react-test.js'
26
};
grunt/config/server.js
+24
-17
@@ -1,9 +1,12 @@
1
'use strict';
2
3
-module.exports = function(grunt){
3
+var fs = require('fs');
4
+var path = require('path');
5
+
6
+module.exports = function(grunt) {
7
var coverageWriteStream;
8
6
- grunt.task.registerTask('finalize-coverage-stream', function(){
9
+ grunt.task.registerTask('finalize-coverage-stream', function() {
10
if (!coverageWriteStream) {
11
return;
12
}
@@ -14,13 +17,13 @@ module.exports = function(grunt){
17
});
18
19
function consoleLoggerMiddleware(req, res, next) {
17
- if (!(req.method == 'POST' && req._parsedUrl.pathname.replace(/\//g,'') == 'console' && Array.isArray(req.body))) {
20
+ if (!(req.method === 'POST' && req._parsedUrl.pathname.replace(/\//g, '') === 'console' && Array.isArray(req.body))) {
21
return next();
22
}
23
res.write('<!doctype html><meta charset=utf-8>');
24
res.end('Got it, thanks!');
25
23
- req.body.forEach(function(log){
26
+ req.body.forEach(function(log) {
27
if (log.message.indexOf('not ok ') === 0) {
28
log.type = 'error';
29
} else if (log.message.indexOf('ok ') === 0) {
@@ -31,20 +34,20 @@ module.exports = function(grunt){
34
log.type = 'coverage done';
35
}
36
34
- if (log.type == 'error') {
37
+ if (log.type === 'error') {
38
grunt.log.error(log.message);
36
- } else if (log.type == 'ok') {
39
+ } else if (log.type === 'ok') {
40
grunt.log.ok(log.message);
38
- } else if (log.type == 'log') {
41
+ } else if (log.type === 'log') {
42
grunt.log.writeln(log.message);
40
- } else if (log.type == 'coverage') {
43
+ } else if (log.type === 'coverage') {
44
if (!coverageWriteStream) {
42
- coverageWriteStream = require('fs').createWriteStream(__dirname + '/../../coverage.log');
45
+ coverageWriteStream = fs.createWriteStream(path.join(__dirname, '/../../coverage.log'));
46
}
47
coverageWriteStream.write(log.message + '\n');
45
- } else if (log.type == 'coverage done') {
48
+ } else if (log.type === 'coverage done') {
49
grunt.task.run('finalize-coverage-stream');
47
- } else if (log.type == 'perf') {
50
+ } else if (log.type === 'perf') {
51
grunt.event.emit('perf results', log.message);
52
} else {
53
grunt.verbose.writeln(log);
@@ -53,7 +56,7 @@ module.exports = function(grunt){
56
}
57
58
function testResultLoggerMiddleware(req, res, next) {
56
- if (!(req.method == 'POST' && req._parsedUrl.pathname.indexOf('/reportTestResults') === 0)) {
59
+ if (!(req.method === 'POST' && req._parsedUrl.pathname.indexOf('/reportTestResults') === 0)) {
60
return next();
61
}
62
res.write('<!doctype html><meta charset=utf-8>');
@@ -62,8 +65,8 @@ module.exports = function(grunt){
65
var logType = 'writeln';
66
var message = req.body;
67
65
- if (req.body.type && req.body.message){
66
- if (req.body.type == 'error') {
68
+ if (req.body.type && req.body.message) {
69
+ if (req.body.type === 'error') {
70
logType = 'error';
71
} else if (req.body.message.indexOf('ok') === 0) {
72
logType = 'ok';
@@ -72,7 +75,7 @@ module.exports = function(grunt){
75
}
76
message = req.body.message;
77
}
75
- if (typeof message != 'string') {
78
+ if (typeof message !== 'string') {
79
message = JSON.stringify(message, null, 2);
80
}
81
grunt.log[logType]('[%s][%s]', req.headers['user-agent'], Date.now(), message);
@@ -86,8 +89,12 @@ module.exports = function(grunt){
89
port: 9999,
90
middleware: function(connect, options) {
91
89
- connect.logger.token('user-agent', function(req, res) { return req.headers['user-agent']; });
90
- connect.logger.token('timestamp', function(req, res) { return Date.now(); });
92
+ connect.logger.token('user-agent', function(req, res) {
93
+ return req.headers['user-agent'];
94
+ });
95
+ connect.logger.token('timestamp', function(req, res) {
96
+ return Date.now();
97
+ });
98
99
return [
100
connect.json(),
grunt/config/webdriver-all.js
+17
-15
@@ -2,20 +2,20 @@
2
3
var grunt = require('grunt');
4
5
-module.exports = function(props){
6
- if (typeof props.url != 'string') {
5
+module.exports = function(props) {
6
+ if (typeof props.url !== 'string') {
7
throw TypeError('expected url string');
8
}
9
- if ('isDoneTimeout' in props && typeof props.isDoneTimeout != 'number') {
9
+ if ('isDoneTimeout' in props && typeof props.isDoneTimeout !== 'number') {
10
throw TypeError('expected isDoneTimeout to be a number');
11
}
12
- if ('onStart' in props && typeof props.onStart != 'function') {
12
+ if ('onStart' in props && typeof props.onStart !== 'function') {
13
throw TypeError('expected onStart to be a function');
14
}
15
- if ('onComplete' in props && typeof props.onComplete != 'function') {
15
+ if ('onComplete' in props && typeof props.onComplete !== 'function') {
16
throw TypeError('expected onComplete to be a function');
17
}
18
- if ('onError' in props && typeof props.onError != 'function') {
18
+ if ('onError' in props && typeof props.onError !== 'function') {
19
throw TypeError('expected onError to be a function');
20
}
21
@@ -33,7 +33,7 @@ module.exports = function(props){
33
};
34
35
if (grunt.option('debug')) {
36
- exports.local.url += (exports.local.url.indexOf('?') == -1 ? '?' : '&') + 'debug=' + grunt.option('debug');
36
+ exports.local.url += (exports.local.url.indexOf('?') === -1 ? '?' : '&') + 'debug=' + grunt.option('debug');
37
}
38
39
exports.saucelabs = {
@@ -49,13 +49,13 @@ module.exports = function(props){
49
}
50
},
51
desiredCapabilities: {
52
- "build": process.env.TRAVIS_BUILD_NUMBER || 'dev' + Date.now(),
53
- "tunnel-identifier": process.env.TRAVIS_JOB_NUMBER || 'my awesome tunnel',
54
- "browserName": "chrome"
52
+ 'build': process.env.TRAVIS_BUILD_NUMBER || 'dev' + Date.now(),
53
+ 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER || 'my awesome tunnel',
54
+ 'browserName': 'chrome'
55
},
56
url: exports.local.url,
57
- onStart: function(browser){
58
- grunt.log.writeln("Starting WebDriver Test. Watch results here: http://saucelabs.com/tests/" + browser.sessionID);
57
+ onStart: function(browser) {
58
+ grunt.log.writeln('Starting WebDriver Test. Watch results here: http://saucelabs.com/tests/' + browser.sessionID);
59
if (props.onStart) {
60
return props.onStart(browser);
61
}
@@ -65,6 +65,7 @@ module.exports = function(props){
65
isDoneTimeout: exports.local.isDoneTimeout
66
};
67
68
+ /*eslint-disable camelcase*/
69
/* https://saucelabs.com/platforms */
70
exports.saucelabs_ios =
71
exports.saucelabs_ios7 = sauceItUp({ browserName: 'iphone', version: '7', platform:'OS X 10.9' });
@@ -94,10 +95,11 @@ module.exports = function(props){
95
exports.saucelabs_ie9 = sauceItUp({ browserName: 'internet explorer', version: 9 });
96
exports.saucelabs_ie10 = sauceItUp({ browserName: 'internet explorer', version: 10 });
97
exports.saucelabs_ie11 = sauceItUp({ browserName: 'internet explorer', version: 11, platform:'Windows 8.1' });
98
+ /*eslint-enable camelcase*/
99
100
function sauceItUp(desiredCapabilities) {
99
- desiredCapabilities["build"] = exports.saucelabs.desiredCapabilities["build"];
100
- desiredCapabilities["tunnel-identifier"] = exports.saucelabs.desiredCapabilities["tunnel-identifier"];
101
+ desiredCapabilities.build = exports.saucelabs.desiredCapabilities.build;
102
+ desiredCapabilities['tunnel-identifier'] = exports.saucelabs.desiredCapabilities['tunnel-identifier'];
103
return {
104
webdriver: exports.saucelabs.webdriver,
105
url: exports.saucelabs.url,
@@ -105,7 +107,7 @@ module.exports = function(props){
107
onComplete: exports.saucelabs.onComplete,
108
onError: exports.saucelabs.onError,
109
isDoneTimeout: exports.saucelabs.isDoneTimeout,
108
- desiredCapabilities: desiredCapabilities,
110
+ desiredCapabilities: desiredCapabilities
111
};
112
}
113
grunt/config/webdriver-jasmine.js
+5
-5
@@ -3,13 +3,13 @@
3
var grunt = require('grunt');
4
5
module.exports = require('./webdriver-all')({
6
- url: "http://127.0.0.1:9999/test/index.html",
7
- onComplete: function(passed){
8
- if (!passed){
9
- grunt.fatal("tests failed");
6
+ url: 'http://127.0.0.1:9999/test/index.html',
7
+ onComplete: function(passed) {
8
+ if (!passed) {
9
+ grunt.fatal('tests failed');
10
}
11
},
12
- onError: function(error){
12
+ onError: function(error) {
13
grunt.fatal(error);
14
}
15
});
grunt/config/webdriver-perf.js
+16
-9
@@ -1,8 +1,9 @@
1
'use strict';
2
3
var grunt = require('grunt');
4
+var path = require('path');
5
5
-var tests = grunt.file.expand(__dirname + '/../../perf/tests/*');
6
+var tests = grunt.file.expand(path.join(__dirname, '/../../perf/tests/*'));
7
8
var maxTime = 5;
9
@@ -15,33 +16,39 @@ var params = []
16
.concat('headless=false')
17
.concat('maxTime=' + maxTime)
18
.concat(tests
18
- .map(function(path){ return path.split(/tests./i).reverse()[0]; })
19
+ .map(function(testPath) {
20
+ return testPath.split(/tests./i).reverse()[0];
21
+ })
22
.map(encodeURIComponent)
20
- .map(function(filename){ return 'test=' + filename; })
23
+ .map(function(filename) {
24
+ return 'test=' + filename;
25
+ })
26
)
27
.concat(reactVersions
28
.map(encodeURIComponent)
24
- .map(function(version){ return 'react=' + version; }
29
+ .map(function(version) {
30
+ return 'react=' + version;
31
+ }
32
)
33
);
34
35
module.exports = require('./webdriver-all')({
36
30
- url: "http://127.0.0.1:9999/perf/index.html?" + params.join('&'),
37
+ url: 'http://127.0.0.1:9999/perf/index.html?' + params.join('&'),
38
39
isDoneTimeout: 15 * 60 * 1000,
40
34
- onStart: function(){
35
- grunt.event.on('perf results', function(results){
41
+ onStart: function() {
42
+ grunt.event.on('perf results', function(results) {
43
console.log(results);
44
});
45
},
46
40
- onComplete: function(completedTestKeys){
47
+ onComplete: function(completedTestKeys) {
48
grunt.verbose.writeln('onComplete ' + JSON.stringify(completedTestKeys));
49
},
50
44
- onError: function(error){
51
+ onError: function(error) {
52
grunt.fatal(error);
53
}
54
grunt/tasks/coverage-parse.js
+20
-19
@@ -1,47 +1,48 @@
1
-"use strict";
1
+'use strict';
2
var grunt = require('grunt');
3
+var path = require('path');
4
+var fs = require('fs');
5
4
-module.exports = function(){
5
- var ROOT = require('path').normalize(__dirname + '/../..');
6
+module.exports = function() {
7
+ var ROOT = path.join(__dirname, '/../..');
8
var done = this.async();
9
var uncoveredExpressionCount = 0;
10
var uncoveredLineCount = 0;
11
10
- require('fs').createReadStream(ROOT + '/coverage.log')
11
- .pipe(require('coverify/parse')(function(error, results){
12
+ fs.createReadStream(ROOT + '/coverage.log')
13
+ .pipe(require('coverify/parse')(function(error, results) {
14
if (error) {
15
grunt.fatal(error);
16
}
17
18
Object.keys(results)
17
- .sort(function(a, b){
19
+ .sort(function(a, b) {
20
return results[a].length - results[b].length;
21
})
22
.reverse()
21
- .forEach(function(path){
22
- if (results[path].length === 0) {
23
+ .forEach(function(concretePath) {
24
+ if (results[concretePath].length === 0) {
25
return;
26
}
25
- var relativePath = path.replace(ROOT, '');
26
- uncoveredExpressionCount += results[path].length;
27
- grunt.log.error(results[path].length + ' expressions not covered ' + relativePath);
27
+ var relativePath = concretePath.replace(ROOT, '');
28
+ uncoveredExpressionCount += results[concretePath].length;
29
+ grunt.log.error(results[concretePath].length + ' expressions not covered ' + relativePath);
30
29
- results[path].forEach(function(c){
31
+ results[concretePath].forEach(function(c) {
32
uncoveredLineCount += c.code.split('\n').length;
31
- console.log('txmt://open?url=' + encodeURIComponent('file://' + path) + '&line=' + (c.lineNum+1) + '&column=' + (c.column[0]+2));
33
+ console.log('txmt://open?url=' + encodeURIComponent('file://' + concretePath) + '&line=' + (c.lineNum + 1) + '&column=' + (c.column[0] + 2));
34
});
35
console.log('');
34
- })
35
- ;
36
+ });
37
37
- Object.keys(results).sort().forEach(function(path){
38
- if (results[path].length > 0) {
38
+ Object.keys(results).sort().forEach(function(concretePath) {
39
+ if (results[concretePath].length > 0) {
40
return;
41
}
41
- var relativePath = path.replace(ROOT, '');
42
+ var relativePath = concretePath.replace(ROOT, '');
43
grunt.log.ok('100% coverage ' + relativePath);
44
});
44
-
45
+
46
if (uncoveredExpressionCount > 0) {
47
grunt.log.error(uncoveredExpressionCount + ' expressions not covered');
48
}
grunt/tasks/download-previous-version.js
+30
-30
@@ -1,47 +1,47 @@
1
-"use strict";
1
+'use strict';
2
3
var grunt = require('grunt');
4
var http = require('http');
5
var fs = require('fs');
6
+var path = require('path');
7
+
8
+function get(url, targetFilePath, completedSuccessfully) {
9
+ grunt.verbose.writeln('getting url \'' + url + '\'');
10
+ http.get(url, function(response) {
11
+ grunt.verbose.writeln('Received status code ' + response.statusCode + ' for \'' + url + '\'');
12
+
13
+ if (response.statusCode !== 200) {
14
+ if (response.headers.location) {
15
+ get(response.headers.location, targetFilePath);
16
+ return;
17
+ } else {
18
+ grunt.fatal('Nothing else to do.');
19
+ completedSuccessfully(false);
20
+ return;
21
+ }
22
+ }
23
+ grunt.verbose.writeln('Writing url to \'' + targetFilePath + '\'');
24
+ response.pipe(fs.createWriteStream(targetFilePath))
25
+ .on('close', function() {
26
+ completedSuccessfully(true);
27
+ });
28
+ });
29
+}
30
31
module.exports = function() {
32
var completedSuccessfully = this.async();
33
get(
10
- "http://react.zpao.com/builds/master/latest/react.min.js",
11
- __dirname + '/../../build/react-previous.min.js',
12
- function(success){
34
+ 'http://react.zpao.com/builds/master/latest/react.min.js',
35
+ path.join(__dirname, '/../../build/react-previous.min.js'),
36
+ function(success) {
37
if (!success) {
38
return completedSuccessfully(success);
39
}
40
get(
17
- "http://react.zpao.com/builds/master/latest/JSXTransformer.js",
18
- __dirname + '/../../build/JSXTransformer-previous.js',
41
+ 'http://react.zpao.com/builds/master/latest/JSXTransformer.js',
42
+ path.join(__dirname, '/../../build/JSXTransformer-previous.js'),
43
completedSuccessfully
44
);
45
}
46
);
23
-
24
- function get(url, targetFilePath, completedSuccessfully) {
25
- grunt.verbose.writeln('getting url "' + url + '"');
26
- http.get(url, function(response) {
27
- grunt.verbose.writeln('Received status code ' + response.statusCode + ' for "' + url + '"');
28
-
29
- if (response.statusCode != 200) {
30
- if (response.headers.location) {
31
- get(response.headers.location, targetFilePath);
32
- return;
33
- } else {
34
- grunt.fatal('Nothing else to do.');
35
- completedSuccessfully(false);
36
- return;
37
- }
38
- }
39
- grunt.verbose.writeln('Writing url to "' + targetFilePath + '"');
40
- response.pipe(fs.createWriteStream(targetFilePath))
41
- .on('close', function() {
42
- completedSuccessfully(true);
43
- })
44
- ;
45
- });
46
- }
47
};
grunt/tasks/eslint.js
new
+22
@@ -0,0 +1,22 @@
1
+'use strict';
2
+
3
+var grunt = require('grunt');
4
+
5
+module.exports = function() {
6
+ var done = this.async();
7
+ grunt.util.spawn({
8
+ cmd: 'node_modules/.bin/eslint',
9
+ args: ['src/', 'Gruntfile.js', 'grunt/', 'main.js', 'perf/', 'test/']
10
+ }, function(err, result, code) {
11
+ if (err) {
12
+ grunt.log.error('Lint failed');
13
+ } else {
14
+ grunt.log.ok('Lint passed (but may contain warnings)');
15
+ }
16
+ if (result.stdout.length) {
17
+ grunt.log.writeln(result.stdout);
18
+ }
19
+
20
+ done(code === 0);
21
+ });
22
+};
grunt/tasks/gem-react-source.js
+14
-10
@@ -12,19 +12,21 @@ var buildFiles = [
12
];
13
14
function buildRelease() {
15
- grunt.file.exists(dest) && grunt.file.delete(dest);
15
+ if (grunt.file.exists(dest)) {
16
+ grunt.file.delete(dest);
17
+ }
18
19
// Copy gem-react-source/**/* to build/gem-react-source
20
var mappings = [].concat(
21
grunt.file.expandMapping('**/*', dest, {cwd: src})
22
);
23
mappings.forEach(function(mapping) {
22
- var src = mapping.src[0];
23
- var dest = mapping.dest;
24
- if (grunt.file.isDir(src)) {
25
- grunt.file.mkdir(dest);
24
+ var mappingSrc = mapping.src[0];
25
+ var mappingDest = mapping.dest;
26
+ if (grunt.file.isDir(mappingSrc)) {
27
+ grunt.file.mkdir(mappingDest);
28
} else {
27
- grunt.file.copy(src, dest);
29
+ grunt.file.copy(mappingSrc, mappingDest);
30
}
31
});
32
@@ -36,7 +38,6 @@ function buildRelease() {
38
}
39
40
function packRelease() {
39
- /*jshint validthis:true */
41
var done = this.async();
42
var spawnCmd = {
43
cmd: 'gem',
@@ -46,12 +47,15 @@ function packRelease() {
47
}
48
};
49
grunt.util.spawn(spawnCmd, function(err, result) {
50
+ if (err) {
51
+ grunt.log.error(err);
52
+ }
53
// Gem packing does weird things to versions so 0.12.0-alpha becomes
54
// 0.12.0.pre.alpha. We need to get the filename printed to stdout.
55
var filename = result.stdout.match(/File: (.*)$/)[1];
52
- var src = 'build/gem-react-source/' + filename;
53
- var dest = 'build/react-source.tgz';
54
- fs.rename(src, dest, done);
56
+ var buildSrc = 'build/gem-react-source/' + filename;
57
+ var buildDest = 'build/react-source.tgz';
58
+ fs.rename(buildSrc, buildDest, done);
59
});
60
}
61
grunt/tasks/jsx.js
+11
-11
@@ -1,7 +1,7 @@
1
'use strict';
2
3
-var path = require("path");
4
-var grunt = require("grunt");
3
+var path = require('path');
4
+var grunt = require('grunt');
5
var expand = grunt.file.expand;
6
var spawn = grunt.util.spawn;
7
@@ -10,27 +10,27 @@ module.exports = function() {
10
var config = this.data;
11
12
var args = [
13
- "--cache-dir", ".module-cache",
14
- "--relativize",
15
- "--follow-requires",
16
- "--use-provides-module",
13
+ '--cache-dir', '.module-cache',
14
+ '--relativize',
15
+ '--follow-requires',
16
+ '--use-provides-module',
17
config.sourceDir,
18
config.outputDir
19
];
20
21
var rootIDs = expand({
22
nonull: true, // Keep IDs that don't expand to anything.
23
- cwd: "src"
23
+ cwd: 'src'
24
}, config.rootIDs).map(function(id) {
25
- return id.replace(/\.js$/i, "");
25
+ return id.replace(/\.js$/i, '');
26
});
27
28
args.push.apply(args, rootIDs);
29
- args.push("--config" /* from stdin */);
29
+ args.push('--config' /* from stdin */);
30
31
var child = spawn({
32
- cmd: "node",
33
- args: [path.join("bin", "jsx-internal")].concat(args)
32
+ cmd: 'node',
33
+ args: [path.join('bin', 'jsx-internal')].concat(args)
34
}, function(error, result, code) {
35
if (error) {
36
grunt.log.error(error);
grunt/tasks/npm-react-tools.js
+11
-10
@@ -7,7 +7,9 @@ var src = 'npm-react-tools';
7
var dest = 'build/npm-react-tools/';
8
9
function buildRelease() {
10
- grunt.file.exists(dest) && grunt.file.delete(dest);
10
+ if (grunt.file.exists(dest)) {
11
+ grunt.file.delete(dest);
12
+ }
13
14
// read our required files from package.json
15
var pkgFiles = grunt.config.data.pkg.files;
@@ -27,18 +29,17 @@ function buildRelease() {
29
});
30
31
mappings.forEach(function(mapping) {
30
- var src = mapping.src[0];
31
- var dest = mapping.dest;
32
- if (grunt.file.isDir(src)) {
33
- grunt.file.mkdir(dest);
32
+ var mappingSrc = mapping.src[0];
33
+ var mappingDest = mapping.dest;
34
+ if (grunt.file.isDir(mappingSrc)) {
35
+ grunt.file.mkdir(mappingDest);
36
} else {
35
- grunt.file.copy(src, dest);
37
+ grunt.file.copy(mappingSrc, mappingDest);
38
}
39
});
40
}
41
42
function packRelease() {
41
- /*jshint validthis:true */
43
var done = this.async();
44
var spawnCmd = {
45
cmd: 'npm',
@@ -48,9 +49,9 @@ function packRelease() {
49
}
50
};
51
grunt.util.spawn(spawnCmd, function() {
51
- var src = 'build/react-tools-' + grunt.config.data.pkg.version + '.tgz';
52
- var dest = 'build/react-tools.tgz';
53
- fs.rename(src, dest, done);
52
+ var buildSrc = 'build/react-tools-' + grunt.config.data.pkg.version + '.tgz';
53
+ var buildDest = 'build/react-tools.tgz';
54
+ fs.rename(buildSrc, buildDest, done);
55
});
56
}
57
grunt/tasks/npm-react.js
+11
-10
@@ -15,7 +15,9 @@ var distFiles = [
15
16
function buildRelease() {
17
// delete build/react-core for fresh start
18
- grunt.file.exists(dest) && grunt.file.delete(dest);
18
+ if (grunt.file.exists(dest)) {
19
+ grunt.file.delete(dest);
20
+ }
21
22
// mkdir -p build/react-core/lib
23
grunt.file.mkdir(lib);
@@ -27,12 +29,12 @@ function buildRelease() {
29
grunt.file.expandMapping('**/*', lib, {cwd: modSrc})
30
);
31
mappings.forEach(function(mapping) {
30
- var src = mapping.src[0];
31
- var dest = mapping.dest;
32
- if (grunt.file.isDir(src)) {
33
- grunt.file.mkdir(dest);
32
+ var mappingSrc = mapping.src[0];
33
+ var mappingDest = mapping.dest;
34
+ if (grunt.file.isDir(mappingSrc)) {
35
+ grunt.file.mkdir(mappingDest);
36
} else {
35
- grunt.file.copy(src, dest);
37
+ grunt.file.copy(mappingSrc, mappingDest);
38
}
39
});
40
@@ -49,7 +51,6 @@ function buildRelease() {
51
}
52
53
function packRelease() {
52
- /*jshint validthis:true */
54
var done = this.async();
55
var spawnCmd = {
56
cmd: 'npm',
@@ -59,9 +60,9 @@ function packRelease() {
60
}
61
};
62
grunt.util.spawn(spawnCmd, function() {
62
- var src = 'build/react-' + grunt.config.data.pkg.version + '.tgz';
63
- var dest = 'build/react.tgz';
64
- fs.rename(src, dest, done);
63
+ var buildSrc = 'build/react-' + grunt.config.data.pkg.version + '.tgz';
64
+ var buildDest = 'build/react.tgz';
65
+ fs.rename(buildSrc, buildDest, done);
66
});
67
}
68
grunt/tasks/npm.js
+24
-24
@@ -1,26 +1,26 @@
1
'use strict';
2
3
-var assert = require("assert");
4
-var path = require("path");
5
-var grunt = require("grunt");
3
+var assert = require('assert');
4
+var path = require('path');
5
+var grunt = require('grunt');
6
var spawn = grunt.util.spawn;
7
8
module.exports = function() {
9
var done = this.async();
10
11
function run(cmd, args, opts, callback) {
12
- assert.strictEqual(typeof cmd, "string");
12
+ assert.strictEqual(typeof cmd, 'string');
13
assert.ok(args instanceof Array);
14
15
- if (typeof opts === "function" && !callback) {
15
+ if (typeof opts === 'function' && !callback) {
16
callback = opts;
17
opts = {};
18
}
19
20
- assert.strictEqual(typeof opts, "object");
21
- assert.strictEqual(typeof callback, "function");
20
+ assert.strictEqual(typeof opts, 'object');
21
+ assert.strictEqual(typeof callback, 'function');
22
23
- grunt.log.writeln("> " + cmd + " " + args.join(" "));
23
+ grunt.log.writeln('> ' + cmd + ' ' + args.join(' '));
24
25
// var proc =
26
spawn({
@@ -42,33 +42,33 @@ module.exports = function() {
42
}
43
44
var pkg = grunt.config.data.pkg;
45
- var tgz = pkg.name + "-" + pkg.version + ".tgz";
45
+ var tgz = pkg.name + '-' + pkg.version + '.tgz';
46
47
- grunt.log.writeln("Packing " + tgz + " (this could take a while)...");
47
+ grunt.log.writeln('Packing ' + tgz + ' (this could take a while)...');
48
49
- run("npm", ["pack", "--verbose", "."], function() {
50
- require("tmp").dir(function(err, dir) {
49
+ run('npm', ['pack', '--verbose', '.'], function() {
50
+ require('tmp').dir(function(err, dir) {
51
if (err) {
52
grunt.log.error(err);
53
done(false);
54
return;
55
}
56
57
- run("cp", [tgz, dir], function() {
58
- run("npm", [
59
- "install",
60
- "--production",
57
+ run('cp', [tgz, dir], function() {
58
+ run('npm', [
59
+ 'install',
60
+ '--production',
61
tgz
62
], { cwd: dir }, function() {
63
- var nodePath = path.join(dir, "node_modules");
63
+ var nodePath = path.join(dir, 'node_modules');
64
var pkgDir = path.join(nodePath, pkg.name);
65
var doneCount = 2;
66
67
// Make sure that bin/jsx is runnable by echoing main.js.
68
- run("bin/jsx", ["main.js"], {
68
+ run('bin/jsx', ['main.js'], {
69
cwd: pkgDir
70
}, function(result) {
71
- assert.ok(result.stdout.indexOf("transform") >= 0, result.stdout);
71
+ assert.ok(result.stdout.indexOf('transform') >= 0, result.stdout);
72
73
if (--doneCount === 0) {
74
done();
@@ -76,17 +76,17 @@ module.exports = function() {
76
});
77
78
// Make sure the .transform package method works.
79
- run("node", [
80
- "--print",
81
- 'require("react-tools").transform(' +
79
+ run('node', [
80
+ '--print',
81
+ 'require(\'react-tools\').transform(' +
82
JSON.stringify(
83
- "/** @jsx React.DOM */ <div>oyez</div>;"
83
+ '/** @jsx React.DOM */ <div>oyez</div>;'
84
) + ')'
85
], {
86
env: { NODE_PATH: nodePath }
87
}, function(result, code) {
88
assert.ok(result.stdout.indexOf(
89
- 'React.DOM.div(null, "oyez");'
89
+ 'React.DOM.div(null, \'oyez\');'
90
) >= 0, result.stdout);
91
92
if (--doneCount === 0) {
grunt/tasks/populist.js
+4
-3
@@ -2,12 +2,13 @@
2
3
var grunt = require('grunt');
4
var fs = require('fs');
5
+var path = require('path');
6
7
module.exports = function() {
8
var config = this.data;
9
var done = this.async();
10
10
- var theFilesToTestScript = fs.createWriteStream(__dirname + '/../../test/the-files-to-test.generated.js');
11
+ var theFilesToTestScript = fs.createWriteStream(path.join(__dirname, '/../../test/the-files-to-test.generated.js'));
12
theFilesToTestScript.write('// Generated by ');
13
theFilesToTestScript.write(JSON.stringify(__filename.split(/(?=grunt)/)[1]));
14
theFilesToTestScript.write(' at ');
@@ -23,12 +24,12 @@ module.exports = function() {
24
nonull: true, // Keep IDs that don't expand to anything.
25
cwd: config.rootDirectory
26
}, requires).forEach(function(name) {
26
- name = name.replace(/\.js$/i, "");
27
+ name = name.replace(/\.js$/i, '');
28
args.push(name);
29
theFilesToTestScript.write('harness.enableTest(' + JSON.stringify(name) + ');\n');
30
});
31
31
- require("populist").buildP({
32
+ require('populist').buildP({
33
rootDirectory: config.rootDirectory,
34
args: args
35
}).then(function(output) {
grunt/tasks/release.js
+1
-5
@@ -1,6 +1,3 @@
1
-// function calls get bound so "possible strict mode violations" aren't
2
-// jshint -W040
3
-
1
'use strict';
2
3
var grunt = require('grunt');
@@ -59,8 +56,7 @@ function _gitCommitAndTag(cwd, commitMsg, tag, cb) {
56
grunt.util.spawn(gitCommit, function() {
57
if (tag) {
58
grunt.util.spawn(gitTag, cb);
62
- }
63
- else {
59
+ } else {
60
cb();
61
}
62
});
grunt/tasks/sauce-tunnel.js
+2
-2
@@ -22,7 +22,7 @@ module.exports = function() {
22
var taskCompletedSuccessfully = task.async();
23
24
var stunnel = new SauceTunnel(SAUCE_USERNAME, SAUCE_ACCESS_KEY, IDENTIFIER, /*tunneled*/true, /*tunnelTimeout*/5);
25
- process.on('exit', stunnel.stop.bind(stunnel, function(){}));
25
+ process.on('exit', stunnel.stop.bind(stunnel, function() {}));
26
27
stunnel.on('log:error', grunt.log.error.bind(grunt.log));
28
stunnel.on('log:writeln', grunt.log.writeln.bind(grunt.log));
@@ -32,7 +32,7 @@ module.exports = function() {
32
stunnel.on('verbose:debug', grunt.verbose.debug.bind(grunt.verbose));
33
stunnel.on('verbose:writeln', grunt.verbose.writeln.bind(grunt.verbose));
34
35
- stunnel.openTunnel(function(isOpen){
35
+ stunnel.openTunnel(function(isOpen) {
36
if (shouldStayAliveForever && isOpen) {
37
grunt.verbose.writeln('Keeping the sauce-tunnel open forever because you used the keepalive flag `' + task.nameArgs + '`');
38
return;
grunt/tasks/webdriver-all.js
+15
-11
@@ -1,11 +1,10 @@
1
-/* jshint evil: true */
2
-
1
+/*eslint-disable consistent-return*/
2
'use strict';
3
5
-var grunt = require("grunt");
4
+var grunt = require('grunt');
5
var wd = require('wd');
6
8
-module.exports = function task(getJSReport){
7
+module.exports = function task(getJSReport) {
8
var config = this.data;
9
var taskSucceeded = this.async();
10
getJSReport = getJSReport.bind(this, config, wd);
@@ -19,7 +18,7 @@ module.exports = function task(getJSReport){
18
desiredCapabilities[key] = config.desiredCapabilities[key];
19
});
20
}
22
- grunt.verbose.writeln("desiredCapabilities", JSON.stringify(desiredCapabilities));
21
+ grunt.verbose.writeln('desiredCapabilities', JSON.stringify(desiredCapabilities));
22
23
var browser = wd.promiseChainRemote(config.webdriver.remote);
24
@@ -38,18 +37,23 @@ module.exports = function task(getJSReport){
37
.init(desiredCapabilities)
38
.then(config.onStart && config.onStart.bind(config, browser))
39
.get(config.url)
41
- .then(function(){return browser;})
40
+ .then(function() {
41
+ return browser;
42
+ })
43
.then(getJSReport)
43
- .then(function(data){ results = data; })
44
- .fail(function(error){
44
+ .then(function(data) {
45
+ results = data;
46
+ })
47
+ .fail(function(error) {
48
grunt.log.error(error);
49
return browser
50
.eval('document.documentElement.innerText || document.documentElement.textContent')
51
.then(grunt.verbose.writeln.bind(grunt.verbose))
49
- .then(function(){ throw error; })
50
- ;
52
+ .then(function() {
53
+ throw error;
54
+ });
55
})
52
- .finally(function(){
56
+ .finally(function() {
57
if (grunt.option('webdriver-keep-open')) {
58
return;
59
}
grunt/tasks/webdriver-jasmine.js
+8
-11
@@ -1,17 +1,14 @@
1
-/* jshint evil: true */
2
-
1
'use strict';
2
5
-module.exports = function(){
6
- return require('./webdriver-all').call(this, function(config, wd, browser){
3
+module.exports = function() {
4
+ return require('./webdriver-all').call(this, function(config, wd, browser) {
5
return browser
8
- .waitFor(wd.asserters.jsCondition("typeof window.jasmine != 'undefined'"), 5e3, 50)
9
- .fail(function(error){
10
- throw Error("The test page didn't load properly. " + error);
6
+ .waitFor(wd.asserters.jsCondition('typeof window.jasmine != \'undefined\''), 5e3, 50)
7
+ .fail(function(error) {
8
+ throw Error('The test page didn\'t load properly. ' + error);
9
})
12
- .waitFor(wd.asserters.jsCondition("typeof window.jasmine.getJSReport != 'undefined'"), 60e3, 100)
13
- .waitFor(wd.asserters.jsCondition("window.postDataToURL.running <= 0"), 30e3, 500)
14
- .eval("jasmine.getJSReport().passed")
15
- ;
10
+ .waitFor(wd.asserters.jsCondition('typeof window.jasmine.getJSReport != \'undefined\''), 60e3, 100)
11
+ .waitFor(wd.asserters.jsCondition('window.postDataToURL.running <= 0'), 30e3, 500)
12
+ .eval('jasmine.getJSReport().passed');
13
});
14
};
grunt/tasks/webdriver-perf.js
+8
-11
@@ -1,23 +1,20 @@
1
-/* jshint evil: true */
2
-
1
'use strict';
2
3
var grunt = require('grunt');
4
7
-module.exports = function(){
8
- return require('./webdriver-all').call(this, function(config, wd, browser){
5
+module.exports = function() {
6
+ return require('./webdriver-all').call(this, function(config, wd, browser) {
7
if (!config.isDoneTimeout) {
8
grunt.verbose.writeln('Expected isDoneTimeout config, using default value');
9
}
10
grunt.verbose.writeln('isDoneTimeout:' + config.isDoneTimeout);
11
return browser
14
- .waitFor(wd.asserters.jsCondition("window.isDone === false"), 5e3, 50)
15
- .fail(function(error){
16
- throw Error("The test page didn't load properly. " + error);
12
+ .waitFor(wd.asserters.jsCondition('window.isDone === false'), 5e3, 50)
13
+ .fail(function(error) {
14
+ throw Error('The test page didn\'t load properly. ' + error);
15
})
18
- .waitFor(wd.asserters.jsCondition("window.isDone === true"), config.isDoneTimeout || 30e3, 1e3)
19
- .waitFor(wd.asserters.jsCondition("window.postDataToURL.running <= 0"), 30e3, 500)
20
- .eval("window.completedTestKeys || window._unhandledError")
21
- ;
16
+ .waitFor(wd.asserters.jsCondition('window.isDone === true'), config.isDoneTimeout || 30e3, 1e3)
17
+ .waitFor(wd.asserters.jsCondition('window.postDataToURL.running <= 0'), 30e3, 500)
18
+ .eval('window.completedTestKeys || window._unhandledError');
19
});
20
};
grunt/tasks/webdriver-phantomjs.js
+6
-6
@@ -2,17 +2,17 @@
2
3
var grunt = require('grunt');
4
5
-module.exports = function(){
5
+module.exports = function() {
6
var onReadyCallback = this.async();
7
8
- var phantomjs = require("phantomjs").path;
9
- var child_process = require('child_process');
8
+ var phantomjs = require('phantomjs').path;
9
+ var childProcess = require('child_process');
10
var config = this.data || {};
11
12
- var args = ["--webdriver=" + (config.port || 9515)];
12
+ var args = ['--webdriver=' + (config.port || 9515)];
13
grunt.verbose.writeln('phantomjs START path:%s args:%s', phantomjs, args);
14
15
- var child = child_process.spawn(phantomjs, args);
15
+ var child = childProcess.spawn(phantomjs, args);
16
process.on('exit', function() {
17
child.kill();
18
});
@@ -29,7 +29,7 @@ module.exports = function(){
29
});
30
31
function verboseWrite(chunk) {
32
- if (onReadyCallback && chunk.toString().indexOf('running on port') != -1) {
32
+ if (onReadyCallback && chunk.toString().indexOf('running on port') !== -1) {
33
grunt.verbose.writeln('phantomjs STARTED');
34
onReadyCallback();
35
onReadyCallback = null;
main.js
+1
-1
@@ -1,5 +1,5 @@
1
'use strict';
2
-
2
+/*eslint-disable no-undef*/
3
var visitors = require('./vendor/fbtransform/visitors');
4
var transform = require('jstransform').transform;
5
var typesSyntax = require('jstransform/visitors/type-syntax');
perf/.eslintrc
new
+21
@@ -0,0 +1,21 @@
1
+globals:
2
+ document: true
3
+ window: true
4
+ Benchmark: true
5
+ React: true
6
+ _rootNode: true
7
+ todolist: true
8
+ _app: true
9
+ _todo1: true
10
+ _todo2: true
11
+ _todo3: true
12
+ _timesToRun: true
13
+ setState: true
14
+
15
+rules:
16
+ strict: false
17
+ no-undef: false
18
+ no-unused-vars: false
19
+ block-scoped-var: false
20
+ consistent-return: false
21
+ no-shadow: false
perf/lib/BrowserPerfRunnerApp.react.js
+60
-46
@@ -10,56 +10,59 @@ var BrowserPerfRunnerApp = React.createClass({
10
headless: React.PropTypes.bool
11
},
12
13
- getInitialState: function(){
13
+ getInitialState: function() {
14
var queue = [];
15
- this.props.tests.forEach(function(testName){
16
- this.props.react.forEach(function(version){
15
+ this.props.tests.forEach(function(testName) {
16
+ this.props.react.forEach(function(version) {
17
queue.push({
18
test: testName,
19
react: version
20
});
21
- },this);
22
- },this);
21
+ }, this);
22
+ }, this);
23
return {
24
queue: queue,
25
results: {}
26
};
27
},
28
29
- handleResults: function(results){
29
+ handleResults: function(results) {
30
this.state.results[results.test + '@' + results.react] = results;
31
this.replaceState(this.state);
32
},
33
34
- handleComplete: function(queueItem){
34
+ handleComplete: function(queueItem) {
35
queueItem.completed = true;
36
-
36
+
37
if (!this.props.onCompleteEach) {
38
return;
39
}
40
// Can't get the resultsForAllVersions if there are still some queued
41
var incompleteCount = 0;
42
- for (var index = this.state.queue.length; --index >= 0;){
42
+ for (var index = this.state.queue.length; --index >= 0;) {
43
if (this.state.queue[index].completed) {
44
continue;
45
}
46
if (this.state.queue[index].test === queueItem.test) {
47
return;
48
}
49
- incompleteCount ++;
49
+ incompleteCount++;
50
}
51
var resultsForAllVersions = Object.keys(this.state.results)
52
- .filter(function(key){return key.indexOf(queueItem.test) === 0;})
53
- .map(function(key){return this.state.results[key];}, this)
54
- ;
52
+ .filter(function(key) {
53
+ return key.indexOf(queueItem.test) === 0;
54
+ })
55
+ .map(function(key) {
56
+ return this.state.results[key];
57
+ }, this);
58
this.props.onCompleteEach(resultsForAllVersions);
56
-
59
+
60
if (this.props.onComplete && incompleteCount === 0) {
61
this.props.onComplete(this.state.results);
62
}
63
},
64
62
- render: function(){
65
+ render: function() {
66
var grid = null;
67
68
if (!this.props.headless) {
@@ -84,31 +87,38 @@ var BrowserPerfRunnerApp = React.createClass({
87
}
88
});
89
87
-BrowserPerfRunnerApp.renderBenchmarkCell = function(props, row, col){
88
- if (col == null && row == null) return React.DOM.th(null);
89
- if (row == null) return React.DOM.th({style:{verticalAlign:'top', textAlign:'center'}}, col);
90
+BrowserPerfRunnerApp.renderBenchmarkCell = function(props, row, col) {
91
+ if (col == null && row == null) {
92
+ return React.DOM.th(null);
93
+ }
94
+ if (row == null) {
95
+ return React.DOM.th({style:{verticalAlign:'top', textAlign:'center'}}, col);
96
+ }
97
98
var benchmarks = Object.keys(props.value)
92
- .filter(function(key){
99
+ .filter(function(key) {
100
return key.indexOf(row) === 0;
101
})
95
- .map(function(key){
102
+ .map(function(key) {
103
return props.value[key];
104
})
98
- .filter(function(benchmark){
105
+ .filter(function(benchmark) {
106
return benchmark && !benchmark.isRunning && benchmark.stats;
100
- })
101
- ;
102
-
103
- if (col == null) return React.DOM.th({style:{verticalAlign:'top', textAlign:'right'}},
104
- React.DOM.a({href:'?test=' + row}, benchmarks[0] && benchmarks[0].name || row)
105
- );
107
+ });
108
+
109
+ if (col == null) {
110
+ return React.DOM.th({style:{verticalAlign:'top', textAlign:'right'}},
111
+ React.DOM.a({href:'?test=' + row}, benchmarks[0] && benchmarks[0].name || row)
112
+ );
113
+ }
114
115
var key = row + '@' + col;
116
var benchmark = props.value[key];
109
- if (!(benchmark && benchmark.stats)) return React.DOM.td({key:key});
110
-
111
-
117
+ if (!(benchmark && benchmark.stats)) {
118
+ return React.DOM.td({key:key});
119
+ }
120
+
121
+
122
var colors = [
123
'000000',
124
'AA0000',
@@ -129,21 +139,25 @@ BrowserPerfRunnerApp.renderBenchmarkCell = function(props, row, col){
139
'FFFFFF'
140
];
141
132
- function chartValue(value){
142
+ function chartValue(value) {
143
return Math.round(valueFromRangeToRange(value, chartValue.min, chartValue.max, 0, 100));
144
}
135
- chartValue.min = Math.min.apply(Math, benchmarks.map(function(benchmark){return Math.min.apply(Math, benchmark.stats.sample);}));
136
- chartValue.max = Math.max.apply(Math, benchmarks.map(function(benchmark){return Math.max.apply(Math, benchmark.stats.sample);}));
137
-
138
- var means = benchmarks.map(function(benchmark){
145
+ chartValue.min = Math.min.apply(Math, benchmarks.map(function(benchmark) {
146
+ return Math.min.apply(Math, benchmark.stats.sample);
147
+ }));
148
+ chartValue.max = Math.max.apply(Math, benchmarks.map(function(benchmark) {
149
+ return Math.max.apply(Math, benchmark.stats.sample);
150
+ }));
151
+
152
+ var means = benchmarks.map(function(benchmark) {
153
return benchmark.stats.mean;
154
});
141
- benchmarks.forEach(function(benchmark){
155
+ benchmarks.forEach(function(benchmark) {
156
benchmark.isTheWinner = benchmark.stats.mean <= Math.min.apply(Math, means);
157
});
158
145
- var chartValues = benchmarks.map(function(benchmark){
146
- // benchmark.stats.sample.sort(function(a,b){return b - a;});
159
+ var chartValues = benchmarks.map(function(benchmark) {
160
+ // benchmark.stats.sample.sort(function(a,b) {return b - a;});
161
return benchmark.stats.sample.map(chartValue).join(',');
162
}).join('|');
163
@@ -151,9 +165,9 @@ BrowserPerfRunnerApp.renderBenchmarkCell = function(props, row, col){
165
React.DOM.td({key:key, style:{textAlign:'center', width:234, verticalAlign:'top'}},
166
benchmark.error && benchmark.error.message || '',
167
React.DOM.div({style: benchmark.isTheWinner ? { backgroundColor:'#0A5', color:'#AFA' } : {backgroundColor:'transparent', color:'inherit'}},
154
- Math.round(1 / benchmark.stats.mean * 100) / 100, " op/s ",
155
- React.DOM.strong(null, Math.round(benchmark.stats.mean * 1000 * 100) / 100, " ms/op "),
156
- React.DOM.small(null, "(±" + (Math.round(benchmark.stats.rme * 10) / 10) + "%)")
168
+ Math.round(1 / benchmark.stats.mean * 100) / 100, ' op/s ',
169
+ React.DOM.strong(null, Math.round(benchmark.stats.mean * 1000 * 100) / 100, ' ms/op '),
170
+ React.DOM.small(null, '(±' + (Math.round(benchmark.stats.rme * 10) / 10) + '%)')
171
),
172
benchmark.isRunning && 'Running' || React.DOM.img({
173
style: {
@@ -167,9 +181,9 @@ BrowserPerfRunnerApp.renderBenchmarkCell = function(props, row, col){
181
})
182
)
183
);
170
-}
184
+};
185
172
-function valueFromRangeToRange(value, fromMin, fromMax, toMin, toMax){
186
+function valueFromRangeToRange(value, fromMin, fromMax, toMin, toMax) {
187
var fromRange = fromMax - fromMin;
188
var toRange = toMax - toMin;
189
return (((value - fromMin) * toRange) / fromRange) + toMin;
@@ -183,11 +197,11 @@ var GridViewTable = React.createClass({
197
renderCell: React.PropTypes.func.isRequired
198
},
199
186
- _renderCell: function(col){
200
+ _renderCell: function(col) {
201
return this.props.renderCell({ value:this.props.value }, this._row, col);
202
},
203
190
- _renderRow: function(row){
204
+ _renderRow: function(row) {
205
this._row = row;
206
return React.DOM.tr({key:row},
207
this._renderCell(null, 0),
@@ -195,7 +209,7 @@ var GridViewTable = React.createClass({
209
);
210
},
211
198
- render: function(){
212
+ render: function() {
213
return React.DOM.table(null,
214
this._renderRow(null, 0),
215
this.props.rows.map(this._renderRow, this)
perf/lib/BrowserPerfRunnerContext.react.js
+39
-33
@@ -8,25 +8,25 @@ var BenchmarkQueue = React.createClass({
8
onError: React.PropTypes.func
9
},
10
11
- getDefaultProps: function(){
11
+ getDefaultProps: function() {
12
return {
13
maxTime: 5
14
};
15
},
16
17
- getInitialState: function(){
17
+ getInitialState: function() {
18
return {
19
queue: this.props.initialQueue.slice()
20
};
21
},
22
23
- setItemState: function(state){
23
+ setItemState: function(state) {
24
state.test = this.state.queue[0].test;
25
state.react = this.state.queue[0].react;
26
this.props.onChange(state);
27
},
28
29
- handleContextReady: function(window){
29
+ handleContextReady: function(window) {
30
var benchmark = window.Benchmark(window.exports);
31
benchmark.options.maxTime = this.props.maxTime; //DEBUG
32
@@ -37,7 +37,7 @@ var BenchmarkQueue = React.createClass({
37
platform: window.Benchmark.platform.description,
38
reactVersion: window.React.version,
39
40
- isMinified: (function(){
40
+ isMinified: (function() {
41
var code = window.React.render.toString();
42
return code.indexOf(',') - code.indexOf('(') <= 2;
43
}())
@@ -46,7 +46,7 @@ var BenchmarkQueue = React.createClass({
46
this.setItemState(itemState);
47
48
var self = this;
49
- benchmark.on('start error cycle complete', function(){
49
+ benchmark.on('start error cycle complete', function() {
50
var stats = JSON.parse(JSON.stringify(benchmark.stats));
51
itemState.stats = stats;
52
itemState.isRunning = benchmark.running;
@@ -56,7 +56,7 @@ var BenchmarkQueue = React.createClass({
56
if (this.props.onError) {
57
benchmark.on('error', this.props.onError);
58
}
59
- benchmark.on('complete', function(){
59
+ benchmark.on('complete', function() {
60
var queue = self.state.queue.slice();
61
var queueItem = queue.shift();
62
if (self.props.onCompleteEach) {
@@ -67,12 +67,12 @@ var BenchmarkQueue = React.createClass({
67
benchmark.run({async:true});
68
},
69
70
- shouldComponentUpdate: function(nextProps, nextState){
70
+ shouldComponentUpdate: function(nextProps, nextState) {
71
return nextState.queue.length < this.state.queue.length;
72
},
73
74
- render: function(){
75
- if (!(this.state.queue && this.state.queue.length > 0)){
74
+ render: function() {
75
+ if (!(this.state.queue && this.state.queue.length > 0)) {
76
return React.DOM.div({style:{display:'none'}});
77
}
78
return BrowserPerfRunnerContext({
@@ -88,61 +88,67 @@ var BrowserPerfRunnerContext = React.createClass({
88
89
propTypes: {
90
debug: React.PropTypes.bool,
91
- test: function(object, key){
91
+ test: function(object, key) {
92
React.PropTypes.string.isRequired(object, key);
93
- if (/\.jsx?$/i.test(object[key])) return;
93
+ if (/\.jsx?$/i.test(object[key])) {
94
+ return;
95
+ }
96
throw Error('Expected `' + key + '` to be a test file name with extension `.js` or `.jsx`');
97
},
96
- react: function(object, key){
98
+ react: function(object, key) {
99
React.PropTypes.string.isRequired(object, key);
98
- if (/^(?:builds\/.+|edge|previous|(?:\d+\.){2}\d+)$/.test(object[key])) return;
99
- throw Error('Expected `' + key + '` prop to be a valid react version string, build string or "edge" or "previous"');
100
+ if (/^(?:builds\/.+|edge|previous|(?:\d+\.){2}\d+)$/.test(object[key])) {
101
+ return;
102
+ }
103
+ throw Error('Expected `' + key + '` prop to be a valid react version string, build string or \'edge\' or \'previous\'');
104
},
105
onReady: React.PropTypes.func.isRequired
106
},
107
104
- getInitialState: function(){
108
+ getInitialState: function() {
109
return {
110
testRunnerURL:'about:blank'
111
};
112
},
113
110
- // _handleFrameError: function(error){
114
+ // _handleFrameError: function(error) {
115
// console.error('BrowserPerfRunnerContext', error);
116
// },
117
//
114
- // _handleFrameLoad: function(event){
118
+ // _handleFrameLoad: function(event) {
119
// console.log('BrowserPerfRunnerContext', event);
120
// },
121
//
118
- _handleMessage: function(event){
119
- if (location.href.indexOf(event.origin) !== 0)
122
+ _handleMessage: function(event) {
123
+ if (location.href.indexOf(event.origin) !== 0) {
124
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message from ' + event.origin);
121
- if (event.source.location.href.indexOf(this.state.testRunnerURL) === -1)
125
+ }
126
+ if (event.source.location.href.indexOf(this.state.testRunnerURL) === -1) {
127
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message from ' + event.source.location.href);
123
- if (event.data !== 'Ready!')
128
+ }
129
+ if (event.data !== 'Ready!') {
130
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message ' + JSON.stringify(event.data));
125
-
131
+ }
132
this.props.onReady(event.source);
133
},
134
129
- _getTestRunnerURL: function(props){
135
+ _getTestRunnerURL: function(props) {
136
return 'runner.html' +
137
'?' +
138
'debug=' + (props.debug ? 1 : 0) +
139
'&' +
140
'react=' + encodeURIComponent(props.react) +
141
'&' +
136
- 'test=' + encodeURIComponent(props.test)
142
+ 'test=' + encodeURIComponent(props.test);
143
},
144
139
- _renderState: function(props){
145
+ _renderState: function(props) {
146
return {
147
testRunnerURL: this._getTestRunnerURL(props)
148
};
149
},
150
145
- componentDidMount: function(){
151
+ componentDidMount: function() {
152
var node = this.refs.iframe.getDOMNode();
153
// node.onload = this._handleFrameLoad;
154
// node.onerror = this._handleFrameError;
@@ -156,7 +162,7 @@ var BrowserPerfRunnerContext = React.createClass({
162
this.setState(this._renderState(this.props));
163
},
164
159
- componentWillUnmount: function(){
165
+ componentWillUnmount: function() {
166
if (window.removeEventListener) {
167
window.removeEventListener('message', this._handleMessage);
168
} else if (window.detachEvent) {
@@ -167,19 +173,19 @@ var BrowserPerfRunnerContext = React.createClass({
173
this.refs.iframe.getDOMNode().src = '';
174
},
175
170
- componentWillReceiveProps: function(nextProps){
176
+ componentWillReceiveProps: function(nextProps) {
177
this.setState(this._renderState(nextProps));
178
},
179
174
- shouldComponentUpdate: function(nextProps, nextState){
175
- return nextState.testRunnerURL != this.state.testRunnerURL;
180
+ shouldComponentUpdate: function(nextProps, nextState) {
181
+ return nextState.testRunnerURL !== this.state.testRunnerURL;
182
},
183
178
- render: function(){
184
+ render: function() {
185
return (
186
React.DOM.iframe({
187
ref: 'iframe',
182
- name: "BrowserPerfRunnerContextFrame",
188
+ name: 'BrowserPerfRunnerContextFrame',
189
style: this.style,
190
src: this.state.testRunnerURL
191
})
perf/lib/perf-test-runner.browser.js
+101
-81
@@ -1,38 +1,44 @@
1
-if (typeof console == 'undefined') console = {
2
- log: function(){},
3
- warn: function(){},
4
- error: function(){},
5
- debug: function(){}
6
-};
1
+if (typeof console === 'undefined') {
2
+ console = {
3
+ log: function() {},
4
+ warn: function() {},
5
+ error: function() {},
6
+ debug: function() {}
7
+ };
8
+}
9
10
var perfRunner;
9
-if (typeof exports == 'object') {
11
+if (typeof exports === 'object') {
12
perfRunner = exports;
13
} else {
14
perfRunner = {};
15
}
16
15
-perfRunner.assert = function(test, message){
16
- if (typeof test == 'function') test = test();
17
- if (test) return;
17
+perfRunner.assert = function(test, message) {
18
+ if (typeof test === 'function') {
19
+ test = test();
20
+ }
21
+ if (test) {
22
+ return;
23
+ }
24
throw Error(message);
19
-}
25
+};
26
21
-perfRunner.WriteScript = function(props){
27
+perfRunner.WriteScript = function(props) {
28
var type = '';
29
if (props.jsx) {
24
- type = ' type="text/jsx"';
30
+ type = ' type=\'text/jsx\'';
31
}
32
var src = props.src;
33
if (!props.cache) {
34
src += src.indexOf('?') === -1 ? '?_' : '&_';
35
src += perfRunner.WriteScript.cacheBust;
36
}
31
- document.write('<script' + type + ' src="' + src + '"><\/script>');
32
-}
33
-perfRunner.WriteScript.cacheBust = (+new Date).toString(36);
37
+ document.write('<script' + type + ' src=\'' + src + '\'><\/script>');
38
+};
39
+perfRunner.WriteScript.cacheBust = (+new Date()).toString(36);
40
35
-perfRunner.WriteReactLibScript = function(params){
41
+perfRunner.WriteReactLibScript = function(params) {
42
var src;
43
var minSuffix;
44
if (params.debug) {
@@ -40,14 +46,16 @@ perfRunner.WriteReactLibScript = function(params){
46
} else {
47
minSuffix = '.min';
48
}
43
-
44
- if (params.version && typeof params.version != 'string') throw TypeError("Expected 'version' to be a string");
45
-
46
- if (params.version == 'edge' || !params.version) {
49
+
50
+ if (params.version && typeof params.version !== 'string') {
51
+ throw TypeError('Expected \'version\' to be a string');
52
+ }
53
+
54
+ if (params.version === 'edge' || !params.version) {
55
console.log('React edge (local)');
56
perfRunner.WriteScript({src:'../build/react' + minSuffix + '.js'});
57
perfRunner.WriteScript({src:'../build/JSXTransformer.js'});
50
- } else if (params.version == 'previous') {
58
+ } else if (params.version === 'previous') {
59
console.log('React previous (local)');
60
perfRunner.WriteScript({cache:true, src:'../build/react-previous' + minSuffix + '.js'});
61
perfRunner.WriteScript({cache:true, src:'../build/JSXTransformer-previous.js'});
@@ -61,113 +69,123 @@ perfRunner.WriteReactLibScript = function(params){
69
}
70
if (params.debug) {
71
console.warn('Loading the unminified build of React, performance may suffer.');
64
- console.warn('Load "' + location.href.replace(/\bdebug=\w+&?|&\bdebug=\w+/ig, '') + '" for better perf.');
72
+ console.warn('Load \'' + location.href.replace(/\bdebug=\w+&?|&\bdebug=\w+/ig, '') + '\' for better perf.');
73
} else {
74
console.warn('Loading the minified build of React, debugging may be harder.');
67
- console.warn('Load "' + location.href.replace(/\bdebug=\w+&?|&\bdebug=\w+/ig, '') + '&debug=1' + '" for easier debugging.');
75
+ console.warn('Load \'' + location.href.replace(/\bdebug=\w+&?|&\bdebug=\w+/ig, '') + '&debug=1' + '\' for easier debugging.');
76
}
69
-}
77
+};
78
71
-perfRunner.WriteTestScript = function(params){
79
+perfRunner.WriteTestScript = function(params) {
80
if (Array.isArray(params.test)) {
81
return params.test
74
- .map(function(test){return {test:test};})
75
- .map(perfRunner.WriteTestScript)
76
- ;
82
+ .map(function(test) {
83
+ return {
84
+ test:test
85
+ };
86
+ })
87
+ .map(perfRunner.WriteTestScript);
88
}
89
perfRunner.assert(params.test.indexOf('..') === -1, 'no relative paths allowed');
90
return perfRunner.WriteScript({jsx:true, src: './tests/' + params.test});
80
-}
91
+};
92
82
-perfRunner.getQueryParamArray = function(key){
93
+perfRunner.getQueryParamArray = function(key) {
94
var values;
95
var queryString = location.search.substr(1);
96
var _key = encodeURIComponent(key) + '=';
86
-
97
+
98
if (queryString.indexOf(_key) > -1) {
99
values = queryString
100
.split(_key)
101
.slice(1)
91
- .map(function(part){return part.split('&')[0];})
102
+ .map(function(part) {
103
+ return part.split('&')[0];
104
+ })
105
.map(decodeURIComponent)
93
- .map(function(string){
106
+ .map(function(string) {
107
try {
108
return JSON.parse(string);
96
- } catch(e){}
109
+ } catch(e) {}
110
return string;
98
- })
99
- ;
111
+ });
112
}
101
-
113
+
114
perfRunner.assert(values && values.length && values[0], 'expected ' + key + ' query param');
115
return values;
104
-}
116
+};
117
106
-perfRunner.getQueryParamArrayOrDefault = function(key, defaultValue){
118
+perfRunner.getQueryParamArrayOrDefault = function(key, defaultValue) {
119
try {
120
return perfRunner.getQueryParamArray(key);
121
} catch (e) {}
122
return defaultValue;
111
-}
123
+};
124
113
-perfRunner.Polyfill = function(){
114
- if (typeof Function.prototype.bind != 'undefined') return;
125
+perfRunner.Polyfill = function() {
126
+ if (typeof Function.prototype.bind !== 'undefined') {
127
+ return;
128
+ }
129
perfRunner.WriteScript({src:'/node_modules/es5-shim/es5-shim.js', cache:true});
130
perfRunner.WriteScript({src:'/node_modules/es5-shim/es5-sham.js', cache:true});
117
-}
131
+};
132
119
-perfRunner.BenchmarkResults = function(props){
120
- return perfRunner.roundNumberWithPrecision(props.stats.mean * 1000) + 'ms/op'
121
-}
133
+perfRunner.BenchmarkResults = function(props) {
134
+ return perfRunner.roundNumberWithPrecision(props.stats.mean * 1000) + 'ms/op';
135
+};
136
123
-perfRunner.roundNumberWithPrecision = function(number, precision){
124
- if (!precision) precision = 1000;
137
+perfRunner.roundNumberWithPrecision = function(number, precision) {
138
+ if (!precision) {
139
+ precision = 1000;
140
+ }
141
return Math.round(number * precision) / precision;
126
-}
142
+};
143
128
-perfRunner.quickBench = function(benchmarkOptions, onComplete, onBeforeStart){
144
+perfRunner.quickBench = function(benchmarkOptions, onComplete, onBeforeStart) {
145
var bench = new Benchmark(benchmarkOptions);
130
- if (onBeforeStart) onBeforeStart(null, bench);
146
+ if (onBeforeStart) {
147
+ onBeforeStart(null, bench);
148
+ }
149
132
- bench.on('error', function(event){
150
+ bench.on('error', function(event) {
151
console.error(event.message);
152
console.log(event.target.compiled.toString());
153
onComplete(Error(event.error));
154
});
155
138
- bench.on('start', function(){
156
+ bench.on('start', function() {
157
console.log('starting', bench.name);
158
});
159
142
- bench.on('cycle', function(){
143
- var bench = this,
144
- size = bench.stats.size;
145
-
146
- if (!bench.aborted) {
147
- console.warn(bench.name + ' × ' + bench.count +
148
- ' (' + bench.stats.sample.length + ' samples)' +
149
- ' (' + Math.round(1 / bench.stats.mean) + ' ops/sec' + ')' +
150
- ' (' + (bench.stats.mean * 1000) + ' ms/op' + ')' +
151
- ' (±' + bench.stats.rme.toFixed(2) + '%)' +
160
+ bench.on('cycle', function() {
161
+ var benchmark = this,
162
+ size = benchmark.stats.size;
163
+
164
+ if (!benchmark.aborted) {
165
+ console.warn(benchmark.name + ' × ' + benchmark.count +
166
+ ' (' + benchmark.stats.sample.length + ' samples)' +
167
+ ' (' + Math.round(1 / benchmark.stats.mean) + ' ops/sec' + ')' +
168
+ ' (' + (benchmark.stats.mean * 1000) + ' ms/op' + ')' +
169
+ ' (±' + benchmark.stats.rme.toFixed(2) + '%)' +
170
' with ' + React.version
171
);
172
}
173
});
174
157
- bench.on('complete', function(){
175
+ bench.on('complete', function() {
176
var results = {
177
platform: Benchmark.platform.description,
178
react: React.version,
161
- name: bench.name,
179
+ name: bench.name
180
// times: bench.times,
181
// stats: bench.stats
182
};
165
-
166
- results['s/op'] = bench.stats.mean
167
- results['ms/op'] = results['s/op'] * 1000
168
- results['op/s'] = 1 / results['s/op']
169
- results["% frame 60"] = results['ms/op'] / (1000 / 60) * 100
170
-
183
+
184
+ results['s/op'] = bench.stats.mean;
185
+ results['ms/op'] = results['s/op'] * 1000;
186
+ results['op/s'] = 1 / results['s/op'];
187
+ results['% frame 60'] = results['ms/op'] / (1000 / 60) * 100;
188
+
189
console.log(results);
190
onComplete(null, results);
191
});
@@ -175,9 +193,9 @@ perfRunner.quickBench = function(benchmarkOptions, onComplete, onBeforeStart){
193
bench.run();
194
};
195
178
-perfRunner.singleTest = function(benchmarkOptions, onComplete){
196
+perfRunner.singleTest = function(benchmarkOptions, onComplete) {
197
var bench = Benchmark(exports);
180
- bench.on('complete', function(){
198
+ bench.on('complete', function() {
199
var results = {
200
platform: Benchmark.platform.description,
201
react: React.version,
@@ -187,18 +205,20 @@ perfRunner.singleTest = function(benchmarkOptions, onComplete){
205
onComplete(results);
206
});
207
bench.run();
190
-}
208
+};
209
192
-perfRunner.ViewObject = function(props){
210
+perfRunner.ViewObject = function(props) {
211
var value = props.value;
212
delete props.value;
195
-
196
- if (typeof value != 'object') return React.DOM.span(props, [JSON.stringify(value), " ", typeof value]);
197
-
198
- return React.DOM.table(props, Object.keys(value).map(function(key){
213
+
214
+ if (typeof value !== 'object') {
215
+ return React.DOM.span(props, [JSON.stringify(value), ' ', typeof value]);
216
+ }
217
+
218
+ return React.DOM.table(props, Object.keys(value).map(function(key) {
219
return React.DOM.tr(null,
220
React.DOM.th(null, key),
221
React.DOM.td(null, perfRunner.ViewObject({key:key, value:value[key]}))
222
);
223
}));
204
-}
224
+};
perf/lib/todolist.browser.js
+56
-34
@@ -1,4 +1,4 @@
1
-/*global*/todolist = {};
1
+todolist = {};
2
3
todolist.ID = Date.now();
4
@@ -9,11 +9,15 @@ todolist.App = React.createClass({
9
fakeDataCount: React.PropTypes.number
10
},
11
12
- getInitialState: function(){
12
+ getInitialState: function() {
13
var todos;
14
if (this.props.fakeDataCount) {
15
- todos = Array(this.props.fakeDataCount + 1).join(',').split(',').map(function(ignore, index){
16
- return {id:index, title:"Title " + index + " " + Math.random().toString(36).substring(2,16), completed:!!(index % 2)};
15
+ todos = Array(this.props.fakeDataCount + 1).join(',').split(',').map(function(ignore, index) {
16
+ return {
17
+ id: index,
18
+ title: 'Title ' + index + ' ' + Math.random().toString(36).substring(2, 16),
19
+ completed: !!(index % 2)
20
+ };
21
});
22
}
23
return {
@@ -23,15 +27,17 @@ todolist.App = React.createClass({
27
todos: todos || this.props.initialData || []
28
};
29
},
26
- componentWillUpdate: function(props, state){
27
- state.todos = state.todos.filter(function(todo){
30
+ componentWillUpdate: function(props, state) {
31
+ state.todos = state.todos.filter(function(todo) {
32
return !todo.deleted;
33
});
34
},
31
- addItem: function(title, callback){
35
+ addItem: function(title, callback) {
36
if (title == null || title === '') {
37
var error = Error('invalid title');
34
- if (!callback) throw error;
38
+ if (!callback) {
39
+ throw error;
40
+ }
41
return callback(error);
42
}
43
var todos = this.state.todos.slice();
@@ -41,82 +47,98 @@ todolist.App = React.createClass({
47
completed: false
48
};
49
todos.push(todo);
44
- if (callback) callback = callback.bind(this, todo);
50
+ if (callback) {
51
+ callback = callback.bind(this, todo);
52
+ }
53
this.setState({ timerEvent:'addItem', timerStart:todolist.now(), timerEnd:null, todos:todos }, callback);
54
return todo;
55
},
48
- deleteItemById: function(id, callback){
56
+ deleteItemById: function(id, callback) {
57
var todo = this._getById(id);
50
- if (!todo) return callback && callback(Error('todo with id ' + id + ' not found'));
58
+ if (!todo) {
59
+ return callback && callback(Error('todo with id ' + id + ' not found'));
60
+ }
61
todo.deleted = true;
62
this.setState({ timerEvent:'deleteItemById', timerStart:todolist.now(), timerEnd:null, todos:this.state.todos }, callback);
63
},
54
- setItemCompleted: function(id, completed, callback){
64
+ setItemCompleted: function(id, completed, callback) {
65
var todo = this._getById(id);
56
- if (!todo) return callback && callback(Error('todo with id ' + id + ' not found'));
66
+ if (!todo) {
67
+ return callback && callback(Error('todo with id ' + id + ' not found'));
68
+ }
69
todo.completed = completed;
70
this.setState({ timerEvent:'setItemCompleted', timerStart:todolist.now(), timerEnd:null, todos:this.state.todos }, callback);
71
},
60
- _getById: function(id){
72
+ _getById: function(id) {
73
id = +id;
74
var todos = this.state.todos;
63
- for (var index = todos.length; --index >= 0;){
64
- if (todos[index].id === id) return todos[index];
75
+ for (var index = todos.length; --index >= 0;) {
76
+ if (todos[index].id === id) {
77
+ return todos[index];
78
+ }
79
}
80
return null;
81
},
68
- _handleItemCompletedCheckboxChange: function(event){
82
+ _handleItemCompletedCheckboxChange: function(event) {
83
var node = event.target;
84
this.setItemCompleted(node.value, node.checked);
85
},
72
- _handleItemDeletedButton: function(event){
86
+ _handleItemDeletedButton: function(event) {
87
var node = event.target;
88
this.deleteItemById(node.value);
89
},
76
- _renderTodoItem: function(todo, index){
90
+ _renderTodoItem: function(todo, index) {
91
return (
92
React.DOM.li({key:todo.id},
93
React.DOM.button({value:todo.id, onClick:this._handleItemDeletedButton}, 'x'),
80
- React.DOM.input({type:"checkbox", value:todo.id, checked:todo.completed, onChange:this._handleItemCompletedCheckboxChange}),
81
- " ",
82
- React.DOM.span({style:{"text-decoration":todo.completed ? "line-through" : ""}}, todo.title)
94
+ React.DOM.input({type:'checkbox', value:todo.id, checked:todo.completed, onChange:this._handleItemCompletedCheckboxChange}),
95
+ ' ',
96
+ React.DOM.span({style:{'text-decoration':todo.completed ? 'line-through' : ''}}, todo.title)
97
)
98
);
99
},
86
- render: function(){
87
- if (!this.state.timerEnd) this.state.timerEnd = todolist.now();
88
- if (this.props.onRender) this.props.onRender();
100
+ render: function() {
101
+ if (!this.state.timerEnd) {
102
+ this.state.timerEnd = todolist.now();
103
+ }
104
+ if (this.props.onRender) {
105
+ this.props.onRender();
106
+ }
107
return (
108
React.DOM.div(null,
91
- React.DOM.h1(null, "TODO"),
92
- React.DOM.h3(null, this.state.timerEvent, " ", this.state.timerEnd - this.state.timerStart, 'ms'),
109
+ React.DOM.h1(null, 'TODO'),
110
+ React.DOM.h3(null, this.state.timerEvent, ' ', this.state.timerEnd - this.state.timerStart, 'ms'),
111
todolist.NewItemForm({onEnter:this.addItem, autoFocus:true}),
112
React.DOM.ol(null, this.state.todos.map(this._renderTodoItem))
113
)
114
);
115
},
98
- componentDidMount: function(rootNode){
99
- if (this.props.onDidMount) this.props.onDidMount(rootNode);
116
+ componentDidMount: function(rootNode) {
117
+ if (this.props.onDidMount) {
118
+ this.props.onDidMount(rootNode);
119
+ }
120
}
121
});
122
123
todolist.NewItemForm = React.createClass({
104
- _handleNewItemKeyDown: function(event){
105
- if (event.which !== 13/*enter key*/) return;
124
+ _handleNewItemKeyDown: function(event) {
125
+ if (event.which !== 13/*enter key*/) {
126
+ return;
127
+ }
128
var node = this.refs.text.getDOMNode();
129
var value = node.value;
130
node.value = '';
131
this.props.onEnter(value);
132
return false;
133
},
112
- render: function(){
134
+ render: function() {
135
var props = {};
136
for (var key in this.props) {
115
- if (key !== "onEnter") {
137
+ if (key !== 'onEnter') {
138
props[key] = this.props[key];
139
}
140
}
119
- props.ref = "text";
141
+ props.ref = 'text';
142
props.onKeyDown = this.props.onEnter && this._handleNewItemKeyDown;
143
return React.DOM.input(props);
144
}
perf/tests/basic-div.js
+4
-9
@@ -1,16 +1,11 @@
1
-/* jshint undef: true, unused: true */
2
-
3
-/* global document */
4
-/* global window */
5
-/* global Benchmark */
6
-/* global React */
7
-
8
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
7
exports.name = 'React.DOM.div, no props';
8
14
-exports.fn = function(){
9
+exports.fn = function() {
10
React.DOM.div(null, 'lol, perf testing ', this.count);
11
};
perf/tests/basic-unmount.js
+11
-13
@@ -1,23 +1,21 @@
1
-/* jshint undef: true, unused: true */
2
-
3
-/* global document */
4
-/* global window */
5
-/* global Benchmark */
6
-/* global React */
7
-
8
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
7
exports.name = 'unmountComponentAtNode';
8
14
-exports.setup = function(){
15
- /*global*/_rootNode = document.createElement('div');
9
+exports.setup = function() {
10
+ _rootNode = document.createElement('div');
11
document.body.appendChild(_rootNode);
12
var _firstChild = React.DOM.div(null, 'lol, perf testing ', this.count);
13
React.render(_firstChild, _rootNode);
14
};
20
-exports.fn = function(){
21
- if (React.unmountAndReleaseReactRootNode) React.unmountAndReleaseReactRootNode(_rootNode);
22
- else React.unmountComponentAtNode(_rootNode);
15
+exports.fn = function() {
16
+ if (React.unmountAndReleaseReactRootNode) {
17
+ React.unmountAndReleaseReactRootNode(_rootNode);
18
+ } else {
19
+ React.unmountComponentAtNode(_rootNode);
20
+ }
21
};
perf/tests/propTypes.js
+16
-10
@@ -1,4 +1,6 @@
1
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
@@ -10,7 +12,11 @@ var ListItem;
12
var MyReactComponent;
13
var _rootNode;
14
13
-exports.setup = function(){
15
+function func() {
16
+ return 'this is a function';
17
+}
18
+
19
+exports.setup = function() {
20
List = React.createClass({
21
propTypes: {
22
array: React.PropTypes.array,
@@ -38,7 +44,7 @@ exports.setup = function(){
44
instanceOf: React.PropTypes.instanceOf(Thing).isRequired,
45
element: React.PropTypes.element.isRequired
46
},
41
- render: function(){
47
+ render: function() {
48
return React.DOM.li(null,
49
this.props.number + this.props.string + this.props.node
50
);
@@ -54,7 +60,7 @@ exports.setup = function(){
60
_rootNode = document.createElement('div');
61
document.body.appendChild(_rootNode);
62
};
57
-exports.fn = function(){
63
+exports.fn = function() {
64
var items = [];
65
for (var i = 0; i < 1000; i++) {
66
items.push(ListItem({
@@ -62,24 +68,24 @@ exports.fn = function(){
68
bool: false,
69
number: Math.random(),
70
string: 'banana banana banana',
65
- func: function() { return 'this is a function'; },
71
+ func: func,
72
node: 'renderable string',
73
node2: [MyReactComponent(), 'a string'],
68
- instanceOf: new Thing,
74
+ instanceOf: new Thing(),
75
element: MyReactComponent()
76
}));
71
- };
77
+ }
78
79
React.render(List({
80
array: [11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
81
bool: false,
82
number: Math.random(),
83
string: 'banana banana banana',
78
- func: function() { return 'this is a function'; },
84
+ func: func,
85
renderable: 'renderable string',
80
- instanceOf: new Thing
86
+ instanceOf: new Thing()
87
}, items), _rootNode);
88
};
83
-exports.teardown = function(){
89
+exports.teardown = function() {
90
React.unmountComponentAtNode(_rootNode);
91
};
perf/tests/renderComponent-basic.js
+12
-14
@@ -1,24 +1,22 @@
1
-/* jshint undef: true, unused: true */
2
-
3
-/* global document */
4
-/* global window */
5
-/* global Benchmark */
6
-/* global React */
7
-
8
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
7
exports.name = 'React.render single div';
8
14
-exports.setup = function(){
15
- /*global*/_rootNode = document.createElement('div');
9
+exports.setup = function() {
10
+ _rootNode = document.createElement('div');
11
document.body.appendChild(_rootNode);
12
};
18
-exports.fn = function(){
13
+exports.fn = function() {
14
React.render(React.DOM.div(null, 'lol, perf testing ', this.count), _rootNode);
15
};
21
-exports.teardown = function(){
22
- if (React.unmountAndReleaseReactRootNode) React.unmountAndReleaseReactRootNode(_rootNode);
23
- else React.unmountComponentAtNode(_rootNode);
16
+exports.teardown = function() {
17
+ if (React.unmountAndReleaseReactRootNode) {
18
+ React.unmountAndReleaseReactRootNode(_rootNode);
19
+ } else {
20
+ React.unmountComponentAtNode(_rootNode);
21
+ }
22
};
perf/tests/sanity.js
+6
-4
@@ -1,15 +1,17 @@
1
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
7
exports.name = 'Trivial benchmark to verify that everything works';
8
7
-exports.setup = function(){
9
+exports.setup = function() {
10
var foo;
11
};
10
-exports.fn = function(){
12
+exports.fn = function() {
13
foo = Array(999).join('Howdy!\n');
14
};
13
-exports.teardown = function(){
15
+exports.teardown = function() {
16
foo = null;
17
};
perf/tests/setState-callback-5.js
+18
-14
@@ -1,4 +1,6 @@
1
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
@@ -6,29 +8,31 @@ exports.name = 'From setState to callback (x5)';
8
9
exports.defer = true;
10
9
-exports.setup = function(){
10
- /*global*/_rootNode = document.createElement('div');
11
+exports.setup = function() {
12
+ _rootNode = document.createElement('div');
13
document.body.appendChild(_rootNode);
12
- /*global*/setState = null;
14
+ setState = null;
15
16
var AwesomeComponent = React.createClass({
15
- getInitialState: function(){
17
+ getInitialState: function() {
18
return { random:null };
19
},
18
- render: function(){
19
- if (!setState) setState = this.setState.bind(this);
20
+ render: function() {
21
+ if (!setState) {
22
+ setState = this.setState.bind(this);
23
+ }
24
return React.DOM.div(null, this.state.random);
25
}
26
});
27
28
React.render(AwesomeComponent(null), _rootNode);
29
};
26
-exports.fn = function(deferred){
27
- setState({random: Date.now() + Math.random()}, function(){
28
- setState({random: Date.now() + Math.random()}, function(){
29
- setState({random: Date.now() + Math.random()}, function(){
30
- setState({random: Date.now() + Math.random()}, function(){
31
- setState({random: Date.now() + Math.random()}, function(){
30
+exports.fn = function(deferred) {
31
+ setState({random: Date.now() + Math.random()}, function() {
32
+ setState({random: Date.now() + Math.random()}, function() {
33
+ setState({random: Date.now() + Math.random()}, function() {
34
+ setState({random: Date.now() + Math.random()}, function() {
35
+ setState({random: Date.now() + Math.random()}, function() {
36
deferred.resolve();
37
});
38
});
@@ -36,6 +40,6 @@ exports.fn = function(deferred){
40
});
41
});
42
};
39
-exports.teardown = function(){
43
+exports.teardown = function() {
44
React.unmountComponentAtNode(_rootNode);
45
};
perf/tests/setState-callback.js
+14
-10
@@ -1,4 +1,6 @@
1
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
@@ -6,28 +8,30 @@ exports.name = 'From setState to callback';
8
9
exports.defer = true;
10
9
-exports.setup = function(){
10
- /*global*/_rootNode = document.createElement('div');
11
+exports.setup = function() {
12
+ _rootNode = document.createElement('div');
13
document.body.appendChild(_rootNode);
12
- /*global*/setState = null;
14
+ setState = null;
15
16
var AwesomeComponent = React.createClass({
15
- getInitialState: function(){
17
+ getInitialState: function() {
18
return { random:null };
19
},
18
- render: function(){
19
- if (!setState) setState = this.setState.bind(this);
20
+ render: function() {
21
+ if (!setState) {
22
+ setState = this.setState.bind(this);
23
+ }
24
return React.DOM.div(null, this.state.random);
25
}
26
});
27
28
React.render(AwesomeComponent(null), _rootNode);
29
};
26
-exports.fn = function(deferred){
27
- setState({random: Date.now() + Math.random()}, function(){
30
+exports.fn = function(deferred) {
31
+ setState({random: Date.now() + Math.random()}, function() {
32
deferred.resolve();
33
});
34
};
31
-exports.teardown = function(){
35
+exports.teardown = function() {
36
React.unmountComponentAtNode(_rootNode);
37
};
perf/tests/shouldComponentUpdate.js
+8
-6
@@ -1,15 +1,17 @@
1
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
7
exports.name = 'shouldComponentUpdate';
8
7
-exports.setup = function(){
9
+exports.setup = function() {
10
var AwesomeComponent = React.createClass({
9
- shouldComponentUpdate: function(){
11
+ shouldComponentUpdate: function() {
12
return false;
13
},
12
- render: function(){
14
+ render: function() {
15
return React.DOM.div({});
16
}
17
});
@@ -17,9 +19,9 @@ exports.setup = function(){
19
var _rootNode = document.createElement('div');
20
document.body.appendChild(_rootNode);
21
};
20
-exports.fn = function(){
22
+exports.fn = function() {
23
React.render(AwesomeComponent(null), _rootNode);
24
};
23
-exports.teardown = function(){
25
+exports.teardown = function() {
26
React.unmountComponentAtNode(_rootNode);
27
};
perf/tests/todolist-add.js
+12
-8
@@ -1,4 +1,6 @@
1
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
@@ -6,20 +8,22 @@ exports.name = 'todolist from addItem to callback';
8
9
exports.defer = true;
10
9
-exports.setup = function(){
10
- /*global*/_rootNode = document.createElement('div');
11
+exports.setup = function() {
12
+ _rootNode = document.createElement('div');
13
document.body.appendChild(_rootNode);
14
var appDescriptor = todolist.App({ fakeDataCount: 333 });
13
- /*global*/_app = React.render(appDescriptor, _rootNode);
15
+ _app = React.render(appDescriptor, _rootNode);
16
};
15
-exports.fn = function(deferred){
17
+exports.fn = function(deferred) {
18
var liCount = document.getElementsByTagName('li').length;
17
- _app.addItem(Math.random(), function(){
18
- if (document.getElementsByTagName('li').length <= liCount) throw Error('expected a list item to be added to the dom');
19
+ _app.addItem(Math.random(), function() {
20
+ if (document.getElementsByTagName('li').length <= liCount) {
21
+ throw Error('expected a list item to be added to the dom');
22
+ }
23
deferred.resolve();
24
});
25
};
22
-exports.teardown = function(){
26
+exports.teardown = function() {
27
React.unmountComponentAtNode(_rootNode);
28
_rootNode.parentNode.removeChild(_rootNode);
29
_rootNode = null;
perf/tests/todolist-do-stuff.js
+19
-15
@@ -1,52 +1,56 @@
1
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
5
-/*global*/_timesToRun = 2;
7
+_timesToRun = 2;
8
9
exports.name = 'todolist add, complete, remove (x' + _timesToRun + ')';
10
11
exports.defer = true;
12
11
-exports.setup = function(){
12
- /*global*/_rootNode = document.createElement('div');
13
+exports.setup = function() {
14
+ _rootNode = document.createElement('div');
15
document.body.appendChild(_rootNode);
16
var appDescriptor = todolist.App({ fakeDataCount: 333 });
15
- /*global*/_app = React.render(appDescriptor, _rootNode);
17
+ _app = React.render(appDescriptor, _rootNode);
18
};
19
18
-exports.fn = function(deferred){
20
+exports.fn = function(deferred) {
21
var originalLiCount = document.getElementsByTagName('li').length;
22
23
var todos = [];
24
var times = _timesToRun;
23
- while (times-- >= 0){
24
- todos.push(_app.addItem(times+1));
25
+ while (times-- >= 0) {
26
+ todos.push(_app.addItem(times + 1));
27
}
28
27
- todos.forEach(function(todo){
29
+ todos.forEach(function(todo) {
30
_app.setItemCompleted(todo.id);
31
});
32
31
- todos.forEach(function(todo){
33
+ todos.forEach(function(todo) {
34
_app.deleteItemById(todo.id);
35
});
36
37
todos = null;
38
37
- _app.addItem(Math.random(), function(todo){
38
- if (document.getElementsByTagName('li').length <= originalLiCount)
39
+ _app.addItem(Math.random(), function(todo) {
40
+ if (document.getElementsByTagName('li').length <= originalLiCount) {
41
throw Error('expected a list item to be added to the dom');
42
+ }
43
41
- _app.deleteItemById(todo.id, function(){
42
- if (document.getElementsByTagName('li').length != originalLiCount)
44
+ _app.deleteItemById(todo.id, function() {
45
+ if (document.getElementsByTagName('li').length !== originalLiCount) {
46
throw Error('expected everything to be done by now');
47
+ }
48
deferred.resolve();
49
});
50
});
51
};
52
49
-exports.teardown = function(){
53
+exports.teardown = function() {
54
React.unmountComponentAtNode(_rootNode);
55
_rootNode.parentNode.removeChild(_rootNode);
56
_rootNode = null;
perf/tests/todolist-edit.js
+12
-10
@@ -1,4 +1,6 @@
1
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
@@ -6,25 +8,25 @@ exports.name = 'todolist setItemCompleted';
8
9
exports.defer = true;
10
9
-exports.setup = function(){
10
- /*global*/_rootNode = document.createElement('div');
11
+exports.setup = function() {
12
+ _rootNode = document.createElement('div');
13
document.body.appendChild(_rootNode);
14
var appDescriptor = todolist.App({ fakeDataCount: 333 });
13
- /*global*/_app = React.render(appDescriptor, _rootNode);
14
- /*global*/_todo1 = _app.addItem("Howdy 1!");
15
- /*global*/_todo2 = _app.addItem("Howdy 2!");
16
- /*global*/_todo3 = _app.addItem("Howdy 3!");
15
+ _app = React.render(appDescriptor, _rootNode);
16
+ _todo1 = _app.addItem('Howdy 1!');
17
+ _todo2 = _app.addItem('Howdy 2!');
18
+ _todo3 = _app.addItem('Howdy 3!');
19
};
20
19
-exports.fn = function(deferred){
21
+exports.fn = function(deferred) {
22
_app.setItemCompleted(_todo1.id, !_todo1.completed);
23
_app.setItemCompleted(_todo2.id, !_todo2.completed);
22
- _app.setItemCompleted(_todo3.id, !_todo3.completed, function(){
24
+ _app.setItemCompleted(_todo3.id, !_todo3.completed, function() {
25
deferred.resolve();
26
});
27
};
28
27
-exports.teardown = function(){
29
+exports.teardown = function() {
30
React.unmountComponentAtNode(_rootNode);
31
_rootNode.parentNode.removeChild(_rootNode);
32
_rootNode = null;
perf/tests/todolist-mount.js
+15
-8
@@ -1,22 +1,29 @@
1
-if (typeof exports == 'undefined') exports = {};
1
+if (typeof exports === 'undefined') {
2
+ exports = {};
3
+}
4
5
/*http://benchmarkjs.com/docs#options*/
6
5
-exports.name = 'todolist from renderComponent to renderComponent callback (333 rows)';
7
+exports.name =
8
+ 'todolist from renderComponent to renderComponent callback (333 rows)';
9
10
exports.defer = true;
11
9
-exports.setup = function(){
10
- if (typeof _rootNode != 'undefined') throw Error("should teardown before running setup again");
11
- /*global*/_rootNode = document.createElement('div');
12
+exports.setup = function() {
13
+ if (typeof _rootNode !== 'undefined') {
14
+ throw Error('should teardown before running setup again');
15
+ }
16
+ _rootNode = document.createElement('div');
17
document.body.appendChild(_rootNode);
18
};
19
15
-exports.fn = function(deferred){
16
- React.render(todolist.App({ fakeDataCount: 333 }), _rootNode, function(){ deferred.resolve(); });
20
+exports.fn = function(deferred) {
21
+ React.render(todolist.App({ fakeDataCount: 333 }), _rootNode, function() {
22
+ deferred.resolve();
23
+ });
24
};
25
19
-exports.teardown = function(){
26
+exports.teardown = function() {
27
React.unmountComponentAtNode(_rootNode);
28
_rootNode.parentNode.removeChild(_rootNode);
29
_rootNode = undefined;
test/.eslintrc
new
+8
@@ -0,0 +1,8 @@
1
+globals:
2
+ harness: true
3
+
4
+rules:
5
+ strict: false
6
+ no-undef: false
7
+ no-unused-vars: false
8
+ block-scoped-var: false
\ No newline at end of file
test/lib/jasmine-execute.js
+5
-5
@@ -1,6 +1,6 @@
1
-document.write('<style> @import "../vendor/jasmine/jasmine.css?_=' + (+new Date).toString(36) + '"; </style>');
1
+document.write('<style> @import \'../vendor/jasmine/jasmine.css?_=' + (+new Date()).toString(36) + '\'; </style>');
2
3
-;(function(env){
3
+(function(env) {
4
var htmlReporter = new jasmine.HtmlReporter();
5
env.addReporter(htmlReporter);
6
env.specFilter = function(spec) {
@@ -10,10 +10,10 @@ document.write('<style> @import "../vendor/jasmine/jasmine.css?_=' + (+new Date)
10
// Clean up any nodes the previous test might have added.
11
env.afterEach(function() {
12
harness.removeNextSiblings(document.body);
13
- harness.removeNextSiblings(document.getElementById("HTMLReporter"));
13
+ harness.removeNextSiblings(document.getElementById('HTMLReporter'));
14
});
15
16
- window.onload = function(){
16
+ window.onload = function() {
17
env.execute();
18
- }
18
+ };
19
})(jasmine.getEnv());
test/lib/postDataToURL.browser.js
+29
-15
@@ -1,34 +1,48 @@
1
-function createXMLHttpRequest(){
2
- try{return new XMLHttpRequest();}
3
- catch(e){}
4
- try {return new ActiveXObject("Msxml2.XMLHTTP");}
1
+/*eslint-disable brace-style*/
2
+function createXMLHttpRequest() {
3
+ try {
4
+ return new XMLHttpRequest();
5
+ }
6
+ catch(e) {}
7
+ try {
8
+ return new ActiveXObject('Msxml2.XMLHTTP');
9
+ }
10
catch (e) {}
6
- try {return new ActiveXObject("Microsoft.XMLHTTP");}
11
+ try {
12
+ return new ActiveXObject('Microsoft.XMLHTTP');
13
+ }
14
catch (e) {}
15
}
16
+/*eslint-enable brace-style*/
17
10
-function getURLSync(url){
18
+function getURLSync(url) {
19
var request = createXMLHttpRequest();
20
request.open('GET', url, /*asynchronous?*/false);
21
return request.responseText;
22
}
23
24
function postDataToURL(data, url, callback) {
17
- if (!callback) callback = postDataToURL.defaultCallback;
25
+ if (!callback) {
26
+ callback = postDataToURL.defaultCallback;
27
+ }
28
var request = createXMLHttpRequest();
19
- if (!request) return callback(Error('XMLHttpRequest is unsupported'));
20
- postDataToURL.running = (postDataToURL.running||0) + 1;
21
- request.onreadystatechange = function(){
22
- if (request.readyState != 4) return;
29
+ if (!request) {
30
+ return callback(Error('XMLHttpRequest is unsupported'));
31
+ }
32
+ postDataToURL.running = (postDataToURL.running || 0) + 1;
33
+ request.onreadystatechange = function() {
34
+ if (request.readyState !== 4) {
35
+ return;
36
+ }
37
request.onreadystatechange = null;
24
- postDataToURL.running = (postDataToURL.running||0) - 1;
25
- callback(request.status == 200 ? null : request.status, request.responseText);
38
+ postDataToURL.running = (postDataToURL.running || 0) - 1;
39
+ callback(request.status === 200 ? null : request.status, request.responseText);
40
};
41
request.open('POST', url);
42
request.setRequestHeader('Content-Type', 'application/json');
43
request.send(JSON.stringify(data));
44
}
45
32
-postDataToURL.defaultCallback = function(error){
46
+postDataToURL.defaultCallback = function(error) {
47
// console.log('postDataToURL.defaultCallback', arguments)
34
-}
48
+};
test/lib/reportTestResults.browser.js
+31
-21
@@ -1,38 +1,46 @@
1
-var __DEBUG__ = location.search.substring(1).indexOf('debug') != -1;
1
+var __DEBUG__ = location.search.substring(1).indexOf('debug') !== -1;
2
3
-if (typeof console == 'undefined') console = {
4
- log: function(){},
5
- warn: function(){},
6
- error: function(){}
7
-};
3
+if (typeof console === 'undefined') {
4
+ console = {
5
+ log: function() {},
6
+ warn: function() {},
7
+ error: function() {}
8
+ };
9
+}
10
11
var __consoleReport__ = [];
12
13
console._log = console.log;
12
-console.log = function(message){
14
+console.log = function(message) {
15
console._log(message);
14
- if (__DEBUG__) postDataToURL({type:'log', message:message}, '/reportTestResults');
15
- else __consoleReport__.push({type:'log', message:message});
16
-}
16
+ if (__DEBUG__) {
17
+ postDataToURL({type:'log', message:message}, '/reportTestResults');
18
+ } else {
19
+ __consoleReport__.push({type:'log', message:message});
20
+ }
21
+};
22
23
console._error = console.error;
19
-console.error = function(message){
24
+console.error = function(message) {
25
console._error(message);
21
- if (__DEBUG__) postDataToURL({type:'error', message:message}, '/reportTestResults');
22
- else __consoleReport__.push({type:'error', message:message});
23
-}
26
+ if (__DEBUG__) {
27
+ postDataToURL({type:'error', message:message}, '/reportTestResults');
28
+ } else {
29
+ __consoleReport__.push({type:'error', message:message});
30
+ }
31
+};
32
25
-console._flush = function(){
33
+console._flush = function() {
34
postDataToURL(__consoleReport__, '/console');
35
__consoleReport__.length = 0;
28
-}
36
+};
37
30
-;(function(env){
38
+(function(env) {
39
env.addReporter(new jasmine.JSReporter());
40
env.addReporter(new TAPReporter(console.log.bind(console)));
41
34
- function report(){
35
- if (typeof jasmine.getJSReport != 'function') {
42
+ function report() {
43
+ if (typeof jasmine.getJSReport !== 'function') {
44
return setTimeout(report, 100);
45
}
46
if (!__DEBUG__) {
@@ -42,8 +50,10 @@ console._flush = function(){
50
}
51
52
var oldCallback = env.currentRunner().finishCallback;
45
- env.currentRunner().finishCallback = function(){
46
- if (oldCallback) oldCallback.apply(this, arguments);
53
+ env.currentRunner().finishCallback = function() {
54
+ if (oldCallback) {
55
+ oldCallback.apply(this, arguments);
56
+ }
57
report();
58
};
59