@venizia/ignis-docs 0.0.8-3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/{wiki → content}/best-practices/api-usage-examples.md +15 -12
- package/{wiki → content}/best-practices/architectural-patterns.md +70 -78
- package/{wiki → content}/best-practices/architecture-decisions.md +91 -60
- package/{wiki → content}/best-practices/code-style-standards/advanced-patterns.md +56 -44
- package/{wiki → content}/best-practices/code-style-standards/constants-configuration.md +11 -11
- package/{wiki → content}/best-practices/code-style-standards/control-flow.md +5 -2
- package/{wiki → content}/best-practices/code-style-standards/documentation.md +13 -13
- package/{wiki → content}/best-practices/code-style-standards/function-patterns.md +9 -10
- package/{wiki → content}/best-practices/code-style-standards/index.md +1 -1
- package/{wiki → content}/best-practices/code-style-standards/naming-conventions.md +10 -8
- package/{wiki → content}/best-practices/code-style-standards/route-definitions.md +30 -12
- package/{wiki → content}/best-practices/code-style-standards/tooling.md +8 -5
- package/{wiki → content}/best-practices/code-style-standards/type-safety.md +13 -12
- package/{wiki → content}/best-practices/common-pitfalls.md +56 -37
- package/{wiki → content}/best-practices/contribution-workflow.md +13 -14
- package/{wiki → content}/best-practices/data-modeling.md +44 -20
- package/{wiki → content}/best-practices/deployment-strategies.md +28 -27
- package/{wiki → content}/best-practices/error-handling.md +48 -24
- package/{wiki → content}/best-practices/index.md +5 -5
- package/{wiki → content}/best-practices/performance-optimization.md +36 -28
- package/{wiki → content}/best-practices/security-guidelines.md +52 -23
- package/{wiki → content}/best-practices/testing-strategies.md +65 -51
- package/{wiki → content}/best-practices/troubleshooting-tips.md +24 -24
- package/{wiki/extensions/components/swagger.md → content/extensions/components/api-reference.md} +40 -31
- package/{wiki → content}/extensions/components/authentication/api.md +19 -19
- package/{wiki → content}/extensions/components/authentication/errors.md +7 -7
- package/{wiki → content}/extensions/components/authentication/index.md +10 -8
- package/{wiki → content}/extensions/components/authentication/usage.md +101 -6
- package/{wiki → content}/extensions/components/authorization/api.md +45 -25
- package/{wiki → content}/extensions/components/authorization/errors.md +6 -6
- package/{wiki → content}/extensions/components/authorization/index.md +11 -10
- package/{wiki → content}/extensions/components/authorization/usage.md +21 -21
- package/{wiki → content}/extensions/components/health-check.md +1 -1
- package/{wiki → content}/extensions/components/index.md +5 -5
- package/{wiki → content}/extensions/components/mail/errors.md +15 -15
- package/{wiki → content}/extensions/components/mail/index.md +1 -2
- package/{wiki → content}/extensions/components/mail/usage.md +1 -1
- package/{wiki → content}/extensions/components/request-tracker.md +1 -1
- package/{wiki → content}/extensions/components/socket-io/api.md +9 -9
- package/{wiki → content}/extensions/components/socket-io/errors.md +5 -5
- package/{wiki → content}/extensions/components/socket-io/index.md +8 -8
- package/{wiki → content}/extensions/components/socket-io/usage.md +1 -1
- package/{wiki → content}/extensions/components/static-asset/api.md +17 -4
- package/{wiki → content}/extensions/components/static-asset/errors.md +4 -4
- package/{wiki → content}/extensions/components/static-asset/index.md +26 -28
- package/{wiki → content}/extensions/components/static-asset/usage.md +13 -12
- package/{wiki → content}/extensions/components/template/index.md +2 -2
- package/{wiki → content}/extensions/components/template/setup-page.md +1 -1
- package/{wiki → content}/extensions/components/websocket/api.md +3 -3
- package/{wiki → content}/extensions/components/websocket/errors.md +5 -5
- package/{wiki → content}/extensions/components/websocket/index.md +5 -5
- package/{wiki → content}/extensions/components/websocket/usage.md +3 -3
- package/{wiki → content}/extensions/helpers/cron/index.md +2 -2
- package/{wiki → content}/extensions/helpers/crypto/index.md +1 -1
- package/{wiki → content}/extensions/helpers/env/index.md +27 -12
- package/content/extensions/helpers/error/index.md +283 -0
- package/{wiki → content}/extensions/helpers/index.md +2 -3
- package/{wiki → content}/extensions/helpers/inversion/index.md +15 -7
- package/{wiki → content}/extensions/helpers/kafka/examples.md +1 -1
- package/{wiki → content}/extensions/helpers/logger/index.md +32 -2
- package/{wiki → content}/extensions/helpers/network/index.md +6 -0
- package/{wiki → content}/extensions/helpers/queue/index.md +14 -17
- package/content/extensions/helpers/redis/index.md +713 -0
- package/{wiki → content}/extensions/helpers/socket-io/index.md +14 -10
- package/{wiki → content}/extensions/helpers/storage/api.md +44 -8
- package/{wiki → content}/extensions/helpers/storage/index.md +43 -7
- package/{wiki → content}/extensions/helpers/template/index.md +6 -3
- package/{wiki → content}/extensions/helpers/types/index.md +11 -8
- package/{wiki → content}/extensions/helpers/websocket/api.md +9 -9
- package/{wiki → content}/extensions/helpers/websocket/index.md +7 -7
- package/{wiki → content}/extensions/helpers/worker-thread/index.md +2 -2
- package/{wiki → content}/extensions/index.md +3 -4
- package/{wiki → content}/extensions/src-details/mcp-server.md +18 -24
- package/{wiki → content}/guides/core-concepts/application/bootstrapping.md +11 -14
- package/{wiki → content}/guides/core-concepts/application/index.md +3 -3
- package/{wiki → content}/guides/core-concepts/components.md +19 -10
- package/{wiki → content}/guides/core-concepts/dependency-injection.md +6 -3
- package/{wiki → content}/guides/core-concepts/grpc-controllers.md +6 -5
- package/{wiki → content}/guides/core-concepts/persistent/datasources.md +33 -27
- package/{wiki → content}/guides/core-concepts/persistent/index.md +16 -5
- package/{wiki → content}/guides/core-concepts/persistent/models.md +24 -20
- package/content/guides/core-concepts/persistent/postgres-drivers.md +167 -0
- package/{wiki → content}/guides/core-concepts/persistent/repositories.md +40 -23
- package/content/guides/core-concepts/persistent/search-meilisearch.md +183 -0
- package/content/guides/core-concepts/persistent/search-typesense.md +429 -0
- package/{wiki → content}/guides/core-concepts/persistent/transactions.md +61 -25
- package/{wiki → content}/guides/core-concepts/rest-controllers.md +12 -9
- package/content/guides/core-concepts/services.md +389 -0
- package/{wiki → content}/guides/get-started/5-minute-quickstart.md +19 -19
- package/{wiki → content}/guides/get-started/philosophy.md +36 -36
- package/{wiki → content}/guides/get-started/setup.md +3 -3
- package/{wiki → content}/guides/index.md +3 -3
- package/content/guides/migrations/redis-helpers-migration.md +177 -0
- package/{wiki → content}/guides/migrations/scoped-rbac-migration.md +17 -17
- package/content/guides/migrations/unified-connectors-migration.md +113 -0
- package/{wiki → content}/guides/reference/glossary.md +19 -12
- package/{wiki → content}/guides/reference/mcp-docs-server.md +22 -18
- package/{wiki → content}/guides/tutorials/building-a-crud-api.md +30 -33
- package/{wiki → content}/guides/tutorials/complete-installation.md +17 -17
- package/{wiki → content}/guides/tutorials/ecommerce-api.md +158 -119
- package/{wiki → content}/guides/tutorials/realtime-chat.md +176 -130
- package/content/guides/tutorials/testing.md +264 -0
- package/content/index.md +5 -0
- package/content/public/apple-touch-icon.png +0 -0
- package/content/public/og-image.png +0 -0
- package/content/public/site.webmanifest +11 -0
- package/{wiki → content}/references/base/application.md +4 -5
- package/{wiki → content}/references/base/bootstrapping.md +18 -5
- package/{wiki → content}/references/base/components.md +149 -120
- package/content/references/base/connectors.md +178 -0
- package/{wiki → content}/references/base/controllers.md +41 -30
- package/content/references/base/datasources.md +527 -0
- package/{wiki → content}/references/base/dependency-injection.md +34 -22
- package/{wiki → content}/references/base/filter-system/application-usage.md +17 -14
- package/{wiki → content}/references/base/filter-system/array-operators.md +7 -2
- package/{wiki → content}/references/base/filter-system/comparison-operators.md +3 -0
- package/{wiki → content}/references/base/filter-system/default-filter.md +89 -71
- package/{wiki → content}/references/base/filter-system/fields-order-pagination.md +22 -22
- package/{wiki → content}/references/base/filter-system/index.md +6 -3
- package/{wiki → content}/references/base/filter-system/json-filtering.md +20 -1
- package/{wiki → content}/references/base/filter-system/list-operators.md +1 -1
- package/{wiki → content}/references/base/filter-system/logical-operators.md +33 -1
- package/{wiki → content}/references/base/filter-system/null-operators.md +30 -1
- package/{wiki → content}/references/base/filter-system/quick-reference.md +23 -4
- package/{wiki → content}/references/base/filter-system/tips.md +5 -5
- package/{wiki → content}/references/base/filter-system/use-cases.md +12 -12
- package/{wiki → content}/references/base/grpc-controllers.md +13 -13
- package/{wiki → content}/references/base/index.md +24 -12
- package/{wiki/references/base/middleware.md → content/references/base/middlewares.md} +205 -24
- package/{wiki → content}/references/base/models.md +63 -49
- package/{wiki → content}/references/base/providers.md +136 -130
- package/{wiki → content}/references/base/repositories/advanced.md +59 -58
- package/{wiki → content}/references/base/repositories/index.md +115 -91
- package/content/references/base/repositories/mixins.md +99 -0
- package/{wiki → content}/references/base/repositories/relations.md +54 -64
- package/{wiki → content}/references/base/repositories/soft-deletable.md +31 -30
- package/content/references/base/services.md +404 -0
- package/{wiki → content}/references/configuration/environment-variables.md +46 -30
- package/{wiki → content}/references/configuration/index.md +6 -6
- package/{wiki → content}/references/index.md +17 -12
- package/{wiki → content}/references/quick-reference.md +65 -106
- package/content/references/utilities/crypto.md +98 -0
- package/{wiki → content}/references/utilities/index.md +3 -3
- package/{wiki → content}/references/utilities/jsx.md +6 -4
- package/content/references/utilities/module.md +90 -0
- package/{wiki → content}/references/utilities/parse.md +4 -14
- package/{wiki → content}/references/utilities/promise.md +9 -7
- package/{wiki → content}/references/utilities/schema.md +5 -3
- package/dist/mcp-server/common/guards.d.ts +8 -0
- package/dist/mcp-server/common/guards.d.ts.map +1 -0
- package/dist/mcp-server/common/guards.js +14 -0
- package/dist/mcp-server/common/guards.js.map +1 -0
- package/dist/mcp-server/common/index.d.ts +1 -0
- package/dist/mcp-server/common/index.d.ts.map +1 -1
- package/dist/mcp-server/common/index.js +1 -0
- package/dist/mcp-server/common/index.js.map +1 -1
- package/dist/mcp-server/common/paths.d.ts.map +1 -1
- package/dist/mcp-server/common/paths.js +2 -2
- package/dist/mcp-server/common/paths.js.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.js +4 -2
- package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
- package/dist/mcp-server/helpers/github.helper.js +1 -1
- package/dist/mcp-server/index.js +7 -2
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/mcp-server/tools/base.tool.d.ts +6 -2
- package/dist/mcp-server/tools/base.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/base.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.js +4 -1
- package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +3 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -1
- package/package.json +12 -12
- package/wiki/extensions/helpers/error/index.md +0 -227
- package/wiki/extensions/helpers/redis/index.md +0 -488
- package/wiki/extensions/helpers/testing/index.md +0 -510
- package/wiki/guides/core-concepts/services.md +0 -119
- package/wiki/guides/tutorials/testing.md +0 -722
- package/wiki/index.md +0 -183
- package/wiki/references/base/datasources.md +0 -454
- package/wiki/references/base/middlewares.md +0 -590
- package/wiki/references/base/repositories/mixins.md +0 -335
- package/wiki/references/base/services.md +0 -201
- package/wiki/references/utilities/crypto.md +0 -56
- package/wiki/references/utilities/module.md +0 -42
- /package/{wiki → content}/extensions/components/mail/api.md +0 -0
- /package/{wiki → content}/extensions/components/template/api-page.md +0 -0
- /package/{wiki → content}/extensions/components/template/errors-page.md +0 -0
- /package/{wiki → content}/extensions/components/template/single-page.md +0 -0
- /package/{wiki → content}/extensions/components/template/usage-page.md +0 -0
- /package/{wiki → content}/extensions/helpers/kafka/admin.md +0 -0
- /package/{wiki → content}/extensions/helpers/kafka/consumer.md +0 -0
- /package/{wiki → content}/extensions/helpers/kafka/index.md +0 -0
- /package/{wiki → content}/extensions/helpers/kafka/producer.md +0 -0
- /package/{wiki → content}/extensions/helpers/kafka/schema-registry.md +0 -0
- /package/{wiki → content}/extensions/helpers/network/api.md +0 -0
- /package/{wiki → content}/extensions/helpers/socket-io/api.md +0 -0
- /package/{wiki → content}/extensions/helpers/template/single-page.md +0 -0
- /package/{wiki → content}/extensions/helpers/uid/index.md +0 -0
- /package/{wiki → content}/guides/core-concepts/components-guide.md +0 -0
- /package/{wiki → content}/public/logo.svg +0 -0
- /package/{wiki → content}/references/base/filter-system/pattern-matching.md +0 -0
- /package/{wiki → content}/references/base/filter-system/range-operators.md +0 -0
- /package/{wiki → content}/references/utilities/date.md +0 -0
- /package/{wiki → content}/references/utilities/performance.md +0 -0
- /package/{wiki → content}/references/utilities/request.md +0 -0
- /package/{wiki → content}/references/utilities/statuses.md +0 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Testing Your IGNIS Application
|
|
2
|
+
|
|
3
|
+
This guide shows you how to write tests for your IGNIS application.
|
|
4
|
+
|
|
5
|
+
**Time to Complete:** ~30 minutes
|
|
6
|
+
|
|
7
|
+
## Choose Your Test Framework
|
|
8
|
+
|
|
9
|
+
**IGNIS works with any test framework.** You can use whichever testing tool you prefer:
|
|
10
|
+
|
|
11
|
+
| Framework | Description |
|
|
12
|
+
|-----------|-------------|
|
|
13
|
+
| **Jest** | Popular, feature-rich testing framework |
|
|
14
|
+
| **Vitest** | Fast, Vite-native testing framework |
|
|
15
|
+
| **Bun Test** | Built-in test runner for Bun |
|
|
16
|
+
| **Playwright** | End-to-end testing for web applications |
|
|
17
|
+
| **node:test** | Node.js native test module |
|
|
18
|
+
| **Mocha** | Flexible testing framework |
|
|
19
|
+
| **Any other** | All test frameworks work with IGNIS |
|
|
20
|
+
|
|
21
|
+
Since IGNIS is just a TypeScript/JavaScript application framework, you can test it with any tool that supports TypeScript.
|
|
22
|
+
|
|
23
|
+
> [!TIP] IGNIS Testing Extension
|
|
24
|
+
> IGNIS does not ship its own test framework - use the runner your project already standardizes on (the framework itself is tested with Bun Test).
|
|
25
|
+
|
|
26
|
+
## Prerequisites
|
|
27
|
+
|
|
28
|
+
Before starting, ensure you have:
|
|
29
|
+
- A working IGNIS application (see [Building a CRUD API](./building-a-crud-api.md))
|
|
30
|
+
- Basic understanding of [Controllers](../core-concepts/rest-controllers.md) and [Repositories](../core-concepts/persistent/)
|
|
31
|
+
|
|
32
|
+
## Quick Examples with Popular Frameworks
|
|
33
|
+
|
|
34
|
+
### Shared Test App Helper
|
|
35
|
+
|
|
36
|
+
`BaseApplication` has no `request()` method of its own, and `getServer()` has no routes mounted on it until `start()` runs `server.route(basePath, rootRouter)`. The router that actually carries your bound controllers is `getRootRouter()` (an `OpenAPIHono` instance, which has Hono's in-process `request()` testing helper). Start the real application once and reuse it across test files:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// __tests__/helpers/test-app.ts
|
|
40
|
+
import { Application, appConfigs } from '../../src/application';
|
|
41
|
+
|
|
42
|
+
export const testApp = new Application({ scope: 'TestApp', config: appConfigs });
|
|
43
|
+
|
|
44
|
+
// getRootRouter() carries the bound controllers - request() exercises them in-process,
|
|
45
|
+
// with no network socket involved.
|
|
46
|
+
export const testServer = () => testApp.getRootRouter();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Using Vitest
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// __tests__/todo.test.ts
|
|
53
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
54
|
+
import { testApp, testServer } from './helpers/test-app';
|
|
55
|
+
|
|
56
|
+
describe('Todo API', () => {
|
|
57
|
+
beforeAll(async () => {
|
|
58
|
+
// start() runs the full lifecycle (preConfigure -> registerDataSources ->
|
|
59
|
+
// registerComponents -> registerControllers) and opens the HTTP server.
|
|
60
|
+
await testApp.start();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
afterAll(async () => {
|
|
64
|
+
await testApp.stop();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should return list of todos', async () => {
|
|
68
|
+
const response = await testServer().request('/api/todos', { method: 'GET' });
|
|
69
|
+
|
|
70
|
+
expect(response.status).toBe(200);
|
|
71
|
+
// ControllerFactory's generated GET / wraps reads in { count, data } by default too
|
|
72
|
+
// (unless the caller sends `x-request-count-data: false`) - unlike the repository API,
|
|
73
|
+
// where find()/findOne()/findById() return rows directly.
|
|
74
|
+
const body = await response.json();
|
|
75
|
+
expect(Array.isArray(body.data)).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should create a new todo', async () => {
|
|
79
|
+
const response = await testServer().request('/api/todos', {
|
|
80
|
+
method: 'POST',
|
|
81
|
+
headers: { 'Content-Type': 'application/json' },
|
|
82
|
+
body: JSON.stringify({ title: 'Test Todo' }),
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(response.status).toBe(201);
|
|
86
|
+
const body = await response.json();
|
|
87
|
+
expect(body.data.title).toBe('Test Todo');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Using Jest
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// __tests__/todo.test.ts
|
|
96
|
+
import { testApp, testServer } from './helpers/test-app';
|
|
97
|
+
|
|
98
|
+
describe('Todo API', () => {
|
|
99
|
+
beforeAll(async () => {
|
|
100
|
+
await testApp.start();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
afterAll(async () => {
|
|
104
|
+
await testApp.stop();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should return list of todos', async () => {
|
|
108
|
+
const response = await testServer().request('/api/todos', { method: 'GET' });
|
|
109
|
+
|
|
110
|
+
expect(response.status).toBe(200);
|
|
111
|
+
const body = await response.json();
|
|
112
|
+
expect(Array.isArray(body.data)).toBe(true);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Using Bun Test
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// __tests__/todo.test.ts
|
|
121
|
+
import { describe, it, expect, beforeAll, afterAll } from 'bun:test';
|
|
122
|
+
import { testApp, testServer } from './helpers/test-app';
|
|
123
|
+
|
|
124
|
+
describe('Todo API', () => {
|
|
125
|
+
beforeAll(async () => {
|
|
126
|
+
await testApp.start();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
afterAll(async () => {
|
|
130
|
+
await testApp.stop();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should return list of todos', async () => {
|
|
134
|
+
const response = await testServer().request('/api/todos', { method: 'GET' });
|
|
135
|
+
|
|
136
|
+
expect(response.status).toBe(200);
|
|
137
|
+
const body = await response.json();
|
|
138
|
+
expect(Array.isArray(body.data)).toBe(true);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Using Playwright (E2E)
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// e2e/todo.spec.ts
|
|
147
|
+
import { test, expect } from '@playwright/test';
|
|
148
|
+
|
|
149
|
+
test.describe('Todo Application', () => {
|
|
150
|
+
test('should display todo list', async ({ request }) => {
|
|
151
|
+
const response = await request.get(`http://localhost:3000/api/todos`);
|
|
152
|
+
|
|
153
|
+
expect(response.ok()).toBeTruthy();
|
|
154
|
+
const todos = await response.json();
|
|
155
|
+
expect(Array.isArray(todos.data)).toBe(true);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Project Structure
|
|
161
|
+
|
|
162
|
+
Organize your tests alongside your source code:
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
my-ignis-app/
|
|
166
|
+
├── src/
|
|
167
|
+
│ ├── controllers/
|
|
168
|
+
│ ├── services/
|
|
169
|
+
│ └── repositories/
|
|
170
|
+
├── __tests__/
|
|
171
|
+
│ ├── controllers/
|
|
172
|
+
│ │ └── todo.controller.test.ts
|
|
173
|
+
│ ├── services/
|
|
174
|
+
│ │ └── todo.service.test.ts
|
|
175
|
+
│ ├── repositories/
|
|
176
|
+
│ │ └── todo.repository.test.ts
|
|
177
|
+
│ └── integration/
|
|
178
|
+
│ └── auth-flow.test.ts
|
|
179
|
+
└── package.json
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Package.json Scripts
|
|
183
|
+
|
|
184
|
+
Choose scripts based on your preferred test framework:
|
|
185
|
+
|
|
186
|
+
**Bun Test:**
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"scripts": {
|
|
190
|
+
"test": "bun test",
|
|
191
|
+
"test:watch": "bun test --watch",
|
|
192
|
+
"test:coverage": "bun test --coverage"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Vitest:**
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"scripts": {
|
|
201
|
+
"test": "vitest run",
|
|
202
|
+
"test:watch": "vitest",
|
|
203
|
+
"test:coverage": "vitest run --coverage"
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Jest:**
|
|
209
|
+
```json
|
|
210
|
+
{
|
|
211
|
+
"scripts": {
|
|
212
|
+
"test": "jest",
|
|
213
|
+
"test:watch": "jest --watch",
|
|
214
|
+
"test:coverage": "jest --coverage"
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Playwright (E2E):**
|
|
220
|
+
```json
|
|
221
|
+
{
|
|
222
|
+
"scripts": {
|
|
223
|
+
"test:e2e": "playwright test",
|
|
224
|
+
"test:e2e:ui": "playwright test --ui"
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Best Practices
|
|
230
|
+
|
|
231
|
+
### 1. Use Descriptive Test Names
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
test('login with valid credentials returns a JWT and the user id', async () => {
|
|
235
|
+
// ...
|
|
236
|
+
});
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### 2. Isolate Test Data
|
|
240
|
+
|
|
241
|
+
Give every test its own fixtures - unique ids, fresh records - so tests never depend on execution order.
|
|
242
|
+
|
|
243
|
+
### 3. Test Edge Cases
|
|
244
|
+
|
|
245
|
+
Cover the boundaries alongside the happy path: empty input, duplicate ids, missing records, unauthorized callers.
|
|
246
|
+
|
|
247
|
+
## Next Steps
|
|
248
|
+
|
|
249
|
+
- [Best Practices](../../best-practices/code-style-standards/) - Code quality standards
|
|
250
|
+
- [Troubleshooting](../../best-practices/troubleshooting-tips.md) - Common issues
|
|
251
|
+
|
|
252
|
+
## Summary
|
|
253
|
+
|
|
254
|
+
| What to Test | How |
|
|
255
|
+
|--------------|-----|
|
|
256
|
+
| **Controllers** | Use `getRootRouter().request()` to make in-process HTTP calls |
|
|
257
|
+
| **Services** | Instantiate and call methods directly |
|
|
258
|
+
| **Repositories** | Use DI container, test with real/mock DB |
|
|
259
|
+
| **Integration** | Chain multiple operations with shared context |
|
|
260
|
+
| **E2E** | Use Playwright or similar for full flow testing |
|
|
261
|
+
|
|
262
|
+
**Key Takeaways:**
|
|
263
|
+
- Use any test framework you prefer (Jest, Vitest, Bun Test, Playwright, etc.)
|
|
264
|
+
- All frameworks work seamlessly with IGNIS applications
|
package/content/index.md
ADDED
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "IGNIS",
|
|
3
|
+
"short_name": "IGNIS",
|
|
4
|
+
"theme_color": "#AF5F5F",
|
|
5
|
+
"background_color": "#0B0A0C",
|
|
6
|
+
"display": "standalone",
|
|
7
|
+
"icons": [
|
|
8
|
+
{ "src": "/logo.svg", "sizes": "any", "type": "image/svg+xml" },
|
|
9
|
+
{ "src": "/apple-touch-icon.png", "sizes": "180x180", "type": "image/png" }
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -6,7 +6,7 @@ difficulty: beginner
|
|
|
6
6
|
|
|
7
7
|
# Deep Dive: Application
|
|
8
8
|
|
|
9
|
-
Technical reference for `AbstractApplication` and `BaseApplication` - the foundation classes for every
|
|
9
|
+
Technical reference for `AbstractApplication` and `BaseApplication` - the foundation classes for every IGNIS application.
|
|
10
10
|
|
|
11
11
|
**Files:**
|
|
12
12
|
- `packages/core/src/base/applications/abstract.ts`
|
|
@@ -49,7 +49,7 @@ The constructor:
|
|
|
49
49
|
|
|
50
50
|
| Feature | Description |
|
|
51
51
|
| :--- | :--- |
|
|
52
|
-
| **Hono Instance** | Creates and holds two `OpenAPIHono` instances
|
|
52
|
+
| **Hono Instance** | Creates and holds two `OpenAPIHono` instances - a main server and a root router |
|
|
53
53
|
| **Runtime Detection** | Auto-detects Bun or Node.js via `RuntimeModules.detect()` and uses the appropriate server implementation |
|
|
54
54
|
| **Core Bindings** | Registers `CoreBindings.APPLICATION_INSTANCE`, `CoreBindings.APPLICATION_SERVER`, and `CoreBindings.APPLICATION_ROOT_ROUTER` |
|
|
55
55
|
| **Lifecycle Management** | Defines abstract methods (`preConfigure`, `postConfigure`, `setupMiddlewares`, `staticConfigure`, `initialize`, `getAppInfo`) |
|
|
@@ -167,7 +167,7 @@ service<Base extends IService, Args extends AnyObject = any>(
|
|
|
167
167
|
opts?: TMixinOpts<Args>,
|
|
168
168
|
): Binding<Base>
|
|
169
169
|
|
|
170
|
-
repository<Base extends IRepository
|
|
170
|
+
repository<Base extends IRepository, Args extends AnyObject = any>(
|
|
171
171
|
ctor: TClass<Base>,
|
|
172
172
|
opts?: TMixinOpts<Args>,
|
|
173
173
|
): Binding<Base>
|
|
@@ -305,8 +305,7 @@ interface IApplicationConfigs {
|
|
|
305
305
|
bootOptions?: IBootOptions; // Boot system configuration
|
|
306
306
|
debug?: { shouldShowRoutes?: boolean }; // Show registered routes on startup
|
|
307
307
|
transports?: TControllerTransport[]; // Controller transports: 'rest' | 'grpc' (default: ['rest'])
|
|
308
|
-
strictPath?: boolean
|
|
309
|
-
[key: string]: any; // Extensible
|
|
308
|
+
[key: string]: any; // Extensible (e.g. strictPath?: boolean - Hono strict path matching, default: true)
|
|
310
309
|
}
|
|
311
310
|
```
|
|
312
311
|
|
|
@@ -262,10 +262,26 @@ interface IBootstrapper {
|
|
|
262
262
|
Report generated after boot completion.
|
|
263
263
|
|
|
264
264
|
```typescript
|
|
265
|
-
interface IBootReport {
|
|
265
|
+
interface IBootReport {
|
|
266
|
+
/** Class names of the booters that actually ran, in execution order. */
|
|
267
|
+
booters: string[];
|
|
268
|
+
phases: IBootPhaseReport[];
|
|
269
|
+
totalDurationMs: number;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
interface IBootPhaseReport {
|
|
273
|
+
phase: TBootPhase;
|
|
274
|
+
durationMs: number;
|
|
275
|
+
}
|
|
266
276
|
```
|
|
267
277
|
|
|
268
|
-
|
|
278
|
+
| Property | Type | Description |
|
|
279
|
+
|----------|------|-------------|
|
|
280
|
+
| `booters` | `string[]` | Class names of the booters that actually ran, in execution order |
|
|
281
|
+
| `phases` | `IBootPhaseReport[]` | Per-phase timing: `{ phase, durationMs }` for each executed phase |
|
|
282
|
+
| `totalDurationMs` | `number` | Total wall-clock duration of the whole `boot()` call |
|
|
283
|
+
|
|
284
|
+
Built by `Bootstrapper.generateReport()` (private) at the end of `boot()`.
|
|
269
285
|
|
|
270
286
|
|
|
271
287
|
### IApplication
|
|
@@ -674,14 +690,12 @@ Load class constructors from files.
|
|
|
674
690
|
```typescript
|
|
675
691
|
async function loadClasses(opts: {
|
|
676
692
|
files: string[];
|
|
677
|
-
root: string;
|
|
678
693
|
}): Promise<AnyType[]>
|
|
679
694
|
```
|
|
680
695
|
|
|
681
696
|
| Parameter | Type | Description |
|
|
682
697
|
|-----------|------|-------------|
|
|
683
698
|
| `files` | `string[]` | Array of file paths to load |
|
|
684
|
-
| `root` | `string` | Project root (for error messages) |
|
|
685
699
|
|
|
686
700
|
**Returns:** `Promise<AnyType[]>` - Array of loaded class constructors (filtered by `isClass` type guard)
|
|
687
701
|
|
|
@@ -693,7 +707,6 @@ const classes = await loadClasses({
|
|
|
693
707
|
'/path/to/project/controllers/user.controller.js',
|
|
694
708
|
'/path/to/project/controllers/product.controller.js'
|
|
695
709
|
],
|
|
696
|
-
root: '/path/to/project'
|
|
697
710
|
});
|
|
698
711
|
// [UserController, ProductController]
|
|
699
712
|
```
|