2021-11-02 07:32:17 -07:00
import fs from 'fs' ;
import path from 'path' ;
import fm from 'front-matter' ;
import { createRequire } from 'module' ;
2019-04-25 09:42:38 -05:00
2021-11-02 07:32:17 -07:00
const require = createRequire ( import . meta . url ) ;
2019-04-25 09:42:38 -05:00
2019-04-26 21:00:40 -05:00
function node4Polyfills ( ) {
2019-04-25 09:42:38 -05:00
// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
if ( ! String . prototype . padEnd ) {
// eslint-disable-next-line no-extend-native
2019-04-26 21:00:40 -05:00
String . prototype . padEnd = function padEnd ( targetLength , padString ) {
2019-04-25 09:42:38 -05:00
targetLength = targetLength >> 0 ; // floor if number or convert non-number to 0;
padString = String ( ( typeof padString !== 'undefined' ? padString : ' ' ) ) ;
if ( this . length > targetLength ) {
return String ( this ) ;
} else {
targetLength = targetLength - this . length ;
if ( targetLength > padString . length ) {
padString += padString . repeat ( targetLength / padString . length ) ; // append to original to ensure we are longer than needed
}
return String ( this ) + padString . slice ( 0 , targetLength ) ;
}
} ;
}
// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
if ( ! String . prototype . padStart ) {
// eslint-disable-next-line no-extend-native
2019-04-26 21:00:40 -05:00
String . prototype . padStart = function padStart ( targetLength , padString ) {
2019-04-25 09:42:38 -05:00
targetLength = targetLength >> 0 ; // truncate if number, or convert non-number to 0;
padString = String ( typeof padString !== 'undefined' ? padString : ' ' ) ;
if ( this . length >= targetLength ) {
return String ( this ) ;
} else {
targetLength = targetLength - this . length ;
if ( targetLength > padString . length ) {
padString += padString . repeat ( targetLength / padString . length ) ; // append to original to ensure we are longer than needed
}
return padString . slice ( 0 , targetLength ) + String ( this ) ;
}
} ;
}
}
node4Polyfills ( ) ;
2021-11-02 07:32:17 -07:00
export function outputCompletionTable ( title , specs ) {
2019-04-25 09:42:38 -05:00
let longestName = 0 ;
let maxSpecs = 0 ;
for ( const section in specs ) {
longestName = Math . max ( section . length , longestName ) ;
maxSpecs = Math . max ( specs [ section ] . total , maxSpecs ) ;
}
const maxSpecsLen = ( '' + maxSpecs ) . length ;
const spaces = maxSpecsLen * 2 + longestName + 11 ;
console . log ( '-' . padEnd ( spaces + 4 , '-' ) ) ;
console . log ( ` | ${ title . padStart ( Math . ceil ( ( spaces + title . length ) / 2 ) ) . padEnd ( spaces ) } | ` ) ;
console . log ( ` | ${ ' ' . padEnd ( spaces ) } | ` ) ;
for ( const section in specs ) {
console . log ( ` | ${ section . padEnd ( longestName ) } ${ ( '' + specs [ section ] . pass ) . padStart ( maxSpecsLen ) } of ${ ( '' + specs [ section ] . total ) . padStart ( maxSpecsLen ) } ${ ( 100 * specs [ section ] . pass / specs [ section ] . total ) . toFixed ( ) . padStart ( 4 ) } % | ` ) ;
}
console . log ( '-' . padEnd ( spaces + 4 , '-' ) ) ;
console . log ( ) ;
}
2021-11-02 07:32:17 -07:00
export function loadFiles ( dir ) {
2019-04-25 09:42:38 -05:00
const files = fs . readdirSync ( dir ) ;
return files . reduce ( ( obj , file ) => {
const ext = path . extname ( file ) ;
const name = path . basename ( file , ext ) ;
const absFile = path . join ( dir , file ) ;
let specs ;
switch ( ext ) {
case '.md' : {
const content = fm ( fs . readFileSync ( absFile , 'utf8' ) ) ;
2019-07-01 09:33:25 -05:00
const skip = content . attributes . skip ;
delete content . attributes . skip ;
const only = content . attributes . only ;
delete content . attributes . only ;
2019-04-25 09:42:38 -05:00
specs = [ {
section : name ,
markdown : content . body ,
html : fs . readFileSync ( absFile . replace ( /[^.]+$/ , 'html' ) , 'utf8' ) ,
2019-07-01 09:33:25 -05:00
options : content . attributes ,
2019-07-01 08:07:36 -05:00
only ,
skip
2019-04-25 09:42:38 -05:00
} ] ;
break ;
}
2021-11-02 07:32:17 -07:00
case '.cjs' :
2019-04-25 09:42:38 -05:00
case '.json' : {
2021-11-02 07:32:17 -07:00
try {
specs = require ( absFile ) ;
} catch ( err ) {
console . log ( ` Error loading ${ absFile } ` ) ;
throw err ;
}
2019-04-25 09:42:38 -05:00
if ( ! Array . isArray ( specs ) ) {
specs = [ specs ] ;
}
break ;
}
default :
return obj ;
}
for ( const spec of specs ) {
if ( ! spec . section ) {
spec . section = name ;
}
if ( ! obj [ spec . section ] ) {
obj [ spec . section ] = {
total : 0 ,
pass : 0 ,
specs : [ ]
} ;
}
obj [ spec . section ] . total ++ ;
obj [ spec . section ] . pass += spec . shouldFail ? 0 : 1 ;
obj [ spec . section ] . specs . push ( spec ) ;
}
return obj ;
} , { } ) ;
}