22
33const fs = require ( 'fs' ) ;
44const chalk = require ( 'chalk' ) ;
5+ const csslint = require ( 'csslint-mod' ) . default ;
56const glob = require ( 'fast-glob' ) ;
67const postcss = require ( 'postcss' ) ;
78const { SRC } = require ( './util' ) ;
89
910( async ( ) => {
10- let res ;
11- for ( const [ fn , msg ] of [
12- [ testGlobalCss ] ,
13- [ testParserlibOnFiles , 'Testing parserlib on all css files...' ] ,
14- ] ) {
15- if ( msg ) process . stdout . write ( msg ) ;
16- res = fn ( res ) ;
17- if ( res instanceof Promise ) res = await res ;
18- if ( msg ) console . log ( ' OK' ) ;
19- }
11+ testGlobalCss ( ) ;
12+ await testParserlibOnFiles ( ) ;
2013 console . log ( chalk . green ( 'CSS tests OK' ) ) ;
2114 process . exit ( 0 ) ;
2215} ) ( ) ;
@@ -36,25 +29,11 @@ function testGlobalCss() {
3629}
3730
3831async function testParserlibOnFiles ( ) {
39- const { default : parserlib } = await import ( 'csslint-mod/dist/parserlib.js' ) ;
40- const parser = new parserlib . css . Parser ( {
41- ieFilters : true ,
42- starHack : true ,
43- underscoreHack : true ,
44- } ) ;
45- let logStr = '' ;
46- parser . fire = ( e , tok = e ) => {
47- if ( ! parser . _events
48- && ( e . type === 'warning' || e . type === 'error' ) && ! / T E S T P A S S E D / . test ( e . message ) ) {
49- const p = e . property ;
50- logStr += ` * ${ tok . line } :${ tok . col } [${ e . type } ] ${ p ? p . text + ': ' : '' } ${ e . message } \n` ;
51- }
52- } ;
53- const opts = parser . options ;
54- let pc , pcPlugins , m ;
55- return Promise . all ( glob . sync ( SRC + '**/*.css' ) . map ( async file => {
56- process . stdout . write ( '.' ) ;
32+ let pc , pcPlugins , m , err ;
33+ const evidenceSize = 2 ;
34+ for ( const file of glob . sync ( SRC + '**/*.css' ) ) {
5735 let text = fs . readFileSync ( file , 'utf8' ) ;
36+ let lines ;
5837 if ( ( m = text . match ( / \/ \* \s * ( p o s t c s s - .+ ?) \s * \* \/ / ) ) ) {
5938 if ( m [ 1 ] !== pcPlugins ) {
6039 pcPlugins = m [ 1 ] ;
@@ -63,11 +42,28 @@ async function testParserlibOnFiles() {
6342 text = await pc . process ( text , { map : false , from : null } ) ;
6443 text = text . css ;
6544 }
66- opts . topDocOnly = true ; parser . parse ( text ) ;
67- opts . topDocOnly = false ; parser . parse ( text ) ;
68- opts . globalsOnly = true ; parser . parse ( text ) ;
69- opts . globalsOnly = false ;
70- if ( logStr ) fail ( 'parserlib' , `\n${ chalk . red ( file ) } \n${ logStr } ` ) ;
71- return [ file , text ] ;
72- } ) ) ;
45+ for ( m of csslint . verify ( text , {
46+ 'duplicate-properties' : 1 ,
47+ 'errors' : 2 ,
48+ 'known-properties' : 1 ,
49+ 'known-pseudos' : 1 ,
50+ 'selector-newline' : 1 ,
51+ 'simple-not' : 2 ,
52+ 'warnings' : 1 ,
53+ } ) . messages ) {
54+ lines ??= text . split ( '\n' ) ;
55+ const from = m . line - evidenceSize - 1 ;
56+ const evidence = lines . slice ( from , m . line + evidenceSize ) . map ( ( s , i ) => {
57+ i += from + 1 ;
58+ s = `${ i } : ${ s } \n` ;
59+ return '\t' + ( i === m . line ? chalk . underline ( s ) : s ) ;
60+ } ) ;
61+ const msg1 = `${ chalk . bold ( file . slice ( SRC . length ) ) } [${ m . rule . id } ] ${ m . message } \n` ;
62+ const isErr = m . type === 'error' ;
63+ console . log ( isErr ? chalk . red ( msg1 ) : msg1 ) ;
64+ console . log ( chalk . dim ( evidence . join ( '' ) ) ) ;
65+ err ||= isErr ;
66+ }
67+ }
68+ if ( err ) process . exit ( 1 ) ;
7369}
0 commit comments