3
3
const fs = require ( 'fs' ) ;
4
4
const path = require ( 'path' ) ;
5
5
const http = require ( 'http' ) ;
6
+ const os = require ( 'os' ) ;
6
7
const { chromium } = require ( 'playwright' ) ;
7
8
const { PNG } = require ( 'pngjs' ) ;
8
9
const pixelmatch = require ( 'pixelmatch' ) ;
9
10
const { optimize } = require ( '../lib/svgo.js' ) ;
10
11
11
- const chunkInto = ( array , chunksCount ) => {
12
- // take upper bound to include tail
13
- const chunkSize = Math . ceil ( array . length / chunksCount ) ;
14
- const result = [ ] ;
15
- for ( let i = 0 ; i < chunksCount ; i += 1 ) {
16
- const offset = i * chunkSize ;
17
- result . push ( array . slice ( offset , offset + chunkSize ) ) ;
18
- }
19
- return result ;
20
- } ;
21
-
22
12
const runTests = async ( { list } ) => {
23
13
let skipped = 0 ;
24
14
let mismatched = 0 ;
25
15
let passed = 0 ;
16
+ list . reverse ( ) ;
26
17
console . info ( 'Start browser...' ) ;
27
18
const processFile = async ( page , name ) => {
28
19
if (
@@ -48,8 +39,6 @@ const runTests = async ({ list }) => {
48
39
skipped += 1 ;
49
40
return ;
50
41
}
51
- const width = 960 ;
52
- const height = 720 ;
53
42
await page . goto ( `http://localhost:5000/original/${ name } ` ) ;
54
43
await page . setViewportSize ( { width, height } ) ;
55
44
const originalBuffer = await page . screenshot ( {
@@ -89,17 +78,19 @@ const runTests = async ({ list }) => {
89
78
}
90
79
}
91
80
} ;
81
+ const worker = async ( ) => {
82
+ let item ;
83
+ const page = await context . newPage ( ) ;
84
+ while ( ( item = list . pop ( ) ) ) {
85
+ await processFile ( page , item ) ;
86
+ }
87
+ await page . close ( ) ;
88
+ } ;
89
+
92
90
const browser = await chromium . launch ( ) ;
93
91
const context = await browser . newContext ( { javaScriptEnabled : false } ) ;
94
- const chunks = chunkInto ( list , 8 ) ;
95
92
await Promise . all (
96
- chunks . map ( async ( chunk ) => {
97
- const page = await context . newPage ( ) ;
98
- for ( const name of chunk ) {
99
- await processFile ( page , name ) ;
100
- }
101
- await page . close ( ) ;
102
- } ) ,
93
+ Array . from ( new Array ( os . cpus ( ) . length * 2 ) , ( ) => worker ( ) ) ,
103
94
) ;
104
95
await browser . close ( ) ;
105
96
console . info ( `Skipped: ${ skipped } ` ) ;
@@ -124,57 +115,48 @@ const readdirRecursive = async (absolute, relative = '') => {
124
115
return result ;
125
116
} ;
126
117
118
+ const width = 960 ;
119
+ const height = 720 ;
127
120
( async ( ) => {
128
121
try {
129
122
const start = process . hrtime . bigint ( ) ;
130
123
const fixturesDir = path . join ( __dirname , 'regression-fixtures' ) ;
131
124
const list = await readdirRecursive ( fixturesDir ) ;
132
- const originalFiles = new Map ( ) ;
133
- const optimizedFiles = new Map ( ) ;
134
- // read original and optimize
135
- let failed = 0 ;
136
- for ( const name of list ) {
125
+ // setup server
126
+ const server = http . createServer ( async ( req , res ) => {
127
+ const name = req . url . slice ( req . url . indexOf ( '/' , 1 ) ) ;
128
+ let file ;
137
129
try {
138
- const file = path . join ( fixturesDir , name ) ;
139
- const original = await fs . promises . readFile ( file , 'utf-8' ) ;
140
- const result = optimize ( original , { path : name , floatPrecision : 4 } ) ;
141
- if ( result . error ) {
142
- console . error ( result . error ) ;
143
- console . error ( `File: ${ name } ` ) ;
144
- failed += 1 ;
145
- } else {
146
- originalFiles . set ( name , original ) ;
147
- optimizedFiles . set ( name , result . data ) ;
148
- }
130
+ file = await fs . promises . readFile (
131
+ path . join ( fixturesDir , name ) ,
132
+ 'utf-8' ,
133
+ ) ;
149
134
} catch ( error ) {
150
- console . error ( error ) ;
151
- console . error ( `File: ${ name } ` ) ;
152
- failed += 1 ;
135
+ res . statusCode = 404 ;
136
+ res . end ( ) ;
137
+ return ;
153
138
}
154
- }
155
- if ( failed !== 0 ) {
156
- throw Error ( `Failed to optimize ${ failed } cases` ) ;
157
- }
158
- // setup server
159
- const server = http . createServer ( ( req , res ) => {
139
+
160
140
if ( req . url . startsWith ( '/original/' ) ) {
161
- const name = req . url . slice ( '/original/' . length ) ;
162
- if ( originalFiles . has ( name ) ) {
163
- res . setHeader ( 'Content-Type' , 'image/svg+xml' ) ;
164
- res . end ( originalFiles . get ( name ) ) ;
165
- return ;
166
- }
141
+ res . setHeader ( 'Content-Type' , 'image/svg+xml' ) ;
142
+ res . end ( file ) ;
143
+ return ;
167
144
}
168
145
if ( req . url . startsWith ( '/optimized/' ) ) {
169
- const name = req . url . slice ( '/optimized/' . length ) ;
170
- if ( optimizedFiles . has ( name ) ) {
171
- res . setHeader ( 'Content-Type' , 'image/svg+xml' ) ;
172
- res . end ( optimizedFiles . get ( name ) ) ;
173
- return ;
146
+ const optimized = optimize ( file , {
147
+ path : name ,
148
+ floatPrecision : 4 ,
149
+ } ) ;
150
+ if ( optimized . error ) {
151
+ throw new Error ( `Failed to optimize ${ name } ` , {
152
+ cause : optimized . error ,
153
+ } ) ;
174
154
}
155
+ res . setHeader ( 'Content-Type' , 'image/svg+xml' ) ;
156
+ res . end ( optimized . data ) ;
157
+ return ;
175
158
}
176
- res . statusCode = 404 ;
177
- res . end ( ) ;
159
+ throw new Error ( `unknown path ${ req . url } ` ) ;
178
160
} ) ;
179
161
await new Promise ( ( resolve ) => {
180
162
server . listen ( 5000 , resolve ) ;
0 commit comments