Skip to content

Commit

Permalink
Tests (#24)
Browse files Browse the repository at this point in the history
* Installs vitest

* Unit tests footer

* Uses beforeEach

* Unit tests kw-links

* Tests p-l component

* Unit tests rel posts component

* Shared var for mock values

* Unit tests HN link

* Manually runs cleanup to remove DOM elements

* Formatting

* Global teardown after each test

* Shared helper

* Formatting

* Uses svelte API to update inputs

* Imports extender before every setup file
  • Loading branch information
kyle-n committed Oct 23, 2023
1 parent 52ea722 commit 7e21802
Show file tree
Hide file tree
Showing 14 changed files with 2,289 additions and 44 deletions.
2,165 changes: 2,129 additions & 36 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"scripts": {
"dev": "vite dev",
"build": "vite build",
"test": "vitest run",
"test:watch": "vitest",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
Expand All @@ -23,6 +25,7 @@
"@pondorasti/remark-img-links": "^1.0.8",
"@sveltejs/adapter-static": "^2.0.3",
"@sveltejs/kit": "^1.20.4",
"@testing-library/svelte": "^4.0.4",
"@types/html-minifier": "^4.0.3",
"@types/jsdom": "^21.1.3",
"@types/showdown": "^2.0.1",
Expand All @@ -32,6 +35,7 @@
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte": "^2.30.0",
"html-minifier": "^4.0.0",
"jest-dom": "^4.0.0",
"mdsvex": "^0.11.0",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.10.1",
Expand All @@ -41,7 +45,9 @@
"svelte-check": "^3.4.3",
"tslib": "^2.4.1",
"typescript": "^5.2.2",
"vite": "^4.4.2"
"vite": "^4.4.2",
"vitest": "^0.34.6",
"vitest-dom": "^0.1.1"
},
"type": "module",
"prettier": {
Expand Down
6 changes: 3 additions & 3 deletions posts/explaining-docker-through-an-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ At my first job, our company made an app for iPhone and Android. The app used [I

Our app worked fine most of the time. Customers would request new features, we'd add them and ship a new copy of the app to the Android and iOS app stores.

The problem was whenever a new developer joined the team, they couldn't build the app to run on a test phone. In order to build the app, you had to install a specific version of [OpenJDK](https://openjdk.org/) (*not* the latest) and a bunch of other Android command-line tools. *Then* you had to set a bunch of global bash variables so all these programs pointed at each other.
The problem was whenever a new developer joined the team, they couldn't build the app to run on a test phone. In order to build the app, you had to install a specific version of [OpenJDK](https://openjdk.org/) (_not_ the latest) and a bunch of other Android command-line tools. _Then_ you had to set a bunch of global bash variables so all these programs pointed at each other.

Even with experience on the command line, it took me an entire day to set up everything the app needed.

Our DevOps person, who was unaware the app required so much setup, watched this with horror. He decided nobody should ever have to go through what I went through again.

The DevOps person spent some time putting together a Docker container. This Docker container was basically a tiny command-line environment where everything was set up *perfectly*. It always had the right version of OpenJDK, the right bash variables and everything else you needed to build the app.
The DevOps person spent some time putting together a Docker container. This Docker container was basically a tiny command-line environment where everything was set up _perfectly_. It always had the right version of OpenJDK, the right bash variables and everything else you needed to build the app.

Once he'd made the container, he gave it to everyone on the frontend team. Now, when we wanted to build the app, we ran a single command, and the Docker container would build it for us. You didn't have to have anything else installed on your PC.

This was, obviously, a huge help. When we got new developers, or an existing developer got a new laptop, all they had to do was download the Docker container.

It also made technical upgrades easier. If the app needed a newer version of some Android command-line tool, the DevOps person could upgrade it once, in the container, and everyone would get the new version next time they did a build and ran the container. It was great!
It also made technical upgrades easier. If the app needed a newer version of some Android command-line tool, the DevOps person could upgrade it once, in the container, and everyone would get the new version next time they did a build and ran the container. It was great!
1 change: 0 additions & 1 deletion posts/markdown-images-for-sveltekit-blogs.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,3 @@ Now when writing Markdown, you can simply put:
```

No `<script>` import, no `{base}` - just put the filename of the image at the folder indicated by the `absolutePath` in your `svelte.config.js`.

2 changes: 1 addition & 1 deletion src/lib/components/all-keywords-link.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
a {
font-size: 24px;
}
</style>
</style>
2 changes: 1 addition & 1 deletion src/lib/components/footer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<hr />
<footer>
<p>© {copyrightYear} Kyle Nazario</p>
<p data-testid="copyright">© {copyrightYear} Kyle Nazario</p>
<RssLink />
</footer>

Expand Down
14 changes: 14 additions & 0 deletions src/lib/components/footer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { describe, test, expect, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/svelte';
import Footer from './footer.svelte';

describe('Footer', () => {
beforeEach(() => {
render(Footer);
});

test('displays copyright for current year', () => {
const currentYear = new Date().getFullYear();
expect(screen.getByTestId('copyright').textContent).toContain(currentYear);
});
});
18 changes: 18 additions & 0 deletions src/lib/components/keyword-links.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { describe, test, expect } from 'vitest';
import { render, screen } from '@testing-library/svelte';
import KeywordLinks from './keyword-links.svelte';

describe('KeywordLinks', () => {
test('displays keywords', () => {
render(KeywordLinks, { keywords: 'foo, bar' });

expect(screen.getByText('#foo')).toBeInTheDocument();
expect(screen.getByText('#bar')).toBeInTheDocument();
});

test('hides component entirely with no keywords', () => {
const { container } = render(KeywordLinks, { keywords: undefined });

expect(container.querySelector('div')?.childElementCount).toBe(0);
});
});
13 changes: 13 additions & 0 deletions src/lib/components/pagination-links.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { describe, test, expect } from 'vitest';
import { render, screen } from '@testing-library/svelte';
import PaginationLinks from './pagination-links.svelte';

describe('PaginationLinks', () => {
test('displays pagination links', () => {
render(PaginationLinks, { currentPage: 1, totalPageCount: 3 });

expect(screen.getByText('1')).toBeInTheDocument();
expect(screen.getByText('2')).toBeInTheDocument();
expect(screen.getByText('3')).toBeInTheDocument();
});
});
86 changes: 86 additions & 0 deletions src/lib/components/related-posts.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { describe, test, expect, beforeEach, vi } from 'vitest';
import { render, screen } from '@testing-library/svelte';
import RelatedPosts from './related-posts.svelte';
import type { PostLink } from '$lib/types';
import { whenStable } from '../../tests/helpers';

const { mockRelatedPosts } = vi.hoisted(() => ({
mockRelatedPosts: [
{
metadata: {
layout: 'post',
title: 'foo title',
description: 'foo',
date: 'foo',
image: 'foo',
caption: 'foo',
keywords: 'foo'
},
postPath: 'foo'
}
] as PostLink[]
}));

describe('RelatedPosts', () => {
beforeEach(() => {
vi.mock('$lib/post-handlers');
});

test('renders nothing with no related posts', () => {
vi.mock('$lib/post-handlers', () => {
return {
getRelatedPosts: vi.fn().mockResolvedValue([])
};
});
const { container } = render(RelatedPosts, {
parentPostTitle: 'foo',
parentPostHnLink: undefined,
parentPostKeywords: undefined
});

expect(container.querySelector('div')?.childElementCount).toBe(0);
});

test('renders related posts', async () => {
vi.mock('$lib/post-handlers', () => {
return {
getRelatedPosts: vi.fn().mockResolvedValue(mockRelatedPosts)
};
});
render(RelatedPosts, {
parentPostTitle: 'foo',
parentPostHnLink: undefined,
parentPostKeywords: undefined
});
await whenStable();

expect(screen.getByText('foo title')).toBeInTheDocument();
});

test('render the HN discussion link', async () => {
vi.mock('$lib/post-handlers', () => {
return {
getRelatedPosts: vi.fn().mockResolvedValue(mockRelatedPosts)
};
});
const env = render(RelatedPosts, {
parentPostTitle: 'foo',
parentPostHnLink: undefined,
parentPostKeywords: undefined
});
await whenStable();

expect(
screen.queryByText('Hacker News discussion')
).not.toBeInTheDocument();

env.component.$set({
parentPostTitle: 'foo',
parentPostHnLink: 'foo',
parentPostKeywords: undefined
});
await whenStable();

expect(screen.getByText('Hacker News discussion')).toBeInTheDocument();
});
});
2 changes: 1 addition & 1 deletion src/routes/blog/keywords/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
</li>
{/each}
</ul>
</div>
</div>
5 changes: 5 additions & 0 deletions src/tests/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { act } from '@testing-library/svelte';

export async function whenStable() {
await act(async () => await new Promise(resolve => setTimeout(resolve, 1)));
}
7 changes: 7 additions & 0 deletions src/tests/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { cleanup } from '@testing-library/svelte';
import { afterEach } from 'vitest';
import 'vitest-dom/extend-expect';

afterEach(() => {
cleanup();
});
4 changes: 4 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ export default defineConfig({
fs: {
allow: ['./posts']
}
},
test: {
environment: 'jsdom',
setupFiles: ['./src/tests/setup.ts']
}
});

0 comments on commit 7e21802

Please sign in to comment.