Skip to content

Commit

Permalink
Fixes #33 - Adds support for multiple formats
Browse files Browse the repository at this point in the history
  • Loading branch information
jrcryer committed Dec 31, 2014
1 parent be251a5 commit 8d5651a
Show file tree
Hide file tree
Showing 13 changed files with 268 additions and 104 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ Default: `nokey`

Unless Specified defaults to use the free tier on PageSpeed Insights. Good for getting a feel for how well this tool works for you.

#### format

Type: `string`
Default: `cli`

The format of the report generated from the PageSpeed Insights API. Supported formats: cli, json and tap.

## CLI support

Expand All @@ -114,7 +120,7 @@ $ psi todomvc.com
Similar to gpagespeed, the following optional flags are also supported:

```sh
$ psi <url> --key=<key> --prettyprint=<true> --userIp=<userIp> --locale=<locale> --strategy=<desktop|mobile>
$ psi <url> --key=<key> --prettyprint=<true> --userIp=<userIp> --locale=<locale> --strategy=<desktop|mobile> --format<cli|json|tap>
```

```sh
Expand Down
33 changes: 18 additions & 15 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
'use strict';
// Adapted from cli.js in gpagespeed

var insights = require('../index')
, pkg = require('../package.json')
, query = process.argv[2]
, argv = require('minimist')((process.argv.slice(2)))
, opts = {}
;
var insights = require('../index');
var pkg = require('../package.json');
var query = process.argv[2];
var argv = require('minimist')((process.argv.slice(2)));
var opts = {};

function printHelp() {
console.log(pkg.description);
Expand All @@ -17,7 +16,7 @@ function printHelp() {
console.log('');
console.log('Optional, supply other arguments.');
console.log('See https://developers.google.com/speed/docs/insights/v1/getting_started for description');
console.log(' $ psi <url> --key=<key> --prettyprint=<true> --userIp=<userIp> --locale=<locale> --strategy=<desktop|mobile>');
console.log(' $ psi <url> --key=<key> --prettyprint=<true> --userIp=<userIp> --locale=<locale> --strategy=<desktop|mobile> --format=<cli|json|tap>');
}

if (!query || process.argv.indexOf('-h') !== -1 || process.argv.indexOf('--help') !== -1) {
Expand All @@ -32,37 +31,41 @@ if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--version') !== -

opts.url = argv._[0];

if(!opts.url){
if (!opts.url) {
printHelp();
return;
}

if(argv.url){
if (argv.url) {
opts.url = argv.url;
}

if(argv.key){
if (argv.key) {
opts.key = argv.key;
}

if(argv.callback){
if (argv.callback) {
opts.callback = argv.callback;
}

if(argv.prettyprint){
if (argv.prettyprint) {
opts.prettyprint = argv.prettyprint;
}

if(argv.userIp){
if (argv.userIp) {
opts.userIp = argv.userIp;
}

if(argv.locale){
if (argv.locale) {
opts.locale = argv.locale;
}

if(argv.strategy){
if (argv.strategy) {
opts.strategy = argv.strategy;
}

if (argv.format) {
opts.format = argv.format;
}

insights(opts);
6 changes: 3 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
'use strict';
var pagespeed = require('gpagespeed');
var prependHttp = require('prepend-http');
var output = require('./output').init();
var output = require('./lib/output').init();

module.exports = function (opts, cb) {
opts = opts || {};
Expand All @@ -20,16 +20,16 @@ module.exports = function (opts, cb) {
}

opts.strategy = opts.strategy || 'desktop';
opts.format = opts.format || 'cli';
opts.nokey = opts.key === undefined;
opts.url = prependHttp(opts.url);

pagespeed(opts, function (err, data) {
pagespeed(opts, function (err, response) {
if (err) {
cb(err);
return;
}

var response = data;
output.process(opts, response, function(processErr) {
cb(processErr || err, response);
});
Expand Down
26 changes: 26 additions & 0 deletions lib/formats/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

var _ = require('lodash');
var chalk = require('chalk');
var utils = require('../utils');

exports.render = function (overview, statistics, ruleSetResults) {

var renderOverview = function (item) {
var color = item.label === 'Score' ? utils.scoreColor(item.value) : chalk.cyan;
return item.label + ':' + utils.buffer(item.label, 11) + color(item.value);
};

var renderSection = function (item) {
return utils.labelize(item.label) + chalk.cyan(item.value);
};

console.log([
utils.divider,
_.map(overview, renderOverview).join('\n') + '\n',
_.map(statistics, renderSection).join('\n'),
utils.labelize(''),
_.map(ruleSetResults, renderSection).join('\n'),
utils.divider
].join('\n'));
};
29 changes: 29 additions & 0 deletions lib/formats/json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

var _ = require('lodash');
var utils = require('../utils');

exports.render = function (overview, statistics, ruleSetResults) {

var mapSection = function (section) {
return utils.firstToUpperCaseAndAddSpace(section.label);
};

var zip = function (section, labelMapping) {
return _.zipObject(_.map(section, labelMapping), _.map(section, 'value'));
};

overview = zip(overview, 'label');
statistics = zip(statistics, mapSection);
ruleSetResults = zip(ruleSetResults, mapSection);
console.log(
JSON.stringify(
{
'overview': overview,
'statistics': statistics,
'ruleResults': ruleSetResults
},
undefined, 2
)
);
};
16 changes: 16 additions & 0 deletions lib/formats/tap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

exports.render = function (overview, statistics, ruleSetResults, threshold) {

var outputTest = function (overview, threshold) {
var score = overview[1].value;
var result = score < threshold ? 'not ok' : 'ok';
return result + ' 1 - psi';
};

console.log([
'TAP version 13',
'1..1',
outputTest(overview, threshold)
].join('\n'));
};
109 changes: 109 additions & 0 deletions lib/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'use strict';
// Based on the reporting in grunt-pagespeed by James Cryer
// TODO: Refactor further as this still uses patterns that
// are based on Grunt conventions.

var prettyBytes = require('pretty-bytes');

exports.init = function () {

/**
* @var {int} default threshold
*/
var threshold = 70;

/**
* Gather overview of PageSpeed results
*
* @param {String} url
* @param {String} strategy
* @param {String} score
* @return array
*/
var overview = function (url, strategy, score) {
var _results = [];
_results.push({label: 'URL', value: url});
_results.push({label: 'Score', value: score});
_results.push({label: 'Strategy', value: strategy});

return _results;
};

/**
* Gather and normalise rule results for PageSpeed result
*
* @param {Object} rulesets
* @return array
*/
var ruleSetResults = function (rulesets) {
var title;
var result;
var ruleImpact;
var _results = [];

for (title in rulesets) {
result = rulesets[title];
ruleImpact = Math.ceil(result.ruleImpact * 100) / 100;
_results.push({label: title, value: ruleImpact});
}

return _results;
};

/**
* Gather and normalise statistics for PageSpeed result
*
* @param {Object} statistics
* @return array
*/
var statistics = function (statistics) {
var title;
var result;
var _results = [];

for (title in statistics) {
result = title.indexOf('Bytes') !== -1 ?
prettyBytes(+statistics[title]) :
statistics[title];

_results.push({label: title, value: result});
}

return _results;
};

/**
* Loads the correct output format
*
* @param {String} formt
* @return Function
*/
var format = function (format) {
if (['cli', 'json', 'tap'].indexOf(format) === -1) {
format = 'cli';
}
return require('./formats/' + format).render;
};

return {
process: function (parameters, response, done) {
var error;
var renderer = format(parameters.format);
done = done || function () {};
threshold = parameters.threshold || threshold;

renderer(
overview(response.id, parameters.strategy, response.score),
statistics(response.pageStats),
ruleSetResults(response.formattedResults.ruleResults),
threshold
);

if (response.score < threshold) {
error = new Error('Threshold of ' + threshold + ' not met with score of ' + response.score);
}

return done(error);
}
};
};
2 changes: 1 addition & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/**
* utils
*
* Collection of functions for report output
Expand Down
81 changes: 0 additions & 81 deletions output.js

This file was deleted.

Loading

0 comments on commit 8d5651a

Please sign in to comment.