import assert from 'assert'; import * as fs from 'fs'; import * as path from 'path'; import { addLineNumbers, loadConfig, setupHtmlEqual, svelte, tryToLoadJson } from '../helpers.js'; function tryToReadFile ( file ) { try { return fs.readFileSync( file, 'utf-8' ); } catch ( err ) { if ( err.code !== 'ENOENT' ) throw err; return null; } } function capitalize ( str ) { return str[0].toUpperCase() + str.slice( 1 ); } describe( 'ssr', () => { before( () => { require( process.env.COVERAGE ? '../../src/server-side-rendering/register.js' : '../../ssr/register' ); return setupHtmlEqual(); }); fs.readdirSync( 'test/server-side-rendering/samples' ).forEach( dir => { if ( dir[0] === '.' ) return; // add .solo to a sample directory name to only run that test, or // .show to always show the output. or both const solo = /\.solo/.test( dir ); let show = /\.show/.test( dir ); if ( solo && process.env.CI ) { throw new Error( 'Forgot to remove `solo: true` from test' ); } ( solo ? it.only : it )( dir, () => { dir = path.resolve( 'test/server-side-rendering/samples', dir ); const component = require( `${dir}/main.html` ); const expectedHtml = tryToReadFile( `${dir}/_expected.html` ); const expectedCss = tryToReadFile( `${dir}/_expected.css` ) || ''; const data = tryToLoadJson( `${dir}/data.json` ); let html; let css; let error; try { html = component.render( data ); css = component.renderCss().css; } catch ( e ) { show = true; error = e; } if ( show ) { fs.readdirSync( dir ).forEach( file => { if ( file[0] === '_' ) return; const source = fs.readFileSync( `${dir}/${file}`, 'utf-8' ); const name = capitalize( file.slice( 0, -path.extname( file ).length ) ); const { code } = svelte.compile( source, { generate: 'ssr', name }); console.group( file ); console.log( addLineNumbers( code ) ); console.groupEnd(); }); } if ( error ) throw error; fs.writeFileSync( `${dir}/_actual.html`, html ); if ( css ) fs.writeFileSync( `${dir}/_actual.css`, css ); assert.htmlEqual( html, expectedHtml ); assert.equal( css.replace( /^\s+/gm, '' ), expectedCss.replace( /^\s+/gm, '' ) ); }); }); // duplicate client-side tests, as far as possible fs.readdirSync( 'test/runtime/samples' ).forEach( dir => { if ( dir[0] === '.' ) return; const config = loadConfig( `./runtime/samples/${dir}/_config.js` ); if ( config.solo && process.env.CI ) { throw new Error( 'Forgot to remove `solo: true` from test' ); } if ( config['skip-ssr'] ) return; ( config.skip ? it.skip : config.solo ? it.only : it )( dir, () => { let compiled; try { const source = fs.readFileSync( `test/runtime/samples/${dir}/main.html`, 'utf-8' ); compiled = svelte.compile( source, { generate: 'ssr' }); } catch ( err ) { if ( config.compileError ) { config.compileError( err ); return; } else { throw err; } } const resolved = require.resolve( `../runtime/samples/${dir}/main.html` ); delete require.cache[ resolved ]; const component = require( resolved ); let html; try { html = component.render( config.data ); if ( config.html ) { assert.htmlEqual( html, config.html ); } } catch ( err ) { console.log( addLineNumbers( compiled.code ) ); // eslint-disable-line no-console throw err; } }); }); });