@ttoss/postgresdb
Advanced tools
+2
-2
| { | ||
| "name": "@ttoss/postgresdb", | ||
| "version": "0.2.23", | ||
| "version": "0.2.24", | ||
| "description": "A library to handle PostgreSQL database connections and queries", | ||
@@ -34,3 +34,3 @@ "license": "MIT", | ||
| "tsup": "^8.5.1", | ||
| "@ttoss/config": "^1.35.10" | ||
| "@ttoss/config": "^1.35.11" | ||
| }, | ||
@@ -37,0 +37,0 @@ "keywords": [ |
+109
-0
@@ -62,2 +62,4 @@ # @ttoss/postgresdb | ||
| **Important:** You must use the `declare` keyword on class properties to ensure TypeScript doesn't emit them as actual fields. Without `declare`, public class fields would shadow Sequelize's getters and setters, blocking access to the model's data. See [Sequelize documentation on public class fields](https://sequelize.org/docs/v6/core-concepts/model-basics/#caveat-with-public-class-fields) for details. | ||
| _All [sequelize-typescript](https://github.com/sequelize/sequelize-typescript) decorators are available._ | ||
@@ -172,2 +174,6 @@ | ||
| { | ||
| "compilerOptions": { | ||
| "experimentalDecorators": true, | ||
| "emitDecoratorMetadata": true | ||
| }, | ||
| "include": ["src", "../postgresdb/src"] | ||
@@ -186,2 +192,105 @@ } | ||
| ## Testing | ||
| Testing models with decorators requires special configuration because Jest's Babel transformer doesn't properly transpile TypeScript decorators. The solution is to build your models before running tests. | ||
| **Why test your models?** Beyond validating functionality, tests serve as a critical safety check for schema changes. They ensure that running `sync --alter` won't accidentally remove columns or relationships from your database. If a model property is missing or incorrectly defined, tests will fail before you can damage production data. | ||
| ### Setup | ||
| **1. Install dependencies:** | ||
| ```bash | ||
| pnpm add -D @testcontainers/postgresql jest @types/jest | ||
| ``` | ||
| **2. Configure `tsconfig.json`:** | ||
| ```json | ||
| { | ||
| "compilerOptions": { | ||
| "experimentalDecorators": true, | ||
| "emitDecoratorMetadata": true | ||
| } | ||
| } | ||
| ``` | ||
| These options are required for decorator support. Without them, TypeScript won't properly compile decorator metadata. | ||
| **3. Add build script to `package.json`:** | ||
| ```json | ||
| { | ||
| "scripts": { | ||
| "build": "tsup", | ||
| "pretest": "pnpm run build", | ||
| "test": "jest" | ||
| } | ||
| } | ||
| ``` | ||
| The `pretest` script ensures models are built before tests run. | ||
| ### Test Example | ||
| ```typescript | ||
| import { | ||
| PostgreSqlContainer, | ||
| StartedPostgreSqlContainer, | ||
| } from '@testcontainers/postgresql'; | ||
| import { initialize, Sequelize } from '@ttoss/postgresdb'; | ||
| import { models } from 'dist/index'; // Import from built output | ||
| let sequelize: Sequelize; | ||
| let postgresContainer: StartedPostgreSqlContainer; | ||
| jest.setTimeout(60000); | ||
| beforeAll(async () => { | ||
| // Start PostgreSQL container | ||
| postgresContainer = await new PostgreSqlContainer('postgres:17').start(); | ||
| // Initialize database with container credentials | ||
| const db = await initialize({ | ||
| models, | ||
| logging: false, | ||
| username: postgresContainer.getUsername(), | ||
| password: postgresContainer.getPassword(), | ||
| database: postgresContainer.getDatabase(), | ||
| host: postgresContainer.getHost(), | ||
| port: postgresContainer.getPort(), | ||
| }); | ||
| sequelize = db.sequelize; | ||
| // Sync database schema | ||
| await sequelize.sync(); | ||
| }); | ||
| afterAll(async () => { | ||
| await sequelize.close(); | ||
| await postgresContainer.stop(); | ||
| }); | ||
| describe('User model', () => { | ||
| test('should create and retrieve user', async () => { | ||
| const userData = { email: 'test@example.com' }; | ||
| const user = await models.User.create(userData); | ||
| const foundUser = await models.User.findByPk(user.id); | ||
| expect(foundUser).toMatchObject(userData); | ||
| }); | ||
| }); | ||
| ``` | ||
| ### Key Points | ||
| - **Import from `dist/`**: Tests must import models from the compiled output (`dist/index`), not source files, because decorators aren't transpiled by Jest's Babel transformer. See [this Stack Overflow answer](https://stackoverflow.com/a/53920890/8786986) for details. | ||
| - **Testcontainers**: Use [`@testcontainers/postgresql`](https://www.npmjs.com/package/@testcontainers/postgresql) to spin up isolated PostgreSQL instances for each test run. | ||
| - **Timeout**: Set a longer timeout with `jest.setTimeout(60000)` as container startup can take time. | ||
| - **Sync schema**: Call `sequelize.sync()` after initialization to create tables based on your models. | ||
| - **Schema validation**: Tests verify that all model properties are correctly defined. This prevents `sync --alter` from accidentally removing database columns due to missing or misconfigured model properties. | ||
| For a complete working example with full test configuration, see the [terezinha-farm/postgresdb](https://github.com/ttoss/ttoss/tree/main/terezinha-farm/postgresdb) example in this repository. | ||
| ## API Reference | ||
@@ -188,0 +297,0 @@ |
12627
47.24%328
49.77%