import isEqual = require ( 'lodash/isEqual' ) ; import { Config , Results } from '../../shared/types' ; import * as storage from './storage' ; export const enum HintStatus { passed = 'passed' , failed = 'failed' , fixed = 'fixed' , fixing = 'fixing' } type ScanStatus = { config ? : Config ; hints : { [ id ] : number ; } ; url ? : string ; } ; const statusKey = `webhint-hint-status` ; /**
 * Extract pass/fail/fixing/fixed status for each hint from scan results.
 * A hint is considered fixed when passing after failing the previous scan.
 * Fixing is when the number of failures decreases between scans.
 *
 * To minimize false-positives for the 'fixing' and 'fixed' statuses, the
 * previous scan must occur on the same URL with the same configuration.
 */ export const determineHintStatus = ( config , results , s = storage ) : { [ key ] : HintStatus ; } => { const hintStatus = { } ; const status = { config , hints : { } , url : results . url } ; let saved = s . getItem ( statusKey ) ; if ( ! saved || ! saved . hints || status . url !== saved . url || ! isEqual ( saved . config , status . config ) ) { saved = { hints : { } } ; } for ( const category of results . categories ) { for ( const hint of category . hints ) { const hintKey = `hint-${ hint . id }` ; const savedCount = saved . hints [ hintKey ] || 0 ; status . hints [ hintKey ] = hint . problems . length ; if ( hint . problems . length ) { if ( savedCount > hint . problems . length ) { hintStatus [ hintKey ] = HintStatus . fixing ; } else { hintStatus [ hintKey ] = HintStatus . failed ; } } else if ( savedCount > 0 ) { hintStatus [ hintKey ] = HintStatus . fixed ; } else { hintStatus [ hintKey ] = HintStatus . passed ; } } } s . setItem ( statusKey , status ) ; return hintStatus ; } ;