test: refactoring tests
This commit is contained in:
parent
3e46055845
commit
1c55b894c9
@ -265,6 +265,7 @@ export default function html(opts: RollupHtmlOptions = {}): Plugin {
|
|||||||
} while (nodeQueue.length > 0);
|
} while (nodeQueue.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Beware leak of AST (we're starting MagicString on a parsed and modified version of the HTML file, sourcemappings in the HTML file will be off. (can't add a sourcemap for a html file anyway, unless it is outputted as JS module)
|
||||||
let htmlJS = new MagicString(serializeHtml(htmlModule.document));
|
let htmlJS = new MagicString(serializeHtml(htmlModule.document));
|
||||||
htmlJS.replaceAll(/`/g,'\\\`').replaceAll(/\$\{/g,'\\${');
|
htmlJS.replaceAll(/`/g,'\\\`').replaceAll(/\$\{/g,'\\${');
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { rollup } from "rollup";
|
|||||||
import urlPlugin from "@rollup/plugin-url";
|
import urlPlugin from "@rollup/plugin-url";
|
||||||
|
|
||||||
import html from "../../src/index.ts";
|
import html from "../../src/index.ts";
|
||||||
import serveTest from "../util/test-server.ts";
|
import serveTest from "../util/serve-test.ts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {OutputOptions}
|
* @type {OutputOptions}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import typescriptPlugin from "@rollup/plugin-typescript";
|
|||||||
import replacePlugin from "@rollup/plugin-replace";
|
import replacePlugin from "@rollup/plugin-replace";
|
||||||
|
|
||||||
import html from "../../src/index.ts";
|
import html from "../../src/index.ts";
|
||||||
import serveTest from "../util/test-server.ts";
|
import serveTest from "../util/serve-test.ts";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -30,6 +30,7 @@ const output= {
|
|||||||
|
|
||||||
import {fileURLToPath} from "node:url";
|
import {fileURLToPath} from "node:url";
|
||||||
import handlebars from "handlebars";
|
import handlebars from "handlebars";
|
||||||
|
import {debugPrintOutput, getCode} from "../util/index.ts";
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
process.chdir(join(__dirname, 'fixtures'));
|
process.chdir(join(__dirname, 'fixtures'));
|
||||||
|
|
||||||
@ -86,5 +87,8 @@ test.serial('web-bundle', async (t) => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
const generated = await bundle.generate(output);
|
const generated = await bundle.generate(output);
|
||||||
|
|
||||||
|
// const code = await getCode(bundle, output);
|
||||||
|
// debugPrintOutput('jsx-web-app',code);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
export * from "./code-output.ts";
|
export * from "./code-output.ts";
|
||||||
export * from "./print-code-output.ts";
|
export * from "./print-code-output.ts";
|
||||||
export * from "./test-server.ts";
|
export * from "./serve-test.ts";
|
||||||
|
|
||||||
|
|
||||||
export * from './misc.js';
|
// export * from './misc.js';
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
// This is still from the old rollup plugin we forked from. For now not used.
|
||||||
|
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import process from "node:process";
|
import process from "node:process";
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import {isInDebugMode} from "./debug-mode.ts";
|
|||||||
|
|
||||||
|
|
||||||
export type PageTestCallback = (page: Page)=>Promise<void>;
|
export type PageTestCallback = (page: Page)=>Promise<void>;
|
||||||
|
|
||||||
export interface TestFilterOptions{
|
export interface TestFilterOptions{
|
||||||
html?: boolean
|
html?: boolean
|
||||||
console?: ('log'|'error'|'warn')[] | true
|
console?: ('log'|'error'|'warn')[] | true
|
||||||
@ -56,7 +57,7 @@ export interface TestOutput{
|
|||||||
* @param opts
|
* @param opts
|
||||||
* @param hostUrl
|
* @param hostUrl
|
||||||
*/
|
*/
|
||||||
export async function runTest(opts: Partial<TestOptions>, hostUrl: string){
|
export async function puppeteerRunTest(opts: Partial<TestOptions>, hostUrl: string){
|
||||||
const options : TestOptions = (<TestOptions>{
|
const options : TestOptions = (<TestOptions>{
|
||||||
...defaultOptions,
|
...defaultOptions,
|
||||||
...opts,
|
...opts,
|
||||||
@ -4,10 +4,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import {runTest, TestFilterOptions, PageTestCallback} from "./run-browser-test.ts";
|
import {puppeteerRunTest, TestFilterOptions, PageTestCallback} from "./puppeteer-run-test.ts";
|
||||||
import {isInDebugMode} from "./debug-mode.ts";
|
import {isInDebugMode} from "./debug-mode.ts";
|
||||||
|
|
||||||
import {resolve, posix} from "node:path";
|
import {resolve, posix} from "node:path";
|
||||||
|
import fs from "node:fs/promises";
|
||||||
|
import type {Stats} from "node:fs";
|
||||||
|
|
||||||
import { createServer as createHttpsServer } from 'https'
|
import { createServer as createHttpsServer } from 'https'
|
||||||
import { createServer} from 'http'
|
import { createServer} from 'http'
|
||||||
@ -26,6 +28,9 @@ import type {
|
|||||||
} from 'http'
|
} from 'http'
|
||||||
import type { ServerOptions } from 'https'
|
import type { ServerOptions } from 'https'
|
||||||
|
|
||||||
|
import type {ExecutionContext} from "ava";
|
||||||
|
import {createReadStream} from "fs";
|
||||||
|
|
||||||
|
|
||||||
type TypeMap = {
|
type TypeMap = {
|
||||||
[key: string]: string[];
|
[key: string]: string[];
|
||||||
@ -45,6 +50,11 @@ export interface RollupServeTestOptions {
|
|||||||
*/
|
*/
|
||||||
filterOutput?: TestFilterOptions;
|
filterOutput?: TestFilterOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback to serving from a specified srcDir
|
||||||
|
*/
|
||||||
|
srcDir?: string|boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback to manually take control of the page and simulate user interactions
|
* A callback to manually take control of the page and simulate user interactions
|
||||||
*/
|
*/
|
||||||
@ -52,7 +62,7 @@ export interface RollupServeTestOptions {
|
|||||||
/**
|
/**
|
||||||
* The AVA context used to test (ie t.snapshot(..) )
|
* The AVA context used to test (ie t.snapshot(..) )
|
||||||
*/
|
*/
|
||||||
t: any
|
t: ExecutionContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to `true` to return index.html (200) instead of error page (404)
|
* Set to `true` to return index.html (200) instead of error page (404)
|
||||||
@ -97,6 +107,7 @@ export interface RollupServeTestOptions {
|
|||||||
onListening?: (server: Server) => void
|
onListening?: (server: Server) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serve your rolled up bundle like webpack-dev-server
|
* Serve your rolled up bundle like webpack-dev-server
|
||||||
* @param {import('..').RollupServeOptions} options
|
* @param {import('..').RollupServeOptions} options
|
||||||
@ -107,6 +118,7 @@ export default function serveTest (options: RollupServeTestOptions ): Plugin {
|
|||||||
port: 0,
|
port: 0,
|
||||||
headers: {},
|
headers: {},
|
||||||
historyApiFallback: true,
|
historyApiFallback: true,
|
||||||
|
srcDir: '', // Serve source dir as fallback (for sourcemaps / debugging)
|
||||||
onListening: function noop (){},
|
onListening: function noop (){},
|
||||||
...options||{},
|
...options||{},
|
||||||
https: options.https??false,
|
https: options.https??false,
|
||||||
@ -116,7 +128,19 @@ export default function serveTest (options: RollupServeTestOptions ): Plugin {
|
|||||||
let server : Server;
|
let server : Server;
|
||||||
let bundle : OutputBundle = {};
|
let bundle : OutputBundle = {};
|
||||||
|
|
||||||
const requestListener = (request: IncomingMessage, response: ServerResponse) => {
|
const logTest = (msg: string, mode: 'info'|'warn' = 'info')=>{
|
||||||
|
if(isInDebugMode()){
|
||||||
|
console.log(msg);
|
||||||
|
}
|
||||||
|
const modeColor = {
|
||||||
|
green: 32,
|
||||||
|
info: 34,
|
||||||
|
warn: 33,
|
||||||
|
}[mode];
|
||||||
|
testOptions.t.log(`\u001b[${modeColor}m${msg}\u001b[0m`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestListener = async (request: IncomingMessage, response: ServerResponse) => {
|
||||||
// Remove querystring
|
// Remove querystring
|
||||||
const unsafePath = decodeURI(request.url!.split('?')[0])
|
const unsafePath = decodeURI(request.url!.split('?')[0])
|
||||||
|
|
||||||
@ -130,9 +154,20 @@ export default function serveTest (options: RollupServeTestOptions ): Plugin {
|
|||||||
function urlToFilePath(url:string){
|
function urlToFilePath(url:string){
|
||||||
return url[0]==='/'?url.slice(1):url;
|
return url[0]==='/'?url.slice(1):url;
|
||||||
}
|
}
|
||||||
let filePath = urlToFilePath(urlPath); // Todo check if we need to strip '/'
|
let filePath = urlToFilePath(urlPath);
|
||||||
let file: OutputChunk|OutputAsset;
|
let absPath: string | undefined = undefined;
|
||||||
if(!bundle[filePath] && testOptions.historyApiFallback) {
|
let stats: Stats | undefined = undefined;
|
||||||
|
|
||||||
|
if(!bundle[filePath]){
|
||||||
|
if(testOptions.srcDir || testOptions.srcDir===''){
|
||||||
|
try{
|
||||||
|
absPath = resolve(<string>testOptions.srcDir||'',filePath);
|
||||||
|
stats = await fs.stat(absPath);
|
||||||
|
}catch(err){
|
||||||
|
// File not found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!(stats?.isFile()) && testOptions.historyApiFallback) {
|
||||||
const fallbackPath = typeof testOptions.historyApiFallback === 'string'
|
const fallbackPath = typeof testOptions.historyApiFallback === 'string'
|
||||||
? testOptions.historyApiFallback
|
? testOptions.historyApiFallback
|
||||||
: '/index.html';
|
: '/index.html';
|
||||||
@ -140,12 +175,35 @@ export default function serveTest (options: RollupServeTestOptions ): Plugin {
|
|||||||
filePath = urlToFilePath(fallbackPath);
|
filePath = urlToFilePath(fallbackPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file = bundle[filePath];
|
}
|
||||||
if(!file){
|
|
||||||
return notFound(response, filePath);
|
const mimeType = mime.getType(filePath!);
|
||||||
}else{
|
if(bundle[filePath]) {
|
||||||
|
let file: OutputChunk | OutputAsset = bundle[filePath];
|
||||||
const content = (<OutputChunk>file).code || (<OutputAsset>file).source; // Todo might need to read a source file;
|
const content = (<OutputChunk>file).code || (<OutputAsset>file).source; // Todo might need to read a source file;
|
||||||
return found(response, mime.getType(filePath!), content);
|
response.writeHead(200, {'Content-Type': mimeType || 'text/plain'});
|
||||||
|
response.end(content, 'utf-8');
|
||||||
|
logTest(`[200] ${request.url}`);
|
||||||
|
return;
|
||||||
|
}else if(stats?.isFile()){
|
||||||
|
response.writeHead(200, {
|
||||||
|
'Content-Type': mimeType || 'text/plain',
|
||||||
|
'Content-Length': stats.size,
|
||||||
|
'Last-Modified': stats.mtime.toUTCString()
|
||||||
|
});
|
||||||
|
const content = await fs.readFile(absPath!);
|
||||||
|
response.end(content);
|
||||||
|
response.end();
|
||||||
|
logTest(`[200] ${request.url} (src)`);
|
||||||
|
}else{
|
||||||
|
response.writeHead(404)
|
||||||
|
response.end(
|
||||||
|
'404 Not Found' + '\n\n' + filePath,
|
||||||
|
'utf-8'
|
||||||
|
)
|
||||||
|
|
||||||
|
logTest(`[404] ${request.url}`, "warn");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +265,7 @@ export default function serveTest (options: RollupServeTestOptions ): Plugin {
|
|||||||
if (first) {
|
if (first) {
|
||||||
first = false
|
first = false
|
||||||
|
|
||||||
const testOutput = await runTest({
|
const testOutput = await puppeteerRunTest({
|
||||||
page: testOptions.path!,
|
page: testOptions.path!,
|
||||||
cb: testOptions.cb,
|
cb: testOptions.cb,
|
||||||
filterOutput: testOptions.filterOutput,
|
filterOutput: testOptions.filterOutput,
|
||||||
@ -221,21 +279,3 @@ export default function serveTest (options: RollupServeTestOptions ): Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function notFound (response: ServerResponse, filePath: string) {
|
|
||||||
response.writeHead(404)
|
|
||||||
response.end(
|
|
||||||
'404 Not Found' + '\n\n' + filePath,
|
|
||||||
'utf-8'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function found (response: ServerResponse, mimeType: string|null, content: any) {
|
|
||||||
response.writeHead(200, { 'Content-Type': mimeType || 'text/plain' })
|
|
||||||
response.end(content, 'utf-8')
|
|
||||||
}
|
|
||||||
|
|
||||||
function green (text: string) {
|
|
||||||
return '\u001b[1m\u001b[32m' + text + '\u001b[39m\u001b[22m'
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user