Skip to content

Commit

Permalink
Start adding some straightforward unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierstoval committed Oct 16, 2023
1 parent 18be2b8 commit 575b866
Show file tree
Hide file tree
Showing 7 changed files with 500 additions and 13 deletions.
18 changes: 10 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --plugin=prettier-plugin-svelte . --check . && eslint src",
"format": "prettier --plugin=prettier-plugin-svelte --write ."
"format": "prettier --plugin=prettier-plugin-svelte --write .",
"test:unit": "vitest"
},
"exports": {
".": {
Expand All @@ -37,28 +38,29 @@
},
"devDependencies": {
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/adapter-static": "^2.0.3",
"@sveltejs/kit": "^1.25.2",
"@sveltejs/package": "^2.0.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"carbon-components-svelte": "^0.81.0",
"carbon-icons-svelte": "^12.3.0",
"carbon-preprocess-svelte": "^0.10.0",
"eslint": "^8.28.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-svelte": "^2.30.0",
"intl-messageformat": "^10.5.3",
"prettier": "^3.0.3",
"prettier-plugin-svelte": "^3.0.3",
"publint": "^0.2.4",
"sass": "^1.69.3",
"svelte": "^4.2.1",
"svelte-check": "^3.4.3",
"svelte-i18n": "^3.7.4",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^4.4.2",
"@sveltejs/adapter-static": "^2.0.3",
"carbon-preprocess-svelte": "^0.10.0",
"intl-messageformat": "^10.5.3",
"carbon-components-svelte": "^0.81.0",
"carbon-icons-svelte": "^12.3.0",
"svelte-i18n": "^3.7.4",
"sass": "^1.69.3"
"vitest": "^0.34.6"
},
"svelte": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
82 changes: 82 additions & 0 deletions src/lib/admin/Crud/definition.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {describe, it, expect, type TestOptions} from 'vitest';
import {
CallbackStateProcessor,
CallbackStateProvider,
CrudDefinition,
List,
} from "$lib";

const testOpts: TestOptions = {repeats: process.env.REPEAT ? parseInt(process.env.REPEAT) : undefined};

type Book = {};

describe(
'Crud definition',
() => {
it('can be instantiated with simple config', () => {
const crud = new CrudDefinition<Book>('books', {
label: {singular: '', plural: ''},
operations: [new List([])],
stateProvider: new CallbackStateProvider<Book>(() => null),
stateProcessor: new CallbackStateProcessor<Book>(() => {}),
});

expect(crud).toBeDefined();
});
it('can be instantiated with simple config containing existing default operation name', () => {
const crud = new CrudDefinition<Book>('books', {
label: {singular: '', plural: ''},
operations: [new List([])],
defaultOperationName: 'list',
stateProvider: new CallbackStateProvider<Book>(() => null),
stateProcessor: new CallbackStateProcessor<Book>(() => {}),
});

expect(crud).toBeDefined();
});

it('cannot be instantiated without operations', () => {
const construct = () => {
new CrudDefinition<Book>('books', {
label: {singular: '', plural: ''},
operations: [],
stateProvider: new CallbackStateProvider<Book>(() => null),
stateProcessor: new CallbackStateProcessor<Book>(() => {}),
});
}

expect(construct).toThrowError(/^Crud definition "books" has no Crud operations set\./g);
});

it('cannot be instantiated if operations list\'s first element is not properly set', () => {
const construct = () => {
const operations = Array(2);
operations[1] = new List([]);
new CrudDefinition<Book>('books', {
label: {singular: '', plural: ''},
operations: operations,
stateProvider: new CallbackStateProvider<Book>(() => null),
stateProcessor: new CallbackStateProcessor<Book>(() => {}),
});
}

expect(construct).toThrowError(/^Crud definition "books" has an invalid default operation name "undefined"\./g);
});

it('cannot be instantiated if default operation name does not exist in operations list', () => {
const construct = () => {
const operations = Array(2);
new CrudDefinition<Book>('books', {
label: {singular: '', plural: ''},
operations: [new List([])],
defaultOperationName: 'edit',
stateProvider: new CallbackStateProvider<Book>(() => null),
stateProcessor: new CallbackStateProcessor<Book>(() => {}),
});
}

expect(construct).toThrowError(/^Crud definition "books" has no default operation named "edit"\./g);
});
},
testOpts
);
3 changes: 2 additions & 1 deletion src/lib/admin/Crud/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class CrudDefinition<T> {

constructor(name: string, options: CrudDefinitionOptions<T>) {
this.name = name;

if (!options?.operations.length) {
throw new Error(
`Crud definition "${name}" has no Crud operations set.\nDid you forget to add an "operations" key when creating your Crud definition?`
Expand All @@ -29,7 +30,7 @@ export class CrudDefinition<T> {
const defaultOperationName = options.defaultOperationName || options.operations[0]?.name;
if (!defaultOperationName || !defaultOperationName.length) {
throw new Error(
`Crud definition "${name}" has an invalid default operation name "${defaultOperationName}".\nYou can fix this issue by adding the "defaultOperationName" option when creating your Crud definition.`
`Crud definition "${name}" has an invalid default operation name "${defaultOperationName}".\nYou can fix this issue by customizing the "defaultOperationName" option when creating your Crud definition.`
);
}

Expand Down
38 changes: 38 additions & 0 deletions src/lib/admin/Dashboard/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {describe, it, expect, type TestOptions} from 'vitest';
import {
CallbackStateProcessor,
CallbackStateProvider,
CrudDefinition,
DashboardDefinition,
List,
} from "$lib";

import {emptyAdminConfig} from "$lib/admin/config/adminConfig.ts";

const testOpts: TestOptions = {repeats: process.env.REPEAT ? parseInt(process.env.REPEAT) : undefined};

type Book = {};

describe(
'Dashboard',
() => {
it('can be instantiated with simple config', () => {
const dashboard = new DashboardDefinition<Book>({
adminConfig: emptyAdminConfig(),
cruds: [
new CrudDefinition<Book>('books', {
label: {singular: 'Book', plural: 'Books'},
operations: [
new List([]),
],
stateProvider: new CallbackStateProvider<Book>(() => null),
stateProcessor: new CallbackStateProcessor<Book>(() => {}),
})
],
});

expect(dashboard).toBeDefined();
});
},
testOpts
);
59 changes: 59 additions & 0 deletions src/lib/admin/DataTable/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {describe, it, expect, type TestOptions} from 'vitest';
import {createEmptyRow} from "$lib/admin/DataTable/DataTable.ts";
import {
List,
CheckboxField,
Field,
NumberField,
TabsField,
TextareaField,
TextField,
ToggleField,
UrlField
} from "$lib";

const testOpts: TestOptions = {repeats: process.env.REPEAT ? parseInt(process.env.REPEAT) : undefined};

type Book = {};

describe(
'DataTable',
() => {
it('can create an empty row from empty CrudOperation', () => {
const row = createEmptyRow(new List([]));

expect(row).toBeDefined();
expect(row).toStrictEqual({
id: 0,
})
});

it('can create an empty row from CrudOperation with all fields', () => {
const fields = [
new CheckboxField('field_1'),
new Field('field_2'),
new NumberField('field_3'),
new TabsField('field_4'),
new TextareaField('field_5'),
new TextField('field_6'),
new ToggleField('field_7'),
new UrlField('field_8'),
];
const row = createEmptyRow(new List(fields));

expect(row).toBeDefined();
expect(row).toStrictEqual({
id: 0,
field_1: '-',
field_2: '-',
field_3: '-',
field_4: '-',
field_5: '-',
field_6: '-',
field_7: '-',
field_8: '-',
})
});
},
testOpts
);
4 changes: 2 additions & 2 deletions src/testApp/BookCrud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import { type CrudOperation, Delete, Edit, List } from '$lib/admin/Crud/Operations.ts';
import type { KeyValueObject } from '$lib/admin/genericTypes.ts';
import { CrudDefinition } from '$lib/admin/Crud/definition.ts';
import { CallbackStateProcessor, type StateProcessorInput } from '$lib/admin/State/Processor.ts';
import { CallbackStateProvider, type StateProviderResult } from '$lib/admin/State/Provider.ts';
import { CallbackStateProcessor } from '$lib/admin/State/Processor.ts';
import { CallbackStateProvider } from '$lib/admin/State/Provider.ts';
import { TextField } from '$lib/admin/FieldDefinitions/Text.ts';
import { TextareaField } from '$lib/admin/FieldDefinitions/Textarea.ts';
import { UrlAction } from '$lib/admin/actions.ts';
Expand Down
Loading

0 comments on commit 575b866

Please sign in to comment.