Skip to content

Commit

Permalink
added configurable assertions - fix #139
Browse files Browse the repository at this point in the history
increased test coverage - #139

updated docs - #139

fix for minifier removing spaces in headline - #139
  • Loading branch information
stefanjudis committed Nov 30, 2014
1 parent 9469ed3 commit 6481855
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 42 deletions.
5 changes: 4 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ module.exports = function( grunt ) {
'consoleMessages' : 0,
'hiddenContentSize' : 65,
'jsErrors' : 0,
'gzipRequests' : 8,
'gzipRequests' : {
'type' : '<',
'value' : 8
},
'medianResponse' : 400,
'nodesWithInlineCSS' : 0,
'requests' : 30,
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ If you don't like the phantomas default styling and want to customize it, you ca
Type: `Object`
Default Value: `{}`

An object that represents possible assertions for your generated UI. Best way is to run `grunt-phantomas` once and setting these values afterwards for particular metrics. The UI will warn you whenever the `median` value of your defined runs of a specific metric will go over the specified value by highlighting depending graphs and showing warnings on top of the builded UI. Using this option you can easily keep track of getting worse values. Performance budget for the win. :)
An object that represents possible assertions for your generated UI. Best way is to run `grunt-phantomas` once and setting these values afterwards for particular metrics. The UI will warn you whenever the `median` value of your defined runs of a specific metric will go over the specified value by highlighting depending graphs and showing warnings on top of the built UI. Using this option you can easily keep track of getting worse values. Performance budget for the win. :)

Example:

Expand All @@ -69,9 +69,13 @@ phantomas : {
grunt : {
options : {
assertions : {
'assetsWithQueryString' : 3, // receive warning, when there are more than 3 assets with a query string
'bodyHTMLSize' : 10500, // receive warning, when the bodyHTMLsize is bigger than 10500
'jsErrors' : 0 // receive warning, when JS errors appear
assetsWithQueryString : 3, // receive warning, when there are more than 3 assets with a query string
bodyHTMLSize : 10500, // receive warning, when the bodyHTMLsize is bigger than 10500
jsErrors : 0, // receive warning, when more than 0 JS errors appear
gzipRequests : { // receive warning, when less compressed assets are loaded then 10 ( might be useful for checking server configurations )
type : '<',
value : 10
}
}
indexPath : './phantomas/',
options : {
Expand Down
1 change: 1 addition & 0 deletions tasks/assets/sass/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ $d-baseWidth : 98%;
*/
$z-filmstrip-time : 5;
$z-header : 6;
$z-loading : 5;


/**
Expand Down
14 changes: 9 additions & 5 deletions tasks/assets/sass/components/_graphs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,6 @@
fill : none;
}

> rect {
fill : $c-red;
stroke : none;
}

> text {
stroke : $c-white;
text-anchor : middle;
Expand All @@ -302,6 +297,15 @@
}
}

.p--lineChart--assertionBox {
fill : rgba( 255, 0, 0, 0.2 );
}

.p--lineChart--assertionTextBg {
fill : $c-red;
stroke : none;
}

.p--lineChart--areaLine {
fill : none;
stroke : $c-green;
Expand Down
77 changes: 63 additions & 14 deletions tasks/assets/scripts/phantomas.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,19 @@
circleContainer.datum( datum )
.append( 'circle' )
.attr( 'class', function( d ) {
return ( assertionValue && d.value[ type ] > assertionValue ) ?
'lineChart--circle failed' :
'lineChart--circle';
if ( assertionValue ) {
if ( assertionValue.type === '>' ) {
return ( d.value[ type ] > assertionValue.value ) ?
'lineChart--circle failed' :
'lineChart--circle';
} else {
return ( d.value[ type ] < assertionValue.value ) ?
'lineChart--circle failed' :
'lineChart--circle';
}
}

return 'lineChart--circle';
} )
.attr( 'r', 4 )
.attr(
Expand Down Expand Up @@ -144,9 +154,19 @@
.attr(
'class',
function( d ) {
return ( assertionValue && d.value[ type ] > assertionValue ) ?
'lineChart--circle highlighted failed' :
'lineChart--circle highlighted';
if ( assertionValue ) {
if ( assertionValue.type === '>' ) {
return ( assertionValue && d.value[ type ] > assertionValue.value ) ?
'lineChart--circle highlighted failed' :
'lineChart--circle highlighted';
} else {
return ( assertionValue && d.value[ type ] < assertionValue.value ) ?
'lineChart--circle highlighted failed' :
'lineChart--circle highlighted';
}
}

return 'lineChart--circle highlighted';
}
)
.attr( 'r', 6 );
Expand All @@ -156,9 +176,19 @@
.attr(
'class',
function( d ) {
return ( assertionValue && d.value[ type ] > assertionValue ) ?
'lineChart--circle failed' :
'lineChart--circle';
if ( assertionValue ) {
if ( assertionValue.type === '>' ) {
return ( d.value[ type ] > assertionValue.value ) ?
'lineChart--circle failed' :
'lineChart--circle';
} else {
return ( d.value[ type ] < assertionValue.value ) ?
'lineChart--circle failed' :
'lineChart--circle';
}
}

return 'lineChart--circle';
}
)
.attr( 'r', 4 );
Expand Down Expand Up @@ -237,7 +267,7 @@
var assertionValue = null;

if ( data[ data.length - 1 ].assertions[ metric ] ) {
assertionValue = data[ data.length - 1 ].assertions[ metric ].value;
assertionValue = data[ data.length - 1 ].assertions[ metric ];
}

// data manipulation first
Expand Down Expand Up @@ -310,9 +340,9 @@
0,
d3.max( data, function( d ) {
if ( d.value ) {
return ( d.value[ type ] > assertionValue ) ?
return ( !assertionValue || d.value[ type ] > assertionValue.value ) ?
d.value[ type ] :
assertionValue;
assertionValue.value;
} else {
return 0;
}
Expand Down Expand Up @@ -347,9 +377,27 @@
// add assertion graphics
if ( assertionValue !== null ) {
assertionGroup = svg.append( 'g' )
.attr( 'transform', 'translate( 0,' + y( assertionValue ) + ')' )
.attr( 'transform', 'translate( 0,' + y( assertionValue.value ) + ')' )
.attr( 'class', 'p--lineChart--assertion' );

if ( assertionValue.type === '>' ) {
assertionGroup.append( 'rect' )
.attr( 'class', 'p--lineChart--assertionBox' )
.attr( 'x', 0 )
.attr( 'y', -y( assertionValue.value ) )
.attr( 'width', width )
.attr( 'height', y( assertionValue.value ) )
.attr( 'fill', 'rgba( 255, 0, 0, 0.5 )' );
} else {
assertionGroup.append( 'rect' )
.attr( 'class', 'p--lineChart--assertionBox' )
.attr( 'x', 0 )
.attr( 'y', 0 )
.attr( 'width', width )
.attr( 'height', height - y( assertionValue.value ) )
.attr( 'fill', 'rgba( 255, 0, 0, 0.5 )' );
}

assertionGroup.append( 'line' )
.attr( 'x1', 0 )
.attr( 'y1', 0 )
Expand All @@ -358,6 +406,7 @@
.attr( 'class', 'p--lineChart--assertion' );

assertionGroup.append( 'rect' )
.attr( 'class', 'p--lineChart--assertionTextBg' )
.attr( 'width', 50 )
.attr( 'height', 20 )
.attr( 'x', 0 )
Expand All @@ -366,7 +415,7 @@
assertionGroup.append( 'text' )
.attr( 'x', 25 )
.attr( 'y', 4 )
.text( assertionValue );
.text( assertionValue.type + ' ' + assertionValue.value );
}

// Add the area path.
Expand Down
59 changes: 47 additions & 12 deletions tasks/lib/phantomas.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ var Phantomas = function( grunt, options, done ) {
this.failedAssertions = [];
this.grunt = grunt;
this.imagePath = path.normalize( options.indexPath + 'images/' );
this.options = options;
this.options = this.normalizeOptions( options );
this.timestamp = +new Date();
this.buildUi = options.buildUi;
};
Expand Down Expand Up @@ -346,13 +346,7 @@ Phantomas.prototype.executePhantomas = function() {
Phantomas.prototype.formResult = function( results ) {
this.grunt.log.ok( this.options.numberOfRuns + ' Phantomas execution(s) done -> checking results:' );
return new Promise( function( resolve ) {
var assertions = _.reduce( this.options.assertions, function( result, num, key ) {
result[ key ] = {
value : num
};

return result;
}, {} ),
var assertions = this.options.assertions,
entries = {},
offenders = {},
fulfilledPromise = _.filter( results, function( promise ) {
Expand Down Expand Up @@ -462,11 +456,27 @@ Phantomas.prototype.formResult = function( results ) {
// depending on median
// to failedAssertions sum up
if (
typeof this.options.assertions[ metric ] === 'number' &&
entry.median > this.options.assertions[ metric ] &&
_.indexOf( this.failedAssertions, metric ) === -1
typeof this.options.assertions[ metric ] !== 'undefined' &&
_.indexOf( this.failedAssertions, metric ) === -1 &&
(
this.options.assertions[ metric ].type === '>' ||
this.options.assertions[ metric ].type === '<'
) &&
typeof this.options.assertions[ metric ].value === 'number'
) {
this.failedAssertions.push( metric );
if (
this.options.assertions[ metric ].type === '>' &&
entry.median > this.options.assertions[ metric ].value
) {
this.failedAssertions.push( metric );
}

if (
this.options.assertions[ metric ].type === '<' &&
entry.median < this.options.assertions[ metric ].value
) {
this.failedAssertions.push( metric );
}
}
}

Expand Down Expand Up @@ -548,6 +558,31 @@ Phantomas.prototype.kickOff = function() {
};


/**
* Normalize the handed in options object
* to deal with legacy configs and different
* allowed option settings
*
* @param {Object} options options
* @return {Object} normalized options
*
* @tested
*/
Phantomas.prototype.normalizeOptions = function( options ) {

options.assertions = _.mapValues( options.assertions, function( assertion ) {
return ( typeof assertion === 'number' ) ?
{
type : '>',
value : assertion
} :
assertion;
} );

return options;
};


/**
* Notify about not displayed metrics during
* the build process
Expand Down
Loading

0 comments on commit 6481855

Please sign in to comment.