@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.
Files changed (70) hide show
  1. package/package.json +10 -8
  2. package/src/__tests__/dedent.test.ts +0 -45
  3. package/src/__tests__/docker-templates.test.ts +0 -134
  4. package/src/__tests__/go-structs.test.ts +0 -184
  5. package/src/__tests__/naming.test.ts +0 -48
  6. package/src/__tests__/python-dataclasses.test.ts +0 -185
  7. package/src/__tests__/rust-structs.test.ts +0 -176
  8. package/src/__tests__/tags-helpers.test.ts +0 -72
  9. package/src/__tests__/type-mapping.test.ts +0 -332
  10. package/src/__tests__/typescript.test.ts +0 -202
  11. package/src/cobol-copybook/test/.gitignore +0 -6
  12. package/src/cobol-copybook/test/Dockerfile +0 -7
  13. package/src/csharp-records/test/.gitignore +0 -6
  14. package/src/csharp-records/test/Dockerfile +0 -6
  15. package/src/diesel/test/.gitignore +0 -6
  16. package/src/diesel/test/Dockerfile +0 -16
  17. package/src/drizzle/test/.gitignore +0 -6
  18. package/src/drizzle/test/Dockerfile +0 -8
  19. package/src/drizzle/test/test.ts +0 -71
  20. package/src/efcore/test/.gitignore +0 -6
  21. package/src/efcore/test/Dockerfile +0 -7
  22. package/src/go-structs/test/.gitignore +0 -6
  23. package/src/go-structs/test/Dockerfile +0 -13
  24. package/src/go-structs/test/test.go +0 -71
  25. package/src/gorm/test/.gitignore +0 -6
  26. package/src/gorm/test/Dockerfile +0 -13
  27. package/src/gorm/test/test.go +0 -65
  28. package/src/java-records/test/.gitignore +0 -6
  29. package/src/java-records/test/Dockerfile +0 -11
  30. package/src/java-records/test/Test.java +0 -93
  31. package/src/jpa/test/.gitignore +0 -6
  32. package/src/jpa/test/Dockerfile +0 -14
  33. package/src/jpa/test/Test.java +0 -111
  34. package/src/json-schema/test/.gitignore +0 -6
  35. package/src/json-schema/test/Dockerfile +0 -18
  36. package/src/knex/test/.gitignore +0 -6
  37. package/src/knex/test/Dockerfile +0 -7
  38. package/src/knex/test/test.ts +0 -75
  39. package/src/kotlin-data/test/.gitignore +0 -6
  40. package/src/kotlin-data/test/Dockerfile +0 -14
  41. package/src/kotlin-data/test/Test.kt +0 -82
  42. package/src/kysely/test/.gitignore +0 -6
  43. package/src/kysely/test/Dockerfile +0 -8
  44. package/src/kysely/test/test.ts +0 -82
  45. package/src/prisma/test/.gitignore +0 -6
  46. package/src/prisma/test/Dockerfile +0 -7
  47. package/src/protobuf/test/.gitignore +0 -6
  48. package/src/protobuf/test/Dockerfile +0 -6
  49. package/src/pydantic/test/.gitignore +0 -6
  50. package/src/pydantic/test/Dockerfile +0 -8
  51. package/src/pydantic/test/test.py +0 -63
  52. package/src/python-dataclasses/test/.gitignore +0 -6
  53. package/src/python-dataclasses/test/Dockerfile +0 -8
  54. package/src/python-dataclasses/test/test.py +0 -63
  55. package/src/rust-structs/test/.gitignore +0 -6
  56. package/src/rust-structs/test/Dockerfile +0 -22
  57. package/src/rust-structs/test/test.rs +0 -82
  58. package/src/sqlalchemy/test/.gitignore +0 -6
  59. package/src/sqlalchemy/test/Dockerfile +0 -8
  60. package/src/sqlalchemy/test/test.py +0 -61
  61. package/src/sqlc/test/.gitignore +0 -6
  62. package/src/sqlc/test/Dockerfile +0 -13
  63. package/src/sqlc/test/test.go +0 -91
  64. package/src/typescript/test/.gitignore +0 -6
  65. package/src/typescript/test/Dockerfile +0 -8
  66. package/src/typescript/test/test.ts +0 -89
  67. package/src/xsd/test/.gitignore +0 -6
  68. package/src/xsd/test/Dockerfile +0 -6
  69. package/src/zod/test/.gitignore +0 -6
  70. package/src/zod/test/Dockerfile +0 -6
@@ -1,202 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import typescript from '../typescript/index.ts'
3
-
4
- const generate = typescript.generate
5
-
6
- import type { AtlasRealm } from '@sqldoc/atlas'
7
- import type { TemplateContext } from '@sqldoc/ns-codegen'
8
-
9
- const testRealm: AtlasRealm = {
10
- schemas: [
11
- {
12
- name: 'public',
13
- tables: [
14
- {
15
- name: 'users',
16
- columns: [
17
- { name: 'id', type: { T: 'bigserial', null: false, category: 'integer' } },
18
- { name: 'email', type: { T: 'character varying', raw: 'varchar(255)', null: false, category: 'string' } },
19
- { name: 'name', type: { T: 'text', null: true, category: 'string' } },
20
- { name: 'age', type: { T: 'integer', null: true, category: 'integer' } },
21
- { name: 'is_active', type: { T: 'boolean', null: false, category: 'boolean' } },
22
- { name: 'metadata', type: { T: 'jsonb', null: true, category: 'json' } },
23
- { name: 'created_at', type: { T: 'timestamp with time zone', null: false, category: 'time' } },
24
- { name: 'tags', type: { T: 'text[]', null: true, category: 'array' } },
25
- { name: 'avatar', type: { T: 'bytea', null: true, category: 'binary' } },
26
- { name: 'balance', type: { T: 'numeric(10,2)', null: true, category: 'decimal' } },
27
- { name: 'external_id', type: { T: 'uuid', null: true, category: 'uuid' } },
28
- ],
29
- primary_key: { parts: [{ column: 'id' }] },
30
- },
31
- {
32
- name: 'posts',
33
- columns: [
34
- { name: 'id', type: { T: 'bigserial', null: false, category: 'integer' } },
35
- { name: 'user_id', type: { T: 'bigint', null: false, category: 'integer' } },
36
- { name: 'title', type: { T: 'text', null: false, category: 'string' } },
37
- { name: 'body', type: { T: 'text', null: false, category: 'string' } },
38
- { name: 'published_at', type: { T: 'timestamp with time zone', null: true, category: 'time' } },
39
- { name: 'view_count', type: { T: 'integer', null: false, category: 'integer' } },
40
- { name: 'rating', type: { T: 'double precision', null: true, category: 'float' } },
41
- ],
42
- primary_key: { parts: [{ column: 'id' }] },
43
- foreign_keys: [
44
- { symbol: 'posts_user_id_fkey', columns: ['user_id'], ref_table: 'users', ref_columns: ['id'] },
45
- ],
46
- },
47
- {
48
- name: 'comments',
49
- columns: [
50
- { name: 'id', type: { T: 'bigserial', null: false, category: 'integer' } },
51
- { name: 'post_id', type: { T: 'bigint', null: false, category: 'integer' } },
52
- { name: 'user_id', type: { T: 'bigint', null: false, category: 'integer' } },
53
- { name: 'content', type: { T: 'text', null: false, category: 'string' } },
54
- { name: 'created_at', type: { T: 'timestamp with time zone', null: false, category: 'time' } },
55
- ],
56
- primary_key: { parts: [{ column: 'id' }] },
57
- foreign_keys: [
58
- { symbol: 'comments_post_id_fkey', columns: ['post_id'], ref_table: 'posts', ref_columns: ['id'] },
59
- { symbol: 'comments_user_id_fkey', columns: ['user_id'], ref_table: 'users', ref_columns: ['id'] },
60
- ],
61
- },
62
- ],
63
- },
64
- ],
65
- }
66
-
67
- function makeCtx(overrides?: Partial<TemplateContext>): TemplateContext {
68
- return {
69
- realm: testRealm,
70
- allFileTags: [],
71
- docsMeta: [],
72
- config: {},
73
- output: './out',
74
- templateName: 'typescript',
75
- ...overrides,
76
- }
77
- }
78
-
79
- describe('typescript template', () => {
80
- it('generates interfaces for all tables', () => {
81
- const result = generate(makeCtx())
82
- expect(result.files).toHaveLength(1)
83
- expect(result.files[0].path).toBe('models.ts')
84
-
85
- const content = result.files[0].content
86
- expect(content).toContain('export interface Users {')
87
- expect(content).toContain('export interface Posts {')
88
- expect(content).toContain('export interface Comments {')
89
- })
90
-
91
- it('maps bigserial to number', () => {
92
- const result = generate(makeCtx())
93
- const content = result.files[0].content
94
- expect(content).toContain('id: number')
95
- })
96
-
97
- it('uses optional (?) for nullable columns by default', () => {
98
- const result = generate(makeCtx())
99
- const content = result.files[0].content
100
- expect(content).toContain('name?: string')
101
- expect(content).toContain('age?: number')
102
- })
103
-
104
- it('uses null-union style when configured', () => {
105
- const result = generate(makeCtx({ config: { nullableStyle: 'null-union' } }))
106
- const content = result.files[0].content
107
- expect(content).toContain('name: string | null')
108
- expect(content).toContain('age: number | null')
109
- })
110
-
111
- it('maps text[] to string[] array type', () => {
112
- const result = generate(makeCtx())
113
- const content = result.files[0].content
114
- expect(content).toContain('tags?: string[]')
115
- })
116
-
117
- it('maps jsonb to unknown', () => {
118
- const result = generate(makeCtx())
119
- const content = result.files[0].content
120
- expect(content).toContain('metadata?: unknown')
121
- })
122
-
123
- it('maps bytea to Buffer', () => {
124
- const result = generate(makeCtx())
125
- const content = result.files[0].content
126
- expect(content).toContain('avatar?: Buffer')
127
- })
128
-
129
- it('maps uuid to string', () => {
130
- const result = generate(makeCtx())
131
- const content = result.files[0].content
132
- expect(content).toContain('externalId?: string')
133
- })
134
-
135
- it('includes header comment', () => {
136
- const result = generate(makeCtx())
137
- const content = result.files[0].content
138
- expect(content).toContain('// Generated by @sqldoc/templates/typescript -- DO NOT EDIT')
139
- })
140
-
141
- it('respects @codegen.skip tag', () => {
142
- const ctx = makeCtx({
143
- allFileTags: [
144
- {
145
- sourceFile: 'test.sql',
146
- objects: [
147
- {
148
- objectName: 'comments',
149
- target: 'table',
150
- tags: [{ namespace: 'codegen', tag: 'skip', args: [] }],
151
- },
152
- ],
153
- },
154
- ],
155
- })
156
- const result = generate(ctx)
157
- const content = result.files[0].content
158
- expect(content).not.toContain('export interface Comments')
159
- expect(content).toContain('export interface Users')
160
- })
161
-
162
- it('respects @codegen.rename tag', () => {
163
- const ctx = makeCtx({
164
- allFileTags: [
165
- {
166
- sourceFile: 'test.sql',
167
- objects: [
168
- {
169
- objectName: 'users',
170
- target: 'table',
171
- tags: [{ namespace: 'codegen', tag: 'rename', args: ['Account'] }],
172
- },
173
- ],
174
- },
175
- ],
176
- })
177
- const result = generate(ctx)
178
- const content = result.files[0].content
179
- expect(content).toContain('export interface Account {')
180
- expect(content).not.toContain('export interface Users {')
181
- })
182
-
183
- it('respects @codegen.type override on column', () => {
184
- const ctx = makeCtx({
185
- allFileTags: [
186
- {
187
- sourceFile: 'test.sql',
188
- objects: [
189
- {
190
- objectName: 'users.metadata',
191
- target: 'column',
192
- tags: [{ namespace: 'codegen', tag: 'type', args: ['Record<string, any>'] }],
193
- },
194
- ],
195
- },
196
- ],
197
- })
198
- const result = generate(ctx)
199
- const content = result.files[0].content
200
- expect(content).toContain('metadata?: Record<string, any>')
201
- })
202
- })
@@ -1,6 +0,0 @@
1
- # Generated by codegen — only Dockerfile and test scripts are tracked
2
- *
3
- !.gitignore
4
- !Dockerfile
5
- !test.*
6
- !Test.*
@@ -1,7 +0,0 @@
1
- FROM debian:bookworm-slim
2
- RUN apt-get update && apt-get install -y --no-install-recommends gnucobol4 && rm -rf /var/lib/apt/lists/*
3
- WORKDIR /app
4
- COPY . .
5
- RUN printf ' IDENTIFICATION DIVISION.\n PROGRAM-ID. TEST-CPY.\n DATA DIVISION.\n WORKING-STORAGE SECTION.\n COPY "schema.cpy".\n PROCEDURE DIVISION.\n STOP RUN.\n' > test.cob
6
- RUN cobc -fsyntax-only test.cob
7
- CMD ["echo", "ok"]
@@ -1,6 +0,0 @@
1
- # Generated by codegen — only Dockerfile and test scripts are tracked
2
- *
3
- !.gitignore
4
- !Dockerfile
5
- !test.*
6
- !Test.*
@@ -1,6 +0,0 @@
1
- FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine
2
- WORKDIR /app
3
- RUN dotnet new classlib -n TypeCheck --force && rm TypeCheck/Class1.cs
4
- COPY *.cs TypeCheck/
5
- RUN dotnet build TypeCheck/
6
- CMD ["echo", "ok"]
@@ -1,6 +0,0 @@
1
- # Generated by codegen — only Dockerfile and test scripts are tracked
2
- *
3
- !.gitignore
4
- !Dockerfile
5
- !test.*
6
- !Test.*
@@ -1,16 +0,0 @@
1
- FROM rust:1.85-slim
2
- WORKDIR /app
3
- RUN cargo init --name typecheck .
4
- RUN cat >> Cargo.toml <<'TOML'
5
- diesel = { version = "2", features = ["postgres"] }
6
- serde = { version = "1", features = ["derive"] }
7
- serde_json = "1"
8
- chrono = { version = "0.4", features = ["serde"] }
9
- uuid = { version = "1", features = ["serde"] }
10
- bigdecimal = { version = "0.4", features = ["serde"] }
11
- TOML
12
- RUN rm src/main.rs
13
- COPY . src/
14
- RUN echo 'mod schema;' > src/lib.rs && echo 'mod models;' >> src/lib.rs
15
- RUN cargo check
16
- CMD ["echo", "ok"]
@@ -1,6 +0,0 @@
1
- # Generated by codegen — only Dockerfile and test scripts are tracked
2
- *
3
- !.gitignore
4
- !Dockerfile
5
- !test.*
6
- !Test.*
@@ -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 drizzle-orm@0.38 pg @types/pg @types/node --save-dev
5
- # Step 1: typecheck the generated schema
6
- RUN npx tsc --noEmit --strict --esModuleInterop --module nodenext --moduleResolution nodenext --allowImportingTsExtensions --skipLibCheck *.ts
7
- # Step 2: run integration test against real DB
8
- CMD ["node", "--experimental-strip-types", "test.ts"]
@@ -1,71 +0,0 @@
1
- /**
2
- * Integration test for @sqldoc/templates/drizzle
3
- * Connects to real Postgres via drizzle-orm, verifies generated schema works.
4
- */
5
- import { drizzle } from 'drizzle-orm/node-postgres'
6
- import { eq } from 'drizzle-orm'
7
- import pg from 'pg'
8
- import * as schema from './schema.ts'
9
-
10
- const DATABASE_URL = process.env.DATABASE_URL
11
- if (!DATABASE_URL) {
12
- console.error('DATABASE_URL not set')
13
- process.exit(1)
14
- }
15
-
16
- const pool = new pg.Pool({ connectionString: DATABASE_URL })
17
- const db = drizzle(pool, { schema })
18
-
19
- let failed = 0
20
- function assert(condition: boolean, msg: string) {
21
- if (!condition) {
22
- console.error(`FAIL: ${msg}`)
23
- failed++
24
- } else {
25
- console.log(` ok: ${msg}`)
26
- }
27
- }
28
-
29
- async function run() {
30
- try {
31
- console.log('--- drizzle integration test ---')
32
-
33
- // 1. Query known seeded user
34
- const users = await db.select().from(schema.users).where(eq(schema.users.id, 1))
35
- assert(users.length === 1, 'seeded user found')
36
- assert(users[0].email === 'test@example.com', 'user email matches')
37
- assert(users[0].name === 'Test User', 'user name matches')
38
-
39
- // 2. Query known seeded post
40
- const posts = await db.select().from(schema.posts).where(eq(schema.posts.id, 1))
41
- assert(posts.length === 1, 'seeded post found')
42
- assert(posts[0].title === 'Hello World', 'post title matches')
43
-
44
- // 3. Insert a new post
45
- await db.insert(schema.posts).values({
46
- userId: 1,
47
- title: 'Post from drizzle',
48
- body: 'test body',
49
- viewCount: 0,
50
- })
51
-
52
- // 4. Read it back
53
- const newPosts = await db.select().from(schema.posts).where(eq(schema.posts.title, 'Post from drizzle'))
54
- assert(newPosts.length === 1, 'inserted post found')
55
- assert(newPosts[0].title === 'Post from drizzle', 'inserted post title matches')
56
- assert(Number(newPosts[0].userId) === 1, 'inserted post user_id matches')
57
-
58
- if (failed > 0) {
59
- console.error(`\n${failed} assertion(s) failed`)
60
- process.exit(1)
61
- }
62
- console.log('\nAll assertions passed!')
63
- } finally {
64
- await pool.end()
65
- }
66
- }
67
-
68
- run().catch((err) => {
69
- console.error(err)
70
- process.exit(1)
71
- })
@@ -1,6 +0,0 @@
1
- # Generated by codegen — only Dockerfile and test scripts are tracked
2
- *
3
- !.gitignore
4
- !Dockerfile
5
- !test.*
6
- !Test.*
@@ -1,7 +0,0 @@
1
- FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine
2
- WORKDIR /app
3
- RUN dotnet new classlib -n TypeCheck --force && rm TypeCheck/Class1.cs
4
- RUN dotnet add TypeCheck/ package Microsoft.EntityFrameworkCore --version 9.0.0
5
- COPY *.cs TypeCheck/
6
- RUN dotnet build TypeCheck/
7
- CMD ["echo", "ok"]
@@ -1,6 +0,0 @@
1
- # Generated by codegen — only Dockerfile and test scripts are tracked
2
- *
3
- !.gitignore
4
- !Dockerfile
5
- !test.*
6
- !Test.*
@@ -1,13 +0,0 @@
1
- FROM golang:1.24-alpine
2
- WORKDIR /app
3
- # Set up Go module with models as a sub-package
4
- RUN go mod init sqldoc-test
5
- RUN mkdir -p models cmd/test
6
- COPY models.go models/
7
- COPY test.go cmd/test/main.go
8
- ENV GOTOOLCHAIN=auto
9
- RUN go get github.com/jackc/pgx/v5 && go mod tidy
10
- # Step 1: typecheck/compile all packages
11
- RUN go build -o /usr/local/bin/test-runner ./cmd/test
12
- # Step 2: run integration test against real DB
13
- CMD ["test-runner"]
@@ -1,71 +0,0 @@
1
- package main
2
-
3
- import (
4
- "context"
5
- "fmt"
6
- "os"
7
-
8
- "github.com/jackc/pgx/v5"
9
-
10
- "sqldoc-test/models"
11
- )
12
-
13
- var failed int
14
-
15
- func assert(condition bool, msg string) {
16
- if !condition {
17
- fmt.Fprintf(os.Stderr, "FAIL: %s\n", msg)
18
- failed++
19
- } else {
20
- fmt.Printf(" ok: %s\n", msg)
21
- }
22
- }
23
-
24
- func main() {
25
- ctx := context.Background()
26
- dbURL := os.Getenv("DATABASE_URL")
27
- if dbURL == "" {
28
- fmt.Fprintln(os.Stderr, "DATABASE_URL not set")
29
- os.Exit(1)
30
- }
31
-
32
- conn, err := pgx.Connect(ctx, dbURL)
33
- if err != nil {
34
- fmt.Fprintf(os.Stderr, "connect error: %v\n", err)
35
- os.Exit(1)
36
- }
37
- defer conn.Close(ctx)
38
-
39
- fmt.Println("--- go-structs integration test ---")
40
-
41
- // 1. Query user into generated struct
42
- var user models.Users
43
- err = conn.QueryRow(ctx, "SELECT id, email, name, age, is_active FROM users WHERE id = 1").
44
- Scan(&user.Id, &user.Email, &user.Name, &user.Age, &user.IsActive)
45
- if err != nil {
46
- fmt.Fprintf(os.Stderr, "query user error: %v\n", err)
47
- os.Exit(1)
48
- }
49
- assert(user.Email == "test@example.com", "user.Email matches")
50
- assert(user.Name != nil && *user.Name == "Test User", "user.Name matches")
51
- assert(user.Age != nil && *user.Age == 30, "user.Age matches")
52
- assert(user.IsActive == true, "user.IsActive matches")
53
-
54
- // 2. Query post into generated struct
55
- var post models.Posts
56
- err = conn.QueryRow(ctx, "SELECT id, user_id, title, body, view_count FROM posts WHERE id = 1").
57
- Scan(&post.Id, &post.UserId, &post.Title, &post.Body, &post.ViewCount)
58
- if err != nil {
59
- fmt.Fprintf(os.Stderr, "query post error: %v\n", err)
60
- os.Exit(1)
61
- }
62
- assert(post.Title == "Hello World", "post.Title matches")
63
- assert(post.UserId == 1, "post.UserId matches")
64
- assert(post.ViewCount == 42, "post.ViewCount matches")
65
-
66
- if failed > 0 {
67
- fmt.Fprintf(os.Stderr, "\n%d assertion(s) failed\n", failed)
68
- os.Exit(1)
69
- }
70
- fmt.Println("\nAll assertions passed!")
71
- }
@@ -1,6 +0,0 @@
1
- # Generated by codegen — only Dockerfile and test scripts are tracked
2
- *
3
- !.gitignore
4
- !Dockerfile
5
- !test.*
6
- !Test.*
@@ -1,13 +0,0 @@
1
- FROM golang:1.24-alpine
2
- WORKDIR /app
3
- # Set up Go module with models as a sub-package
4
- RUN go mod init sqldoc-test
5
- RUN mkdir -p models cmd/test
6
- COPY models.go models/
7
- COPY test.go cmd/test/main.go
8
- ENV GOTOOLCHAIN=auto
9
- RUN go get github.com/jackc/pgx/v5 gorm.io/gorm gorm.io/driver/postgres && go mod tidy
10
- # Step 1: typecheck/compile all packages
11
- RUN go build -o /usr/local/bin/test-runner ./cmd/test
12
- # Step 2: run integration test against real DB
13
- CMD ["test-runner"]
@@ -1,65 +0,0 @@
1
- package main
2
-
3
- import (
4
- "fmt"
5
- "os"
6
-
7
- "sqldoc-test/models"
8
-
9
- "gorm.io/driver/postgres"
10
- "gorm.io/gorm"
11
- )
12
-
13
- var failed int
14
-
15
- func assert(condition bool, msg string) {
16
- if !condition {
17
- fmt.Fprintf(os.Stderr, "FAIL: %s\n", msg)
18
- failed++
19
- } else {
20
- fmt.Printf(" ok: %s\n", msg)
21
- }
22
- }
23
-
24
- func main() {
25
- dbURL := os.Getenv("DATABASE_URL")
26
- if dbURL == "" {
27
- fmt.Fprintln(os.Stderr, "DATABASE_URL not set")
28
- os.Exit(1)
29
- }
30
-
31
- db, err := gorm.Open(postgres.Open(dbURL), &gorm.Config{})
32
- if err != nil {
33
- fmt.Fprintf(os.Stderr, "connect error: %v\n", err)
34
- os.Exit(1)
35
- }
36
-
37
- fmt.Println("--- gorm integration test ---")
38
-
39
- // 1. Query user via GORM using generated model
40
- var user models.Users
41
- if err := db.First(&user, 1).Error; err != nil {
42
- fmt.Fprintf(os.Stderr, "query user error: %v\n", err)
43
- os.Exit(1)
44
- }
45
- assert(user.Email == "test@example.com", "user.Email matches")
46
- assert(user.Name != nil && *user.Name == "Test User", "user.Name matches")
47
- assert(user.Age != nil && *user.Age == 30, "user.Age matches")
48
- assert(user.IsActive == true, "user.IsActive matches")
49
-
50
- // 2. Query post via GORM using generated model
51
- var post models.Posts
52
- if err := db.First(&post, 1).Error; err != nil {
53
- fmt.Fprintf(os.Stderr, "query post error: %v\n", err)
54
- os.Exit(1)
55
- }
56
- assert(post.Title == "Hello World", "post.Title matches")
57
- assert(post.UserId == 1, "post.UserId matches")
58
- assert(post.ViewCount == 42, "post.ViewCount matches")
59
-
60
- if failed > 0 {
61
- fmt.Fprintf(os.Stderr, "\n%d assertion(s) failed\n", failed)
62
- os.Exit(1)
63
- }
64
- fmt.Println("\nAll assertions passed!")
65
- }
@@ -1,6 +0,0 @@
1
- # Generated by codegen — only Dockerfile and test scripts are tracked
2
- *
3
- !.gitignore
4
- !Dockerfile
5
- !test.*
6
- !Test.*
@@ -1,11 +0,0 @@
1
- FROM eclipse-temurin:21-jdk-alpine
2
- WORKDIR /app
3
- RUN apk add --no-cache curl
4
- # Download PostgreSQL JDBC driver
5
- RUN mkdir -p /deps && \
6
- 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
7
- COPY . .
8
- # Step 1: compile the generated records + test
9
- RUN javac -cp "/deps/*:." *.java Test.java
10
- # Step 2: run integration test against real DB
11
- CMD ["java", "-cp", "/deps/*:.", "Test"]
@@ -1,93 +0,0 @@
1
- import java.sql.*;
2
- import java.time.OffsetDateTime;
3
-
4
- /**
5
- * Integration test for @sqldoc/templates/java-records
6
- * Connects to real Postgres, verifies generated records work with actual 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
- public static void main(String[] args) throws Exception {
21
- String dbUrl = System.getenv("DATABASE_URL");
22
- if (dbUrl == null || dbUrl.isEmpty()) {
23
- System.err.println("DATABASE_URL not set");
24
- System.exit(1);
25
- }
26
-
27
- // Convert postgres(ql):// to jdbc:postgresql://, extracting userinfo for JDBC
28
- var uri = java.net.URI.create(dbUrl.replaceFirst("^postgres(ql)?://", "http://"));
29
- var userInfo = uri.getUserInfo();
30
- var jdbcUrl = "jdbc:postgresql://" + uri.getHost() + ":" + (uri.getPort() > 0 ? uri.getPort() : 5432) + uri.getPath();
31
- var query = uri.getQuery();
32
- if (userInfo != null) {
33
- var parts = userInfo.split(":", 2);
34
- var sep = query != null ? "&" : "?";
35
- jdbcUrl += (query != null ? "?" + query : "") + sep + "user=" + parts[0] + "&password=" + (parts.length > 1 ? parts[1] : "");
36
- } else if (query != null) {
37
- jdbcUrl += "?" + query;
38
- }
39
- dbUrl = jdbcUrl;
40
-
41
- System.out.println("--- java-records integration test ---");
42
-
43
- try (Connection conn = DriverManager.getConnection(dbUrl)) {
44
- // 1. Query user and construct generated record
45
- try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id = 1")) {
46
- ResultSet rs = ps.executeQuery();
47
- rs.next();
48
- var user = new Users(
49
- rs.getLong("id"),
50
- rs.getString("email"),
51
- rs.getString("name"),
52
- rs.getObject("age") != null ? rs.getInt("age") : null,
53
- rs.getBoolean("is_active"),
54
- rs.getString("metadata"),
55
- null, // address (composite)
56
- rs.getObject("created_at", OffsetDateTime.class),
57
- null, // tags (array)
58
- rs.getBytes("avatar"),
59
- rs.getBigDecimal("balance"),
60
- rs.getObject("external_id") != null ? java.util.UUID.fromString(rs.getString("external_id")) : null
61
- );
62
- assertEq(user.email(), "test@example.com", "user.email() matches");
63
- assertEq(user.name(), "Test User", "user.name() matches");
64
- assertEq(user.age(), 30, "user.age() matches");
65
- assertEq(user.isActive(), true, "user.isActive() matches");
66
- }
67
-
68
- // 2. Query post and construct generated record
69
- try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM posts WHERE id = 1")) {
70
- ResultSet rs = ps.executeQuery();
71
- rs.next();
72
- var post = new Posts(
73
- rs.getLong("id"),
74
- rs.getLong("user_id"),
75
- rs.getString("title"),
76
- rs.getString("body"),
77
- rs.getObject("published_at") != null ? rs.getObject("published_at", OffsetDateTime.class) : null,
78
- rs.getInt("view_count"),
79
- rs.getObject("rating") != null ? rs.getDouble("rating") : null
80
- );
81
- assertEq(post.title(), "Hello World", "post.title() matches");
82
- assertEq(post.userId(), 1L, "post.userId() matches");
83
- assertEq(post.viewCount(), 42, "post.viewCount() matches");
84
- }
85
- }
86
-
87
- if (failed > 0) {
88
- System.err.printf("%n%d assertion(s) failed%n", failed);
89
- System.exit(1);
90
- }
91
- System.out.println("\nAll assertions passed!");
92
- }
93
- }
@@ -1,6 +0,0 @@
1
- # Generated by codegen — only Dockerfile and test scripts are tracked
2
- *
3
- !.gitignore
4
- !Dockerfile
5
- !test.*
6
- !Test.*