11import json
2- from typing import Awaitable , Callable , Type
2+ from typing import Awaitable , Callable , Type , Union
33
44import pytest
55import sqlalchemy as sa
@@ -30,8 +30,10 @@ class TestModel(base): # type: ignore[misc,valid-type]
3030 }
3131 # Autoincremented PK should not be in create form
3232 assert r .inputs == {
33- "id" : {"type" : "NumberInput" , "show_create" : False , "props" : {}},
34- "num" : {"type" : "TextInput" , "show_create" : True , "props" : {}}
33+ "id" : {"type" : "NumberInput" , "show_create" : False , "props" : {},
34+ "validators" : [("required" ,)]},
35+ "num" : {"type" : "TextInput" , "show_create" : True , "props" : {},
36+ "validators" : [("required" ,)]}
3537 }
3638
3739
@@ -49,8 +51,10 @@ def test_table(mock_engine: AsyncEngine) -> None:
4951 }
5052 # Autoincremented PK should not be in create form
5153 assert r .inputs == {
52- "id" : {"type" : "NumberInput" , "show_create" : False , "props" : {}},
53- "num" : {"type" : "TextInput" , "show_create" : True , "props" : {}}
54+ "id" : {"type" : "NumberInput" , "show_create" : False , "props" : {},
55+ "validators" : [("required" ,)]},
56+ "num" : {"type" : "TextInput" , "show_create" : True , "props" : {},
57+ "validators" : [("maxLength" , 30 )]}
5458 }
5559
5660
@@ -69,7 +73,8 @@ class TestChildModel(base): # type: ignore[misc,valid-type]
6973 assert r .fields == {"id" : {"type" : "ReferenceField" , "props" : {"reference" : "dummy" }}}
7074 # PK with FK constraint should be shown in create form.
7175 assert r .inputs == {"id" : {
72- "type" : "ReferenceInput" , "show_create" : True , "props" : {"reference" : "dummy" }}}
76+ "type" : "ReferenceInput" , "show_create" : True , "props" : {"reference" : "dummy" },
77+ "validators" : [("required" ,)]}}
7378
7479
7580def test_relationship (base : Type [DeclarativeBase ], mock_engine : AsyncEngine ) -> None :
@@ -92,6 +97,47 @@ class TestOne(base): # type: ignore[misc,valid-type]
9297 assert "ones" not in r .inputs
9398
9499
100+ def test_check_constraints (base : Type [DeclarativeBase ], mock_engine : AsyncEngine ) -> None :
101+ class TestCC (base ): # type: ignore[misc,valid-type]
102+ __tablename__ = "test"
103+ pk : Mapped [int ] = mapped_column (primary_key = True )
104+ default : Mapped [int ] = mapped_column (default = 5 )
105+ server_default : Mapped [int ] = mapped_column (server_default = "4" )
106+ nullable : Mapped [Union [int , None ]]
107+ not_nullable : Mapped [int ]
108+ max_length : Mapped [str ] = mapped_column (sa .String (16 ))
109+ gt : Mapped [int ] = mapped_column ()
110+ gte : Mapped [int ] = mapped_column ()
111+ lt : Mapped [int ] = mapped_column ()
112+ lte : Mapped [Union [int , None ]] = mapped_column ()
113+ min_length : Mapped [str ] = mapped_column ()
114+ min_length_gt : Mapped [str ] = mapped_column ()
115+ regex : Mapped [str ] = mapped_column ()
116+
117+ __table_args__ = (sa .CheckConstraint (gt > 3 ), sa .CheckConstraint (gte >= 3 ),
118+ sa .CheckConstraint (lt < 3 ), sa .CheckConstraint (lte <= 3 ),
119+ sa .CheckConstraint (sa .func .char_length (min_length ) >= 5 ),
120+ sa .CheckConstraint (sa .func .char_length (min_length_gt ) > 5 ),
121+ sa .CheckConstraint (sa .func .regexp (regex , r"abc.*" )))
122+
123+ r = SAResource (mock_engine , TestCC )
124+
125+ f = r .inputs
126+ assert f ["pk" ]["validators" ] == [("required" ,)]
127+ assert f ["default" ]["validators" ] == []
128+ assert f ["server_default" ]["validators" ] == []
129+ assert f ["nullable" ]["validators" ] == []
130+ assert f ["not_nullable" ]["validators" ] == [("required" ,)]
131+ assert f ["max_length" ]["validators" ] == [("required" ,), ("maxLength" , 16 )]
132+ assert f ["gt" ]["validators" ] == [("required" ,), ("minValue" , 4 )]
133+ assert f ["gte" ]["validators" ] == [("required" ,), ("minValue" , 3 )]
134+ assert f ["lt" ]["validators" ] == [("required" ,), ("maxValue" , 2 )]
135+ assert f ["lte" ]["validators" ] == [("maxValue" , 3 )]
136+ assert f ["min_length" ]["validators" ] == [("required" ,), ("minLength" , 5 )]
137+ assert f ["min_length_gt" ]["validators" ] == [("required" ,), ("minLength" , 6 )]
138+ assert f ["regex" ]["validators" ] == [("required" ,), ("regex" , "abc.*" )]
139+
140+
95141async def test_nonid_pk (base : Type [DeclarativeBase ], mock_engine : AsyncEngine ) -> None :
96142 class TestModel (base ): # type: ignore[misc,valid-type]
97143 __tablename__ = "test"
@@ -106,8 +152,10 @@ class TestModel(base): # type: ignore[misc,valid-type]
106152 "other" : {"type" : "TextField" , "props" : {}}
107153 }
108154 assert r .inputs == {
109- "num" : {"type" : "NumberInput" , "show_create" : False , "props" : {}},
110- "other" : {"type" : "TextInput" , "show_create" : True , "props" : {}}
155+ "num" : {"type" : "NumberInput" , "show_create" : False , "props" : {},
156+ "validators" : [("required" ,)]},
157+ "other" : {"type" : "TextInput" , "show_create" : True , "props" : {},
158+ "validators" : [("required" ,)]}
111159 }
112160
113161
0 commit comments