@@ -12,6 +12,13 @@ namespace PowerSync.Common.Tests.DB.Schema;
1212/// </summary>
1313public class SchemaTests
1414{
15+ private void TestParser ( Type type , CompiledTable expected )
16+ {
17+ var parser = new AttributeParser ( type ) ;
18+ var table = parser . ParseTable ( ) . Compile ( ) ;
19+ Assert . Equivalent ( expected , table , strict : true ) ;
20+ }
21+
1522 [
1623 Table (
1724 "test_assets" ,
@@ -132,6 +139,14 @@ public void AttributeParser_Products_Test()
132139 TestParser ( typeof ( Product ) , expected ) ;
133140 }
134141
142+ enum LogLevel
143+ {
144+ Info ,
145+ Debug ,
146+ Warning ,
147+ Error
148+ }
149+
135150 [
136151 Table (
137152 "test_logs" ,
@@ -141,11 +156,22 @@ public void AttributeParser_Products_Test()
141156 IgnoreEmptyUpdates = true
142157 )
143158 ]
144- class Logs
159+ class Log
145160 {
146- public string id { get ; set ; }
147- public string description { get ; set ; }
148- public DateTimeOffset timestamp { get ; set ; }
161+ [ Column ( "id" ) ]
162+ public string LogId { get ; set ; }
163+
164+ [ Column ( "description" ) ]
165+ public string Description { get ; set ; }
166+
167+ [ Column ( "timestamp" ) ]
168+ public DateTimeOffset Timestamp { get ; set ; }
169+
170+ [ Column ( "log_level" ) ]
171+ public LogLevel LogLevel { get ; set ; }
172+
173+ [ Ignored ]
174+ public string LogLevelString { get { return LogLevel . ToString ( ) ; } }
149175 }
150176
151177 [ Fact ]
@@ -157,6 +183,7 @@ public void AttributeParser_Logs_Test()
157183 {
158184 [ "description" ] = ColumnType . Text ,
159185 [ "timestamp" ] = ColumnType . Text ,
186+ [ "log_level" ] = ColumnType . Integer ,
160187 } ,
161188 new TableOptions
162189 {
@@ -170,13 +197,121 @@ public void AttributeParser_Logs_Test()
170197 }
171198 ) ;
172199
173- TestParser ( typeof ( Logs ) , expected ) ;
200+ TestParser ( typeof ( Log ) , expected ) ;
174201 }
175202
176- private void TestParser ( Type type , CompiledTable expected )
203+ class Invalid1 { public string id { get ; set ; } }
204+ [ Fact ]
205+ public async void AttributeParser_InvalidSchema_1 ( )
177206 {
178- var parser = new AttributeParser ( type ) ;
179- var table = parser . ParseTable ( ) . Compile ( ) ;
180- Assert . Equivalent ( expected , table , strict : true ) ;
207+ var ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) =>
208+ {
209+ new AttributeParser ( typeof ( Invalid1 ) ) . ParseTable ( ) ;
210+ } ) ;
211+ Assert . Contains ( "must be marked with TableAttribute" , ex . Message ) ;
212+ }
213+
214+ [ Table ( "invalid" ) ]
215+ class Invalid2 { }
216+ [ Fact ]
217+ public async void AttributeParser_InvalidSchema_2 ( )
218+ {
219+ var ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) =>
220+ {
221+ new AttributeParser ( typeof ( Invalid2 ) ) . ParseTable ( ) ;
222+ } ) ;
223+ Assert . Contains ( "'id' property is required" , ex . Message ) ;
224+ }
225+
226+ [ Table ( "invalid" ) ]
227+ class Invalid3 { public int id { get ; set ; } }
228+ [ Fact ]
229+ public async void AttributeParser_InvalidSchema_3 ( )
230+ {
231+ var ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) =>
232+ {
233+ new AttributeParser ( typeof ( Invalid3 ) ) . ParseTable ( ) ;
234+ } ) ;
235+ Assert . Contains ( "must be of type string" , ex . Message ) ;
236+ }
237+
238+ [ Table ( "invalid" ) ]
239+ class Invalid4
240+ {
241+ [ Column ( ColumnType = ColumnType . Real ) ]
242+ public string id { get ; set ; }
243+ }
244+ [ Fact ]
245+ public async void AttributeParser_InvalidSchema_4 ( )
246+ {
247+ var ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) =>
248+ {
249+ new AttributeParser ( typeof ( Invalid4 ) ) . ParseTable ( ) ;
250+ } ) ;
251+ Assert . Contains ( "must have ColumnType set to ColumnType.Text or ColumnType.Inferred" , ex . Message ) ;
252+ }
253+
254+ [ Table ( "invalid" ) ]
255+ class Invalid5
256+ {
257+ public string id { get ; set ; }
258+ public Invalid1 invalid_type { get ; set ; }
259+ }
260+ [ Fact ]
261+ public async void AttributeParser_InvalidSchema_5 ( )
262+ {
263+ var ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) =>
264+ {
265+ new AttributeParser ( typeof ( Invalid5 ) ) . ParseTable ( ) ;
266+ } ) ;
267+ Assert . Contains ( "Unable to automatically infer ColumnType" , ex . Message ) ;
268+ }
269+
270+ [ Table ( "invalid" , TrackPreviousValues = TrackPrevious . Columns | TrackPrevious . Table ) ]
271+ class Invalid6
272+ {
273+ public string id { get ; set ; }
274+ }
275+ [ Fact ]
276+ public async void AttributeParser_InvalidSchema_6 ( )
277+ {
278+ var ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) =>
279+ {
280+ new AttributeParser ( typeof ( Invalid6 ) ) . ParseTable ( ) ;
281+ } ) ;
282+ Assert . Contains ( "Cannot specify both TrackPrevious.Columns and TrackPrevious.Table" , ex . Message ) ;
283+ }
284+
285+ [ Table ( "invalid" , TrackPreviousValues = TrackPrevious . OnlyWhenChanged ) ]
286+ class Invalid7
287+ {
288+ public string id { get ; set ; }
289+ }
290+ [ Fact ]
291+ public async void AttributeParser_InvalidSchema_7 ( )
292+ {
293+ var ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) =>
294+ {
295+ new AttributeParser ( typeof ( Invalid7 ) ) . ParseTable ( ) ;
296+ } ) ;
297+ Assert . Contains ( "Cannot specify TrackPrevious.OnlyWhenChanged without also specifying" , ex . Message ) ;
298+ }
299+
300+ [ Fact ]
301+ public async void AttributeParser_TypeMap_CustomRegistered ( )
302+ {
303+ // Log has Column aliases
304+ new AttributeParser ( typeof ( Log ) ) . RegisterDapperTypeMap ( ) ;
305+ var typeMap = Dapper . SqlMapper . GetTypeMap ( typeof ( Log ) ) ;
306+ Assert . False ( typeMap is Dapper . DefaultTypeMap ) ;
307+ }
308+
309+ [ Fact ]
310+ public async void AttributeParser_TypeMap_DefaultRegistered ( )
311+ {
312+ // Asset has no Column aliases
313+ new AttributeParser ( typeof ( Asset ) ) . RegisterDapperTypeMap ( ) ;
314+ var typeMap = Dapper . SqlMapper . GetTypeMap ( typeof ( Asset ) ) ;
315+ Assert . True ( typeMap is Dapper . DefaultTypeMap ) ;
181316 }
182317}
0 commit comments