mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
add tests
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- run: npm run build
|
||||
- run: npm run check
|
||||
- run: npm run lint
|
||||
- run: npm test
|
||||
@@ -5,6 +5,7 @@ This is a PoC that was a result of about 2 hours coding, investigating a possibl
|
||||
For simplicity I used [Pico CSS](https://picocss.com/) and didn't focus on styling at all.
|
||||
|
||||
Therefore, Pico CSS is the only Dependency that got added beside necessary ones from Svelte and Developer Tooling (Sass, Linter, Formatter, etc).
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
@@ -35,6 +36,7 @@ Once you've created a project and installed dependencies with `npm install`, sta
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
@@ -43,6 +45,13 @@ npm run build
|
||||
|
||||
> You can preview the built app with `npm run preview`, regardless of whether you installed an adapter. This should _not_ be used to serve your app in production.
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
This will run tests in the `tests/` directory.
|
||||
|
||||
## Format
|
||||
|
||||
|
||||
Generated
+9095
-178
File diff suppressed because it is too large
Load Diff
+33
-4
@@ -9,25 +9,54 @@
|
||||
"check": "svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint .",
|
||||
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
|
||||
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. .",
|
||||
"test": "jest tests",
|
||||
"test:watch": "npm run test -- --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@picocss/pico": "^1.4.3",
|
||||
"@sveltejs/adapter-static": "next",
|
||||
"@sveltejs/kit": "next",
|
||||
"@testing-library/dom": "^7.31.2",
|
||||
"@testing-library/jest-dom": "^5.16.1",
|
||||
"@testing-library/svelte": "^3.0.3",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.9.0",
|
||||
"@typescript-eslint/parser": "^5.9.0",
|
||||
"eslint": "^8.6.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-svelte3": "^3.2.1",
|
||||
"jest": "^27.4.7",
|
||||
"prettier": "^2.4.1",
|
||||
"prettier-plugin-svelte": "^2.4.0",
|
||||
"sass": "^1.46.0",
|
||||
"svelte": "^3.44.0",
|
||||
"svelte-check": "^2.2.11",
|
||||
"svelte-preprocess": "^4.9.4",
|
||||
"svelte-jester": "^2.1.5",
|
||||
"svelte-preprocess": "^4.10.1",
|
||||
"ts-jest": "^27.1.2",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.4.3"
|
||||
"typescript": "^4.5.4"
|
||||
},
|
||||
"type": "module"
|
||||
"type": "module",
|
||||
"jest": {
|
||||
"testEnvironment": "jsdom",
|
||||
"setupFilesAfterEnv": [
|
||||
"@testing-library/jest-dom/extend-expect"
|
||||
],
|
||||
"transform": {
|
||||
"^.+\\.svelte$": [
|
||||
"svelte-jester",
|
||||
{
|
||||
"preprocess": true
|
||||
}
|
||||
],
|
||||
"^.+\\.ts$": "ts-jest"
|
||||
},
|
||||
"moduleFileExtensions": [
|
||||
"js",
|
||||
"ts",
|
||||
"svelte"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ export { default as InputText } from './inputText.svelte';
|
||||
export { default as InputNumber } from './inputNumber.svelte';
|
||||
export { default as InputBoolean } from './inputBoolean.svelte';
|
||||
export { default as InputTags } from './inputTags.svelte';
|
||||
export { default as InputFile } from './inputFile.svelte';
|
||||
export { default as Modal } from './modal.svelte';
|
||||
export { default as Table } from './table/table.svelte';
|
||||
export { default as Pagination } from './pagination.svelte';
|
||||
export * from "./table";
|
||||
export * from './table';
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<script lang="ts">
|
||||
export let label: string;
|
||||
export let value: boolean;
|
||||
export let value = false;
|
||||
export let required = false;
|
||||
export let disabled = false;
|
||||
</script>
|
||||
|
||||
<label>
|
||||
<span>{label}</span>
|
||||
<input type="checkbox" bind:checked={value} role="switch" {required} />
|
||||
<input type="checkbox" bind:checked={value} role="switch" {required} {disabled} />
|
||||
</label>
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let label: string;
|
||||
export let value: string;
|
||||
export let value = '';
|
||||
export let placeholder = '';
|
||||
export let required = false;
|
||||
export let autofocus = false;
|
||||
export let disabled = false;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
|
||||
@@ -18,5 +19,5 @@
|
||||
|
||||
<label>
|
||||
<span>{label}</span>
|
||||
<input {placeholder} {required} type="email" bind:value bind:this={element} />
|
||||
<input {placeholder} {required} {disabled} type="email" bind:value bind:this={element} />
|
||||
</label>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
export let label: string;
|
||||
export let files: FileList;
|
||||
export let required = false;
|
||||
export let disabled = false;
|
||||
</script>
|
||||
|
||||
<label>
|
||||
<span>{label}</span>
|
||||
<input type="file" bind:files {required} />
|
||||
<input type="file" bind:files {required} {disabled} />
|
||||
</label>
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let label: string;
|
||||
export let value: number;
|
||||
export let value: number = null;
|
||||
export let placeholder = '';
|
||||
export let required = false;
|
||||
export let autofocus = false;
|
||||
export let disabled = false;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
|
||||
@@ -18,5 +19,5 @@
|
||||
|
||||
<label>
|
||||
<span>{label}</span>
|
||||
<input {placeholder} {required} type="number" bind:value bind:this={element} />
|
||||
<input {placeholder} {disabled} {required} type="number" bind:value bind:this={element} />
|
||||
</label>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let label: string;
|
||||
export let value: string;
|
||||
export let value = '';
|
||||
export let placeholder = '';
|
||||
export let required = false;
|
||||
export let disabled = false;
|
||||
export let autofocus = false;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
@@ -18,5 +19,5 @@
|
||||
|
||||
<label>
|
||||
<span>{label}</span>
|
||||
<input {placeholder} {required} type="password" bind:value bind:this={element} />
|
||||
<input {placeholder} {disabled} {required} type="password" bind:value bind:this={element} />
|
||||
</label>
|
||||
|
||||
@@ -55,9 +55,9 @@
|
||||
</ul>
|
||||
<input
|
||||
type="text"
|
||||
{placeholder}
|
||||
on:keydown={handleInput}
|
||||
on:blur={handleBlur}
|
||||
{placeholder}
|
||||
bind:value
|
||||
bind:this={element}
|
||||
/>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let label: string;
|
||||
export let value: string;
|
||||
export let value = '';
|
||||
export let placeholder = '';
|
||||
export let required = false;
|
||||
export let disabled = false;
|
||||
export let autofocus = false;
|
||||
|
||||
let element: HTMLInputElement;
|
||||
@@ -18,5 +19,5 @@
|
||||
|
||||
<label>
|
||||
<span>{label}</span>
|
||||
<input {placeholder} {required} type="text" bind:value bind:this={element} />
|
||||
<input {placeholder} {disabled} {required} type="text" bind:value bind:this={element} />
|
||||
</label>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<dialog open>
|
||||
<article>
|
||||
<header>
|
||||
<span on:click={() => (show = false)} aria-label="Close" class="close" />
|
||||
<span on:click={() => (show = false)} aria-label="Close" title="Close" class="close" />
|
||||
<slot name="header" />
|
||||
</header>
|
||||
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
import { Button } from '.';
|
||||
|
||||
export let limit;
|
||||
export let offset;
|
||||
export let sum;
|
||||
export let limit: number;
|
||||
export let offset: number;
|
||||
export let sum: number;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const next = () => {
|
||||
offset += limit;
|
||||
if (offset + limit > sum) {
|
||||
offset = sum;
|
||||
} else {
|
||||
offset += limit;
|
||||
}
|
||||
dispatch('change');
|
||||
};
|
||||
|
||||
const prev = () => {
|
||||
offset -= limit;
|
||||
if (offset - limit < 0) {
|
||||
offset = 0;
|
||||
} else {
|
||||
offset -= limit;
|
||||
}
|
||||
dispatch('change');
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<tbody>
|
||||
<slot />
|
||||
</tbody>
|
||||
<slot />
|
||||
</tbody>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<tfoot>
|
||||
<tr>
|
||||
<slot />
|
||||
</tr>
|
||||
</tfoot>
|
||||
<tr>
|
||||
<slot />
|
||||
</tr>
|
||||
</tfoot>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<slot />
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<slot />
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export { default as Table } from "./table.svelte";
|
||||
export { default as TableBody } from "./body.svelte";
|
||||
export { default as TableHeader } from "./header.svelte";
|
||||
export { default as TableFooter } from "./footer.svelte";
|
||||
export { default as TableCell } from "./cell.svelte";
|
||||
export { default as TableRow } from "./row.svelte";
|
||||
export { default as Table } from './table.svelte';
|
||||
export { default as TableBody } from './body.svelte';
|
||||
export { default as TableHeader } from './header.svelte';
|
||||
export { default as TableFooter } from './footer.svelte';
|
||||
export { default as TableCell } from './cell.svelte';
|
||||
export { default as TableRow } from './row.svelte';
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<tr>
|
||||
<slot />
|
||||
</tr>
|
||||
<slot />
|
||||
</tr>
|
||||
|
||||
@@ -31,6 +31,5 @@
|
||||
$line-height: 1rem;
|
||||
$typography-spacing-vertical: 1rem;
|
||||
|
||||
|
||||
@import '@picocss/pico/scss/pico';
|
||||
</style>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
let selected: Option;
|
||||
|
||||
const change = (e) => {
|
||||
const change = (e: any) => {
|
||||
if (e.target.value >= 0) {
|
||||
selected = options[e.target.value];
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ function createCollection() {
|
||||
updateAttribute: (attribute: Models.Attributes) =>
|
||||
update((n) => {
|
||||
const index = n.attributes.findIndex((a) => a.key === attribute.key);
|
||||
n.attributes[index] =attribute;
|
||||
n.attributes[index] = attribute;
|
||||
|
||||
return n;
|
||||
}),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Button from '$lib/components/button.svelte';
|
||||
import InputFile from '$lib/components/inputFile.svelte';
|
||||
import InputTags from '$lib/components/inputTags.svelte';
|
||||
import InputTags from '$lib/components/inputTags.svelte';
|
||||
import Modal from '$lib/components/modal.svelte';
|
||||
import { sdkForProject } from '$lib/stores/sdk';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { sdkForProject } from '$lib/stores/sdk';
|
||||
import { Table, Button, Pagination, TableHeader, TableCell, TableBody, TableRow } from '$lib/components';
|
||||
import {
|
||||
Table,
|
||||
Button,
|
||||
Pagination,
|
||||
TableHeader,
|
||||
TableCell,
|
||||
TableBody,
|
||||
TableRow
|
||||
} from '$lib/components';
|
||||
import Create from './_create.svelte';
|
||||
|
||||
let search = '';
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
|
||||
const project = $page.params.project;
|
||||
const getAvatar = (name: string) => sdkForProject.avatars.getInitials(name, 30, 30).toString();
|
||||
const getUsers = () => sdkForProject.users.list(search, limit, offset, undefined, undefined, 'DESC');
|
||||
const getUsers = () =>
|
||||
sdkForProject.users.list(search, limit, offset, undefined, undefined, 'DESC');
|
||||
const doSearch = () => {
|
||||
offset = 0;
|
||||
request = getUsers();
|
||||
@@ -46,7 +47,7 @@
|
||||
{#each response.users as user}
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<img src={getAvatar(user.name)} alt={user.name} class="avatar">
|
||||
<img src={getAvatar(user.name)} alt={user.name} class="avatar" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<a href={`/console/${project}/users/user/${user.$id}`}>
|
||||
@@ -67,8 +68,8 @@
|
||||
<Button on:click={() => (showCreate = true)}>Create User</Button>
|
||||
<Create bind:showCreate on:created={() => (request = getUsers())} />
|
||||
|
||||
<style>
|
||||
.avatar {
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.avatar {
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
import { Button } from '$lib/components';
|
||||
import { sdkForProject } from '$lib/stores/sdk';
|
||||
|
||||
let id: HTMLInputElement;
|
||||
const request = sdkForProject.users.get($page.params.user);
|
||||
const getAvatar = (name: string) => sdkForProject.avatars.getInitials(name, 128, 128).toString();
|
||||
const deleteUser = async (id: string) => {
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render, fireEvent } from '@testing-library/svelte';
|
||||
|
||||
import { Button } from '../../../src/lib/components';
|
||||
|
||||
test('shows button', () => {
|
||||
const { getByRole } = render(Button);
|
||||
|
||||
expect(getByRole('button')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('shows button - disabled', () => {
|
||||
const { getByRole } = render(Button, { disabled: true });
|
||||
|
||||
expect(getByRole('button')).toBeDisabled();
|
||||
});
|
||||
|
||||
test('shows button - submit', () => {
|
||||
const { getByRole } = render(Button, { submit: true });
|
||||
|
||||
expect(getByRole('button')).toHaveAttribute('type', 'submit');
|
||||
});
|
||||
|
||||
test('shows button - outline', () => {
|
||||
const { getByRole } = render(Button, { outline: true });
|
||||
|
||||
expect(getByRole('button')).toHaveClass('outline');
|
||||
});
|
||||
|
||||
test('shows button - contrast', () => {
|
||||
const { getByRole } = render(Button, { contrast: true });
|
||||
|
||||
expect(getByRole('button')).toHaveClass('contrast');
|
||||
});
|
||||
|
||||
test('shows button - secondary', () => {
|
||||
const { getByRole } = render(Button, { secondary: true });
|
||||
|
||||
expect(getByRole('button')).toHaveClass('secondary');
|
||||
});
|
||||
|
||||
test('shows button - on:click', async () => {
|
||||
const { getByRole, component } = render(Button);
|
||||
const button = getByRole('button');
|
||||
const callback = jest.fn();
|
||||
component.$on('click', callback);
|
||||
|
||||
await fireEvent.click(button);
|
||||
expect(callback).toHaveBeenCalled();
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render, fireEvent } from '@testing-library/svelte';
|
||||
import { InputBoolean } from '../../../src/lib/components';
|
||||
|
||||
test('shows boolean input', () => {
|
||||
const { getByText, getByRole } = render(InputBoolean, { label: 'Bool' });
|
||||
const checkbox = getByRole('switch');
|
||||
|
||||
expect(getByText('Bool')).toBeInTheDocument();
|
||||
expect(checkbox).toBeInTheDocument();
|
||||
expect(checkbox).toHaveAttribute('type', 'checkbox');
|
||||
});
|
||||
|
||||
test('shows boolean input - required', () => {
|
||||
const { getByRole } = render(InputBoolean, { label: 'Bool', required: true });
|
||||
|
||||
expect(getByRole('switch')).toBeRequired();
|
||||
});
|
||||
|
||||
test('shows boolean input - disabled', () => {
|
||||
const { getByRole } = render(InputBoolean, { label: 'Bool', disabled: true });
|
||||
|
||||
expect(getByRole('switch')).toBeDisabled();
|
||||
});
|
||||
|
||||
test('state', async () => {
|
||||
const { getByRole, component } = render(InputBoolean, { label: 'Bool' });
|
||||
const checkbox = getByRole('switch');
|
||||
|
||||
expect(checkbox).not.toBeChecked();
|
||||
expect(component.value).toStrictEqual(false);
|
||||
|
||||
await fireEvent.click(checkbox);
|
||||
expect(checkbox).toBeChecked();
|
||||
expect(component.value).toStrictEqual(true);
|
||||
|
||||
await fireEvent.click(checkbox);
|
||||
expect(checkbox).not.toBeChecked();
|
||||
expect(component.value).toStrictEqual(false);
|
||||
|
||||
component.value = true;
|
||||
expect(checkbox).toBeChecked();
|
||||
expect(component.value).toStrictEqual(true);
|
||||
|
||||
component.value = false;
|
||||
expect(checkbox).not.toBeChecked();
|
||||
expect(component.value).toStrictEqual(false);
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render } from '@testing-library/svelte';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { InputEmail } from '../../../src/lib/components';
|
||||
|
||||
test('shows email input', () => {
|
||||
const { getByText, getByLabelText } = render(InputEmail, { label: 'input' });
|
||||
const input = getByLabelText('input');
|
||||
|
||||
expect(getByText('input')).toBeInTheDocument();
|
||||
expect(input).toBeInTheDocument();
|
||||
expect(input).toHaveAttribute('type', 'email');
|
||||
});
|
||||
|
||||
test('shows email input - required', () => {
|
||||
const { getByLabelText } = render(InputEmail, { label: 'input', required: true });
|
||||
|
||||
expect(getByLabelText('input')).toBeRequired();
|
||||
});
|
||||
|
||||
test('shows email input - disabled', () => {
|
||||
const { getByLabelText } = render(InputEmail, { label: 'input', disabled: true });
|
||||
|
||||
expect(getByLabelText('input')).toBeDisabled();
|
||||
});
|
||||
|
||||
test('shows email input - autofocus', () => {
|
||||
const { getByLabelText } = render(InputEmail, { label: 'input', autofocus: true });
|
||||
|
||||
expect(getByLabelText('input')).toHaveFocus();
|
||||
});
|
||||
|
||||
test('shows email input - placeholder', () => {
|
||||
const { getByPlaceholderText } = render(InputEmail, { label: 'input', placeholder: 'find me' });
|
||||
|
||||
expect(getByPlaceholderText('find me')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('state', async () => {
|
||||
const { component, getByLabelText } = render(InputEmail, { label: 'input', value: '' });
|
||||
const input = getByLabelText('input');
|
||||
|
||||
expect(component.value).toEqual('');
|
||||
await userEvent.type(input, 'lorem');
|
||||
expect(component.value).toEqual('lorem');
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render } from '@testing-library/svelte';
|
||||
import { InputFile } from '../../../src/lib/components';
|
||||
|
||||
test('shows file input', () => {
|
||||
const { getByText, getByLabelText } = render(InputFile, { label: 'input', files: null });
|
||||
const input = getByLabelText('input');
|
||||
|
||||
expect(getByText('input')).toBeInTheDocument();
|
||||
expect(input).toBeInTheDocument();
|
||||
expect(input).toHaveAttribute('type', 'file');
|
||||
});
|
||||
|
||||
test('shows file input - required', () => {
|
||||
const { getByLabelText } = render(InputFile, { label: 'input', required: true, files: null });
|
||||
|
||||
expect(getByLabelText('input')).toBeRequired();
|
||||
});
|
||||
|
||||
test('shows file input - disabled', () => {
|
||||
const { getByLabelText } = render(InputFile, { label: 'input', disabled: true, files: null });
|
||||
|
||||
expect(getByLabelText('input')).toBeDisabled();
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render } from '@testing-library/svelte';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { InputNumber } from '../../../src/lib/components';
|
||||
|
||||
test('shows number input', () => {
|
||||
const { getByText, getByLabelText } = render(InputNumber, { label: 'input' });
|
||||
const input = getByLabelText('input');
|
||||
|
||||
expect(getByText('input')).toBeInTheDocument();
|
||||
expect(input).toBeInTheDocument();
|
||||
expect(input).toHaveAttribute('type', 'number');
|
||||
});
|
||||
|
||||
test('shows number input - required', () => {
|
||||
const { getByLabelText } = render(InputNumber, { label: 'input', required: true });
|
||||
|
||||
expect(getByLabelText('input')).toBeRequired();
|
||||
});
|
||||
|
||||
test('shows number input - disabled', () => {
|
||||
const { getByLabelText } = render(InputNumber, { label: 'input', disabled: true });
|
||||
|
||||
expect(getByLabelText('input')).toBeDisabled();
|
||||
});
|
||||
|
||||
test('shows number input - autofocus', () => {
|
||||
const { getByLabelText } = render(InputNumber, { label: 'input', autofocus: true });
|
||||
|
||||
expect(getByLabelText('input')).toHaveFocus();
|
||||
});
|
||||
|
||||
test('shows number input - placeholder', () => {
|
||||
const { getByPlaceholderText } = render(InputNumber, { label: 'input', placeholder: 'find me' });
|
||||
|
||||
expect(getByPlaceholderText('find me')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('state', async () => {
|
||||
const { component, getByLabelText } = render(InputNumber, { label: 'input' });
|
||||
const input = getByLabelText('input');
|
||||
|
||||
expect(component.value).toEqual(null);
|
||||
await userEvent.type(input, '123');
|
||||
expect(component.value).toEqual(123);
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render } from '@testing-library/svelte';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { InputPassword } from '../../../src/lib/components';
|
||||
|
||||
test('shows password input', () => {
|
||||
const { getByText, getByLabelText } = render(InputPassword, { label: 'input' });
|
||||
const input = getByLabelText('input');
|
||||
|
||||
expect(getByText('input')).toBeInTheDocument();
|
||||
expect(input).toBeInTheDocument();
|
||||
expect(input).toHaveAttribute('type', 'password');
|
||||
});
|
||||
|
||||
test('shows password input - required', () => {
|
||||
const { getByLabelText } = render(InputPassword, { label: 'input', required: true });
|
||||
|
||||
expect(getByLabelText('input')).toBeRequired();
|
||||
});
|
||||
|
||||
test('shows password input - disabled', () => {
|
||||
const { getByLabelText } = render(InputPassword, { label: 'input', disabled: true });
|
||||
|
||||
expect(getByLabelText('input')).toBeDisabled();
|
||||
});
|
||||
|
||||
test('shows password input - autofocus', () => {
|
||||
const { getByLabelText } = render(InputPassword, { label: 'input', autofocus: true });
|
||||
|
||||
expect(getByLabelText('input')).toHaveFocus();
|
||||
});
|
||||
|
||||
test('shows password input - placeholder', () => {
|
||||
const { getByPlaceholderText } = render(InputPassword, {
|
||||
label: 'input',
|
||||
placeholder: 'find me'
|
||||
});
|
||||
|
||||
expect(getByPlaceholderText('find me')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('state', async () => {
|
||||
const { component, getByLabelText } = render(InputPassword, { label: 'input', value: '' });
|
||||
const input = getByLabelText('input');
|
||||
|
||||
expect(component.value).toEqual('');
|
||||
await userEvent.type(input, 'lorem');
|
||||
expect(component.value).toEqual('lorem');
|
||||
});
|
||||
@@ -0,0 +1,74 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { render, fireEvent } from '@testing-library/svelte';
|
||||
import { InputTags } from '../../../src/lib/components';
|
||||
|
||||
test('shows label', () => {
|
||||
const { getByText } = render(InputTags, { label: 'Tags' });
|
||||
|
||||
expect(getByText('Tags')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('shows input - autofocus', () => {
|
||||
const { getByLabelText } = render(InputTags, { label: 'Tags', autofocus: true });
|
||||
|
||||
expect(getByLabelText('Tags')).toHaveFocus();
|
||||
});
|
||||
|
||||
test('shows tags', () => {
|
||||
const { getByText } = render(InputTags, { label: 'Tags', tags: ['first', 'second'] });
|
||||
|
||||
expect(getByText('first')).toBeInTheDocument();
|
||||
expect(getByText('second')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('adds and removes tags by input', async () => {
|
||||
const { component, getByLabelText } = render(InputTags, { label: 'Tags' });
|
||||
const input = getByLabelText('Tags');
|
||||
|
||||
// Add tag by enter
|
||||
await userEvent.type(input, 'first{enter}');
|
||||
expect(component.tags).toHaveLength(1);
|
||||
expect(component.tags).toContain('first');
|
||||
|
||||
// Add tag by space
|
||||
await userEvent.type(input, 'second ');
|
||||
expect(component.tags).toHaveLength(2);
|
||||
expect(component.tags).toContain('second');
|
||||
|
||||
// Remove tag by backspace
|
||||
await userEvent.type(input, '{backspace}');
|
||||
expect(component.tags).toContain('first');
|
||||
expect(component.tags).not.toContain('second');
|
||||
expect(component.tags).toHaveLength(1);
|
||||
|
||||
// Remove tag by delete
|
||||
await userEvent.type(input, '{delete}');
|
||||
expect(component.tags).not.toContain('first');
|
||||
expect(component.tags).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('removes tag on click', async () => {
|
||||
const { component, getByText, queryByText } = render(InputTags, {
|
||||
label: 'Tags',
|
||||
tags: ['first', 'second']
|
||||
});
|
||||
|
||||
expect(component.tags).toHaveLength(2);
|
||||
expect(component.tags).toContain('first');
|
||||
expect(component.tags).toContain('second');
|
||||
|
||||
const first = getByText('first');
|
||||
await fireEvent.click(first);
|
||||
expect(component.tags).toHaveLength(1);
|
||||
expect(component.tags).toContain('second');
|
||||
expect(component.tags).not.toContain('first');
|
||||
expect(queryByText('first')).not.toBeInTheDocument();
|
||||
|
||||
const second = getByText('second');
|
||||
await fireEvent.click(second);
|
||||
expect(component.tags).toHaveLength(0);
|
||||
expect(component.tags).not.toContain('second');
|
||||
expect(component.tags).not.toContain('first');
|
||||
expect(queryByText('second')).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render } from '@testing-library/svelte';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { InputText } from '../../../src/lib/components';
|
||||
|
||||
test('shows text input', () => {
|
||||
const { getByText, getByLabelText } = render(InputText, { label: 'input' });
|
||||
const input = getByLabelText('input');
|
||||
|
||||
expect(getByText('input')).toBeInTheDocument();
|
||||
expect(input).toBeInTheDocument();
|
||||
expect(input).toHaveAttribute('type', 'text');
|
||||
});
|
||||
|
||||
test('shows text input - required', () => {
|
||||
const { getByLabelText } = render(InputText, { label: 'input', required: true });
|
||||
|
||||
expect(getByLabelText('input')).toBeRequired();
|
||||
});
|
||||
|
||||
test('shows text input - disabled', () => {
|
||||
const { getByLabelText } = render(InputText, { label: 'input', disabled: true });
|
||||
|
||||
expect(getByLabelText('input')).toBeDisabled();
|
||||
});
|
||||
|
||||
test('shows text input - autofocus', () => {
|
||||
const { getByLabelText } = render(InputText, { label: 'input', autofocus: true });
|
||||
|
||||
expect(getByLabelText('input')).toHaveFocus();
|
||||
});
|
||||
|
||||
test('shows text input - placeholder', () => {
|
||||
const { getByPlaceholderText } = render(InputText, { label: 'input', placeholder: 'find me' });
|
||||
|
||||
expect(getByPlaceholderText('find me')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('state', async () => {
|
||||
const { component, getByLabelText } = render(InputText, { label: 'input', value: '' });
|
||||
const input = getByLabelText('input');
|
||||
|
||||
expect(component.value).toEqual('');
|
||||
await userEvent.type(input, 'lorem');
|
||||
expect(component.value).toEqual('lorem');
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
<script>
|
||||
import { Modal } from '../../../src/lib/components';
|
||||
|
||||
export let show = false;
|
||||
</script>
|
||||
|
||||
<Modal bind:show>
|
||||
<span>Content</span>
|
||||
</Modal>
|
||||
@@ -0,0 +1,40 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { render, fireEvent } from '@testing-library/svelte';
|
||||
import Modal from './modal.test.svelte';
|
||||
|
||||
test('shows modal', () => {
|
||||
const { queryByText, component } = render(Modal);
|
||||
|
||||
expect(queryByText('Content')).not.toBeInTheDocument();
|
||||
|
||||
component.show = true;
|
||||
expect(queryByText('Content')).toBeInTheDocument();
|
||||
|
||||
component.show = false;
|
||||
expect(queryByText('Content')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('close modal by click', async () => {
|
||||
const { queryByText, component, getByTitle } = render(Modal, {
|
||||
show: true
|
||||
});
|
||||
|
||||
expect(queryByText('Content')).toBeInTheDocument();
|
||||
await fireEvent.click(getByTitle('Close'));
|
||||
|
||||
expect(queryByText('Content')).not.toBeInTheDocument();
|
||||
expect(component.show).toStrictEqual(false);
|
||||
});
|
||||
|
||||
test('close modal by key', async () => {
|
||||
const { queryByText, component } = render(Modal, {
|
||||
show: true
|
||||
});
|
||||
|
||||
expect(queryByText('Content')).toBeInTheDocument();
|
||||
|
||||
await userEvent.keyboard('[Escape]');
|
||||
expect(queryByText('Content')).not.toBeInTheDocument();
|
||||
expect(component.show).toStrictEqual(false);
|
||||
});
|
||||
@@ -0,0 +1,91 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render, fireEvent } from '@testing-library/svelte';
|
||||
import { Pagination } from '../../../src/lib/components';
|
||||
|
||||
test('shows controls', () => {
|
||||
const { getByText } = render(Pagination, {
|
||||
limit: 0,
|
||||
offset: 0,
|
||||
sum: 100
|
||||
});
|
||||
|
||||
expect(getByText('<')).toBeInTheDocument();
|
||||
expect(getByText('>')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('pagination - first page', () => {
|
||||
const { getByText } = render(Pagination, {
|
||||
limit: 25,
|
||||
offset: 0,
|
||||
sum: 100
|
||||
});
|
||||
|
||||
expect(getByText('<')).toBeDisabled();
|
||||
expect(getByText('>')).not.toBeDisabled();
|
||||
});
|
||||
|
||||
test('pagination - last page', () => {
|
||||
const { getByText } = render(Pagination, {
|
||||
limit: 25,
|
||||
offset: 25,
|
||||
sum: 30
|
||||
});
|
||||
|
||||
expect(getByText('<')).not.toBeDisabled();
|
||||
expect(getByText('>')).toBeDisabled();
|
||||
});
|
||||
|
||||
test('pagination - forward', async () => {
|
||||
const { getByText, component } = render(Pagination, {
|
||||
limit: 25,
|
||||
offset: 0,
|
||||
sum: 60
|
||||
});
|
||||
|
||||
const back = getByText('<');
|
||||
const forth = getByText('>');
|
||||
expect(back).toBeDisabled();
|
||||
|
||||
await fireEvent.click(forth);
|
||||
expect(component.offset).toEqual(25);
|
||||
|
||||
await fireEvent.click(forth);
|
||||
expect(component.offset).toEqual(50);
|
||||
|
||||
await fireEvent.click(forth);
|
||||
expect(component.offset).toEqual(60);
|
||||
expect(forth).toBeDisabled();
|
||||
});
|
||||
|
||||
test('pagination - backwards', async () => {
|
||||
const { getByText, component } = render(Pagination, {
|
||||
limit: 25,
|
||||
offset: 55,
|
||||
sum: 60
|
||||
});
|
||||
|
||||
const back = getByText('<');
|
||||
const forth = getByText('>');
|
||||
expect(forth).toBeDisabled();
|
||||
|
||||
await fireEvent.click(back);
|
||||
expect(component.offset).toEqual(30);
|
||||
|
||||
await fireEvent.click(back);
|
||||
expect(component.offset).toEqual(5);
|
||||
|
||||
await fireEvent.click(back);
|
||||
expect(component.offset).toEqual(0);
|
||||
expect(back).toBeDisabled();
|
||||
});
|
||||
|
||||
test('shows no controls', () => {
|
||||
const { queryByText } = render(Pagination, {
|
||||
limit: 25,
|
||||
offset: 0,
|
||||
sum: 10
|
||||
});
|
||||
|
||||
expect(queryByText('<')).not.toBeInTheDocument();
|
||||
expect(queryByText('>')).not.toBeInTheDocument();
|
||||
});
|
||||
Reference in New Issue
Block a user