11var fs = require ( 'fs' ) ;
2- var path = require ( 'path' ) ;
32
4- var constants = require ( '../../tasks/util/constants' ) ;
5- var getOptions = require ( '../../tasks/util/get_image_request_options' ) ;
3+ var getMockList = require ( './assets/get_mock_list' ) ;
4+ var getRequestOpts = require ( './assets/get_image_request_options' ) ;
5+ var getImagePaths = require ( './assets/get_image_paths' ) ;
66
77// packages inside the image server docker
8- var request = require ( 'request' ) ;
98var test = require ( 'tape' ) ;
9+ var request = require ( 'request' ) ;
1010var gm = require ( 'gm' ) ;
1111
12- var TOLERANCE = 1e-6 ; // pixel comparison tolerance
13- var BASE_TIMEOUT = 500 ; // base timeout time
14- var BATCH_SIZE = 5 ; // size of each test 'batch'
15- var running = 0 ; // number of tests currently running
12+ // pixel comparison tolerance
13+ var TOLERANCE = 1e-6 ;
14+
15+ // wait time between each test batch
16+ var BATCH_WAIT = 500 ;
17+
18+ // number of tests in each test batch
19+ var BATCH_SIZE = 5 ;
20+
21+ // wait time between each test in test queue
22+ var QUEUE_WAIT = 10 ;
23+
24+ /**
25+ * Image pixel comparison test script.
26+ *
27+ * Called by `tasks/test_image.sh in `npm run test-image`.
28+ *
29+ * CLI arguments:
30+ *
31+ * 1. 'pattern' :
32+ * glob determining which mock(s) are to be tested
33+ * 2. --queue :
34+ * if sent, the image will be run in queue instead of in batch.
35+ * Makes the test run significantly longer, but is Recommended on weak hardware.
36+ *
37+ * Examples:
38+ *
39+ * Run all tests in batch:
40+ *
41+ * npm run test-image
42+ *
43+ * Run the 'contour_nolines' test:
44+ *
45+ * npm run test-image -- contour_nolines
46+ *
47+ * Run all gl3d image test in queue:
48+ *
49+ * npm run test-image -- gl3d_* --queue
50+ */
51+
52+ var pattern = process . argv [ 2 ] ;
53+ var mockList = getMockList ( pattern ) ;
54+ var isInQueue = ( process . argv [ 3 ] === '--queue' ) ;
55+
56+ if ( mockList . length === 0 ) {
57+ throw new Error ( 'No mocks found with pattern ' + pattern ) ;
58+ }
1659
17- var touch = function ( fileName ) {
18- fs . closeSync ( fs . openSync ( fileName , 'w' ) ) ;
19- } ;
60+ mockList = mockList . filter ( untestableFilter ) ;
2061
62+ if ( mockList . length === 0 ) {
63+ throw new Error ( 'All mocks found with pattern ' + pattern + ' are currently untestable' ) ;
64+ }
2165
22- // make artifact folders
23- if ( ! fs . existsSync ( constants . pathToTestImagesDiff ) ) {
24- fs . mkdirSync ( constants . pathToTestImagesDiff ) ;
66+ // main
67+ if ( isInQueue ) {
68+ runInQueue ( mockList ) ;
2569}
26- if ( ! fs . existsSync ( constants . pathToTestImages ) ) {
27- fs . mkdirSync ( constants . pathToTestImages ) ;
70+ else {
71+ runInBatch ( mockList ) ;
2872}
2973
30- var userFileName = process . argv [ 2 ] ;
74+ /* Test cases:
75+ *
76+ * - font-wishlist
77+ * - all gl2d
78+ * - all mapbox
79+ *
80+ * don't behave consistently from run-to-run and/or
81+ * machine-to-machine; skip over them for now.
82+ *
83+ */
84+ function untestableFilter ( mockName ) {
85+ return ! (
86+ mockName === 'font-wishlist' ||
87+ mockName . indexOf ( 'gl2d_' ) !== - 1 ||
88+ mockName . indexOf ( 'mapbox_' ) !== - 1
89+ ) ;
90+ }
3191
32- // run the test(s)
33- if ( ! userFileName ) runAll ( ) ;
34- else runSingle ( userFileName ) ;
92+ function runInBatch ( mockList ) {
93+ var running = 0 ;
3594
36- function runAll ( ) {
37- test ( 'testing mocks' , function ( t ) {
95+ // remove mapbox mocks if circle ci
3896
39- var fileNames = fs . readdirSync ( constants . pathToTestImageMocks ) ;
97+ test ( 'testing mocks in batch' , function ( t ) {
98+ t . plan ( mockList . length ) ;
4099
41- // eliminate pollutants (e.g .DS_Store) that can accumulate in the mock directory
42- var allMocks = fileNames . filter ( function ( name ) { return name . slice ( - 5 ) === '.json' ; } ) ;
100+ for ( var i = 0 ; i < mockList . length ; i ++ ) {
101+ run ( mockList [ i ] , t ) ;
102+ }
103+ } ) ;
43104
44- /* Test cases:
45- *
46- * - font-wishlist
47- * - all gl2d
48- *
49- * don't behave consistently from run-to-run and/or
50- * machine-to-machine; skip over them.
51- *
52- */
53- var mocks = allMocks . filter ( function ( mock ) {
54- return ! (
55- mock === 'font-wishlist.json' ||
56- mock . indexOf ( 'gl2d' ) !== - 1
57- ) ;
58- } ) ;
105+ function run ( mockName , t ) {
106+ if ( running >= BATCH_SIZE ) {
107+ setTimeout ( function ( ) {
108+ run ( mockName , t ) ;
109+ } , BATCH_WAIT ) ;
110+ return ;
111+ }
112+ running ++ ;
59113
60- // skip mapbox mocks for now
61- mocks = mocks . filter ( function ( mock ) {
62- return mock . indexOf ( 'mapbox_' ) === - 1 ;
114+ // throttle the number of tests running concurrently
115+
116+ comparePixels ( mockName , function ( isEqual , mockName ) {
117+ running -- ;
118+ t . ok ( isEqual , mockName + ' should be pixel perfect' ) ;
63119 } ) ;
120+ }
121+ }
64122
65- t . plan ( mocks . length ) ;
123+ function runInQueue ( mockList ) {
124+ var index = 0 ;
66125
67- for ( var i = 0 ; i < mocks . length ; i ++ ) {
68- testMock ( mocks [ i ] , t ) ;
69- }
126+ test ( 'testing mocks in queue' , function ( t ) {
127+ t . plan ( mockList . length ) ;
70128
129+ run ( mockList [ index ] , t ) ;
71130 } ) ;
72- }
73131
74- function runSingle ( userFileName ) {
75- test ( 'testing single mock: ' + userFileName , function ( t ) {
76- t . plan ( 1 ) ;
77- testMock ( userFileName , t ) ;
78- } ) ;
79- }
132+ function run ( mockName , t ) {
133+ comparePixels ( mockName , function ( isEqual , mockName ) {
134+ t . ok ( isEqual , mockName + ' should be pixel perfect' ) ;
80135
81- function testMock ( fileName , t ) {
82- // throttle the number of tests running concurrently
83- if ( running >= BATCH_SIZE ) {
84- setTimeout ( function ( ) { testMock ( fileName , t ) ; } , BASE_TIMEOUT ) ;
85- return ;
136+ index ++ ;
137+ if ( index < mockList . length ) {
138+ setTimeout ( function ( ) {
139+ run ( mockList [ index ] , t ) ;
140+ } , QUEUE_WAIT ) ;
141+ }
142+ } ) ;
86143 }
87- running ++ ;
88-
89- var figure = require ( path . join ( constants . pathToTestImageMocks , fileName ) ) ;
90- var bodyMock = {
91- figure : figure ,
92- format : 'png' ,
93- scale : 1
94- } ;
144+ }
95145
96- var imageFileName = fileName . split ( '.' ) [ 0 ] + '.png' ;
97- var savedImagePath = path . join ( constants . pathToTestImages , imageFileName ) ;
98- var diffPath = path . join ( constants . pathToTestImagesDiff , 'diff-' + imageFileName ) ;
99- var savedImageStream = fs . createWriteStream ( savedImagePath ) ;
100- var options = getOptions ( bodyMock , 'http://localhost:9010/' ) ;
146+ function comparePixels ( mockName , cb ) {
147+ var requestOpts = getRequestOpts ( { mockName : mockName } ) ,
148+ imagePaths = getImagePaths ( mockName ) ,
149+ saveImageStream = fs . createWriteStream ( imagePaths . test ) ;
101150
102151 function checkImage ( ) {
103- running -- ;
104-
105- var options = {
106- file : diffPath ,
152+ var gmOpts = {
153+ file : imagePaths . diff ,
107154 highlightColor : 'purple' ,
108155 tolerance : TOLERANCE
109156 } ;
@@ -125,26 +172,30 @@ function testMock(fileName, t) {
125172 */
126173
127174 gm . compare (
128- savedImagePath ,
129- path . join ( constants . pathToTestImageBaselines , imageFileName ) ,
130- options ,
175+ imagePaths . test ,
176+ imagePaths . baseline ,
177+ gmOpts ,
131178 onEqualityCheck
132179 ) ;
133180 }
134181
135182 function onEqualityCheck ( err , isEqual ) {
136183 if ( err ) {
137- touch ( diffPath ) ;
138- return console . error ( err , imageFileName ) ;
184+ touch ( imagePaths . diff ) ;
185+ return console . error ( err , mockName ) ;
139186 }
140187 if ( isEqual ) {
141- fs . unlinkSync ( diffPath ) ;
188+ fs . unlinkSync ( imagePaths . diff ) ;
142189 }
143190
144- t . ok ( isEqual , imageFileName + ' should be pixel perfect' ) ;
191+ cb ( isEqual , mockName ) ;
145192 }
146193
147- request ( options )
148- . pipe ( savedImageStream )
194+ request ( requestOpts )
195+ . pipe ( saveImageStream )
149196 . on ( 'close' , checkImage ) ;
150197}
198+
199+ function touch ( filePath ) {
200+ fs . closeSync ( fs . openSync ( filePath , 'w' ) ) ;
201+ }
0 commit comments