@@ -173,4 +173,126 @@ mod tests {
173173 assert_eq ! ( rendered, "String" ) ;
174174 assert_eq ! ( attr. as_deref( ) , native) ;
175175 }
176+
177+ /// Exhaustive oracle for every simple type except `Uuid` (whose scalar
178+ /// itself is provider-dependent — covered by its dedicated test above).
179+ /// Each row is independent test data, so flipping any production mapping
180+ /// tuple (mutation testing) fails here immediately.
181+ #[ rstest]
182+ #[ case:: postgres( PrismaProvider :: Postgres ) ]
183+ #[ case:: mysql( PrismaProvider :: MySql ) ]
184+ #[ case:: sqlite( PrismaProvider :: Sqlite ) ]
185+ fn simple_type_mapping_matrix ( #[ case] provider : PrismaProvider ) {
186+ use SimpleColumnType as S ;
187+ // (type, scalar, postgres attr, mysql attr) — sqlite is always attr-less.
188+ let rows: & [ ( S , & str , Option < & str > , Option < & str > ) ] = & [
189+ (
190+ S :: SmallInt ,
191+ "Int" ,
192+ Some ( "@db.SmallInt" ) ,
193+ Some ( "@db.SmallInt" ) ,
194+ ) ,
195+ ( S :: Integer , "Int" , None , None ) ,
196+ ( S :: BigInt , "BigInt" , None , None ) ,
197+ ( S :: Real , "Float" , Some ( "@db.Real" ) , Some ( "@db.Float" ) ) ,
198+ ( S :: DoublePrecision , "Float" , None , None ) ,
199+ ( S :: Text , "String" , Some ( "@db.Text" ) , Some ( "@db.Text" ) ) ,
200+ ( S :: Boolean , "Boolean" , None , None ) ,
201+ ( S :: Date , "DateTime" , Some ( "@db.Date" ) , Some ( "@db.Date" ) ) ,
202+ ( S :: Time , "DateTime" , Some ( "@db.Time" ) , Some ( "@db.Time" ) ) ,
203+ (
204+ S :: Timestamp ,
205+ "DateTime" ,
206+ Some ( "@db.Timestamp" ) ,
207+ Some ( "@db.Timestamp" ) ,
208+ ) ,
209+ (
210+ S :: Timestamptz ,
211+ "DateTime" ,
212+ Some ( "@db.Timestamptz" ) ,
213+ Some ( "@db.Timestamp" ) ,
214+ ) ,
215+ ( S :: Interval , "String" , None , Some ( "@db.Text" ) ) ,
216+ ( S :: Bytea , "Bytes" , None , None ) ,
217+ ( S :: Json , "Json" , None , None ) ,
218+ ( S :: Inet , "String" , Some ( "@db.Inet" ) , Some ( "@db.Text" ) ) ,
219+ ( S :: Cidr , "String" , None , Some ( "@db.Text" ) ) ,
220+ ( S :: Macaddr , "String" , None , Some ( "@db.Text" ) ) ,
221+ ( S :: Xml , "String" , Some ( "@db.Xml" ) , Some ( "@db.Text" ) ) ,
222+ ] ;
223+
224+ for ( ty, scalar, pg, mysql) in rows {
225+ let expected = match provider {
226+ PrismaProvider :: Postgres => * pg,
227+ PrismaProvider :: MySql => * mysql,
228+ PrismaProvider :: Sqlite => None ,
229+ } ;
230+ let ( rendered, attr) = column_type_to_prisma ( & ColumnType :: Simple ( * ty) , false , provider) ;
231+ assert_eq ! ( rendered, * scalar, "{ty:?} scalar under {provider:?}" ) ;
232+ assert_eq ! ( attr. as_deref( ) , expected, "{ty:?} attr under {provider:?}" ) ;
233+ }
234+ }
235+
236+ #[ rstest]
237+ #[ case:: postgres(
238+ PrismaProvider :: Postgres ,
239+ Some ( "@db.Char(3)" ) ,
240+ Some ( "@db.Decimal(10, 2)" )
241+ ) ]
242+ #[ case:: mysql( PrismaProvider :: MySql , Some ( "@db.Char(3)" ) , Some ( "@db.Decimal(10, 2)" ) ) ]
243+ #[ case:: sqlite( PrismaProvider :: Sqlite , None , None ) ]
244+ fn char_and_numeric_natives_follow_provider (
245+ #[ case] provider : PrismaProvider ,
246+ #[ case] char_native : Option < & str > ,
247+ #[ case] numeric_native : Option < & str > ,
248+ ) {
249+ let ( rendered, attr) = column_type_to_prisma (
250+ & ColumnType :: Complex ( ComplexColumnType :: Char { length : 3 } ) ,
251+ false ,
252+ provider,
253+ ) ;
254+ assert_eq ! ( rendered, "String" ) ;
255+ assert_eq ! ( attr. as_deref( ) , char_native) ;
256+
257+ let ( rendered, attr) = column_type_to_prisma (
258+ & ColumnType :: Complex ( ComplexColumnType :: Numeric {
259+ precision : 10 ,
260+ scale : 2 ,
261+ } ) ,
262+ true ,
263+ provider,
264+ ) ;
265+ assert_eq ! ( rendered, "Decimal?" ) ;
266+ assert_eq ! ( attr. as_deref( ) , numeric_native) ;
267+ }
268+
269+ #[ rstest]
270+ #[ case:: postgres( PrismaProvider :: Postgres ) ]
271+ #[ case:: mysql( PrismaProvider :: MySql ) ]
272+ #[ case:: sqlite( PrismaProvider :: Sqlite ) ]
273+ fn custom_and_enum_types_are_provider_invariant ( #[ case] provider : PrismaProvider ) {
274+ let ( rendered, attr) = column_type_to_prisma (
275+ & ColumnType :: Complex ( ComplexColumnType :: Custom {
276+ custom_type : "ltree" . into ( ) ,
277+ } ) ,
278+ false ,
279+ provider,
280+ ) ;
281+ assert_eq ! ( rendered, "Unsupported(\" ltree\" )" ) ;
282+ assert_eq ! ( attr, None ) ;
283+
284+ let ( rendered, attr) = column_type_to_prisma (
285+ & ColumnType :: Complex ( ComplexColumnType :: Enum {
286+ name : "order_status" . into ( ) ,
287+ values : vespertide_core:: schema:: column:: EnumValues :: String ( vec ! [
288+ "open" . into( ) ,
289+ "closed" . into( ) ,
290+ ] ) ,
291+ } ) ,
292+ false ,
293+ provider,
294+ ) ;
295+ assert_eq ! ( rendered, "OrderStatus" ) ;
296+ assert_eq ! ( attr, None ) ;
297+ }
176298}
0 commit comments