11"""Roundtrip and edge-case tests for SchemaForge — SQL DDL ↔ Prisma."""
2+
23from __future__ import annotations
34
45import sys
6566
6667# ── Roundtrip Fidelity Tests ──
6768
69+
6870def test_sql_to_prisma_to_sql_roundtrip ():
6971 """Full roundtrip: SQL → Prisma → SQL preserves table structure.
7072
@@ -152,6 +154,7 @@ def test_prisma_to_sql_to_prisma_roundtrip():
152154
153155# ── Edge Case Tests ──
154156
157+
155158def test_empty_sql ():
156159 """Empty input should produce empty schema."""
157160 parser = SQLParser ()
@@ -266,16 +269,22 @@ def test_prisma_complex_types():
266269
267270# ── Generator Edge Cases ──
268271
272+
269273def test_generate_without_enum ():
270274 """SQL generation without enums should not include CREATE TYPE."""
271275 from schemaforge .ir import Column , ColumnType , Schema , Table
272276
273- schema = Schema (tables = [
274- Table (name = "items" , columns = [
275- Column (name = "id" , type = ColumnType .INTEGER , primary_key = True ),
276- Column (name = "name" , type = ColumnType .STRING , nullable = False ),
277- ])
278- ])
277+ schema = Schema (
278+ tables = [
279+ Table (
280+ name = "items" ,
281+ columns = [
282+ Column (name = "id" , type = ColumnType .INTEGER , primary_key = True ),
283+ Column (name = "name" , type = ColumnType .STRING , nullable = False ),
284+ ],
285+ )
286+ ]
287+ )
279288 gen = SQLGenerator ()
280289 output = gen .generate (schema )
281290 assert "CREATE TYPE" not in output
@@ -298,18 +307,30 @@ def test_prisma_generate_complex():
298307 """Prisma generation should handle all column types."""
299308 from schemaforge .ir import Column , ColumnType , Index , Schema , Table
300309
301- schema = Schema (tables = [
302- Table (name = "Item" , columns = [
303- Column (name = "id" , type = ColumnType .INTEGER , primary_key = True ),
304- Column (name = "name" , type = ColumnType .STRING , type_args = {"length" : 100 }),
305- Column (name = "price" , type = ColumnType .DECIMAL , type_args = {"precision" : 12 , "scale" : 4 }),
306- Column (name = "active" , type = ColumnType .BOOLEAN , default = True ),
307- Column (name = "data" , type = ColumnType .JSON , nullable = True ),
308- Column (name = "token" , type = ColumnType .UUID , unique = True ),
309- ], indexes = [
310- Index (name = "idx_name" , columns = ["name" ]),
311- ])
312- ])
310+ schema = Schema (
311+ tables = [
312+ Table (
313+ name = "Item" ,
314+ columns = [
315+ Column (name = "id" , type = ColumnType .INTEGER , primary_key = True ),
316+ Column (
317+ name = "name" , type = ColumnType .STRING , type_args = {"length" : 100 }
318+ ),
319+ Column (
320+ name = "price" ,
321+ type = ColumnType .DECIMAL ,
322+ type_args = {"precision" : 12 , "scale" : 4 },
323+ ),
324+ Column (name = "active" , type = ColumnType .BOOLEAN , default = True ),
325+ Column (name = "data" , type = ColumnType .JSON , nullable = True ),
326+ Column (name = "token" , type = ColumnType .UUID , unique = True ),
327+ ],
328+ indexes = [
329+ Index (name = "idx_name" , columns = ["name" ]),
330+ ],
331+ )
332+ ]
333+ )
313334 gen = PrismaGenerator ()
314335 output = gen .generate (schema )
315336 assert "model Item" in output
@@ -322,6 +343,7 @@ def test_prisma_generate_complex():
322343
323344# ── Conversion Edge Cases ──
324345
346+
325347def test_convert_same_format_returns_original ():
326348 """Converting a format to itself should return the original text."""
327349 result = convert_schema ("hello world" , "sql" , "sql" )
@@ -331,6 +353,7 @@ def test_convert_same_format_returns_original():
331353def test_convert_unsupported_format ():
332354 """Unsupported format should raise ValueError."""
333355 import pytest
356+
334357 with pytest .raises (ValueError , match = "Unsupported source format" ):
335358 convert_schema ("data" , "unsupported" , "sql" )
336359 with pytest .raises (ValueError , match = "Unsupported target format" ):
@@ -362,6 +385,7 @@ def test_sql_default_values():
362385
363386# ── SQL Parser Edge Case Tests ──
364387
388+
365389def test_sql_temporary_table ():
366390 """CREATE TEMPORARY TABLE should be parsed."""
367391 parser = SQLParser ()
@@ -415,11 +439,11 @@ def test_sql_backtick_quoted_schema_table():
415439def test_sql_double_quoted_table ():
416440 """Double-quoted table names should be parsed."""
417441 parser = SQLParser ()
418- schema = parser .parse ('''
442+ schema = parser .parse ("""
419443 CREATE TABLE "users" (
420444 "id" INTEGER PRIMARY KEY
421445 );
422- ''' )
446+ """ )
423447 assert len (schema .tables ) == 1
424448 assert schema .tables [0 ].name == "users"
425449
@@ -485,14 +509,30 @@ def test_sql_current_date_default():
485509def test_sql_fn_default_generates_without_quotes ():
486510 """fn: prefixed defaults should generate without quotes in SQL DDL."""
487511 from schemaforge .ir import Column , ColumnType , Schema , Table
488- schema = Schema (tables = [
489- Table (name = "events" , columns = [
490- Column (name = "id" , type = ColumnType .INTEGER , primary_key = True ),
491- Column (name = "created_at" , type = ColumnType .DATETIME , default = "fn:CURRENT_TIMESTAMP" ),
492- Column (name = "updated_at" , type = ColumnType .DATETIME , default = "fn:NOW()" ),
493- Column (name = "token" , type = ColumnType .UUID , default = "fn:gen_random_uuid()" ),
494- ])
495- ])
512+
513+ schema = Schema (
514+ tables = [
515+ Table (
516+ name = "events" ,
517+ columns = [
518+ Column (name = "id" , type = ColumnType .INTEGER , primary_key = True ),
519+ Column (
520+ name = "created_at" ,
521+ type = ColumnType .DATETIME ,
522+ default = "fn:CURRENT_TIMESTAMP" ,
523+ ),
524+ Column (
525+ name = "updated_at" , type = ColumnType .DATETIME , default = "fn:NOW()"
526+ ),
527+ Column (
528+ name = "token" ,
529+ type = ColumnType .UUID ,
530+ default = "fn:gen_random_uuid()" ,
531+ ),
532+ ],
533+ )
534+ ]
535+ )
496536 gen = SQLGenerator ()
497537 output = gen .generate (schema )
498538 assert "DEFAULT CURRENT_TIMESTAMP" in output
@@ -550,6 +590,7 @@ def test_prisma_now_default_roundtrip():
550590
551591# ── MySQL Table Options Tests ──
552592
593+
553594def test_sql_mysql_engine_option ():
554595 """ENGINE=InnoDB table option should be parsed."""
555596 parser = SQLParser ()
@@ -621,11 +662,18 @@ def test_sql_table_options_roundtrip():
621662def test_sql_table_options_generated ():
622663 """MySQL table options from IR should generate correctly."""
623664 from schemaforge .ir import Column , ColumnType , Schema , Table
624- schema = Schema (tables = [
625- Table (name = "users" , columns = [
626- Column (name = "id" , type = ColumnType .INTEGER , primary_key = True ),
627- ], options = {"ENGINE" : "InnoDB" , "DEFAULT CHARSET" : "utf8mb4" })
628- ])
665+
666+ schema = Schema (
667+ tables = [
668+ Table (
669+ name = "users" ,
670+ columns = [
671+ Column (name = "id" , type = ColumnType .INTEGER , primary_key = True ),
672+ ],
673+ options = {"ENGINE" : "InnoDB" , "DEFAULT CHARSET" : "utf8mb4" },
674+ )
675+ ]
676+ )
629677 gen = SQLGenerator ()
630678 output = gen .generate (schema )
631679 assert "ENGINE=InnoDB" in output
@@ -634,6 +682,7 @@ def test_sql_table_options_generated():
634682
635683# ── Inline ENUM('a','b','c') Tests ──
636684
685+
637686def test_sql_inline_enum_column ():
638687 """Inline ENUM('a','b','c') column type should be parsed."""
639688 parser = SQLParser ()
@@ -666,13 +715,22 @@ def test_sql_inline_enum_roundtrip():
666715def test_sql_inline_enum_generated ():
667716 """ENUM with inline values from IR should generate correctly."""
668717 from schemaforge .ir import Column , ColumnType , Schema , Table
669- schema = Schema (tables = [
670- Table (name = "tshirts" , columns = [
671- Column (name = "id" , type = ColumnType .INTEGER , primary_key = True ),
672- Column (name = "size" , type = ColumnType .ENUM ,
673- type_args = {"values" : ["small" , "medium" , "large" ]}),
674- ])
675- ])
718+
719+ schema = Schema (
720+ tables = [
721+ Table (
722+ name = "tshirts" ,
723+ columns = [
724+ Column (name = "id" , type = ColumnType .INTEGER , primary_key = True ),
725+ Column (
726+ name = "size" ,
727+ type = ColumnType .ENUM ,
728+ type_args = {"values" : ["small" , "medium" , "large" ]},
729+ ),
730+ ],
731+ )
732+ ]
733+ )
676734 gen = SQLGenerator ()
677735 output = gen .generate (schema )
678736 assert "ENUM('small', 'medium', 'large')" in output
0 commit comments