diff --git a/tests/output/Dockerfile b/tests/output/Dockerfile
new file mode 100644
index 0000000..c974819
--- /dev/null
+++ b/tests/output/Dockerfile
@@ -0,0 +1,5 @@
+FROM ghcr.io/printeers/trek:latest
+COPY ./trek.yaml /data
+COPY ./testdata /data/testdata
+COPY ./migrations /data/migrations
+COPY ./hooks /data/hooks
diff --git a/tests/output/docker-compose.yaml b/tests/output/docker-compose.yaml
new file mode 100644
index 0000000..b5af8fd
--- /dev/null
+++ b/tests/output/docker-compose.yaml
@@ -0,0 +1,34 @@
+version: "3.7"
+
+services:
+
+ postgres:
+ image: postgres:14
+ environment:
+ POSTGRES_PASSWORD: postgres
+ ports:
+ - "5432:5432"
+ volumes:
+ - postgres-data:/var/lib/postgresql/data
+ restart: always
+
+ migrations:
+ build:
+ context: .
+ environment:
+ TREK_POSTGRES_HOST: postgres
+ TREK_POSTGRES_PORT: 5432
+ TREK_POSTGRES_USER: postgres
+ TREK_POSTGRES_PASSWORD: postgres
+ TREK_POSTGRES_DATABASE: postgres
+ TREK_POSTGRES_SSLMODE: disable
+ TREK_RESET_DATABASE: "false"
+ TREK_INSERT_TEST_DATA: "true"
+ volumes:
+ - ./:/data
+ depends_on:
+ - postgres
+ restart: on-failure
+
+volumes:
+ postgres-data:
diff --git a/tests/output/hooks/apply-reset-post.sample b/tests/output/hooks/apply-reset-post.sample
new file mode 100755
index 0000000..9a7ec44
--- /dev/null
+++ b/tests/output/hooks/apply-reset-post.sample
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -euxo pipefail
+
+echo "This is apply-reset-post"
diff --git a/tests/output/hooks/apply-reset-pre.sample b/tests/output/hooks/apply-reset-pre.sample
new file mode 100755
index 0000000..e14b172
--- /dev/null
+++ b/tests/output/hooks/apply-reset-pre.sample
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -euxo pipefail
+
+echo "This is apply-reset-pre"
diff --git a/tests/output/hooks/generate-migration-post.sample b/tests/output/hooks/generate-migration-post.sample
new file mode 100755
index 0000000..35a0e2a
--- /dev/null
+++ b/tests/output/hooks/generate-migration-post.sample
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -euxo pipefail
+
+echo "This is generate-migration-post"
+echo "Running on migration file $1"
diff --git a/tests/output/migrations/001_init.up.sql b/tests/output/migrations/001_init.up.sql
new file mode 100644
index 0000000..ac6bcd1
--- /dev/null
+++ b/tests/output/migrations/001_init.up.sql
@@ -0,0 +1,26 @@
+-- Database generated with pgModeler (PostgreSQL Database Modeler).
+-- pgModeler version: 1.0.6
+-- PostgreSQL version: 16.0
+-- Project Site: pgmodeler.io
+-- Model Author: ---
+-- -- object: santa | type: ROLE --
+-- -- DROP ROLE IF EXISTS santa;
+-- CREATE ROLE santa WITH ;
+-- -- ddl-end --
+--
+-- -- object: worker | type: ROLE --
+-- -- DROP ROLE IF EXISTS worker;
+-- CREATE ROLE worker WITH ;
+-- -- ddl-end --
+--
+
+-- Database creation must be performed outside a multi lined SQL file.
+-- These commands were put in this file only as a convenience.
+--
+-- -- object: north_pole | type: DATABASE --
+-- -- DROP DATABASE IF EXISTS north_pole;
+-- CREATE DATABASE north_pole;
+-- -- ddl-end --
+--
+
+
diff --git a/tests/output/migrations/002_schemas.up.sql b/tests/output/migrations/002_schemas.up.sql
new file mode 100644
index 0000000..e787d56
--- /dev/null
+++ b/tests/output/migrations/002_schemas.up.sql
@@ -0,0 +1,2 @@
+create schema if not exists "factory";
+create schema if not exists "warehouse";
diff --git a/tests/output/migrations/003_tables.up.sql b/tests/output/migrations/003_tables.up.sql
new file mode 100644
index 0000000..d06ede5
--- /dev/null
+++ b/tests/output/migrations/003_tables.up.sql
@@ -0,0 +1,10 @@
+create table "factory"."machines" (
+ "name" text not null,
+ "toys_produced" bigint not null
+);
+create table "warehouse"."storage_locations" (
+ "shelf" bigint not null,
+ "total_capacity" bigint not null,
+ "used_capacity" bigint not null,
+ "current_toy_type" text not null
+);
diff --git a/tests/output/migrations/004_sequences.up.sql b/tests/output/migrations/004_sequences.up.sql
new file mode 100644
index 0000000..ead74fb
--- /dev/null
+++ b/tests/output/migrations/004_sequences.up.sql
@@ -0,0 +1,8 @@
+create sequence "factory"."seq_machines_id";
+create sequence "warehouse"."seq_storage_locations_id";
+alter table "factory"."machines" add column "id" bigint not null default nextval('factory.seq_machines_id'::regclass);
+alter table "warehouse"."storage_locations" add column "id" bigint not null default nextval('warehouse.seq_storage_locations_id'::regclass);
+CREATE UNIQUE INDEX machines_pk ON factory.machines USING btree (id);
+CREATE UNIQUE INDEX storage_locations_pk ON warehouse.storage_locations USING btree (id);
+alter table "factory"."machines" add constraint "machines_pk" PRIMARY KEY using index "machines_pk";
+alter table "warehouse"."storage_locations" add constraint "storage_locations_pk" PRIMARY KEY using index "storage_locations_pk";
diff --git a/tests/output/migrations/005_checks.up.sql b/tests/output/migrations/005_checks.up.sql
new file mode 100644
index 0000000..679e303
--- /dev/null
+++ b/tests/output/migrations/005_checks.up.sql
@@ -0,0 +1 @@
+alter table "warehouse"."storage_locations" add constraint "ck_capacity" CHECK ((total_capacity >= used_capacity));
diff --git a/tests/output/migrations/006_triggers.up.sql b/tests/output/migrations/006_triggers.up.sql
new file mode 100644
index 0000000..413479b
--- /dev/null
+++ b/tests/output/migrations/006_triggers.up.sql
@@ -0,0 +1,14 @@
+set check_function_bodies = off;
+CREATE OR REPLACE FUNCTION factory.tr_machines_toys_produced_increase()
+ RETURNS trigger
+ LANGUAGE plpgsql
+ COST 1
+AS $function$
+BEGIN
+ IF NEW.toys_produced < OLD.toys_produced THEN
+ RAISE EXCEPTION 'Toys produced count can not be lowered';
+ END IF;
+END;
+$function$
+;
+CREATE TRIGGER toys_produced_increase BEFORE UPDATE OF toys_produced ON factory.machines FOR EACH ROW EXECUTE FUNCTION factory.tr_machines_toys_produced_increase();
diff --git a/tests/output/santas_warehouse.dbm b/tests/output/santas_warehouse.dbm
new file mode 100644
index 0000000..86a6581
--- /dev/null
+++ b/tests/output/santas_warehouse.dbm
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ = used_capacity]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/output/santas_warehouse.png b/tests/output/santas_warehouse.png
new file mode 100644
index 0000000..d325c34
Binary files /dev/null and b/tests/output/santas_warehouse.png differ
diff --git a/tests/output/santas_warehouse.sql b/tests/output/santas_warehouse.sql
new file mode 100644
index 0000000..9a1dd10
--- /dev/null
+++ b/tests/output/santas_warehouse.sql
@@ -0,0 +1,133 @@
+-- Database generated with pgModeler (PostgreSQL Database Modeler).
+-- pgModeler version: 1.0.6
+-- PostgreSQL version: 16.0
+-- Project Site: pgmodeler.io
+-- Model Author: ---
+-- -- object: santa | type: ROLE --
+-- -- DROP ROLE IF EXISTS santa;
+-- CREATE ROLE santa WITH ;
+-- -- ddl-end --
+--
+-- -- object: worker | type: ROLE --
+-- -- DROP ROLE IF EXISTS worker;
+-- CREATE ROLE worker WITH ;
+-- -- ddl-end --
+--
+
+-- Database creation must be performed outside a multi lined SQL file.
+-- These commands were put in this file only as a convenience.
+--
+-- -- object: north_pole | type: DATABASE --
+-- -- DROP DATABASE IF EXISTS north_pole;
+-- CREATE DATABASE north_pole;
+-- -- ddl-end --
+--
+
+SET check_function_bodies = false;
+-- ddl-end --
+
+-- object: warehouse | type: SCHEMA --
+-- DROP SCHEMA IF EXISTS warehouse CASCADE;
+CREATE SCHEMA warehouse;
+-- ddl-end --
+ALTER SCHEMA warehouse OWNER TO postgres;
+-- ddl-end --
+
+-- object: factory | type: SCHEMA --
+-- DROP SCHEMA IF EXISTS factory CASCADE;
+CREATE SCHEMA factory;
+-- ddl-end --
+ALTER SCHEMA factory OWNER TO postgres;
+-- ddl-end --
+
+SET search_path TO pg_catalog,public,warehouse,factory;
+-- ddl-end --
+
+-- object: warehouse.seq_storage_locations_id | type: SEQUENCE --
+-- DROP SEQUENCE IF EXISTS warehouse.seq_storage_locations_id CASCADE;
+CREATE SEQUENCE warehouse.seq_storage_locations_id
+ INCREMENT BY 1
+ MINVALUE 0
+ MAXVALUE 2147483647
+ START WITH 1
+ CACHE 1
+ NO CYCLE
+ OWNED BY NONE;
+
+-- ddl-end --
+ALTER SEQUENCE warehouse.seq_storage_locations_id OWNER TO postgres;
+-- ddl-end --
+
+-- object: factory.seq_machines_id | type: SEQUENCE --
+-- DROP SEQUENCE IF EXISTS factory.seq_machines_id CASCADE;
+CREATE SEQUENCE factory.seq_machines_id
+ INCREMENT BY 1
+ MINVALUE 0
+ MAXVALUE 2147483647
+ START WITH 1
+ CACHE 1
+ NO CYCLE
+ OWNED BY NONE;
+
+-- ddl-end --
+ALTER SEQUENCE factory.seq_machines_id OWNER TO postgres;
+-- ddl-end --
+
+-- object: factory.machines | type: TABLE --
+-- DROP TABLE IF EXISTS factory.machines CASCADE;
+CREATE TABLE factory.machines (
+ id bigint NOT NULL DEFAULT nextval('factory.seq_machines_id'::regclass),
+ name text NOT NULL,
+ toys_produced bigint NOT NULL,
+ CONSTRAINT machines_pk PRIMARY KEY (id)
+);
+-- ddl-end --
+ALTER TABLE factory.machines OWNER TO postgres;
+-- ddl-end --
+
+-- object: warehouse.storage_locations | type: TABLE --
+-- DROP TABLE IF EXISTS warehouse.storage_locations CASCADE;
+CREATE TABLE warehouse.storage_locations (
+ id bigint NOT NULL DEFAULT nextval('warehouse.seq_storage_locations_id'::regclass),
+ shelf bigint NOT NULL,
+ total_capacity bigint NOT NULL,
+ used_capacity bigint NOT NULL,
+ current_toy_type text NOT NULL,
+ CONSTRAINT storage_locations_pk PRIMARY KEY (id),
+ CONSTRAINT ck_capacity CHECK (total_capacity >= used_capacity)
+);
+-- ddl-end --
+ALTER TABLE warehouse.storage_locations OWNER TO postgres;
+-- ddl-end --
+
+-- object: factory.tr_machines_toys_produced_increase | type: FUNCTION --
+-- DROP FUNCTION IF EXISTS factory.tr_machines_toys_produced_increase() CASCADE;
+CREATE FUNCTION factory.tr_machines_toys_produced_increase ()
+ RETURNS trigger
+ LANGUAGE plpgsql
+ VOLATILE
+ CALLED ON NULL INPUT
+ SECURITY INVOKER
+ PARALLEL UNSAFE
+ COST 1
+ AS $$
+BEGIN
+ IF NEW.toys_produced < OLD.toys_produced THEN
+ RAISE EXCEPTION 'Toys produced count can not be lowered';
+ END IF;
+END;
+$$;
+-- ddl-end --
+ALTER FUNCTION factory.tr_machines_toys_produced_increase() OWNER TO postgres;
+-- ddl-end --
+
+-- object: toys_produced_increase | type: TRIGGER --
+-- DROP TRIGGER IF EXISTS toys_produced_increase ON factory.machines CASCADE;
+CREATE TRIGGER toys_produced_increase
+ BEFORE UPDATE OF toys_produced
+ ON factory.machines
+ FOR EACH ROW
+ EXECUTE PROCEDURE factory.tr_machines_toys_produced_increase();
+-- ddl-end --
+
+
diff --git a/tests/output/testdata/001_0101-content.sql b/tests/output/testdata/001_0101-content.sql
new file mode 100644
index 0000000..e69de29
diff --git a/tests/output/trek.yaml b/tests/output/trek.yaml
new file mode 100644
index 0000000..59d9672
--- /dev/null
+++ b/tests/output/trek.yaml
@@ -0,0 +1,5 @@
+model_name: santas_warehouse
+db_name: north_pole
+db_users:
+ - santa
+ - worker
diff --git a/tests/run.sh b/tests/run.sh
new file mode 100755
index 0000000..f538a45
--- /dev/null
+++ b/tests/run.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+set -euxo pipefail
+cd "$(dirname "$0")"
+
+rm -rf output
+mkdir -p output
+
+(
+ cd output
+
+ function trek {
+ go run ../.. "${@}"
+ }
+
+ TREK_VERSION=latest \
+ TREK_MODEL_NAME=santas_warehouse \
+ TREK_DATABASE_NAME=north_pole \
+ TREK_DATABASE_USERS=santa,worker \
+ trek init
+
+ trek check
+
+ for file in ../stages/*; do
+ cp "$file" santas_warehouse.dbm
+
+ trek generate "$(basename "$file" | cut -d "-" -f 2 | cut -d "." -f 1)"
+
+ trek check
+ done
+)
diff --git a/tests/stages/01-schemas.dbm b/tests/stages/01-schemas.dbm
new file mode 100644
index 0000000..871fddf
--- /dev/null
+++ b/tests/stages/01-schemas.dbm
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/stages/02-tables.dbm b/tests/stages/02-tables.dbm
new file mode 100644
index 0000000..01dc918
--- /dev/null
+++ b/tests/stages/02-tables.dbm
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/stages/03-sequences-indexes.dbm b/tests/stages/03-sequences-indexes.dbm
new file mode 100644
index 0000000..ae4c06f
--- /dev/null
+++ b/tests/stages/03-sequences-indexes.dbm
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/stages/04-checks.dbm b/tests/stages/04-checks.dbm
new file mode 100644
index 0000000..ad4c7a6
--- /dev/null
+++ b/tests/stages/04-checks.dbm
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ = used_capacity]]>
+
+
+
+
diff --git a/tests/stages/05-triggers.dbm b/tests/stages/05-triggers.dbm
new file mode 100644
index 0000000..86a6581
--- /dev/null
+++ b/tests/stages/05-triggers.dbm
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ = used_capacity]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+