Skip to content

Commit b37b260

Browse files
committed
01/02: add exercise texts
1 parent 5f23d24 commit b37b260

File tree

21 files changed

+593
-35
lines changed

21 files changed

+593
-35
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Multiple workspaces
2+
3+
Vitest is an extremely versatile testing framework. You can use it for your unit tests in Node.js, for your integration tests, for component-level testing with the [Browser Mode](https://vitest.dev/guide/browser/), for benchmarking... All within the same tool. But those are still quite different tests and as such, they may require different configurations to run.
4+
5+
You can configure multiple test projects, or [workspaces](https://vitest.dev/guide/workspace.html#defining-a-workspace), within the same repository to help Vitest differentiate between all the layers of testing you have. This is a great way to utilize Vitest to the fullest while implementing a great test coverage.
6+
7+
## Your task
8+
9+
This brings me to the application at hand, which has two testing layers: unit and integration tests. While the unit tests run in a regular Node.js environment, the integration tests are a bit different.
10+
11+
See, our application happened to use _edge functions_ (find them in `src/api`). We still have to test those functions in isolation but that's where a Node.js test won't cut it. Edge environment is fundamentally different from Node.js both in available APIs and behaviors.
12+
13+
So to test our edge functions we are going to use a _custom environment_ called `edge-runtime`. It's modelled after the common runtimes you can find in providers like Vercel or Netlify, and it will allow us to bring our edge functions to a similar habitat as production.
14+
15+
👨‍💼 In this exercise, your goal is to configure Vitest to have two different workspaces: one for the unit tests and another for the edge tests. Start from the instructions below.
16+
17+
🐨 First, install `edge-runtime`, `@edge-runtime/vm`, and `@edge-runtime/types` in your project. You will use these to procure the correct test environment for your edge functions.
18+
19+
```
20+
npm install edge-runtime @edge-runtime/vm @edge-runtime/types --save-dev
21+
```
22+
23+
🐨 Next, head to <InlineFile file="vitest.config.ts" /> and complete it to have two different workspaces defined. Use different filename patterns to apply workspaces to their respective tests: `**/*.test.ts` for unit tests and `**/*.edge.test.ts` for the edge tests.
24+
25+
🐨 Once the Vitest is configured, head to the test files at <InlineFile file="src/slugify.test.ts" /> and <InlineFile file="src/api/handler.edge.test.ts" /> and follow the instructions to write a few tests.
26+
27+
And, of course, run `npm test` to verify that all the tests are running in their correct environments and passing. Good luck!
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module '*?raw' {
2+
const src: string
3+
export default src
4+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"type": "module",
3+
"name": "exercises_01.setup_02.problem.multiple-workspaces",
4+
"scripts": {
5+
"test": "vitest",
6+
"build": "vite build"
7+
},
8+
"devDependencies": {
9+
"vitest": "^3.1.1"
10+
}
11+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// 🐨 Import the `EdgeRuntime` class from the `edge-runtime` package.
2+
// 💰 import { EdgeRuntime } from 'edge-runtime
3+
//
4+
// 🐨 Import your handler from the `./handler` module.
5+
// Use a "?raw" import modified to import it as a string.
6+
// 💰 import initialCode from './handler?raw'
7+
//
8+
// 🐨 Declare a new variable called `runtime`.
9+
// Assign it a new instance of `EdgeRuntime` that uses
10+
// the `initialCode` as its initial code.
11+
// 💰 const runtime = new EdgeRuntime({ initialCode })
12+
//
13+
// 🐨 Declare a new test case. Here, ensure that your edge
14+
// runtime handles HTTP requests correctly.
15+
// 💰 test('...', async () => {})
16+
//
17+
// 🐨 Inside the test, call `runtime.dispatchFetch(url)`
18+
// to perform a request.
19+
// 💰 const response = await runtime.dispatchFetch(url)
20+
//
21+
// 🐨 Finally, add an asynchronous assertion over `request.json()`
22+
// that validates the received response body against the
23+
// response returned from the "fetch" event listener in
24+
// the `./handler` module.
25+
// 💰 await expect(response.json()).resolves.toEqual(expected)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
addEventListener('fetch', (event) => {
2+
event.respondWith(
3+
Response.json({
4+
id: 'abc-123',
5+
name: 'John Maverick',
6+
}),
7+
)
8+
})
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { slugify } from './slugify'
2+
3+
// 🐨 Create a new test case for the `slugify` function`.
4+
// In this one, ensure that calling that function with a "hello world"
5+
// as the argument returns the correct slugified string.
6+
// 💰 test('...', () => {})
7+
// 💰 expect(actual).toBe(expected)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function slugify(input: string): string {
2+
return input.replace(/\s+/g, '-')
3+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "./tsconfig.base.json",
3+
"include": ["src/**/*"],
4+
"exclude": ["src/**/*.test.ts"],
5+
"compilerOptions": {
6+
"lib": ["esnext"]
7+
}
8+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ESNext",
4+
"module": "ESNext",
5+
"useDefineForClassFields": true,
6+
"skipLibCheck": true,
7+
8+
/* Bundler mode */
9+
"moduleResolution": "bundler",
10+
"allowImportingTsExtensions": true,
11+
"isolatedModules": true,
12+
"moduleDetection": "force",
13+
"noEmit": true,
14+
"verbatimModuleSyntax": true,
15+
16+
/* Linting */
17+
"strict": true,
18+
"noUnusedLocals": false,
19+
"noUnusedParameters": false,
20+
"noFallthroughCasesInSwitch": true,
21+
"noUncheckedSideEffectImports": true
22+
}
23+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "./tsconfig.base.json",
3+
"include": ["src/api"],
4+
"exclude": ["**/*.test.ts"],
5+
"compilerOptions": {
6+
"lib": [],
7+
"types": ["@types/node", "@edge-runtime/types"]
8+
}
9+
}

0 commit comments

Comments
 (0)