Skip to content

Commit 849a357

Browse files
committed
get test coverage back
Signed-off-by: karthik2804 <[email protected]>
1 parent 39d3ebb commit 849a357

File tree

7 files changed

+197
-18
lines changed

7 files changed

+197
-18
lines changed

test/test-app/package-lock.json

Lines changed: 12 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/test-app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
},
2020
"dependencies": {
2121
"@spinframework/build-tools": "file:../../packages/build-tools",
22+
"@spinframework/spin-kv": "file:../../packages/spin-kv",
2223
"@spinframework/spin-variables": "file:../../packages/spin-variables",
23-
"@spinframework/spin-redis": "file:../../packages/spin-redis",
2424
"@spinframework/wasi-http-proxy": "file:../../packages/http-trigger",
2525
"itty-router": "^5.0.18"
2626
},

test/test-app/spin.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ component = "test-app"
1313
[component.test-app]
1414
source = "dist/test-app.wasm"
1515
exclude_files = ["**/node_modules"]
16+
allowed_outbound_hosts = ["http://localhost:3000"]
17+
key_value_stores = ["default"]
1618
[component.test-app.build]
1719
command = ["npm install", "npm run build"]
1820
watch = ["src/**/*.ts"]

test/test-app/src/helpers.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const decoder = new TextDecoder();
2+
const encoder = new TextEncoder();
3+
4+
export function isEqualBytes(
5+
bytes1: Uint8Array,
6+
bytes2: Uint8Array
7+
8+
): boolean {
9+
10+
if (bytes1.length !== bytes2.length) {
11+
return false;
12+
}
13+
14+
for (let i = 0; i < bytes1.length; i++) {
15+
if (bytes1[i] !== bytes2[i]) {
16+
return false;
17+
}
18+
}
19+
20+
return true;
21+
22+
}
23+
24+
export function sleep(ms: number) {
25+
return new Promise((resolve) => setTimeout(resolve, ms));
26+
}
27+
28+
export async function readStreamChunks(stream: ReadableStream) {
29+
const reader = stream.getReader();
30+
const chunks = [];
31+
32+
while (true) {
33+
const { done, value } = await reader.read();
34+
if (done) break;
35+
chunks.push(decoder.decode(value));
36+
}
37+
38+
return chunks;
39+
}
40+
41+
export async function pushStreamChunks(stream: WritableStream<any>, chunks: string[]) {
42+
const writer = stream.getWriter();
43+
44+
for (const chunk of chunks) {
45+
await writer.write(encoder.encode(chunk));
46+
await sleep(20);
47+
}
48+
49+
writer.close();
50+
}

test/test-app/src/index.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
// For AutoRouter documentation refer to https://itty.dev/itty-router/routers/autorouter
2-
import { AutoRouter } from 'itty-router';
3-
import * as Variables from '@spinframework/spin-variables';
1+
import { AutoRouter } from "itty-router"
2+
import { headersTest, health, kvTest, kvTestUint8Array, outboundHttp, statusTest, stream, streamTest, testFunctionality } from "./test";
43

5-
let router = AutoRouter();
4+
let router = AutoRouter()
65

7-
// Route ordering matters, the first route that matches will be used
8-
// Any route that does not return will be treated as a middleware
9-
// Any unmatched route will return a 404
10-
router
11-
.get("/", () => new Response("hello universe"))
12-
.get('/hello/:name', ({ name }) => `Hello, ${name}!`)
6+
router.get("/health", health)
7+
router.get("/stream", stream)
8+
router.get("/statusTest", statusTest)
9+
router.get("/headersTest", headersTest)
10+
router.get("/outboundHttp", outboundHttp)
11+
router.get("/kvTest", kvTest)
12+
router.get("/kvTestUint8Array", kvTestUint8Array)
13+
router.get("/streamTest", streamTest)
14+
router.get("/testFunctionality", testFunctionality)
1315

1416
//@ts-ignore
1517
addEventListener('fetch', async (event: FetchEvent) => {
16-
console.log(Variables.get('test'));
1718
event.respondWith(router.fetch(event.request));
18-
});
19+
});

test/test-app/src/test.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import * as Kv from "@spinframework/spin-kv";
2+
import { pushStreamChunks, isEqualBytes, readStreamChunks } from "./helpers";
3+
4+
const decoder = new TextDecoder()
5+
const streamingChunks = ["chunk1", "chunk2", "chunk3", "chunk4", "chunk5"]
6+
7+
function health(req: Request) {
8+
return new Response("Healthy", { status: 200 })
9+
}
10+
11+
function stream(req: Request) {
12+
const { readable, writable } = new TransformStream();
13+
pushStreamChunks(writable, streamingChunks)
14+
15+
// Return the stream as a Response
16+
return new Response(readable, {
17+
headers: { 'Content-Type': 'text/plain' },
18+
})
19+
}
20+
21+
function statusTest(req: Request) {
22+
return new Response(null, { status: 201 })
23+
}
24+
25+
function headersTest(req: Request) {
26+
return new Response(null, { headers: { "content-type": "text/html" } })
27+
}
28+
29+
async function outboundHttp(req: Request) {
30+
let requestUrl = "http://localhost:3000/health"
31+
let response = await fetch(requestUrl)
32+
if (response.status == 200) {
33+
if (await response.text() == "Healthy") {
34+
return new Response("success", { status: 200 })
35+
}
36+
}
37+
return new Response("failed", { status: 500 })
38+
}
39+
40+
function kvTest(req: Request) {
41+
let store = Kv.openDefault()
42+
store.set("test", "try")
43+
if (decoder.decode(store.get("test") || new Uint8Array()) == "try") {
44+
return new Response("success", { status: 200 })
45+
}
46+
return new Response("failed", { status: 500 })
47+
}
48+
49+
function kvTestUint8Array(req: Request) {
50+
let store = Kv.openDefault()
51+
52+
let arr = new Uint8Array([1, 2, 3])
53+
store.set("arr", arr)
54+
let ret = store.get("arr")
55+
56+
if (ret == null || !isEqualBytes(ret, arr)) {
57+
return new Response("failed", { status: 500 })
58+
}
59+
return new Response("success", { status: 200 })
60+
}
61+
62+
async function streamTest(req: Request) {
63+
let response = await fetch("http://localhost:3000/stream")
64+
65+
if (response.body == null) {
66+
return new Response("response has no body", { status: 500 })
67+
}
68+
69+
let chunks = await readStreamChunks(response.body)
70+
71+
if (chunks.length != streamingChunks.length) {
72+
return new Response("chunks length mismatch", { status: 500 })
73+
}
74+
75+
for (let i = 0; i < chunks.length; i++) {
76+
if (chunks[i] != streamingChunks[i]) {
77+
return new Response("chunks mismatch", { status: 500 })
78+
}
79+
}
80+
81+
return new Response("success", { status: 200 })
82+
}
83+
84+
async function testFunctionality(req: Request) {
85+
const testCases = [
86+
{ name: "statusTest", validate: (resp: Response) => resp.status === 201 },
87+
{ name: "headersTest", validate: (resp: Response) => resp.status === 200 && resp.headers.get("Content-Type") === "text/html" },
88+
{ name: "outboundHttp", validate: (resp: Response) => resp.status === 200 },
89+
{ name: "kvTest", validate: (resp: Response) => resp.status === 200 },
90+
{ name: "kvTestUint8Array", validate: (resp: Response) => resp.status === 200 },
91+
{ name: "streamTest", validate: (resp: Response) => resp.status === 200 },
92+
];
93+
94+
const results: { [key: string]: boolean } = {};
95+
96+
for (const test of testCases) {
97+
const resp = await fetch(`http://localhost:3000/${test.name}`);
98+
results[test.name] = test.validate(resp);
99+
}
100+
101+
const allPassed = Object.values(results).every(Boolean);
102+
let status = allPassed ? 200 : 500;
103+
return new Response(JSON.stringify(results, null, 2), { status });
104+
}
105+
106+
107+
export {
108+
health,
109+
stream,
110+
testFunctionality,
111+
headersTest,
112+
statusTest,
113+
outboundHttp,
114+
kvTest,
115+
kvTestUint8Array,
116+
streamTest
117+
}

test/test.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ SPIN_PID=$!
2222

2323
# wait for app to be up and running
2424
echo "Waiting for Spin app to be ready"
25-
timeout 60s bash -c 'until curl --silent -f http://localhost:3000/ > /dev/null; do sleep 2; done'
25+
timeout 60s bash -c 'until curl --silent -f http://localhost:3000/health > /dev/null; do sleep 2; done'
2626

2727
# start the test
2828
echo "Starting test\n"
29-
curl -f http://localhost:3000/ || isFailed=true
29+
curl -f http://localhost:3000/testFunctionality || isFailed=true
3030
echo "\n\nTest completed"
3131

3232
# kill the spin app

0 commit comments

Comments
 (0)