From 201d6fe9f98a8da550d64378e2c16d5366bb4193 Mon Sep 17 00:00:00 2001 From: Anshul Sanghi Date: Thu, 12 Oct 2023 13:53:29 +0530 Subject: [PATCH] Add Tests And Fix Build Issue For "Rework active enum" PR (#1900) * Add Tests For Root JSON Arrays And Active Enum Vectors * Fix Build Issue When Using `DeriveActiveEnum` --- sea-orm-macros/src/derives/active_enum.rs | 2 +- tests/active_enum_tests.rs | 71 +++++++++++++++++++++++ tests/common/features/active_enum_vec.rs | 16 +++++ tests/common/features/categories.rs | 15 +++++ tests/common/features/json_vec_derive.rs | 58 +++++++++++++----- tests/common/features/mod.rs | 5 ++ tests/common/features/schema.rs | 43 +++++++++++++- tests/json_vec_tests.rs | 49 ++++++++++++---- 8 files changed, 231 insertions(+), 28 deletions(-) create mode 100644 tests/common/features/active_enum_vec.rs create mode 100644 tests/common/features/categories.rs diff --git a/sea-orm-macros/src/derives/active_enum.rs b/sea-orm-macros/src/derives/active_enum.rs index db4d5f6e..f163275f 100644 --- a/sea-orm-macros/src/derives/active_enum.rs +++ b/sea-orm-macros/src/derives/active_enum.rs @@ -342,7 +342,7 @@ impl ActiveEnum { fn try_get_by(res: &sea_orm::QueryResult, index: I) -> std::result::Result, sea_orm::TryGetError> { <::Value as sea_orm::ActiveEnumValue>::try_get_vec_by(res, index)? .into_iter() - .map(|value| Self::try_from_value(&value).map_err(Into::into)) + .map(|value| ::try_from_value(&value).map_err(Into::into)) .collect() } } diff --git a/tests/active_enum_tests.rs b/tests/active_enum_tests.rs index e1aff3f9..843d5105 100644 --- a/tests/active_enum_tests.rs +++ b/tests/active_enum_tests.rs @@ -22,6 +22,11 @@ async fn main() -> Result<(), DbErr> { create_tables(&ctx.db).await?; insert_active_enum(&ctx.db).await?; insert_active_enum_child(&ctx.db).await?; + + if cfg!(feature = "sqlx-postgres") { + insert_active_enum_vec(&ctx.db).await?; + } + find_related_active_enum(&ctx.db).await?; find_linked_active_enum(&ctx.db).await?; ctx.delete().await; @@ -205,6 +210,72 @@ pub async fn insert_active_enum_child(db: &DatabaseConnection) -> Result<(), DbE Ok(()) } +pub async fn insert_active_enum_vec(db: &DatabaseConnection) -> Result<(), DbErr> { + use categories::*; + + let model = Model { + id: 1, + categories: None, + }; + + assert_eq!( + model, + ActiveModel { + id: Set(1), + categories: Set(None), + ..Default::default() + } + .insert(db) + .await? + ); + assert_eq!(model, Entity::find().one(db).await?.unwrap()); + assert_eq!( + model, + Entity::find() + .filter(Column::Id.is_not_null()) + .filter(Column::Categories.is_null()) + .one(db) + .await? + .unwrap() + ); + + let _ = ActiveModel { + id: Set(1), + categories: Set(Some(vec![Category::Big, Category::Small])), + ..model.into_active_model() + } + .save(db) + .await?; + + let model = Entity::find().one(db).await?.unwrap(); + assert_eq!( + model, + Model { + id: 1, + categories: Some(vec![Category::Big, Category::Small]), + } + ); + assert_eq!( + model, + Entity::find() + .filter(Column::Id.eq(1)) + .filter(Expr::cust_with_values( + r#"$1 = ANY("categories")"#, + vec![Category::Big] + )) + .one(db) + .await? + .unwrap() + ); + + let res = model.delete(db).await?; + + assert_eq!(res.rows_affected, 1); + assert_eq!(Entity::find().one(db).await?, None); + + Ok(()) +} + pub async fn find_related_active_enum(db: &DatabaseConnection) -> Result<(), DbErr> { assert_eq!( active_enum::Model { diff --git a/tests/common/features/active_enum_vec.rs b/tests/common/features/active_enum_vec.rs new file mode 100644 index 00000000..66bda0de --- /dev/null +++ b/tests/common/features/active_enum_vec.rs @@ -0,0 +1,16 @@ +use super::sea_orm_active_enums::*; +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] +#[cfg_attr(feature = "sqlx-postgres", sea_orm(schema_name = "public"))] +#[sea_orm(table_name = "active_enum")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub categories: Option>, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/tests/common/features/categories.rs b/tests/common/features/categories.rs new file mode 100644 index 00000000..00f25674 --- /dev/null +++ b/tests/common/features/categories.rs @@ -0,0 +1,15 @@ +use super::sea_orm_active_enums::*; +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] +#[sea_orm(table_name = "categories")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: i32, + pub categories: Option>, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/tests/common/features/json_vec_derive.rs b/tests/common/features/json_vec_derive.rs index cc6e177b..dcf16a73 100644 --- a/tests/common/features/json_vec_derive.rs +++ b/tests/common/features/json_vec_derive.rs @@ -1,19 +1,49 @@ -use sea_orm::entity::prelude::*; -use sea_orm::FromJsonQueryResult; -use serde::{Deserialize, Serialize}; +pub mod json_string_vec { + use sea_orm::entity::prelude::*; + use sea_orm::FromJsonQueryResult; + use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] -#[sea_orm(table_name = "json_vec")] -pub struct Model { - #[sea_orm(primary_key)] - pub id: i32, - pub str_vec: Option, + #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] + #[sea_orm(table_name = "json_vec")] + pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub str_vec: Option, + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] + pub enum Relation {} + + impl ActiveModelBehavior for ActiveModel {} + + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult)] + pub struct StringVec(pub Vec); } -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation {} +pub mod json_struct_vec { + use sea_orm::entity::prelude::*; + use sea_orm_macros::FromJsonQueryResult; + use sea_query::with_array::NotU8; + use serde::{Deserialize, Serialize}; -impl ActiveModelBehavior for ActiveModel {} + #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult)] + pub struct JsonColumn { + pub value: String, + } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult)] -pub struct StringVec(pub Vec); + impl NotU8 for JsonColumn {} + + #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] + #[sea_orm(table_name = "json_struct_vec")] + pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "JsonBinary")] + pub struct_vec: Vec, + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] + pub enum Relation {} + + impl ActiveModelBehavior for ActiveModel {} +} diff --git a/tests/common/features/mod.rs b/tests/common/features/mod.rs index 84a6f7f2..f60950f8 100644 --- a/tests/common/features/mod.rs +++ b/tests/common/features/mod.rs @@ -1,9 +1,11 @@ pub mod active_enum; pub mod active_enum_child; +pub mod active_enum_vec; pub mod applog; pub mod binary; pub mod bits; pub mod byte_primary_key; +pub mod categories; pub mod collection; pub mod collection_expanded; pub mod custom_active_model; @@ -28,10 +30,12 @@ pub mod value_type; pub use active_enum::Entity as ActiveEnum; pub use active_enum_child::Entity as ActiveEnumChild; +pub use active_enum_vec::Entity as ActiveEnumVec; pub use applog::Entity as Applog; pub use binary::Entity as Binary; pub use bits::Entity as Bits; pub use byte_primary_key::Entity as BytePrimaryKey; +pub use categories::Entity as Categories; pub use collection::Entity as Collection; pub use collection_expanded::Entity as CollectionExpanded; pub use dyn_table_name_lazy_static::Entity as DynTableNameLazyStatic; @@ -40,6 +44,7 @@ pub use event_trigger::Entity as EventTrigger; pub use insert_default::Entity as InsertDefault; pub use json_struct::Entity as JsonStruct; pub use json_vec::Entity as JsonVec; +pub use json_vec_derive::json_struct_vec::Entity as JsonStructVec; pub use metadata::Entity as Metadata; pub use pi::Entity as Pi; pub use repository::Entity as Repository; diff --git a/tests/common/features/schema.rs b/tests/common/features/schema.rs index 6e1f71cc..dbb5551d 100644 --- a/tests/common/features/schema.rs +++ b/tests/common/features/schema.rs @@ -1,11 +1,13 @@ use super::*; +use crate::common::features::json_vec_derive::json_struct_vec; use crate::common::setup::{create_enum, create_table, create_table_without_asserts}; use sea_orm::{ error::*, sea_query, ConnectionTrait, DatabaseConnection, DbBackend, DbConn, EntityName, ExecResult, Schema, }; use sea_query::{ - extension::postgres::Type, Alias, BlobSize, ColumnDef, ForeignKeyCreateStatement, IntoIden, + extension::postgres::Type, Alias, BlobSize, ColumnDef, ColumnType, ForeignKeyCreateStatement, + IntoIden, }; pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> { @@ -18,7 +20,6 @@ pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> { create_byte_primary_key_table(db).await?; create_satellites_table(db).await?; create_transaction_log_table(db).await?; - create_json_vec_table(db).await?; create_json_struct_table(db).await?; let create_enum_stmts = match db_backend { @@ -54,6 +55,9 @@ pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> { create_value_type_postgres_table(db).await?; create_collection_table(db).await?; create_event_trigger_table(db).await?; + create_json_vec_table(db).await?; + create_json_struct_vec_table(db).await?; + create_categories_table(db).await?; } Ok(()) @@ -319,6 +323,26 @@ pub async fn create_json_vec_table(db: &DbConn) -> Result { create_table(db, &create_table_stmt, JsonVec).await } +pub async fn create_json_struct_vec_table(db: &DbConn) -> Result { + let create_table_stmt = sea_query::Table::create() + .table(json_struct_vec::Entity.table_ref()) + .col( + ColumnDef::new(json_struct_vec::Column::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col( + ColumnDef::new(json_struct_vec::Column::StructVec) + .json_binary() + .not_null(), + ) + .to_owned(); + + create_table(db, &create_table_stmt, JsonStructVec).await +} + pub async fn create_json_struct_table(db: &DbConn) -> Result { let stmt = sea_query::Table::create() .table(json_struct::Entity) @@ -521,6 +545,21 @@ pub async fn create_teas_table(db: &DbConn) -> Result { create_table(db, &create_table_stmt, Teas).await } +pub async fn create_categories_table(db: &DbConn) -> Result { + let create_table_stmt = sea_query::Table::create() + .table(categories::Entity.table_ref()) + .col( + ColumnDef::new(categories::Column::Id) + .integer() + .not_null() + .primary_key(), + ) + .col(ColumnDef::new(categories::Column::Categories).array(ColumnType::String(Some(1)))) + .to_owned(); + + create_table(db, &create_table_stmt, Categories).await +} + pub async fn create_binary_table(db: &DbConn) -> Result { let create_table_stmt = sea_query::Table::create() .table(binary::Entity.table_ref()) diff --git a/tests/json_vec_tests.rs b/tests/json_vec_tests.rs index 9af2a330..ab5bab2e 100644 --- a/tests/json_vec_tests.rs +++ b/tests/json_vec_tests.rs @@ -5,16 +5,14 @@ use pretty_assertions::assert_eq; use sea_orm::{entity::prelude::*, entity::*, DatabaseConnection}; #[sea_orm_macros::test] -#[cfg(any( - feature = "sqlx-mysql", - feature = "sqlx-sqlite", - feature = "sqlx-postgres" -))] +#[cfg(feature = "sqlx-postgres")] async fn main() -> Result<(), DbErr> { let ctx = TestContext::new("json_vec_tests").await; create_tables(&ctx.db).await?; insert_json_vec(&ctx.db).await?; - insert_json_vec_derive(&ctx.db).await?; + + insert_json_string_vec_derive(&ctx.db).await?; + ctx.delete().await; Ok(()) @@ -44,10 +42,10 @@ pub async fn insert_json_vec(db: &DatabaseConnection) -> Result<(), DbErr> { Ok(()) } -pub async fn insert_json_vec_derive(db: &DatabaseConnection) -> Result<(), DbErr> { - let json_vec = json_vec_derive::Model { +pub async fn insert_json_string_vec_derive(db: &DatabaseConnection) -> Result<(), DbErr> { + let json_vec = json_vec_derive::json_string_vec::Model { id: 2, - str_vec: Some(json_vec_derive::StringVec(vec![ + str_vec: Some(json_vec_derive::json_string_vec::StringVec(vec![ "4".to_string(), "5".to_string(), "6".to_string(), @@ -58,8 +56,37 @@ pub async fn insert_json_vec_derive(db: &DatabaseConnection) -> Result<(), DbErr assert_eq!(result, json_vec); - let model = json_vec_derive::Entity::find() - .filter(json_vec_derive::Column::Id.eq(json_vec.id)) + let model = json_vec_derive::json_string_vec::Entity::find() + .filter(json_vec_derive::json_string_vec::Column::Id.eq(json_vec.id)) + .one(db) + .await?; + + assert_eq!(model, Some(json_vec)); + + Ok(()) +} + +pub async fn insert_json_struct_vec_derive(db: &DatabaseConnection) -> Result<(), DbErr> { + let json_vec = json_vec_derive::json_struct_vec::Model { + id: 2, + struct_vec: vec![ + json_vec_derive::json_struct_vec::JsonColumn { + value: "4".to_string(), + }, + json_vec_derive::json_struct_vec::JsonColumn { + value: "5".to_string(), + }, + json_vec_derive::json_struct_vec::JsonColumn { + value: "6".to_string(), + }, + ], + }; + + let result = json_vec.clone().into_active_model().insert(db).await?; + assert_eq!(result, json_vec); + + let model = json_vec_derive::json_struct_vec::Entity::find() + .filter(json_vec_derive::json_struct_vec::Column::Id.eq(json_vec.id)) .one(db) .await?;