@ -7,23 +7,19 @@
import * as fs from 'node:fs' ;
import * as fs from 'node:fs' ;
import { assert } from 'vitest' ;
import { assert } from 'vitest' ;
import { render , renderAsync } from 'svelte/server' ;
import { render , renderAsync } from 'svelte/server' ;
import {
import { compile_directory , should_update_expected , try_read_file } from '../helpers.js' ;
async_mode ,
compile_directory ,
should_update_expected ,
try_read_file
} from '../helpers.js' ;
import { assert_html_equal_with_options } from '../html_equal.js' ;
import { assert_html_equal_with_options } from '../html_equal.js' ;
import { suite , type BaseTest } from '../suite.js' ;
import { suite_with_variants , type BaseTest } from '../suite.js' ;
import type { CompileOptions } from '#compiler' ;
import type { CompileOptions } from '#compiler' ;
interface SSRTest extends BaseTest {
interface SSRTest extends BaseTest {
mode ? : ( 'sync' | 'async' ) [ ] ;
compileOptions? : Partial < CompileOptions > ;
compileOptions? : Partial < CompileOptions > ;
load_compiled? : boolean ;
load_compiled? : boolean ;
props? : Record < string , any > ;
props? : Record < string , any > ;
id_prefix? : string ;
id_prefix? : string ;
withoutNormalizeHtml? : boolean ;
withoutNormalizeHtml? : boolean ;
error s ?: string [ ] ;
error ?: string ;
}
}
// TODO remove this shim when we can
// TODO remove this shim when we can
@ -40,86 +36,101 @@ Promise.withResolvers = () => {
return { promise , resolve , reject } ;
return { promise , resolve , reject } ;
} ;
} ;
// eslint-disable-next-line no-console
const { test , run } = suite_with_variants < SSRTest , ' sync ' | ' async ' , CompileOptions > (
let console_error = console . error ;
[ 'sync' , 'async' ] ,
( variant , config , test_name ) = > {
if ( config . mode && ! config . mode . includes ( variant ) ) {
return 'no-test' ;
}
const { test , run } = suite < SSRTest > ( async ( config , test_dir ) = > {
if ( test_name . startsWith ( 'async' ) && variant === 'sync' ) {
const compile_options = {
return 'no-test' ;
experimental : {
}
async : async_mode ,
. . . config . compileOptions ? . experimental
} ,
. . . config . compileOptions
} ;
if ( ! config . load_compiled ) {
return false ;
await compile_directory ( test_dir , 'server' , compile_options ) ;
} ,
}
async ( config , test_dir ) = > {
const compile_options = {
experimental : {
async : true ,
. . . config . compileOptions ? . experimental
} ,
. . . config . compileOptions
} ;
if ( ! config . load_compiled ) {
await compile_directory ( test_dir , 'server' , compile_options ) ;
}
const errors : string [ ] = [ ] ;
return compile_options ;
} ,
console . error = ( . . . args ) = > {
async ( config , test_dir , variant , compile_options ) = > {
errors . push ( . . . args ) ;
const Component = ( await import ( ` ${ test_dir } /_output/server/main.svelte.js ` ) ) . default ;
} ;
const expected_html = try_read_file ( ` ${ test_dir } /_expected.html ` ) ;
let rendered ;
const Component = ( await import ( ` ${ test_dir } /_output/server/main.svelte.js ` ) ) . default ;
try {
const expected_html = try_read_file ( ` ${ test_dir } /_expected.html ` ) ;
rendered =
const rendered = async_mode
variant === 'async'
? await renderAsync ( Component , {
? await renderAsync ( Component , {
props : config.props || { } ,
props : config.props || { } ,
idPrefix : config.id_prefix
idPrefix : config.id_prefix
} )
} )
: render ( Component , {
: render ( Component , {
props : config.props || { } ,
props : config.props || { } ,
idPrefix : config.id_prefix
idPrefix : config.id_prefix
} ) ;
} ) ;
const { body , head } = rendered ;
} catch ( error ) {
if ( config . error ) {
assert . deepEqual ( ( error as Error ) . message , config . error ) ;
return ;
} else {
throw error ;
}
}
fs . writeFileSync ( ` ${ test_dir } /_output/rendered.html ` , body ) ;
const { body , head } = rendered ;
if ( head ) {
const prefix = variant === 'async' ? 'async_' : '' ;
fs . writeFileSync ( ` ${ test_dir } /_output/rendered_head.html ` , head ) ;
fs . writeFileSync ( ` ${ test_dir } /_output/ ${ prefix } rendered.html ` , body ) ;
}
try {
if ( head ) {
assert_html_equal_with_options ( body , expected_html || '' , {
fs . writeFileSync ( ` ${ test_dir } /_output/ ${ prefix } rendered_head.html ` , head ) ;
preserveComments : compile_options.preserveComments ,
withoutNormalizeHtml : config.withoutNormalizeHtml
} ) ;
} catch ( error : any ) {
if ( should_update_expected ( ) ) {
fs . writeFileSync ( ` ${ test_dir } /_expected.html ` , body ) ;
console . log ( ` Updated ${ test_dir } /_expected.html. ` ) ;
} else {
error . message += '\n' + ` ${ test_dir } /main.svelte ` ;
throw error ;
}
}
}
if ( fs . existsSync ( ` ${ test_dir } /_expected_head.html ` ) ) {
try {
try {
assert_html_equal_with_options (
assert_html_equal_with_options ( body , expected_html || '' , {
head ,
preserveComments : compile_options.preserveComments ,
fs . readFileSync ( ` ${ test_dir } /_expected_head.html ` , 'utf-8' ) ,
withoutNormalizeHtml : config.withoutNormalizeHtml
{ }
} ) ;
) ;
} catch ( error : any ) {
} catch ( error : any ) {
if ( should_update_expected ( ) ) {
if ( should_update_expected ( ) ) {
fs . writeFileSync ( ` ${ test_dir } /_expected_head.html ` , head ) ;
fs . writeFileSync ( ` ${ test_dir } /_expected.html ` , body ) ;
console . log ( ` Updated ${ test_dir } /_expected_head.html. ` ) ;
console . log ( ` Updated ${ test_dir } /_expected.html. ` ) ;
error . message += '\n' + ` ${ test_dir } /main.svelte ` ;
} else {
} else {
error . message += '\n' + ` ${ test_dir } /main.svelte ` ;
throw error ;
throw error ;
}
}
}
}
}
if ( errors . length > 0 ) {
if ( fs . existsSync ( ` ${ test_dir } /_expected_head.html ` ) ) {
assert . deepEqual ( config . errors , errors ) ;
try {
assert_html_equal_with_options (
head ,
fs . readFileSync ( ` ${ test_dir } /_expected_head.html ` , 'utf-8' ) ,
{ }
) ;
} catch ( error : any ) {
if ( should_update_expected ( ) ) {
fs . writeFileSync ( ` ${ test_dir } /_expected_head.html ` , head ) ;
console . log ( ` Updated ${ test_dir } /_expected_head.html. ` ) ;
error . message += '\n' + ` ${ test_dir } /main.svelte ` ;
} else {
throw error ;
}
}
}
}
}
) ;
console . error = console_error ;
} ) ;
export { test } ;
export { test } ;