| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448 |
- using Invercargill.DataStructures;
- using Invercargill.Expressions;
- using InvercargillSql;
- using InvercargillSql.Orm;
- using InvercargillSql.Dialects;
- using InvercargillSql.Expressions;
- /**
- * Test entity for ORM tests.
- */
- public class TestUser : Object {
- public int64 id { get; set; }
- public string name { get; set; }
- public string email { get; set; }
- public int64 age { get; set; } // Use int64 for SQLite compatibility
- public double? salary { get; set; } // Nullable for database compatibility
- public bool? is_active { get; set; } // Nullable for database compatibility
- public DateTime? created_at { get; set; } // Nullable for database compatibility
-
- public TestUser() {
- name = "";
- email = "";
- }
- }
- /**
- * Test entity with binary data.
- */
- public class TestDocument : Object {
- public int64 id { get; set; }
- public string filename { get; set; }
- public Invercargill.BinaryData? content { get; set; }
-
- public TestDocument() {
- filename = "";
- }
- }
- /**
- * Test entity for Product ORM tests.
- */
- public class TestProduct : Object {
- public int64 id { get; set; }
- public string name { get; set; }
- public string category { get; set; }
- public double price { get; set; }
- public int64 stock { get; set; }
-
- public TestProduct() {
- name = "";
- category = "";
- }
- }
- /**
- * Test entity for Order ORM tests.
- */
- public class TestOrder : Object {
- public int64 id { get; set; }
- public int64 user_id { get; set; }
- public int64 product_id { get; set; }
- public int64 quantity { get; set; }
- public double total { get; set; }
- public string status { get; set; }
- public DateTime? created_at { get; set; }
-
- public TestOrder() {
- status = "";
- }
- }
- /**
- * Comprehensive tests for Invercargill-Sql ORM.
- */
- public int main(string[] args) {
- print("=== Invercargill-Sql ORM Tests ===\n\n");
-
- try {
- // ColumnType tests
- print("--- ColumnType Tests ---\n");
- test_column_type_from_gtype_int();
- test_column_type_from_gtype_int64();
- test_column_type_from_gtype_string();
- test_column_type_from_gtype_bool();
- test_column_type_from_gtype_double();
- test_column_type_from_gtype_float();
- test_column_type_from_gtype_datetime();
- test_column_type_from_gtype_binary();
- test_column_type_from_gtype_unsupported();
-
- // ColumnDefinition tests
- print("\n--- ColumnDefinition Tests ---\n");
- test_column_definition_defaults();
- test_column_definition_properties();
-
- // IndexDefinition tests
- print("\n--- IndexDefinition Tests ---\n");
- test_index_definition_defaults();
- test_index_definition_add_columns();
-
- // EntityMapperBuilder tests
- print("\n--- EntityMapperBuilder Tests ---\n");
- test_entity_mapper_builder_table_name();
- test_entity_mapper_builder_simple_column();
- test_entity_mapper_builder_chained_columns();
-
- // EntityMapper tests
- print("\n--- EntityMapper Tests ---\n");
- test_entity_mapper_build_for();
- test_entity_mapper_materialise();
- test_entity_mapper_map_from();
-
- // SqliteDialect tests
- print("\n--- SqliteDialect Tests ---\n");
- test_sqlite_dialect_translate_type_int32();
- test_sqlite_dialect_translate_type_int64();
- test_sqlite_dialect_translate_type_text();
- test_sqlite_dialect_translate_type_boolean();
- test_sqlite_dialect_translate_type_decimal();
- test_sqlite_dialect_translate_type_datetime();
- test_sqlite_dialect_translate_type_binary();
- test_sqlite_dialect_translate_type_uuid();
- test_sqlite_dialect_build_select_all();
- test_sqlite_dialect_build_select_by_id();
- test_sqlite_dialect_build_insert_sql();
- test_sqlite_dialect_build_update_sql();
- test_sqlite_dialect_build_delete_sql();
-
- // ExpressionToSqlVisitor tests
- print("\n--- ExpressionToSqlVisitor Tests ---\n");
- test_expression_visitor_binary_equal();
- test_expression_visitor_binary_not_equal();
- test_expression_visitor_binary_greater_than();
- test_expression_visitor_binary_greater_equal();
- test_expression_visitor_binary_less_than();
- test_expression_visitor_binary_less_equal();
- test_expression_visitor_binary_and();
- test_expression_visitor_binary_or();
- test_expression_visitor_unary_not();
- test_expression_visitor_unary_negate();
- test_expression_visitor_literal();
- test_expression_visitor_property();
- test_expression_visitor_complex_nested();
- test_expression_visitor_arithmetic();
-
- // OrmSession integration tests
- print("\n--- OrmSession Integration Tests ---\n");
- test_orm_session_register();
- test_orm_session_register_with_schema();
- test_orm_session_create_query();
- test_orm_session_insert();
- test_orm_session_query_with_where();
- test_orm_session_update();
- test_orm_session_delete();
- test_orm_session_order_by();
- test_orm_session_limit_offset();
- test_orm_session_first();
-
- // Schema introspection tests
- print("\n--- Schema Introspection Tests ---\n");
- test_schema_introspection_basic();
- test_schema_introspection_with_register();
-
- // Primary key back-population tests
- print("\n--- Primary Key Back-Population Tests ---\n");
- test_insert_back_populates_primary_key();
- test_insert_back_populates_different_ids();
- test_insert_back_populates_product();
- test_insert_back_populates_order();
-
- print("\n=== All ORM tests passed! ===\n");
- return 0;
- } catch (Error e) {
- printerr("\n=== Test failed: %s ===\n", e.message);
- return 1;
- }
- }
- // ========================================
- // ColumnType Tests
- // ========================================
- void test_column_type_from_gtype_int() throws Error {
- print("Test: ColumnType.from_gtype(int)... ");
- var result = ColumnType.from_gtype(typeof(int));
- assert(result == ColumnType.INT_32);
- print("PASSED\n");
- }
- void test_column_type_from_gtype_int64() throws Error {
- print("Test: ColumnType.from_gtype(int64)... ");
- var result = ColumnType.from_gtype(typeof(int64));
- assert(result == ColumnType.INT_64);
- print("PASSED\n");
- }
- void test_column_type_from_gtype_string() throws Error {
- print("Test: ColumnType.from_gtype(string)... ");
- var result = ColumnType.from_gtype(typeof(string));
- assert(result == ColumnType.TEXT);
- print("PASSED\n");
- }
- void test_column_type_from_gtype_bool() throws Error {
- print("Test: ColumnType.from_gtype(bool)... ");
- var result = ColumnType.from_gtype(typeof(bool));
- assert(result == ColumnType.BOOLEAN);
- print("PASSED\n");
- }
- void test_column_type_from_gtype_double() throws Error {
- print("Test: ColumnType.from_gtype(double)... ");
- var result = ColumnType.from_gtype(typeof(double));
- assert(result == ColumnType.DECIMAL);
- print("PASSED\n");
- }
- void test_column_type_from_gtype_float() throws Error {
- print("Test: ColumnType.from_gtype(float)... ");
- var result = ColumnType.from_gtype(typeof(float));
- assert(result == ColumnType.DECIMAL);
- print("PASSED\n");
- }
- void test_column_type_from_gtype_datetime() throws Error {
- print("Test: ColumnType.from_gtype(DateTime)... ");
- var result = ColumnType.from_gtype(typeof(DateTime));
- assert(result == ColumnType.DATETIME);
- print("PASSED\n");
- }
- void test_column_type_from_gtype_binary() throws Error {
- print("Test: ColumnType.from_gtype(BinaryData)... ");
- var result = ColumnType.from_gtype(typeof(Invercargill.BinaryData));
- assert(result == ColumnType.BINARY);
- print("PASSED\n");
- }
- void test_column_type_from_gtype_unsupported() throws Error {
- print("Test: ColumnType.from_gtype(unsupported)... ");
- var result = ColumnType.from_gtype(typeof(Object));
- assert(result == null);
- print("PASSED\n");
- }
- // ========================================
- // ColumnDefinition Tests
- // ========================================
- void test_column_definition_defaults() throws Error {
- print("Test: ColumnDefinition defaults... ");
- var col = new ColumnDefinition();
- col.name = "test_col";
- col.column_type = ColumnType.TEXT;
-
- assert(col.name == "test_col");
- assert(col.column_type == ColumnType.TEXT);
- print("PASSED\n");
- }
- void test_column_definition_properties() throws Error {
- print("Test: ColumnDefinition properties... ");
- var col = new ColumnDefinition();
- col.name = "id";
- col.column_type = ColumnType.INT_64;
-
- assert(col.name == "id");
- assert(col.column_type == ColumnType.INT_64);
- print("PASSED\n");
- }
- // ========================================
- // IndexDefinition Tests
- // ========================================
- void test_index_definition_defaults() throws Error {
- print("Test: IndexDefinition defaults... ");
- var idx = new IndexDefinition();
- idx.name = "idx_test";
-
- assert(idx.name == "idx_test");
- assert(idx.is_unique == false);
- assert(idx.columns != null);
- assert(idx.columns.count() == 0);
- print("PASSED\n");
- }
- void test_index_definition_add_columns() throws Error {
- print("Test: IndexDefinition add columns... ");
- var idx = new IndexDefinition();
- idx.name = "idx_multi";
- idx.is_unique = true;
- idx.columns.add("col1");
- idx.columns.add("col2");
- idx.columns.add("col3");
-
- assert(idx.name == "idx_multi");
- assert(idx.is_unique == true);
- assert(idx.columns.count() == 3);
-
- var arr = idx.columns.to_array();
- assert(arr[0] == "col1");
- assert(arr[1] == "col2");
- assert(arr[2] == "col3");
- print("PASSED\n");
- }
- // ========================================
- // EntityMapperBuilder Tests
- // ========================================
- void test_entity_mapper_builder_table_name() throws Error {
- print("Test: EntityMapperBuilder table name... ");
- var mapper = EntityMapper.build_for<TestUser>(b => {
- b.table("users");
- });
-
- assert(mapper.table_name == "users");
- print("PASSED\n");
- }
- void test_entity_mapper_builder_simple_column() throws Error {
- print("Test: EntityMapperBuilder simple column... ");
- var mapper = EntityMapper.build_for<TestUser>(b => {
- b.table("users");
- b.column<int64?>("id", u => u.id, (u, v) => u.id = v);
- b.column<string>("name", u => u.name, (u, v) => u.name = v);
- });
-
- assert(mapper.columns.count() == 2);
-
- var cols = mapper.columns.to_array();
- assert(cols[0].name == "id");
- assert(cols[0].column_type == ColumnType.INT_64);
- assert(cols[1].name == "name");
- assert(cols[1].column_type == ColumnType.TEXT);
- print("PASSED\n");
- }
- void test_entity_mapper_builder_chained_columns() throws Error {
- print("Test: EntityMapperBuilder chained columns... ");
- // The new API allows natural chaining since column<T>() returns EntityMapperBuilder<T>
- var mapper = EntityMapper.build_for<TestUser>(b => {
- b.table("users")
- .column<int64?>("id", u => u.id, (u, v) => u.id = v)
- .column<string>("name", u => u.name, (u, v) => u.name = v)
- .column<string>("email", u => u.email, (u, v) => u.email = v);
- });
-
- assert(mapper.table_name == "users");
- assert(mapper.columns.count() == 3);
-
- var cols = mapper.columns.to_array();
- assert(cols[0].name == "id");
- assert(cols[1].name == "name");
- assert(cols[2].name == "email");
- print("PASSED\n");
- }
- // ========================================
- // EntityMapper Tests
- // ========================================
- void test_entity_mapper_build_for() throws Error {
- print("Test: EntityMapper.build_for... ");
- var mapper = EntityMapper.build_for<TestUser>(b => {
- b.table("users");
- b.column<int64?>("id", u => u.id, (u, v) => u.id = v);
- b.column<string>("name", u => u.name, (u, v) => u.name = v);
- });
-
- assert(mapper != null);
- assert(mapper.table_name == "users");
- assert(mapper.columns.count() == 2);
- assert(mapper.property_mapper != null);
- print("PASSED\n");
- }
- void test_entity_mapper_materialise() throws Error {
- print("Test: EntityMapper.materialise... ");
- var mapper = EntityMapper.build_for<TestUser>(b => {
- b.table("users");
- b.column<int64?>("id", u => u.id, (u, v) => u.id = v);
- b.column<string>("name", u => u.name, (u, v) => u.name = v);
- b.column<string>("email", u => u.email, (u, v) => u.email = v);
- });
-
- var props = new PropertyDictionary();
- props.set_native<int64?>("id", 42);
- props.set_native<string>("name", "Alice");
- props.set_native<string>("email", "alice@example.com");
-
- var user = mapper.materialise(props);
-
- assert(user.id == 42);
- assert(user.name == "Alice");
- assert(user.email == "alice@example.com");
- print("PASSED\n");
- }
- void test_entity_mapper_map_from() throws Error {
- print("Test: EntityMapper.map_from... ");
- var mapper = EntityMapper.build_for<TestUser>(b => {
- b.table("users");
- b.column<int64?>("id", u => u.id, (u, v) => u.id = v);
- b.column<string>("name", u => u.name, (u, v) => u.name = v);
- b.column<string>("email", u => u.email, (u, v) => u.email = v);
- });
-
- var user = new TestUser();
- user.id = 123;
- user.name = "Bob";
- user.email = "bob@example.com";
-
- var props = mapper.map_from(user);
-
- assert(props != null);
- var id_elem = props.get("id");
- var name_elem = props.get("name");
- var email_elem = props.get("email");
-
- assert(id_elem != null);
- assert(name_elem != null);
- assert(email_elem != null);
- print("PASSED\n");
- }
- // ========================================
- // SqliteDialect Tests
- // ========================================
- void test_sqlite_dialect_translate_type_int32() throws Error {
- print("Test: SqliteDialect.translate_type(INT_32)... ");
- var dialect = new SqliteDialect();
- var result = dialect.translate_type(ColumnType.INT_32);
- assert(result == "INTEGER");
- print("PASSED\n");
- }
- void test_sqlite_dialect_translate_type_int64() throws Error {
- print("Test: SqliteDialect.translate_type(INT_64)... ");
- var dialect = new SqliteDialect();
- var result = dialect.translate_type(ColumnType.INT_64);
- assert(result == "INTEGER");
- print("PASSED\n");
- }
- void test_sqlite_dialect_translate_type_text() throws Error {
- print("Test: SqliteDialect.translate_type(TEXT)... ");
- var dialect = new SqliteDialect();
- var result = dialect.translate_type(ColumnType.TEXT);
- assert(result == "TEXT");
- print("PASSED\n");
- }
- void test_sqlite_dialect_translate_type_boolean() throws Error {
- print("Test: SqliteDialect.translate_type(BOOLEAN)... ");
- var dialect = new SqliteDialect();
- var result = dialect.translate_type(ColumnType.BOOLEAN);
- assert(result == "INTEGER");
- print("PASSED\n");
- }
- void test_sqlite_dialect_translate_type_decimal() throws Error {
- print("Test: SqliteDialect.translate_type(DECIMAL)... ");
- var dialect = new SqliteDialect();
- var result = dialect.translate_type(ColumnType.DECIMAL);
- assert(result == "REAL");
- print("PASSED\n");
- }
- void test_sqlite_dialect_translate_type_datetime() throws Error {
- print("Test: SqliteDialect.translate_type(DATETIME)... ");
- var dialect = new SqliteDialect();
- var result = dialect.translate_type(ColumnType.DATETIME);
- assert(result == "INTEGER");
- print("PASSED\n");
- }
- void test_sqlite_dialect_translate_type_binary() throws Error {
- print("Test: SqliteDialect.translate_type(BINARY)... ");
- var dialect = new SqliteDialect();
- var result = dialect.translate_type(ColumnType.BINARY);
- assert(result == "BLOB");
- print("PASSED\n");
- }
- void test_sqlite_dialect_translate_type_uuid() throws Error {
- print("Test: SqliteDialect.translate_type(UUID)... ");
- var dialect = new SqliteDialect();
- var result = dialect.translate_type(ColumnType.UUID);
- assert(result == "TEXT");
- print("PASSED\n");
- }
- void test_sqlite_dialect_build_select_all() throws Error {
- print("Test: SqliteDialect.build_select_all... ");
- var dialect = new SqliteDialect();
- var sql = dialect.build_select_all("users");
- assert(sql == "SELECT * FROM users");
- print("PASSED\n");
- }
- void test_sqlite_dialect_build_select_by_id() throws Error {
- print("Test: SqliteDialect.build_select_by_id... ");
- var dialect = new SqliteDialect();
- var sql = dialect.build_select_by_id("users", "id");
- assert(sql == "SELECT * FROM users WHERE id = :id");
- print("PASSED\n");
- }
- void test_sqlite_dialect_build_insert_sql() throws Error {
- print("Test: SqliteDialect.build_insert_sql... ");
- var dialect = new SqliteDialect();
- var columns = new Vector<string>();
- columns.add("name");
- columns.add("email");
-
- var sql = dialect.build_insert_sql("users", columns);
- assert(sql == "INSERT INTO users (name, email) VALUES (:name, :email)");
- print("PASSED\n");
- }
- void test_sqlite_dialect_build_update_sql() throws Error {
- print("Test: SqliteDialect.build_update_sql... ");
- var dialect = new SqliteDialect();
- var columns = new Vector<string>();
- columns.add("id");
- columns.add("name");
- columns.add("email");
-
- var sql = dialect.build_update_sql("users", columns, "id");
- // id should be excluded from SET clause
- assert("UPDATE users SET" in sql);
- assert("name = :name" in sql);
- assert("email = :email" in sql);
- assert("WHERE id = :id" in sql);
- print("PASSED\n");
- }
- void test_sqlite_dialect_build_delete_sql() throws Error {
- print("Test: SqliteDialect.build_delete_sql... ");
- var dialect = new SqliteDialect();
- var sql = dialect.build_delete_sql("users", "id");
- assert(sql == "DELETE FROM users WHERE id = :id");
- print("PASSED\n");
- }
- // ========================================
- // ExpressionToSqlVisitor Tests
- // ========================================
- EntityMapper get_test_mapper() {
- return EntityMapper.build_for<TestUser>(b => {
- b.table("users");
- b.column<int64?>("id", u => u.id, (u, v) => u.id = v);
- b.column<string>("name", u => u.name, (u, v) => u.name = v);
- b.column<int64?>("age", u => u.age, (u, v) => u.age = v);
- });
- }
- void test_expression_visitor_binary_equal() throws Error {
- print("Test: ExpressionToSqlVisitor binary equal... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var left = new PropertyExpression(new VariableExpression("u"), "age");
- var right = new LiteralExpression(new Invercargill.NativeElement<int?>(25));
- var expr = new BinaryExpression(left, right, BinaryOperator.EQUAL);
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("(age = :p1)" == sql);
- assert(visitor.get_parameters().count() == 1);
- print("PASSED\n");
- }
- void test_expression_visitor_binary_not_equal() throws Error {
- print("Test: ExpressionToSqlVisitor binary not equal... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var left = new PropertyExpression(new VariableExpression("u"), "age");
- var right = new LiteralExpression(new Invercargill.NativeElement<int?>(25));
- var expr = new BinaryExpression(left, right, BinaryOperator.NOT_EQUAL);
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("(age <> :p1)" == sql);
- print("PASSED\n");
- }
- void test_expression_visitor_binary_greater_than() throws Error {
- print("Test: ExpressionToSqlVisitor binary greater than... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var left = new PropertyExpression(new VariableExpression("u"), "age");
- var right = new LiteralExpression(new Invercargill.NativeElement<int?>(18));
- var expr = new BinaryExpression(left, right, BinaryOperator.GREATER_THAN);
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("(age > :p1)" == sql);
- print("PASSED\n");
- }
- void test_expression_visitor_binary_greater_equal() throws Error {
- print("Test: ExpressionToSqlVisitor binary greater equal... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var left = new PropertyExpression(new VariableExpression("u"), "age");
- var right = new LiteralExpression(new Invercargill.NativeElement<int?>(18));
- var expr = new BinaryExpression(left, right, BinaryOperator.GREATER_EQUAL);
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("(age >= :p1)" == sql);
- print("PASSED\n");
- }
- void test_expression_visitor_binary_less_than() throws Error {
- print("Test: ExpressionToSqlVisitor binary less than... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var left = new PropertyExpression(new VariableExpression("u"), "age");
- var right = new LiteralExpression(new Invercargill.NativeElement<int?>(65));
- var expr = new BinaryExpression(left, right, BinaryOperator.LESS_THAN);
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("(age < :p1)" == sql);
- print("PASSED\n");
- }
- void test_expression_visitor_binary_less_equal() throws Error {
- print("Test: ExpressionToSqlVisitor binary less equal... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var left = new PropertyExpression(new VariableExpression("u"), "age");
- var right = new LiteralExpression(new Invercargill.NativeElement<int?>(65));
- var expr = new BinaryExpression(left, right, BinaryOperator.LESS_EQUAL);
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("(age <= :p1)" == sql);
- print("PASSED\n");
- }
- void test_expression_visitor_binary_and() throws Error {
- print("Test: ExpressionToSqlVisitor binary AND... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var left = new BinaryExpression(
- new PropertyExpression(new VariableExpression("u"), "age"),
- new LiteralExpression(new Invercargill.NativeElement<int?>(18)),
- BinaryOperator.GREATER_THAN
- );
- var right = new BinaryExpression(
- new PropertyExpression(new VariableExpression("u"), "age"),
- new LiteralExpression(new Invercargill.NativeElement<int?>(65)),
- BinaryOperator.LESS_THAN
- );
- var expr = new BinaryExpression(left, right, BinaryOperator.AND);
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("((age > :p1) AND (age < :p2))" == sql);
- assert(visitor.get_parameters().count() == 2);
- print("PASSED\n");
- }
- void test_expression_visitor_binary_or() throws Error {
- print("Test: ExpressionToSqlVisitor binary OR... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var left = new BinaryExpression(
- new PropertyExpression(new VariableExpression("u"), "name"),
- new LiteralExpression(new Invercargill.NativeElement<string>("Alice")),
- BinaryOperator.EQUAL
- );
- var right = new BinaryExpression(
- new PropertyExpression(new VariableExpression("u"), "name"),
- new LiteralExpression(new Invercargill.NativeElement<string>("Bob")),
- BinaryOperator.EQUAL
- );
- var expr = new BinaryExpression(left, right, BinaryOperator.OR);
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("((name = :p1) OR (name = :p2))" == sql);
- assert(visitor.get_parameters().count() == 2);
- print("PASSED\n");
- }
- void test_expression_visitor_unary_not() throws Error {
- print("Test: ExpressionToSqlVisitor unary NOT... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var operand = new BinaryExpression(
- new PropertyExpression(new VariableExpression("u"), "age"),
- new LiteralExpression(new Invercargill.NativeElement<int?>(25)),
- BinaryOperator.EQUAL
- );
- var expr = new UnaryExpression(UnaryOperator.NOT, operand);
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("NOT (age = :p1)" == sql);
- print("PASSED\n");
- }
- void test_expression_visitor_unary_negate() throws Error {
- print("Test: ExpressionToSqlVisitor unary NEGATE... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var operand = new PropertyExpression(new VariableExpression("u"), "age");
- var expr = new UnaryExpression(UnaryOperator.NEGATE, operand);
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("-age" == sql);
- print("PASSED\n");
- }
- void test_expression_visitor_literal() throws Error {
- print("Test: ExpressionToSqlVisitor literal... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var expr = new LiteralExpression(new Invercargill.NativeElement<string>("test"));
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert(":p1" == sql);
- assert(visitor.get_parameters().count() == 1);
- print("PASSED\n");
- }
- void test_expression_visitor_property() throws Error {
- print("Test: ExpressionToSqlVisitor property... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- var expr = new PropertyExpression(new VariableExpression("u"), "name");
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("name" == sql);
- print("PASSED\n");
- }
- void test_expression_visitor_complex_nested() throws Error {
- print("Test: ExpressionToSqlVisitor complex nested... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- // (age > 18 AND age < 65) OR (name = 'Admin')
- var age_range = new BinaryExpression(
- new BinaryExpression(
- new PropertyExpression(new VariableExpression("u"), "age"),
- new LiteralExpression(new Invercargill.NativeElement<int?>(18)),
- BinaryOperator.GREATER_THAN
- ),
- new BinaryExpression(
- new PropertyExpression(new VariableExpression("u"), "age"),
- new LiteralExpression(new Invercargill.NativeElement<int?>(65)),
- BinaryOperator.LESS_THAN
- ),
- BinaryOperator.AND
- );
- var is_admin = new BinaryExpression(
- new PropertyExpression(new VariableExpression("u"), "name"),
- new LiteralExpression(new Invercargill.NativeElement<string>("Admin")),
- BinaryOperator.EQUAL
- );
- var expr = new BinaryExpression(age_range, is_admin, BinaryOperator.OR);
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("(((age > :p1) AND (age < :p2)) OR (name = :p3))" == sql);
- assert(visitor.get_parameters().count() == 3);
- print("PASSED\n");
- }
- void test_expression_visitor_arithmetic() throws Error {
- print("Test: ExpressionToSqlVisitor arithmetic... ");
- var dialect = new SqliteDialect();
- var mapper = get_test_mapper();
- var visitor = new ExpressionToSqlVisitor(dialect, mapper);
-
- // age + 10
- var expr = new BinaryExpression(
- new PropertyExpression(new VariableExpression("u"), "age"),
- new LiteralExpression(new Invercargill.NativeElement<int?>(10)),
- BinaryOperator.ADD
- );
-
- expr.accept(visitor);
-
- var sql = visitor.get_sql();
- assert("(age + :p1)" == sql);
- print("PASSED\n");
- }
- // ========================================
- // OrmSession Integration Tests
- // ========================================
- OrmSession setup_test_session() throws SqlError {
- var conn = ConnectionFactory.create_and_open("sqlite::memory:");
- var dialect = new SqliteDialect();
- var registry = new TypeRegistry();
-
- // Create table first (schema is managed by migrations)
- conn.execute("""
- CREATE TABLE users (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- name TEXT NOT NULL,
- email TEXT,
- age INTEGER,
- salary REAL,
- is_active INTEGER,
- created_at INTEGER
- )
- """);
-
- // Register TestUser mapper with schema introspection on registry
- registry.register_entity<TestUser>(EntityMapper.build_for<TestUser>(b => {
- b.table("users");
- b.column<int64?>("id", u => u.id, (u, v) => u.id = v);
- b.column<string>("name", u => u.name, (u, v) => u.name = v);
- b.column<string>("email", u => u.email, (u, v) => u.email = v);
- b.column<int64?>("age", u => u.age, (u, v) => u.age = v);
- b.column<double?>("salary", u => u.salary, (u, v) => u.salary = v);
- b.column<bool?>("is_active", u => u.is_active, (u, v) => u.is_active = v);
- b.column<DateTime?>("created_at", u => u.created_at, (u, v) => u.created_at = v);
- }));
-
- return new OrmSession(conn, registry, dialect);
- }
- void test_orm_session_register() throws Error {
- print("Test: OrmSession register... ");
- var conn = ConnectionFactory.create_and_open("sqlite::memory:");
- var dialect = new SqliteDialect();
- var registry = new TypeRegistry();
-
- // Create table first
- conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
-
- // Register using the simplified API on registry
- registry.register_entity<TestUser>(EntityMapper.build_for<TestUser>(b => {
- b.table("users");
- b.column<int64?>("id", u => u.id, (u, v) => u.id = v);
- b.column<string>("name", u => u.name, (u, v) => u.name = v);
- }));
-
- var session = new OrmSession(conn, registry, dialect);
-
- // If we got here without exception, registration worked
- print("PASSED\n");
- conn.close();
- }
- void test_orm_session_register_with_schema() throws Error {
- print("Test: OrmSession register_with_schema... ");
- var conn = ConnectionFactory.create_and_open("sqlite::memory:");
- var dialect = new SqliteDialect();
- var registry = new TypeRegistry();
-
- // Create table with auto-increment primary key
- conn.execute("""
- CREATE TABLE users (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- name TEXT NOT NULL,
- email TEXT
- )
- """);
-
- // Register with schema introspection on registry - PK and auto-increment discovered automatically
- registry.register_entity<TestUser>(EntityMapper.build_for<TestUser>(b => {
- b.table("users");
- b.column<int64?>("id", u => u.id, (u, v) => u.id = v);
- b.column<string>("name", u => u.name, (u, v) => u.name = v);
- b.column<string>("email", u => u.email, (u, v) => u.email = v);
- }));
-
- var session = new OrmSession(conn, registry, dialect);
-
- // Verify the mapper has the schema information
- var mapper = session.get_mapper<TestUser>();
- assert(mapper != null);
- assert(mapper.table_name == "users");
- assert(mapper.get_effective_primary_key() == "id");
- assert(mapper.is_auto_increment("id") == true);
-
- print("PASSED\n");
- conn.close();
- }
- void test_orm_session_create_query() throws Error {
- print("Test: OrmSession create query... ");
- var session = setup_test_session();
-
- var query = session.query<TestUser>();
- assert(query != null);
-
- print("PASSED\n");
- }
- void test_orm_session_insert() throws Error {
- print("Test: OrmSession insert... ");
- var session = setup_test_session();
-
- var user = new TestUser();
- user.name = "Alice";
- user.email = "alice@example.com";
- user.age = 30;
- user.salary = 50000.0;
- user.is_active = true;
- user.created_at = new DateTime.now_utc();
-
- session.insert(user);
-
- // Verify insert worked by querying
- var results = session.query<TestUser>().materialise();
- var arr = results.to_array();
- assert(arr.length == 1);
-
- var inserted = arr[0];
- assert(inserted != null);
- assert(inserted.name == "Alice");
- assert(inserted.email == "alice@example.com");
- assert(inserted.age == 30);
-
- print("PASSED\n");
- }
- void test_orm_session_query_with_where() throws Error {
- print("Test: OrmSession query with where... ");
- var session = setup_test_session();
-
- // Insert test data
- var alice = new TestUser();
- alice.name = "Alice";
- alice.age = 30;
- session.insert(alice);
-
- var bob = new TestUser();
- bob.name = "Bob";
- bob.age = 25;
- session.insert(bob);
-
- var charlie = new TestUser();
- charlie.name = "Charlie";
- charlie.age = 35;
- session.insert(charlie);
-
- // Query with where clause
- var results = session.query<TestUser>()
- .where("age > 28")
- .materialise();
-
- var arr = results.to_array();
- assert(arr.length == 2);
-
- print("PASSED\n");
- }
- void test_orm_session_update() throws Error {
- print("Test: OrmSession update... ");
- var session = setup_test_session();
-
- // Insert test data
- var user = new TestUser();
- user.name = "Alice";
- user.email = "alice@example.com";
- user.age = 30;
- session.insert(user);
-
- // Get the inserted user with ID - use age for lookup since string literals
- // in expressions aren't supported by the expression parser
- var inserted_arr = session.query<TestUser>()
- .where("age == 30")
- .first();
- assert(inserted_arr != null);
-
- // Update the user
- inserted_arr.name = "Alice Updated";
- inserted_arr.age = 31;
- session.update(inserted_arr);
-
- // Verify update - use the ID we now know
- var updated = session.query<TestUser>()
- .where("id == " + inserted_arr.id.to_string())
- .first();
- assert(updated != null);
- assert(updated.name == "Alice Updated");
- assert(updated.age == 31);
-
- print("PASSED\n");
- }
- void test_orm_session_delete() throws Error {
- print("Test: OrmSession delete... ");
- var session = setup_test_session();
-
- // Insert test data
- var user = new TestUser();
- user.name = "ToDelete";
- user.age = 99;
- session.insert(user);
-
- // Get the inserted user with ID - use age for lookup
- var inserted = session.query<TestUser>()
- .where("age == 99")
- .first();
- assert(inserted != null);
-
- // Delete the user
- session.delete(inserted);
-
- // Verify deletion - use the ID
- var results = session.query<TestUser>()
- .where("id == " + inserted.id.to_string())
- .materialise();
- var arr = results.to_array();
- assert(arr.length == 0);
-
- print("PASSED\n");
- }
- void test_orm_session_order_by() throws Error {
- print("Test: OrmSession order by... ");
- var session = setup_test_session();
-
- // Insert test data
- var alice = new TestUser();
- alice.name = "Alice";
- alice.age = 30;
- session.insert(alice);
-
- var bob = new TestUser();
- bob.name = "Bob";
- bob.age = 25;
- session.insert(bob);
-
- var charlie = new TestUser();
- charlie.name = "Charlie";
- charlie.age = 35;
- session.insert(charlie);
-
- // Query with order by ascending
- var results = session.query<TestUser>()
- .order_by("age")
- .materialise();
-
- var arr = results.to_array();
- assert(arr.length == 3);
- assert(arr[0].age == 25); // Bob
- assert(arr[1].age == 30); // Alice
- assert(arr[2].age == 35); // Charlie
-
- // Query with order by descending
- var desc_results = session.query<TestUser>()
- .order_by_desc("age")
- .materialise();
-
- var desc_arr = desc_results.to_array();
- assert(desc_arr.length == 3);
- assert(desc_arr[0].age == 35); // Charlie
- assert(desc_arr[1].age == 30); // Alice
- assert(desc_arr[2].age == 25); // Bob
-
- print("PASSED\n");
- }
- void test_orm_session_limit_offset() throws Error {
- print("Test: OrmSession limit/offset... ");
- var session = setup_test_session();
-
- // Insert test data
- for (int i = 0; i < 10; i++) {
- var user = new TestUser();
- user.name = "User%d".printf(i);
- user.age = 20 + i;
- session.insert(user);
- }
-
- // Query with limit
- var limited = session.query<TestUser>()
- .order_by("age")
- .limit(3)
- .materialise();
-
- var limited_arr = limited.to_array();
- assert(limited_arr.length == 3);
-
- // Query with limit and offset
- var paged = session.query<TestUser>()
- .order_by("age")
- .limit(3)
- .offset(3)
- .materialise();
-
- var paged_arr = paged.to_array();
- assert(paged_arr.length == 3);
- assert(paged_arr[0].age == 23); // Skipped 20, 21, 22
-
- print("PASSED\n");
- }
- void test_orm_session_first() throws Error {
- print("Test: OrmSession first... ");
- var session = setup_test_session();
-
- // Insert test data
- var alice = new TestUser();
- alice.name = "Alice";
- alice.age = 30;
- session.insert(alice);
-
- var bob = new TestUser();
- bob.name = "Bob";
- bob.age = 25;
- session.insert(bob);
-
- // Get first with order
- var first = session.query<TestUser>()
- .order_by("age")
- .first();
-
- assert(first != null);
- assert(first.name == "Bob"); // Youngest
- assert(first.age == 25);
-
- // Query empty result
- var empty = session.query<TestUser>()
- .where("age > 100")
- .first();
-
- assert(empty == null);
-
- print("PASSED\n");
- }
- // ========================================
- // Schema Introspection Tests
- // ========================================
- void test_schema_introspection_basic() throws Error {
- print("Test: Schema introspection basic... ");
- var conn = ConnectionFactory.create_and_open("sqlite::memory:");
- var dialect = new SqliteDialect();
-
- // Create a table with various column types
- conn.execute("""
- CREATE TABLE test_table (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- name TEXT NOT NULL,
- email TEXT,
- age INTEGER,
- salary REAL,
- created_at INTEGER
- )
- """);
-
- // Introspect the schema
- var schema = dialect.introspect_schema(conn, "test_table");
-
- assert(schema != null);
- assert(schema.table_name == "test_table");
- assert(schema.primary_key_column == "id");
- assert(schema.columns.count() == 6);
-
- // Find the id column and verify it's marked as PK and auto-increment
- var id_col = schema.get_column("id");
- assert(id_col != null);
- assert(id_col.is_primary_key == true);
- assert(id_col.auto_increment == true);
-
- // Find the name column and verify it's required
- var name_col = schema.get_column("name");
- assert(name_col != null);
- assert(name_col.is_required == true);
-
- print("PASSED\n");
- conn.close();
- }
- void test_schema_introspection_with_register() throws Error {
- print("Test: Schema introspection with register... ");
- var conn = ConnectionFactory.create_and_open("sqlite::memory:");
- var dialect = new SqliteDialect();
- var registry = new TypeRegistry();
-
- // Create table with composite structure
- conn.execute("""
- CREATE TABLE products (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- name TEXT NOT NULL,
- price REAL NOT NULL,
- description TEXT,
- created_at INTEGER
- )
- """);
-
- // Define a simple product class inline using TestUser as proxy
- // Register with schema introspection on registry
- registry.register_entity<TestUser>(EntityMapper.build_for<TestUser>(b => {
- b.table("products");
- b.column<int64?>("id", u => u.id, (u, v) => u.id = v);
- b.column<string>("name", u => u.name, (u, v) => u.name = v);
- }));
-
- var session = new OrmSession(conn, registry, dialect);
-
- // Verify schema was introspected and applied
- var mapper = session.get_mapper<TestUser>();
- assert(mapper != null);
- assert(mapper.table_name == "products");
- assert(mapper.get_effective_primary_key() == "id");
-
- print("PASSED\n");
- conn.close();
- }
- // ========================================
- // Primary Key Back-Population Tests
- // ========================================
- /**
- * Helper to set up a session with products table for testing.
- */
- OrmSession setup_product_session() throws SqlError {
- var conn = ConnectionFactory.create_and_open("sqlite::memory:");
- var dialect = new SqliteDialect();
- var registry = new TypeRegistry();
-
- conn.execute("""
- CREATE TABLE products (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- name TEXT NOT NULL,
- category TEXT,
- price REAL,
- stock INTEGER
- )
- """);
-
- registry.register_entity<TestProduct>(EntityMapper.build_for<TestProduct>(b => {
- b.table("products");
- b.column<int64?>("id", p => p.id, (p, v) => p.id = v);
- b.column<string>("name", p => p.name, (p, v) => p.name = v);
- b.column<string>("category", p => p.category, (p, v) => p.category = v);
- b.column<double?>("price", p => p.price, (p, v) => p.price = v);
- b.column<int64?>("stock", p => p.stock, (p, v) => p.stock = v);
- }));
-
- return new OrmSession(conn, registry, dialect);
- }
- /**
- * Helper to set up a session with orders table for testing.
- */
- OrmSession setup_order_session() throws SqlError {
- var conn = ConnectionFactory.create_and_open("sqlite::memory:");
- var dialect = new SqliteDialect();
- var registry = new TypeRegistry();
-
- conn.execute("""
- CREATE TABLE orders (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- user_id INTEGER,
- product_id INTEGER,
- quantity INTEGER,
- total REAL,
- status TEXT,
- created_at INTEGER
- )
- """);
-
- registry.register_entity<TestOrder>(EntityMapper.build_for<TestOrder>(b => {
- b.table("orders");
- b.column<int64?>("id", o => o.id, (o, v) => o.id = v);
- b.column<int64?>("user_id", o => o.user_id, (o, v) => o.user_id = v);
- b.column<int64?>("product_id", o => o.product_id, (o, v) => o.product_id = v);
- b.column<int64?>("quantity", o => o.quantity, (o, v) => o.quantity = v);
- b.column<double?>("total", o => o.total, (o, v) => o.total = v);
- b.column<string>("status", o => o.status, (o, v) => o.status = v);
- b.column<DateTime?>("created_at", o => o.created_at, (o, v) => o.created_at = v);
- }));
-
- return new OrmSession(conn, registry, dialect);
- }
- /**
- * Test: Basic insert back-populates primary key on User entity.
- *
- * Verifies that after inserting a new User entity with id = 0,
- * the id property is updated with the auto-generated database ID.
- */
- void test_insert_back_populates_primary_key() throws Error {
- print("Test: insert back-populates primary key on User... ");
- var session = setup_test_session();
-
- // Create a new user with id = 0 (default for new entities)
- var user = new TestUser();
- user.name = "TestUser";
- user.email = "test@example.com";
- user.age = 25;
-
- // Verify initial state - id should be 0
- assert(user.id == 0);
-
- // Insert the user
- session.insert(user);
-
- // After insert, the id should be back-populated with the generated ID
- assert(user.id > 0);
-
- print("PASSED\n");
- }
- /**
- * Test: Multiple inserts get different auto-generated IDs.
- *
- * Verifies that inserting multiple entities results in each
- * getting a unique, incrementing primary key.
- */
- void test_insert_back_populates_different_ids() throws Error {
- print("Test: multiple inserts get different IDs... ");
- var session = setup_test_session();
-
- // Create and insert first user
- var user1 = new TestUser();
- user1.name = "User1";
- user1.age = 20;
- session.insert(user1);
-
- // Create and insert second user
- var user2 = new TestUser();
- user2.name = "User2";
- user2.age = 25;
- session.insert(user2);
-
- // Both should have IDs > 0
- assert(user1.id > 0);
- assert(user2.id > 0);
-
- // IDs should be different
- assert(user1.id != user2.id);
-
- print("PASSED\n");
- }
- /**
- * Test: Insert back-populates primary key on Product entity.
- *
- * Verifies that the back-population works correctly for different
- * entity types, not just User.
- */
- void test_insert_back_populates_product() throws Error {
- print("Test: insert back-populates primary key on Product... ");
- var session = setup_product_session();
-
- // Create a new product with id = 0
- var product = new TestProduct();
- product.name = "Test Product";
- product.category = "Electronics";
- product.price = 99.99;
- product.stock = 100;
-
- // Verify initial state
- assert(product.id == 0);
-
- // Insert the product
- session.insert(product);
-
- // After insert, the id should be back-populated
- assert(product.id > 0);
-
- print("PASSED\n");
- }
- /**
- * Test: Insert back-populates primary key on Order entity.
- *
- * Verifies that the back-population works correctly for Order entities
- * which have different column types including DateTime.
- */
- void test_insert_back_populates_order() throws Error {
- print("Test: insert back-populates primary key on Order... ");
- var session = setup_order_session();
-
- // Create a new order with id = 0
- var order = new TestOrder();
- order.user_id = 1;
- order.product_id = 1;
- order.quantity = 2;
- order.total = 199.98;
- order.status = "pending";
- order.created_at = new DateTime.now_utc();
-
- // Verify initial state
- assert(order.id == 0);
-
- // Insert the order
- session.insert(order);
-
- // After insert, the id should be back-populated
- assert(order.id > 0);
-
- print("PASSED\n");
- }
|