Skip to content

Commit 8962400

Browse files
committed
test: Port end-to-end tests to this repo
1 parent 13c7690 commit 8962400

File tree

44 files changed

+824
-9
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+824
-9
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
name: make
1+
name: go
22
on:
33
push:
44
branches:
55
- main
66
pull_request:
77
jobs:
8-
build:
8+
test:
99
name: test
1010
runs-on: ubuntu-latest
1111
steps:
1212
- uses: actions/checkout@v3
1313
- uses: actions/setup-go@v4
1414
with:
15-
go-version: '1.21.0-rc.2'
15+
go-version: '1.21'
1616
- run: make
17+
- run: make test

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bin

Makefile

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
all: sqlc-gen-python sqlc-gen-python.wasm
1+
.PHONY: build test
22

3-
sqlc-gen-python:
4-
cd plugin && go build -o ~/bin/sqlc-gen-python ./main.go
3+
build:
4+
go build ./...
55

6-
sqlc-gen-python.wasm:
7-
cd plugin && GOOS=wasip1 GOARCH=wasm go build -o sqlc-gen-python.wasm main.go
8-
openssl sha256 plugin/sqlc-gen-python.wasm
6+
test: bin/sqlc-gen-python.wasm
7+
go test ./...
8+
9+
all: bin/sqlc-gen-python bin/sqlc-gen-python.wasm
10+
11+
bin/sqlc-gen-python: bin go.mod go.sum $(wildcard **/*.go)
12+
cd plugin && go build -o ../bin/sqlc-gen-python ./main.go
13+
14+
bin/sqlc-gen-python.wasm: bin/sqlc-gen-python
15+
cd plugin && GOOS=wasip1 GOARCH=wasm go build -o ../bin/sqlc-gen-python.wasm main.go
16+
17+
bin:
18+
mkdir -p bin

internal/endtoend/endtoend_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package endtoend
2+
3+
import (
4+
"os"
5+
"os/exec"
6+
"path/filepath"
7+
"testing"
8+
9+
"github.com/google/go-cmp/cmp"
10+
)
11+
12+
func FindTests(t *testing.T, root string) []string {
13+
t.Helper()
14+
var dirs []string
15+
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
16+
if err != nil {
17+
return err
18+
}
19+
if info.Name() == "sqlc.yaml" {
20+
dirs = append(dirs, filepath.Dir(path))
21+
return filepath.SkipDir
22+
}
23+
return nil
24+
})
25+
if err != nil {
26+
t.Fatal(err)
27+
}
28+
return dirs
29+
}
30+
31+
func LookPath(t *testing.T, cmds ...string) string {
32+
t.Helper()
33+
for _, cmd := range cmds {
34+
path, err := exec.LookPath(cmd)
35+
if err == nil {
36+
return path
37+
}
38+
}
39+
t.Fatalf("could not find command(s) in $PATH: %s", cmds)
40+
return ""
41+
}
42+
43+
func ExpectedOutput(t *testing.T, dir string) []byte {
44+
t.Helper()
45+
path := filepath.Join(dir, "stderr.txt")
46+
if _, err := os.Stat(path); err != nil {
47+
if os.IsNotExist(err) {
48+
return []byte{}
49+
} else {
50+
t.Fatal(err)
51+
}
52+
}
53+
output, err := os.ReadFile(path)
54+
if err != nil {
55+
t.Fatal(err)
56+
}
57+
return output
58+
}
59+
60+
func TestGenerate(t *testing.T) {
61+
sqlc := LookPath(t, "sqlc-dev", "sqlc")
62+
63+
for _, dir := range FindTests(t, "testdata") {
64+
dir := dir
65+
t.Run(dir, func(t *testing.T) {
66+
want := ExpectedOutput(t, dir)
67+
cmd := exec.Command(sqlc, "diff")
68+
cmd.Dir = dir
69+
got, err := cmd.CombinedOutput()
70+
if diff := cmp.Diff(want, got); diff != "" {
71+
t.Errorf("sqlc diff mismatch (-want +got):\n%s", diff)
72+
}
73+
if len(want) == 0 && err != nil {
74+
t.Error(err)
75+
}
76+
})
77+
}
78+
}

internal/endtoend/testdata/emit_pydantic_models/db/__init__.py

Whitespace-only changes.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.23.0
4+
import pydantic
5+
from typing import Optional
6+
7+
8+
class Author(pydantic.BaseModel):
9+
id: int
10+
name: str
11+
bio: Optional[str]
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.23.0
4+
# source: query.sql
5+
from typing import AsyncIterator, Iterator, Optional
6+
7+
import sqlalchemy
8+
import sqlalchemy.ext.asyncio
9+
10+
from db import models
11+
12+
13+
CREATE_AUTHOR = """-- name: create_author \\:one
14+
INSERT INTO authors (
15+
name, bio
16+
) VALUES (
17+
:p1, :p2
18+
)
19+
RETURNING id, name, bio
20+
"""
21+
22+
23+
DELETE_AUTHOR = """-- name: delete_author \\:exec
24+
DELETE FROM authors
25+
WHERE id = :p1
26+
"""
27+
28+
29+
GET_AUTHOR = """-- name: get_author \\:one
30+
SELECT id, name, bio FROM authors
31+
WHERE id = :p1 LIMIT 1
32+
"""
33+
34+
35+
LIST_AUTHORS = """-- name: list_authors \\:many
36+
SELECT id, name, bio FROM authors
37+
ORDER BY name
38+
"""
39+
40+
41+
class Querier:
42+
def __init__(self, conn: sqlalchemy.engine.Connection):
43+
self._conn = conn
44+
45+
def create_author(self, *, name: str, bio: Optional[str]) -> Optional[models.Author]:
46+
row = self._conn.execute(sqlalchemy.text(CREATE_AUTHOR), {"p1": name, "p2": bio}).first()
47+
if row is None:
48+
return None
49+
return models.Author(
50+
id=row[0],
51+
name=row[1],
52+
bio=row[2],
53+
)
54+
55+
def delete_author(self, *, id: int) -> None:
56+
self._conn.execute(sqlalchemy.text(DELETE_AUTHOR), {"p1": id})
57+
58+
def get_author(self, *, id: int) -> Optional[models.Author]:
59+
row = self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id}).first()
60+
if row is None:
61+
return None
62+
return models.Author(
63+
id=row[0],
64+
name=row[1],
65+
bio=row[2],
66+
)
67+
68+
def list_authors(self) -> Iterator[models.Author]:
69+
result = self._conn.execute(sqlalchemy.text(LIST_AUTHORS))
70+
for row in result:
71+
yield models.Author(
72+
id=row[0],
73+
name=row[1],
74+
bio=row[2],
75+
)
76+
77+
78+
class AsyncQuerier:
79+
def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection):
80+
self._conn = conn
81+
82+
async def create_author(self, *, name: str, bio: Optional[str]) -> Optional[models.Author]:
83+
row = (await self._conn.execute(sqlalchemy.text(CREATE_AUTHOR), {"p1": name, "p2": bio})).first()
84+
if row is None:
85+
return None
86+
return models.Author(
87+
id=row[0],
88+
name=row[1],
89+
bio=row[2],
90+
)
91+
92+
async def delete_author(self, *, id: int) -> None:
93+
await self._conn.execute(sqlalchemy.text(DELETE_AUTHOR), {"p1": id})
94+
95+
async def get_author(self, *, id: int) -> Optional[models.Author]:
96+
row = (await self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id})).first()
97+
if row is None:
98+
return None
99+
return models.Author(
100+
id=row[0],
101+
name=row[1],
102+
bio=row[2],
103+
)
104+
105+
async def list_authors(self) -> AsyncIterator[models.Author]:
106+
result = await self._conn.stream(sqlalchemy.text(LIST_AUTHORS))
107+
async for row in result:
108+
yield models.Author(
109+
id=row[0],
110+
name=row[1],
111+
bio=row[2],
112+
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-- name: GetAuthor :one
2+
SELECT * FROM authors
3+
WHERE id = $1 LIMIT 1;
4+
5+
-- name: ListAuthors :many
6+
SELECT * FROM authors
7+
ORDER BY name;
8+
9+
-- name: CreateAuthor :one
10+
INSERT INTO authors (
11+
name, bio
12+
) VALUES (
13+
$1, $2
14+
)
15+
RETURNING *;
16+
17+
-- name: DeleteAuthor :exec
18+
DELETE FROM authors
19+
WHERE id = $1;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CREATE TABLE authors (
2+
id BIGSERIAL PRIMARY KEY,
3+
name text NOT NULL,
4+
bio text
5+
);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
version: '2'
2+
plugins:
3+
- name: py
4+
wasm:
5+
url: file://../../../../bin/sqlc-gen-python.wasm
6+
sql:
7+
- schema: schema.sql
8+
queries: query.sql
9+
engine: postgresql
10+
codegen:
11+
- plugin: py
12+
out: db
13+
options:
14+
package: db
15+
emit_sync_querier: true
16+
emit_async_querier: true
17+
emit_pydantic_models: true
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.23.0
4+
import dataclasses
5+
6+
7+
@dataclasses.dataclass()
8+
class Bar:
9+
id: int
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.23.0
4+
# source: query.sql
5+
import sqlalchemy
6+
import sqlalchemy.ext.asyncio
7+
8+
from querytest import models
9+
10+
11+
DELETE_BAR_BY_ID = """-- name: delete_bar_by_id \\:execresult
12+
DELETE FROM bar WHERE id = :p1
13+
"""
14+
15+
16+
class Querier:
17+
def __init__(self, conn: sqlalchemy.engine.Connection):
18+
self._conn = conn
19+
20+
def delete_bar_by_id(self, *, id: int) -> sqlalchemy.engine.Result:
21+
return self._conn.execute(sqlalchemy.text(DELETE_BAR_BY_ID), {"p1": id})
22+
23+
24+
class AsyncQuerier:
25+
def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection):
26+
self._conn = conn
27+
28+
async def delete_bar_by_id(self, *, id: int) -> sqlalchemy.engine.Result:
29+
return await self._conn.execute(sqlalchemy.text(DELETE_BAR_BY_ID), {"p1": id})
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- name: DeleteBarByID :execresult
2+
DELETE FROM bar WHERE id = $1;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CREATE TABLE bar (id serial not null);
2+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
version: '2'
2+
plugins:
3+
- name: py
4+
wasm:
5+
url: file://../../../../bin/sqlc-gen-python.wasm
6+
sql:
7+
- schema: schema.sql
8+
queries: query.sql
9+
engine: postgresql
10+
codegen:
11+
- plugin: py
12+
out: python
13+
options:
14+
package: querytest
15+
emit_sync_querier: true
16+
emit_async_querier: true
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.23.0
4+
import dataclasses
5+
6+
7+
@dataclasses.dataclass()
8+
class Bar:
9+
id: int

0 commit comments

Comments
 (0)