1
1
var fs = require ( 'fs' ) ;
2
- var path = require ( 'path' ) ;
3
2
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' ) ;
6
6
7
7
// packages inside the image server docker
8
- var request = require ( 'request' ) ;
9
8
var test = require ( 'tape' ) ;
9
+ var request = require ( 'request' ) ;
10
10
var gm = require ( 'gm' ) ;
11
11
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
+ }
16
59
17
- var touch = function ( fileName ) {
18
- fs . closeSync ( fs . openSync ( fileName , 'w' ) ) ;
19
- } ;
60
+ mockList = mockList . filter ( untestableFilter ) ;
20
61
62
+ if ( mockList . length === 0 ) {
63
+ throw new Error ( 'All mocks found with pattern ' + pattern + ' are currently untestable' ) ;
64
+ }
21
65
22
- // make artifact folders
23
- if ( ! fs . existsSync ( constants . pathToTestImagesDiff ) ) {
24
- fs . mkdirSync ( constants . pathToTestImagesDiff ) ;
66
+ // main
67
+ if ( isInQueue ) {
68
+ runInQueue ( mockList ) ;
25
69
}
26
- if ( ! fs . existsSync ( constants . pathToTestImages ) ) {
27
- fs . mkdirSync ( constants . pathToTestImages ) ;
70
+ else {
71
+ runInBatch ( mockList ) ;
28
72
}
29
73
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
+ }
31
91
32
- // run the test(s)
33
- if ( ! userFileName ) runAll ( ) ;
34
- else runSingle ( userFileName ) ;
92
+ function runInBatch ( mockList ) {
93
+ var running = 0 ;
35
94
36
- function runAll ( ) {
37
- test ( 'testing mocks' , function ( t ) {
95
+ // remove mapbox mocks if circle ci
38
96
39
- var fileNames = fs . readdirSync ( constants . pathToTestImageMocks ) ;
97
+ test ( 'testing mocks in batch' , function ( t ) {
98
+ t . plan ( mockList . length ) ;
40
99
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
+ } ) ;
43
104
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 ++ ;
59
113
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' ) ;
63
119
} ) ;
120
+ }
121
+ }
64
122
65
- t . plan ( mocks . length ) ;
123
+ function runInQueue ( mockList ) {
124
+ var index = 0 ;
66
125
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 ) ;
70
128
129
+ run ( mockList [ index ] , t ) ;
71
130
} ) ;
72
- }
73
131
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' ) ;
80
135
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
+ } ) ;
86
143
}
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
+ }
95
145
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 ) ;
101
150
102
151
function checkImage ( ) {
103
- running -- ;
104
-
105
- var options = {
106
- file : diffPath ,
152
+ var gmOpts = {
153
+ file : imagePaths . diff ,
107
154
highlightColor : 'purple' ,
108
155
tolerance : TOLERANCE
109
156
} ;
@@ -125,26 +172,30 @@ function testMock(fileName, t) {
125
172
*/
126
173
127
174
gm . compare (
128
- savedImagePath ,
129
- path . join ( constants . pathToTestImageBaselines , imageFileName ) ,
130
- options ,
175
+ imagePaths . test ,
176
+ imagePaths . baseline ,
177
+ gmOpts ,
131
178
onEqualityCheck
132
179
) ;
133
180
}
134
181
135
182
function onEqualityCheck ( err , isEqual ) {
136
183
if ( err ) {
137
- touch ( diffPath ) ;
138
- return console . error ( err , imageFileName ) ;
184
+ touch ( imagePaths . diff ) ;
185
+ return console . error ( err , mockName ) ;
139
186
}
140
187
if ( isEqual ) {
141
- fs . unlinkSync ( diffPath ) ;
188
+ fs . unlinkSync ( imagePaths . diff ) ;
142
189
}
143
190
144
- t . ok ( isEqual , imageFileName + ' should be pixel perfect' ) ;
191
+ cb ( isEqual , mockName ) ;
145
192
}
146
193
147
- request ( options )
148
- . pipe ( savedImageStream )
194
+ request ( requestOpts )
195
+ . pipe ( saveImageStream )
149
196
. on ( 'close' , checkImage ) ;
150
197
}
198
+
199
+ function touch ( filePath ) {
200
+ fs . closeSync ( fs . openSync ( filePath , 'w' ) ) ;
201
+ }
0 commit comments