import { TextEncoder , TextDecoder } from "util" ; import { Macro } from "ava" ; import { Comment , DocumentHandlers , Element , ElementHandlers , HTMLRewriter as RawHTMLRewriter , TextChunk , } from ".." ; const encoder = new TextEncoder ( ) ; const decoder = new TextDecoder ( ) ; export class HTMLRewriter { private elementHandlers : [ selector : string , handlers : ElementHandlers ] [ ] = [ ] ; private documentHandlers : DocumentHandlers [ ] = [ ] ; on ( selector , handlers ) { this . elementHandlers . push ( [ selector , handlers ] ) ; return this ; } onDocument ( handlers ) { this . documentHandlers . push ( handlers ) ; return this ; } async transform ( input ) { let output = "" ; const rewriter = new RawHTMLRewriter ( ( chunk ) => { output += decoder . decode ( chunk ) ; } ) ; for ( const [ selector , handlers ] of this . elementHandlers ) { rewriter . on ( selector , handlers ) ; } for ( const handlers of this . documentHandlers ) { rewriter . onDocument ( handlers ) ; } try { await rewriter . write ( encoder . encode ( input ) ) ; await rewriter . end ( ) ; return output ; } finally { rewriter . free ( ) ; } } } export function wait ( t ) { return new Promise ( ( resolve ) => setTimeout ( resolve , t ) ) ; } export const mutationsMacro = async ( t , func , input , expected ) => { let res = await func ( new HTMLRewriter ( ) , ( token ) => { if ( "text" in token && ! token . text ) return ; token . before ( "<span>before</span>" ) ; token . before ( "<span>before html</span>" , { html : true } ) ; token . after ( "<span>after</span>" ) ; token . after ( "<span>after html</span>" , { html : true } ) ; } ) . transform ( input ) ; t . is ( res , expected . beforeAfter ) ; res = await func ( new HTMLRewriter ( ) , ( token ) => { if ( "text" in token && ! token . text ) return ; token . replace ( "<span>replace</span>" ) ; } ) . transform ( input ) ; t . is ( res , expected . replace ) ; res = await func ( new HTMLRewriter ( ) , ( token ) => { if ( "text" in token && ! token . text ) return ; token . replace ( "<span>replace</span>" , { html : true } ) ; } ) . transform ( input ) ; t . is ( res , expected . replaceHtml ) ; res = await func ( new HTMLRewriter ( ) , ( token ) => { if ( "text" in token && ! token . text ) return ; t . false ( token . removed ) ; token . remove ( ) ; t . true ( token . removed ) ; } ) . transform ( input ) ; t . is ( res , expected . remove ) ; } ;