@sqldoc/templates 0.0.1 → 0.0.2
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/package.json +10 -8
- package/src/__tests__/dedent.test.ts +0 -45
- package/src/__tests__/docker-templates.test.ts +0 -134
- package/src/__tests__/go-structs.test.ts +0 -184
- package/src/__tests__/naming.test.ts +0 -48
- package/src/__tests__/python-dataclasses.test.ts +0 -185
- package/src/__tests__/rust-structs.test.ts +0 -176
- package/src/__tests__/tags-helpers.test.ts +0 -72
- package/src/__tests__/type-mapping.test.ts +0 -332
- package/src/__tests__/typescript.test.ts +0 -202
- package/src/cobol-copybook/test/.gitignore +0 -6
- package/src/cobol-copybook/test/Dockerfile +0 -7
- package/src/csharp-records/test/.gitignore +0 -6
- package/src/csharp-records/test/Dockerfile +0 -6
- package/src/diesel/test/.gitignore +0 -6
- package/src/diesel/test/Dockerfile +0 -16
- package/src/drizzle/test/.gitignore +0 -6
- package/src/drizzle/test/Dockerfile +0 -8
- package/src/drizzle/test/test.ts +0 -71
- package/src/efcore/test/.gitignore +0 -6
- package/src/efcore/test/Dockerfile +0 -7
- package/src/go-structs/test/.gitignore +0 -6
- package/src/go-structs/test/Dockerfile +0 -13
- package/src/go-structs/test/test.go +0 -71
- package/src/gorm/test/.gitignore +0 -6
- package/src/gorm/test/Dockerfile +0 -13
- package/src/gorm/test/test.go +0 -65
- package/src/java-records/test/.gitignore +0 -6
- package/src/java-records/test/Dockerfile +0 -11
- package/src/java-records/test/Test.java +0 -93
- package/src/jpa/test/.gitignore +0 -6
- package/src/jpa/test/Dockerfile +0 -14
- package/src/jpa/test/Test.java +0 -111
- package/src/json-schema/test/.gitignore +0 -6
- package/src/json-schema/test/Dockerfile +0 -18
- package/src/knex/test/.gitignore +0 -6
- package/src/knex/test/Dockerfile +0 -7
- package/src/knex/test/test.ts +0 -75
- package/src/kotlin-data/test/.gitignore +0 -6
- package/src/kotlin-data/test/Dockerfile +0 -14
- package/src/kotlin-data/test/Test.kt +0 -82
- package/src/kysely/test/.gitignore +0 -6
- package/src/kysely/test/Dockerfile +0 -8
- package/src/kysely/test/test.ts +0 -82
- package/src/prisma/test/.gitignore +0 -6
- package/src/prisma/test/Dockerfile +0 -7
- package/src/protobuf/test/.gitignore +0 -6
- package/src/protobuf/test/Dockerfile +0 -6
- package/src/pydantic/test/.gitignore +0 -6
- package/src/pydantic/test/Dockerfile +0 -8
- package/src/pydantic/test/test.py +0 -63
- package/src/python-dataclasses/test/.gitignore +0 -6
- package/src/python-dataclasses/test/Dockerfile +0 -8
- package/src/python-dataclasses/test/test.py +0 -63
- package/src/rust-structs/test/.gitignore +0 -6
- package/src/rust-structs/test/Dockerfile +0 -22
- package/src/rust-structs/test/test.rs +0 -82
- package/src/sqlalchemy/test/.gitignore +0 -6
- package/src/sqlalchemy/test/Dockerfile +0 -8
- package/src/sqlalchemy/test/test.py +0 -61
- package/src/sqlc/test/.gitignore +0 -6
- package/src/sqlc/test/Dockerfile +0 -13
- package/src/sqlc/test/test.go +0 -91
- package/src/typescript/test/.gitignore +0 -6
- package/src/typescript/test/Dockerfile +0 -8
- package/src/typescript/test/test.ts +0 -89
- package/src/xsd/test/.gitignore +0 -6
- package/src/xsd/test/Dockerfile +0 -6
- package/src/zod/test/.gitignore +0 -6
- package/src/zod/test/Dockerfile +0 -6
package/src/jpa/test/Dockerfile
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
FROM eclipse-temurin:21-jdk-alpine
|
|
2
|
-
WORKDIR /app
|
|
3
|
-
RUN apk add --no-cache curl
|
|
4
|
-
# Download Jakarta Persistence API JARs and PostgreSQL JDBC driver
|
|
5
|
-
RUN mkdir -p /deps && \
|
|
6
|
-
curl -sL -o /deps/jakarta.persistence-api-3.2.0.jar https://repo1.maven.org/maven2/jakarta/persistence/jakarta.persistence-api/3.2.0/jakarta.persistence-api-3.2.0.jar && \
|
|
7
|
-
curl -sL -o /deps/jakarta.validation-api-3.1.0.jar https://repo1.maven.org/maven2/jakarta/validation/jakarta.validation-api/3.1.0/jakarta.validation-api-3.1.0.jar && \
|
|
8
|
-
curl -sL -o /deps/jakarta.annotation-api-3.0.0.jar https://repo1.maven.org/maven2/jakarta/annotation/jakarta.annotation-api/3.0.0/jakarta.annotation-api-3.0.0.jar && \
|
|
9
|
-
curl -sL -o /deps/postgresql-42.7.4.jar https://repo1.maven.org/maven2/org/postgresql/postgresql/42.7.4/postgresql-42.7.4.jar
|
|
10
|
-
COPY . .
|
|
11
|
-
# Step 1: compile the generated JPA entities + test
|
|
12
|
-
RUN javac -cp "/deps/*:." *.java Test.java
|
|
13
|
-
# Step 2: run integration test against real DB
|
|
14
|
-
CMD ["java", "-cp", "/deps/*:.", "Test"]
|
package/src/jpa/test/Test.java
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import java.sql.*;
|
|
2
|
-
import java.lang.reflect.Field;
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Integration test for @sqldoc/templates/jpa
|
|
6
|
-
* Verifies generated JPA entities compile, have expected fields, and DB has expected data.
|
|
7
|
-
*/
|
|
8
|
-
public class Test {
|
|
9
|
-
static int failed = 0;
|
|
10
|
-
|
|
11
|
-
static void assertEq(Object actual, Object expected, String msg) {
|
|
12
|
-
if (!actual.equals(expected)) {
|
|
13
|
-
System.err.printf("FAIL: %s (got %s, expected %s)%n", msg, actual, expected);
|
|
14
|
-
failed++;
|
|
15
|
-
} else {
|
|
16
|
-
System.out.printf(" ok: %s%n", msg);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
static void assertHasField(Class<?> cls, String fieldName, String msg) {
|
|
21
|
-
try {
|
|
22
|
-
cls.getDeclaredField(fieldName);
|
|
23
|
-
System.out.printf(" ok: %s%n", msg);
|
|
24
|
-
} catch (NoSuchFieldException e) {
|
|
25
|
-
System.err.printf("FAIL: %s (field '%s' not found)%n", msg, fieldName);
|
|
26
|
-
failed++;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public static void main(String[] args) throws Exception {
|
|
31
|
-
String dbUrl = System.getenv("DATABASE_URL");
|
|
32
|
-
if (dbUrl == null || dbUrl.isEmpty()) {
|
|
33
|
-
System.err.println("DATABASE_URL not set");
|
|
34
|
-
System.exit(1);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Convert postgres(ql):// to jdbc:postgresql://, extracting userinfo for JDBC
|
|
38
|
-
var uri = java.net.URI.create(dbUrl.replaceFirst("^postgres(ql)?://", "http://"));
|
|
39
|
-
var userInfo = uri.getUserInfo();
|
|
40
|
-
var jdbcUrl = "jdbc:postgresql://" + uri.getHost() + ":" + (uri.getPort() > 0 ? uri.getPort() : 5432) + uri.getPath();
|
|
41
|
-
var query = uri.getQuery();
|
|
42
|
-
if (userInfo != null) {
|
|
43
|
-
var parts = userInfo.split(":", 2);
|
|
44
|
-
var sep = query != null ? "&" : "?";
|
|
45
|
-
jdbcUrl += (query != null ? "?" + query : "") + sep + "user=" + parts[0] + "&password=" + (parts.length > 1 ? parts[1] : "");
|
|
46
|
-
} else if (query != null) {
|
|
47
|
-
jdbcUrl += "?" + query;
|
|
48
|
-
}
|
|
49
|
-
dbUrl = jdbcUrl;
|
|
50
|
-
|
|
51
|
-
System.out.println("--- jpa integration test ---");
|
|
52
|
-
|
|
53
|
-
// 1. Verify generated entity classes have expected fields
|
|
54
|
-
assertHasField(Users.class, "id", "Users has 'id' field");
|
|
55
|
-
assertHasField(Users.class, "email", "Users has 'email' field");
|
|
56
|
-
assertHasField(Users.class, "name", "Users has 'name' field");
|
|
57
|
-
assertHasField(Users.class, "isActive", "Users has 'isActive' field");
|
|
58
|
-
assertHasField(Posts.class, "title", "Posts has 'title' field");
|
|
59
|
-
assertHasField(Posts.class, "viewCount", "Posts has 'viewCount' field");
|
|
60
|
-
|
|
61
|
-
// 2. Instantiate entity and populate via reflection (JPA entities have private fields)
|
|
62
|
-
try (Connection conn = DriverManager.getConnection(dbUrl)) {
|
|
63
|
-
try (PreparedStatement ps = conn.prepareStatement(
|
|
64
|
-
"SELECT id, email, name, age, is_active FROM users WHERE id = 1")) {
|
|
65
|
-
ResultSet rs = ps.executeQuery();
|
|
66
|
-
rs.next();
|
|
67
|
-
var user = new Users();
|
|
68
|
-
setField(user, "id", rs.getLong("id"));
|
|
69
|
-
setField(user, "email", rs.getString("email"));
|
|
70
|
-
setField(user, "name", rs.getString("name"));
|
|
71
|
-
setField(user, "age", rs.getObject("age") != null ? rs.getInt("age") : null);
|
|
72
|
-
setField(user, "isActive", rs.getBoolean("is_active"));
|
|
73
|
-
|
|
74
|
-
assertEq(getField(user, "email"), "test@example.com", "user.email matches");
|
|
75
|
-
assertEq(getField(user, "name"), "Test User", "user.name matches");
|
|
76
|
-
assertEq(getField(user, "isActive"), true, "user.isActive matches");
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
try (PreparedStatement ps = conn.prepareStatement(
|
|
80
|
-
"SELECT id, title, view_count FROM posts WHERE id = 1")) {
|
|
81
|
-
ResultSet rs = ps.executeQuery();
|
|
82
|
-
rs.next();
|
|
83
|
-
var post = new Posts();
|
|
84
|
-
setField(post, "id", rs.getLong("id"));
|
|
85
|
-
setField(post, "title", rs.getString("title"));
|
|
86
|
-
setField(post, "viewCount", rs.getInt("view_count"));
|
|
87
|
-
|
|
88
|
-
assertEq(getField(post, "title"), "Hello World", "post.title matches");
|
|
89
|
-
assertEq(getField(post, "viewCount"), 42, "post.viewCount matches");
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (failed > 0) {
|
|
94
|
-
System.err.printf("%n%d assertion(s) failed%n", failed);
|
|
95
|
-
System.exit(1);
|
|
96
|
-
}
|
|
97
|
-
System.out.println("\nAll assertions passed!");
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
static void setField(Object obj, String name, Object value) throws Exception {
|
|
101
|
-
Field f = obj.getClass().getDeclaredField(name);
|
|
102
|
-
f.setAccessible(true);
|
|
103
|
-
f.set(obj, value);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
static Object getField(Object obj, String name) throws Exception {
|
|
107
|
-
Field f = obj.getClass().getDeclaredField(name);
|
|
108
|
-
f.setAccessible(true);
|
|
109
|
-
return f.get(obj);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
FROM node:23-slim
|
|
2
|
-
WORKDIR /app
|
|
3
|
-
COPY . .
|
|
4
|
-
RUN npm init -y && npm install ajv@8 ajv-formats@3 --save-dev
|
|
5
|
-
RUN node -e " \
|
|
6
|
-
const Ajv = require('ajv/dist/2020'); \
|
|
7
|
-
const addFormats = require('ajv-formats'); \
|
|
8
|
-
const schema = require('./schema.json'); \
|
|
9
|
-
const ajv = new Ajv({ allErrors: true }); \
|
|
10
|
-
addFormats(ajv); \
|
|
11
|
-
for (const [name, def] of Object.entries(schema.\$defs || {})) { \
|
|
12
|
-
const valid = ajv.validateSchema(def); \
|
|
13
|
-
if (!valid) { console.error('INVALID:', name, ajv.errors); process.exit(1); } \
|
|
14
|
-
console.log('OK:', name); \
|
|
15
|
-
} \
|
|
16
|
-
console.log('All schemas valid'); \
|
|
17
|
-
"
|
|
18
|
-
CMD ["echo", "ok"]
|
package/src/knex/test/.gitignore
DELETED
package/src/knex/test/Dockerfile
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
FROM node:23-slim
|
|
2
|
-
WORKDIR /app
|
|
3
|
-
COPY . .
|
|
4
|
-
RUN npm init -y && npm pkg set type=module && npm install typescript@5 knex@3 pg @types/pg @types/node --save-dev
|
|
5
|
-
# Note: knex module augmentation (knex/types/tables) doesn't typecheck under nodenext.
|
|
6
|
-
# Skip tsc and focus on the runtime integration test.
|
|
7
|
-
CMD ["node", "--experimental-strip-types", "test.ts"]
|
package/src/knex/test/test.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration test for @sqldoc/templates/knex
|
|
3
|
-
* Connects to real Postgres via Knex, verifies generated table types work.
|
|
4
|
-
*/
|
|
5
|
-
import knex from 'knex'
|
|
6
|
-
// Import to ensure the module augmentation is loaded
|
|
7
|
-
import type {} from './database.ts'
|
|
8
|
-
|
|
9
|
-
const DATABASE_URL = process.env.DATABASE_URL
|
|
10
|
-
if (!DATABASE_URL) {
|
|
11
|
-
console.error('DATABASE_URL not set')
|
|
12
|
-
process.exit(1)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const db = knex({
|
|
16
|
-
client: 'pg',
|
|
17
|
-
connection: DATABASE_URL,
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
let failed = 0
|
|
21
|
-
function assert(condition: boolean, msg: string) {
|
|
22
|
-
if (!condition) {
|
|
23
|
-
console.error(`FAIL: ${msg}`)
|
|
24
|
-
failed++
|
|
25
|
-
} else {
|
|
26
|
-
console.log(` ok: ${msg}`)
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async function run() {
|
|
31
|
-
try {
|
|
32
|
-
console.log('--- knex integration test ---')
|
|
33
|
-
|
|
34
|
-
// 1. Query known seeded user using Knex's type-safe table method
|
|
35
|
-
const users = await db('users').where({ id: 1 })
|
|
36
|
-
const user = users[0]
|
|
37
|
-
|
|
38
|
-
assert(user.email === 'test@example.com', 'user email matches')
|
|
39
|
-
assert(user.name === 'Test User', 'user name matches')
|
|
40
|
-
assert(user.is_active === true, 'user is_active matches')
|
|
41
|
-
|
|
42
|
-
// 2. Query known seeded post
|
|
43
|
-
const posts = await db('posts').where({ id: 1 })
|
|
44
|
-
assert(posts.length === 1, 'seeded post found')
|
|
45
|
-
assert(posts[0].title === 'Hello World', 'post title matches')
|
|
46
|
-
|
|
47
|
-
// 3. Insert a new post
|
|
48
|
-
await db('posts').insert({
|
|
49
|
-
user_id: 1,
|
|
50
|
-
title: 'Post from knex',
|
|
51
|
-
body: 'test body',
|
|
52
|
-
view_count: 0,
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
// 4. Read it back
|
|
56
|
-
const newPosts = await db('posts').where({ title: 'Post from knex' })
|
|
57
|
-
assert(newPosts.length === 1, 'inserted post found')
|
|
58
|
-
assert(newPosts[0].title === 'Post from knex', 'inserted post title matches')
|
|
59
|
-
// pg returns bigint columns as strings; use Number() for comparison
|
|
60
|
-
assert(Number(newPosts[0].user_id) === 1, 'inserted post user_id matches')
|
|
61
|
-
|
|
62
|
-
if (failed > 0) {
|
|
63
|
-
console.error(`\n${failed} assertion(s) failed`)
|
|
64
|
-
process.exit(1)
|
|
65
|
-
}
|
|
66
|
-
console.log('\nAll assertions passed!')
|
|
67
|
-
} finally {
|
|
68
|
-
await db.destroy()
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
run().catch((err) => {
|
|
73
|
-
console.error(err)
|
|
74
|
-
process.exit(1)
|
|
75
|
-
})
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
FROM eclipse-temurin:21-jdk-alpine
|
|
2
|
-
RUN apk add --no-cache curl unzip zip bash
|
|
3
|
-
# Install Kotlin via SDKMAN
|
|
4
|
-
RUN curl -s https://get.sdkman.io | bash && \
|
|
5
|
-
bash -c "source /root/.sdkman/bin/sdkman-init.sh && sdk install kotlin"
|
|
6
|
-
# Download PostgreSQL JDBC driver
|
|
7
|
-
RUN mkdir -p /deps && \
|
|
8
|
-
curl -sL -o /deps/postgresql-42.7.4.jar https://repo1.maven.org/maven2/org/postgresql/postgresql/42.7.4/postgresql-42.7.4.jar
|
|
9
|
-
WORKDIR /app
|
|
10
|
-
COPY . .
|
|
11
|
-
# Step 1: compile the generated data classes + test
|
|
12
|
-
RUN bash -c "source /root/.sdkman/bin/sdkman-init.sh && kotlinc -cp /deps/* *.kt Test.kt -include-runtime -d out.jar"
|
|
13
|
-
# Step 2: run integration test against real DB
|
|
14
|
-
CMD ["java", "-cp", "out.jar:/deps/*", "TestKt"]
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import java.sql.DriverManager
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Integration test for @sqldoc/templates/kotlin-data
|
|
5
|
-
* Connects to real Postgres via JDBC, verifies generated data classes work with actual data.
|
|
6
|
-
*/
|
|
7
|
-
var failed = 0
|
|
8
|
-
|
|
9
|
-
fun assertEq(actual: Any?, expected: Any?, msg: String) {
|
|
10
|
-
if (actual != expected) {
|
|
11
|
-
System.err.println("FAIL: $msg (got $actual, expected $expected)")
|
|
12
|
-
failed++
|
|
13
|
-
} else {
|
|
14
|
-
println(" ok: $msg")
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
fun main() {
|
|
19
|
-
var dbUrl = System.getenv("DATABASE_URL")
|
|
20
|
-
if (dbUrl.isNullOrEmpty()) {
|
|
21
|
-
System.err.println("DATABASE_URL not set")
|
|
22
|
-
System.exit(1)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Convert postgres(ql):// to jdbc:postgresql://, extracting userinfo for JDBC
|
|
26
|
-
val uri = java.net.URI(dbUrl.replaceFirst(Regex("^postgres(ql)?://"), "http://"))
|
|
27
|
-
val userInfo = uri.userInfo
|
|
28
|
-
var jdbcUrl = "jdbc:postgresql://${uri.host}:${if (uri.port > 0) uri.port else 5432}${uri.path}"
|
|
29
|
-
val query = uri.query
|
|
30
|
-
if (userInfo != null) {
|
|
31
|
-
val parts = userInfo.split(":", limit = 2)
|
|
32
|
-
val sep = if (query != null) "&" else "?"
|
|
33
|
-
jdbcUrl += (if (query != null) "?$query" else "") + "${sep}user=${parts[0]}&password=${parts.getOrElse(1) { "" }}"
|
|
34
|
-
} else if (query != null) {
|
|
35
|
-
jdbcUrl += "?$query"
|
|
36
|
-
}
|
|
37
|
-
dbUrl = jdbcUrl
|
|
38
|
-
|
|
39
|
-
println("--- kotlin-data integration test ---")
|
|
40
|
-
|
|
41
|
-
DriverManager.getConnection(dbUrl).use { conn ->
|
|
42
|
-
// 1. Query user and construct generated data class
|
|
43
|
-
conn.prepareStatement("SELECT id, email, name, age, is_active, created_at FROM users WHERE id = 1").use { ps ->
|
|
44
|
-
val rs = ps.executeQuery()
|
|
45
|
-
rs.next()
|
|
46
|
-
val user = Users(
|
|
47
|
-
id = rs.getLong("id"),
|
|
48
|
-
email = rs.getString("email"),
|
|
49
|
-
name = rs.getString("name"),
|
|
50
|
-
age = rs.getInt("age"),
|
|
51
|
-
isActive = rs.getBoolean("is_active"),
|
|
52
|
-
createdAt = rs.getObject("created_at", java.time.OffsetDateTime::class.java)
|
|
53
|
-
)
|
|
54
|
-
assertEq(user.email, "test@example.com", "user.email matches")
|
|
55
|
-
assertEq(user.name, "Test User", "user.name matches")
|
|
56
|
-
assertEq(user.age, 30, "user.age matches")
|
|
57
|
-
assertEq(user.isActive, true, "user.isActive matches")
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// 2. Query post and construct generated data class
|
|
61
|
-
conn.prepareStatement("SELECT id, user_id, title, body, view_count FROM posts WHERE id = 1").use { ps ->
|
|
62
|
-
val rs = ps.executeQuery()
|
|
63
|
-
rs.next()
|
|
64
|
-
val post = Posts(
|
|
65
|
-
id = rs.getLong("id"),
|
|
66
|
-
userId = rs.getLong("user_id"),
|
|
67
|
-
title = rs.getString("title"),
|
|
68
|
-
body = rs.getString("body"),
|
|
69
|
-
viewCount = rs.getInt("view_count")
|
|
70
|
-
)
|
|
71
|
-
assertEq(post.title, "Hello World", "post.title matches")
|
|
72
|
-
assertEq(post.userId, 1L, "post.userId matches")
|
|
73
|
-
assertEq(post.viewCount, 42, "post.viewCount matches")
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (failed > 0) {
|
|
78
|
-
System.err.println("\n$failed assertion(s) failed")
|
|
79
|
-
System.exit(1)
|
|
80
|
-
}
|
|
81
|
-
println("\nAll assertions passed!")
|
|
82
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
FROM node:23-slim
|
|
2
|
-
WORKDIR /app
|
|
3
|
-
COPY . .
|
|
4
|
-
RUN npm init -y && npm pkg set type=module && npm install typescript@5 kysely@0.27 pg @types/pg @types/node --save-dev
|
|
5
|
-
# Step 1: typecheck the generated types
|
|
6
|
-
RUN npx tsc --noEmit --strict --esModuleInterop --module nodenext --moduleResolution nodenext database.ts
|
|
7
|
-
# Step 2: run integration test against real DB
|
|
8
|
-
CMD ["node", "--experimental-strip-types", "test.ts"]
|
package/src/kysely/test/test.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration test for @sqldoc/templates/kysely
|
|
3
|
-
* Connects to real Postgres via Kysely, verifies generated Database interface works.
|
|
4
|
-
*/
|
|
5
|
-
import { Kysely, PostgresDialect } from 'kysely'
|
|
6
|
-
import pg from 'pg'
|
|
7
|
-
import type { Database } from './database.ts'
|
|
8
|
-
|
|
9
|
-
const DATABASE_URL = process.env.DATABASE_URL
|
|
10
|
-
if (!DATABASE_URL) {
|
|
11
|
-
console.error('DATABASE_URL not set')
|
|
12
|
-
process.exit(1)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const db = new Kysely<Database>({
|
|
16
|
-
dialect: new PostgresDialect({
|
|
17
|
-
pool: new pg.Pool({ connectionString: DATABASE_URL }),
|
|
18
|
-
}),
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
let failed = 0
|
|
22
|
-
function assert(condition: boolean, msg: string) {
|
|
23
|
-
if (!condition) {
|
|
24
|
-
console.error(`FAIL: ${msg}`)
|
|
25
|
-
failed++
|
|
26
|
-
} else {
|
|
27
|
-
console.log(` ok: ${msg}`)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async function run() {
|
|
32
|
-
try {
|
|
33
|
-
console.log('--- kysely integration test ---')
|
|
34
|
-
|
|
35
|
-
// 1. Query known seeded user using Kysely's type-safe query builder
|
|
36
|
-
const user = await db.selectFrom('users').selectAll().where('id', '=', 1).executeTakeFirstOrThrow()
|
|
37
|
-
|
|
38
|
-
assert(user.email === 'test@example.com', 'user email matches')
|
|
39
|
-
assert(user.name === 'Test User', 'user name matches')
|
|
40
|
-
assert(user.is_active === true, 'user is_active matches')
|
|
41
|
-
|
|
42
|
-
// 2. Query known seeded post
|
|
43
|
-
const post = await db.selectFrom('posts').selectAll().where('id', '=', 1).executeTakeFirstOrThrow()
|
|
44
|
-
|
|
45
|
-
assert(post.title === 'Hello World', 'post title matches')
|
|
46
|
-
|
|
47
|
-
// 3. Insert a new post via type-safe insert
|
|
48
|
-
await db
|
|
49
|
-
.insertInto('posts')
|
|
50
|
-
.values({
|
|
51
|
-
user_id: 1,
|
|
52
|
-
title: 'Post from kysely',
|
|
53
|
-
body: 'test body',
|
|
54
|
-
view_count: 0,
|
|
55
|
-
})
|
|
56
|
-
.execute()
|
|
57
|
-
|
|
58
|
-
// 4. Read it back
|
|
59
|
-
const newPost = await db
|
|
60
|
-
.selectFrom('posts')
|
|
61
|
-
.selectAll()
|
|
62
|
-
.where('title', '=', 'Post from kysely')
|
|
63
|
-
.executeTakeFirstOrThrow()
|
|
64
|
-
|
|
65
|
-
assert(newPost.title === 'Post from kysely', 'inserted post title matches')
|
|
66
|
-
// pg returns bigint columns as strings; use loose equality for numeric comparison
|
|
67
|
-
assert(Number(newPost.user_id) === 1, 'inserted post user_id matches')
|
|
68
|
-
|
|
69
|
-
if (failed > 0) {
|
|
70
|
-
console.error(`\n${failed} assertion(s) failed`)
|
|
71
|
-
process.exit(1)
|
|
72
|
-
}
|
|
73
|
-
console.log('\nAll assertions passed!')
|
|
74
|
-
} finally {
|
|
75
|
-
await db.destroy()
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
run().catch((err) => {
|
|
80
|
-
console.error(err)
|
|
81
|
-
process.exit(1)
|
|
82
|
-
})
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Integration test for @sqldoc/templates/pydantic
|
|
3
|
-
Connects to real Postgres, verifies generated Pydantic models work with actual data.
|
|
4
|
-
"""
|
|
5
|
-
import os
|
|
6
|
-
import sys
|
|
7
|
-
import psycopg2
|
|
8
|
-
|
|
9
|
-
from models import Users, Posts
|
|
10
|
-
|
|
11
|
-
DATABASE_URL = os.environ.get("DATABASE_URL")
|
|
12
|
-
if not DATABASE_URL:
|
|
13
|
-
print("DATABASE_URL not set", file=sys.stderr)
|
|
14
|
-
sys.exit(1)
|
|
15
|
-
|
|
16
|
-
failed = 0
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def assert_eq(actual, expected, msg):
|
|
20
|
-
global failed
|
|
21
|
-
if actual != expected:
|
|
22
|
-
print(f"FAIL: {msg} (got {actual!r}, expected {expected!r})", file=sys.stderr)
|
|
23
|
-
failed += 1
|
|
24
|
-
else:
|
|
25
|
-
print(f" ok: {msg}")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def main():
|
|
29
|
-
global failed
|
|
30
|
-
conn = psycopg2.connect(DATABASE_URL)
|
|
31
|
-
conn.autocommit = True
|
|
32
|
-
cur = conn.cursor()
|
|
33
|
-
|
|
34
|
-
print("--- pydantic integration test ---")
|
|
35
|
-
|
|
36
|
-
# 1. Query user and construct Pydantic model
|
|
37
|
-
cur.execute("SELECT id, email, name, age, is_active, created_at FROM users WHERE id = 1")
|
|
38
|
-
row = cur.fetchone()
|
|
39
|
-
user = Users(id=row[0], email=row[1], name=row[2], age=row[3], is_active=row[4], created_at=row[5])
|
|
40
|
-
assert_eq(user.email, "test@example.com", "user.email matches")
|
|
41
|
-
assert_eq(user.name, "Test User", "user.name matches")
|
|
42
|
-
assert_eq(user.age, 30, "user.age matches")
|
|
43
|
-
assert_eq(user.is_active, True, "user.is_active matches")
|
|
44
|
-
|
|
45
|
-
# 2. Query post and construct Pydantic model
|
|
46
|
-
cur.execute("SELECT id, user_id, title, body, view_count, rating FROM posts WHERE id = 1")
|
|
47
|
-
row = cur.fetchone()
|
|
48
|
-
post = Posts(id=row[0], user_id=row[1], title=row[2], body=row[3], view_count=row[4], rating=row[5])
|
|
49
|
-
assert_eq(post.title, "Hello World", "post.title matches")
|
|
50
|
-
assert_eq(post.user_id, 1, "post.user_id matches")
|
|
51
|
-
assert_eq(post.view_count, 42, "post.view_count matches")
|
|
52
|
-
|
|
53
|
-
cur.close()
|
|
54
|
-
conn.close()
|
|
55
|
-
|
|
56
|
-
if failed > 0:
|
|
57
|
-
print(f"\n{failed} assertion(s) failed", file=sys.stderr)
|
|
58
|
-
sys.exit(1)
|
|
59
|
-
print("\nAll assertions passed!")
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if __name__ == "__main__":
|
|
63
|
-
main()
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Integration test for @sqldoc/templates/python-dataclasses
|
|
3
|
-
Connects to real Postgres, verifies generated dataclasses work with actual data.
|
|
4
|
-
"""
|
|
5
|
-
import os
|
|
6
|
-
import sys
|
|
7
|
-
import psycopg2
|
|
8
|
-
|
|
9
|
-
from models import Users, Posts
|
|
10
|
-
|
|
11
|
-
DATABASE_URL = os.environ.get("DATABASE_URL")
|
|
12
|
-
if not DATABASE_URL:
|
|
13
|
-
print("DATABASE_URL not set", file=sys.stderr)
|
|
14
|
-
sys.exit(1)
|
|
15
|
-
|
|
16
|
-
failed = 0
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def assert_eq(actual, expected, msg):
|
|
20
|
-
global failed
|
|
21
|
-
if actual != expected:
|
|
22
|
-
print(f"FAIL: {msg} (got {actual!r}, expected {expected!r})", file=sys.stderr)
|
|
23
|
-
failed += 1
|
|
24
|
-
else:
|
|
25
|
-
print(f" ok: {msg}")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def main():
|
|
29
|
-
global failed
|
|
30
|
-
conn = psycopg2.connect(DATABASE_URL)
|
|
31
|
-
conn.autocommit = True
|
|
32
|
-
cur = conn.cursor()
|
|
33
|
-
|
|
34
|
-
print("--- python-dataclasses integration test ---")
|
|
35
|
-
|
|
36
|
-
# 1. Query user and construct dataclass
|
|
37
|
-
cur.execute("SELECT id, email, name, age, is_active, created_at FROM users WHERE id = 1")
|
|
38
|
-
row = cur.fetchone()
|
|
39
|
-
user = Users(id=row[0], email=row[1], name=row[2], age=row[3], is_active=row[4], created_at=row[5])
|
|
40
|
-
assert_eq(user.email, "test@example.com", "user.email matches")
|
|
41
|
-
assert_eq(user.name, "Test User", "user.name matches")
|
|
42
|
-
assert_eq(user.age, 30, "user.age matches")
|
|
43
|
-
assert_eq(user.is_active, True, "user.is_active matches")
|
|
44
|
-
|
|
45
|
-
# 2. Query post and construct dataclass
|
|
46
|
-
cur.execute("SELECT id, user_id, title, body, view_count, rating FROM posts WHERE id = 1")
|
|
47
|
-
row = cur.fetchone()
|
|
48
|
-
post = Posts(id=row[0], user_id=row[1], title=row[2], body=row[3], view_count=row[4], rating=row[5])
|
|
49
|
-
assert_eq(post.title, "Hello World", "post.title matches")
|
|
50
|
-
assert_eq(post.user_id, 1, "post.user_id matches")
|
|
51
|
-
assert_eq(post.view_count, 42, "post.view_count matches")
|
|
52
|
-
|
|
53
|
-
cur.close()
|
|
54
|
-
conn.close()
|
|
55
|
-
|
|
56
|
-
if failed > 0:
|
|
57
|
-
print(f"\n{failed} assertion(s) failed", file=sys.stderr)
|
|
58
|
-
sys.exit(1)
|
|
59
|
-
print("\nAll assertions passed!")
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if __name__ == "__main__":
|
|
63
|
-
main()
|