Skip to content

Commit a22c272

Browse files
committed
test: add example app with integration tests
1 parent 4699dc1 commit a22c272

30 files changed

Lines changed: 493 additions & 113 deletions

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ node_modules
1414
.eslintcache
1515

1616
# Build output
17-
/dist
17+
dist
18+
19+
# Turbo
20+
.turbo

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2023-2025 Drew Davis
3+
Copyright (c) 2023-2026 Drew Davis
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

apps/example/eslint.config.mjs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// @ts-check
2+
3+
import js from "@eslint/js";
4+
import prettier from "eslint-config-prettier";
5+
import { defineConfig, globalIgnores } from "eslint/config";
6+
import ts from "typescript-eslint";
7+
8+
export default defineConfig([
9+
globalIgnores(["dist"]),
10+
js.configs.recommended,
11+
...ts.configs.recommended,
12+
prettier,
13+
]);

apps/example/index.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Vite Plugin Serve Static Example</title>
7+
</head>
8+
<body>
9+
<main>
10+
<h1>Vite Plugin Serve Static Example</h1>
11+
<p>Quick links to the static test files:</p>
12+
<ul>
13+
<li><a href="/metadata.json">/metadata.json</a></li>
14+
<li><a href="/data/dog-treats">/data/dog-treats</a></li>
15+
<li><a href="/pages/index">/pages/index</a></li>
16+
</ul>
17+
</main>
18+
</body>
19+
</html>

apps/example/package.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "vite-plugin-serve-static-example-app",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"build": "vite build",
7+
"clean": "rimraf dist",
8+
"dev": "vite",
9+
"lint": "tsc && eslint --cache --max-warnings=0 .",
10+
"lint:fix": "tsc && eslint --fix --cache --max-warnings=0 .",
11+
"preview": "vite preview",
12+
"test": "vitest --run"
13+
},
14+
"devDependencies": {
15+
"vite-plugin-serve-static": "workspace:*",
16+
"rimraf": "^6.0.1",
17+
"typescript": "~5.7.2",
18+
"vite": "^7.3.0",
19+
"vitest": "^4.0.16"
20+
}
21+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
id,dog_name,favorite_treat
2+
1,Miso,peanut butter biscuit
3+
2,Pickles,cheddar cube
4+
3,Maple,frozen banana

apps/example/static/metadata.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"version": "1.3.2",
3+
"environment": "local",
4+
"build": {
5+
"commit": "4f9d7c1b2a6e4f0a9f0e9b1e2c3d4a5b6c7d8e9f",
6+
"timestamp": "2026-03-01T00:00:00Z"
7+
}
8+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Serve Static Playground</title>
6+
</head>
7+
<body>
8+
<h1>Serve Static Playground</h1>
9+
<p>Stashing tiny files for fast integration checks.</p>
10+
<p>Today's forecast: 100% chance of stable MIME types.</p>
11+
</body>
12+
</html>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import fs from "fs/promises";
2+
import path from "path";
3+
import { fileURLToPath } from "url";
4+
5+
import { createServer, ViteDevServer } from "vite";
6+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
7+
8+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
9+
const staticDir = path.resolve(__dirname, "..", "static");
10+
11+
describe("plugin integration", () => {
12+
let server: ViteDevServer;
13+
let baseUrl: string;
14+
15+
beforeAll(async () => {
16+
const configFile = path.resolve(__dirname, "..", "vite.config.ts");
17+
18+
server = await createServer({
19+
configFile,
20+
server: {
21+
port: 0,
22+
strictPort: false,
23+
},
24+
});
25+
26+
await server.listen();
27+
28+
const address = server.httpServer?.address();
29+
if (!address || typeof address === "string") throw new Error("Failed to start Vite dev server");
30+
31+
baseUrl = `http://localhost:${address.port}`;
32+
});
33+
34+
afterAll(async () => {
35+
await server?.close();
36+
});
37+
38+
it("serves a configured static JSON file", async () => {
39+
const response = await fetch(`${baseUrl}/metadata.json`);
40+
41+
const contentType = response.headers.get("content-type") ?? "";
42+
43+
expect(response.status).toBe(200);
44+
expect(contentType).toContain("application/json");
45+
46+
const expected = await fs.readFile(path.join(staticDir, "metadata.json"), "utf-8");
47+
await expect(response.text()).resolves.toBe(expected);
48+
});
49+
50+
it("serves files matched by a wildcard pattern", async () => {
51+
const response = await fetch(`${baseUrl}/data/dog-treats`);
52+
53+
const contentType = response.headers.get("content-type") ?? "";
54+
55+
expect(response.status).toBe(200);
56+
expect(contentType).toContain("text/csv");
57+
58+
const expected = await fs.readFile(path.join(staticDir, "data", "dog-treats.csv"), "utf-8");
59+
await expect(response.text()).resolves.toBe(expected);
60+
});
61+
62+
it("serves files matched by a capture group pattern", async () => {
63+
const response = await fetch(`${baseUrl}/pages/index`);
64+
65+
const contentType = response.headers.get("content-type") ?? "";
66+
67+
expect(response.status).toBe(200);
68+
expect(contentType).toContain("text/html");
69+
70+
const expected = await fs.readFile(path.join(staticDir, "pages", "index.html"), "utf-8");
71+
await expect(response.text()).resolves.toBe(expected);
72+
});
73+
74+
it("returns 404 for missing files", async () => {
75+
const response = await fetch(`${baseUrl}/data/missing`);
76+
77+
expect(response.status).toBe(404);
78+
await expect(response.text()).resolves.toBe("Not found");
79+
});
80+
});

apps/example/tsconfig.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"module": "ESNext",
5+
"moduleResolution": "Bundler",
6+
"allowImportingTsExtensions": true,
7+
"forceConsistentCasingInFileNames": true,
8+
"isolatedModules": true,
9+
"noEmit": true,
10+
"noImplicitOverride": true,
11+
"noImplicitReturns": true,
12+
"noPropertyAccessFromIndexSignature": true,
13+
"noUncheckedIndexedAccess": true,
14+
"noUnusedParameters": true,
15+
"skipLibCheck": true,
16+
"strict": true
17+
}
18+
}

0 commit comments

Comments
 (0)