Skip to content

Commit 4710aae

Browse files
committed
test: add Jest snapshots for deparsed round-trip output
Each fixture's deparseEnhanced() output is now snapshotted so any future deparser changes show up as snapshot diffs. 63 total tests (15 scanner + 13 integration + 35 fixture round-trip), 7 snapshots.
1 parent 3624d33 commit 4710aae

2 files changed

Lines changed: 190 additions & 0 deletions

File tree

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2+
3+
exports[`fixture round-trip (CST) alter-and-drop deparsed output matches snapshot 1`] = `
4+
"-- Add columns to existing table
5+
ALTER TABLE app.users
6+
ADD COLUMN bio text;
7+
ALTER TABLE app.users
8+
ADD COLUMN avatar_url text;
9+
10+
-- Rename a column
11+
ALTER TABLE app.users RENAME COLUMN username TO display_name;
12+
13+
-- Drop unused objects
14+
DROP INDEX IF EXISTS app.idx_old_index;
15+
16+
-- Recreate with new definition
17+
CREATE INDEX idx_users_display_name ON app.users (display_name);"
18+
`;
19+
20+
exports[`fixture round-trip (CST) edge-cases deparsed output matches snapshot 1`] = `
21+
"-- Comments with special characters: don't break "parsing"
22+
SELECT 1;
23+
24+
-- Inline comment after statement
25+
SELECT 2;
26+
-- trailing note
27+
28+
-- Adjacent comments with no blank line
29+
-- first line
30+
-- second line
31+
SELECT 3;
32+
33+
-- Dollar-quoted body with internal comments (should NOT be extracted)
34+
CREATE FUNCTION app.noop() RETURNS void AS $$
35+
BEGIN
36+
-- this comment is inside the function body
37+
NULL;
38+
END;
39+
$$ LANGUAGE plpgsql;
40+
41+
-- String that looks like a comment
42+
SELECT '-- not a comment' AS val;
43+
44+
-- Empty statement list edge
45+
SELECT 4;"
46+
`;
47+
48+
exports[`fixture round-trip (CST) grants-and-policies deparsed output matches snapshot 1`] = `
49+
"-- RLS policies for the users table
50+
ALTER TABLE app.users
51+
ENABLE ROW LEVEL SECURITY;
52+
53+
-- Admins can see all rows
54+
CREATE POLICY admin_all
55+
ON app.users
56+
AS PERMISSIVE
57+
FOR ALL
58+
TO admin_role
59+
USING (
60+
true
61+
);
62+
63+
-- Users can only see their own row
64+
CREATE POLICY own_row
65+
ON app.users
66+
AS PERMISSIVE
67+
FOR SELECT
68+
TO authenticated
69+
USING (
70+
id = (current_setting('app.current_user_id'))::int
71+
);
72+
73+
-- Grant basic access
74+
GRANT USAGE ON SCHEMA app TO authenticated;
75+
GRANT SELECT ON app.users TO authenticated;
76+
GRANT ALL ON app.users TO admin_role;"
77+
`;
78+
79+
exports[`fixture round-trip (CST) multi-statement deparsed output matches snapshot 1`] = `
80+
"-- Schema setup
81+
CREATE SCHEMA IF NOT EXISTS app;
82+
83+
-- Users table
84+
CREATE TABLE app.users (
85+
id serial PRIMARY KEY,
86+
username text NOT NULL,
87+
created_at timestamptz DEFAULT now()
88+
);
89+
90+
-- Roles table
91+
CREATE TABLE app.roles (
92+
id serial PRIMARY KEY,
93+
name text UNIQUE NOT NULL
94+
);
95+
96+
-- Junction table
97+
CREATE TABLE app.user_roles (
98+
user_id int REFERENCES app.users (id),
99+
role_id int REFERENCES app.roles (id),
100+
PRIMARY KEY (user_id, role_id)
101+
);
102+
103+
-- Seed default roles
104+
INSERT INTO app.roles (
105+
name
106+
) VALUES
107+
('admin'),
108+
('viewer');"
109+
`;
110+
111+
exports[`fixture round-trip (CST) pgpm-header deparsed output matches snapshot 1`] = `
112+
"-- Deploy schemas/my-app/tables/users to pg
113+
-- requires: schemas/my-app/schema
114+
115+
BEGIN;
116+
117+
-- Create the main users table
118+
CREATE TABLE my_app.users (
119+
id serial PRIMARY KEY,
120+
name text NOT NULL,
121+
email text UNIQUE
122+
);
123+
124+
-- Add an index for fast lookups
125+
CREATE INDEX idx_users_email ON my_app.users (email);
126+
127+
COMMIT;"
128+
`;
129+
130+
exports[`fixture round-trip (CST) plpgsql-function deparsed output matches snapshot 1`] = `
131+
"-- Deploy schemas/app/functions/get_user to pg
132+
-- requires: schemas/app/tables/users
133+
134+
BEGIN;
135+
136+
-- Function to get a user by ID
137+
CREATE FUNCTION app.get_user(
138+
p_id int
139+
) RETURNS TABLE (
140+
id int,
141+
username text,
142+
created_at timestamptz
143+
) AS $$
144+
BEGIN
145+
-- Return the matching user
146+
RETURN QUERY
147+
SELECT u.id, u.username, u.created_at
148+
FROM app.users u
149+
WHERE u.id = p_id;
150+
END;
151+
$$ LANGUAGE plpgsql STABLE;
152+
153+
-- Grant execute to authenticated users
154+
GRANT EXECUTE ON FUNCTION app.get_user(int) TO authenticated;
155+
156+
COMMIT;"
157+
`;
158+
159+
exports[`fixture round-trip (CST) views-and-triggers deparsed output matches snapshot 1`] = `
160+
"-- Active users view
161+
CREATE VIEW app.active_users AS SELECT
162+
id,
163+
username,
164+
created_at
165+
FROM app.users
166+
WHERE
167+
created_at > (now() - '90 days'::interval);
168+
169+
-- Audit trigger function
170+
CREATE FUNCTION app.audit_trigger() RETURNS trigger AS $$
171+
BEGIN
172+
INSERT INTO app.audit_log (table_name, action, row_id)
173+
VALUES (TG_TABLE_NAME, TG_OP, NEW.id);
174+
RETURN NEW;
175+
END;
176+
$$ LANGUAGE plpgsql;
177+
178+
-- Attach trigger to users table
179+
CREATE TRIGGER users_audit
180+
AFTER INSERT OR UPDATE
181+
ON app.users
182+
FOR EACH ROW
183+
EXECUTE PROCEDURE app.audit_trigger();"
184+
`;

packages/parse/__tests__/roundtrip.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ beforeAll(async () => {
2626
describe('fixture round-trip (CST)', () => {
2727
for (const { name, sql } of fixtures) {
2828
describe(name, () => {
29+
it('deparsed output matches snapshot', () => {
30+
const result = parseSync(sql);
31+
const output = deparseEnhanced(result);
32+
expect(output).toMatchSnapshot();
33+
});
34+
2935
it('parse→deparse→parse→deparse is idempotent', () => {
3036
// First round trip
3137
const result1 = parseSync(sql);

0 commit comments

Comments
 (0)