run clippy & fix
This commit is contained in:
+2
-3
@@ -135,7 +135,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
// WebAuthn config from env vars. RP_ID must match the host users access the site from.
|
// WebAuthn config from env vars. RP_ID must match the host users access the site from.
|
||||||
let rp_id = env::var("RP_ID").unwrap_or_else(|_| {
|
let rp_id = env::var("RP_ID").unwrap_or_else(|_| {
|
||||||
let host = public_base_url
|
public_base_url
|
||||||
.trim_start_matches("http://")
|
.trim_start_matches("http://")
|
||||||
.trim_start_matches("https://")
|
.trim_start_matches("https://")
|
||||||
.split('/')
|
.split('/')
|
||||||
@@ -144,8 +144,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.split(':')
|
.split(':')
|
||||||
.next()
|
.next()
|
||||||
.unwrap_or("localhost")
|
.unwrap_or("localhost")
|
||||||
.to_owned();
|
.to_owned()
|
||||||
host
|
|
||||||
});
|
});
|
||||||
let rp_name = env::var("RP_NAME").unwrap_or_else(|_| "Sustenance".into());
|
let rp_name = env::var("RP_NAME").unwrap_or_else(|_| "Sustenance".into());
|
||||||
let origin =
|
let origin =
|
||||||
|
|||||||
@@ -153,6 +153,10 @@ pub trait ItemRepository: Send + Sync {
|
|||||||
item_id: i64,
|
item_id: i64,
|
||||||
checked: bool,
|
checked: bool,
|
||||||
) -> DomainResult<i64>;
|
) -> DomainResult<i64>;
|
||||||
|
/// Update the mutable fields of an item. The bare field list mirrors the
|
||||||
|
/// edit form's inputs; clippy flags the argument count, which is justified
|
||||||
|
/// here by the flat domain signature.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn update_item(
|
async fn update_item(
|
||||||
&self,
|
&self,
|
||||||
txn: &mut SqliteConnection,
|
txn: &mut SqliteConnection,
|
||||||
@@ -276,6 +280,9 @@ pub trait MealIngredientRepository: Send + Sync {
|
|||||||
note: String,
|
note: String,
|
||||||
category_id: Option<i64>,
|
category_id: Option<i64>,
|
||||||
) -> DomainResult<i64>;
|
) -> DomainResult<i64>;
|
||||||
|
/// Update the mutable fields of a meal ingredient. Same flat signature
|
||||||
|
/// rationale as `ItemRepository::update_item`.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn update_ingredient(
|
async fn update_ingredient(
|
||||||
&self,
|
&self,
|
||||||
txn: &mut SqliteConnection,
|
txn: &mut SqliteConnection,
|
||||||
|
|||||||
@@ -345,6 +345,9 @@ pub struct MealService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MealService {
|
impl MealService {
|
||||||
|
/// Builds the meal service from its dependencies. The argument count is
|
||||||
|
/// intentional: it assembles the service's repository/notifier graph.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
db: SqliteDatabase,
|
db: SqliteDatabase,
|
||||||
meals: Arc<dyn MealRepository>,
|
meals: Arc<dyn MealRepository>,
|
||||||
|
|||||||
+107
-115
@@ -1539,7 +1539,7 @@ mod tests {
|
|||||||
let users = SqliteUserRepository;
|
let users = SqliteUserRepository;
|
||||||
let email = email.to_owned();
|
let email = email.to_owned();
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let users = users.clone();
|
let users = users;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
users
|
users
|
||||||
.create_user(txn, email, "Test User".into(), "hash".into())
|
.create_user(txn, email, "Test User".into(), "hash".into())
|
||||||
@@ -1554,7 +1554,7 @@ mod tests {
|
|||||||
let lists = SqliteListRepository;
|
let lists = SqliteListRepository;
|
||||||
let name = name.to_owned();
|
let name = name.to_owned();
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let lists = lists.clone();
|
let lists = lists;
|
||||||
Box::pin(async move { lists.create_list(txn, name).await })
|
Box::pin(async move { lists.create_list(txn, name).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1565,7 +1565,7 @@ mod tests {
|
|||||||
let items = SqliteItemRepository;
|
let items = SqliteItemRepository;
|
||||||
let name_for_insert = name.to_owned();
|
let name_for_insert = name.to_owned();
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
items
|
items
|
||||||
.add_item(
|
.add_item(
|
||||||
@@ -1583,7 +1583,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let items = SqliteItemRepository;
|
let items = SqliteItemRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move { items.items(txn, list_id).await })
|
Box::pin(async move { items.items(txn, list_id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1596,7 +1596,7 @@ mod tests {
|
|||||||
async fn get_items(db: &SqliteDatabase, list_id: i64) -> Vec<Item> {
|
async fn get_items(db: &SqliteDatabase, list_id: i64) -> Vec<Item> {
|
||||||
let items = SqliteItemRepository;
|
let items = SqliteItemRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move { items.items(txn, list_id).await })
|
Box::pin(async move { items.items(txn, list_id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1606,7 +1606,7 @@ mod tests {
|
|||||||
async fn get_categories(db: &SqliteDatabase) -> Vec<Category> {
|
async fn get_categories(db: &SqliteDatabase) -> Vec<Category> {
|
||||||
let categories = SqliteCategoryRepository;
|
let categories = SqliteCategoryRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let categories = categories.clone();
|
let categories = categories;
|
||||||
Box::pin(async move { categories.categories(txn).await })
|
Box::pin(async move { categories.categories(txn).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1631,7 +1631,7 @@ mod tests {
|
|||||||
let users = SqliteUserRepository;
|
let users = SqliteUserRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let users = users.clone();
|
let users = users;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
users
|
users
|
||||||
.create_user(
|
.create_user(
|
||||||
@@ -1654,7 +1654,7 @@ mod tests {
|
|||||||
let users = SqliteUserRepository;
|
let users = SqliteUserRepository;
|
||||||
let found = db
|
let found = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let users = users.clone();
|
let users = users;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
users
|
users
|
||||||
.find_user_by_email(txn, "alice@example.com".into())
|
.find_user_by_email(txn, "alice@example.com".into())
|
||||||
@@ -1675,7 +1675,7 @@ mod tests {
|
|||||||
let users = SqliteUserRepository;
|
let users = SqliteUserRepository;
|
||||||
let found = db
|
let found = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let users = users.clone();
|
let users = users;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
users
|
users
|
||||||
.find_user_by_email(txn, "ALICE@EXAMPLE.COM".into())
|
.find_user_by_email(txn, "ALICE@EXAMPLE.COM".into())
|
||||||
@@ -1693,7 +1693,7 @@ mod tests {
|
|||||||
let users = SqliteUserRepository;
|
let users = SqliteUserRepository;
|
||||||
let found = db
|
let found = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let users = users.clone();
|
let users = users;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
users
|
users
|
||||||
.find_user_by_email(txn, "nobody@example.com".into())
|
.find_user_by_email(txn, "nobody@example.com".into())
|
||||||
@@ -1711,7 +1711,7 @@ mod tests {
|
|||||||
let users = SqliteUserRepository;
|
let users = SqliteUserRepository;
|
||||||
let empty = db
|
let empty = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let users = users.clone();
|
let users = users;
|
||||||
Box::pin(async move { users.has_users(txn).await })
|
Box::pin(async move { users.has_users(txn).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1721,7 +1721,7 @@ mod tests {
|
|||||||
create_user(&db, "alice@example.com").await;
|
create_user(&db, "alice@example.com").await;
|
||||||
let has = db
|
let has = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let users = users.clone();
|
let users = users;
|
||||||
Box::pin(async move { users.has_users(txn).await })
|
Box::pin(async move { users.has_users(txn).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1738,7 +1738,7 @@ mod tests {
|
|||||||
let sessions = SqliteSessionRepository;
|
let sessions = SqliteSessionRepository;
|
||||||
let (token, csrf) = db
|
let (token, csrf) = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let sessions = sessions.clone();
|
let sessions = sessions;
|
||||||
Box::pin(async move { sessions.create_session(txn, user.id).await })
|
Box::pin(async move { sessions.create_session(txn, user.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1748,7 +1748,7 @@ mod tests {
|
|||||||
|
|
||||||
let session = db
|
let session = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let sessions = sessions.clone();
|
let sessions = sessions;
|
||||||
Box::pin(async move { sessions.session_user(txn, token.clone()).await })
|
Box::pin(async move { sessions.session_user(txn, token.clone()).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1764,7 +1764,7 @@ mod tests {
|
|||||||
let sessions = SqliteSessionRepository;
|
let sessions = SqliteSessionRepository;
|
||||||
let session = db
|
let session = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let sessions = sessions.clone();
|
let sessions = sessions;
|
||||||
Box::pin(async move { sessions.session_user(txn, "bogus".into()).await })
|
Box::pin(async move { sessions.session_user(txn, "bogus".into()).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1779,7 +1779,7 @@ mod tests {
|
|||||||
let sessions = SqliteSessionRepository;
|
let sessions = SqliteSessionRepository;
|
||||||
let (token, _) = db
|
let (token, _) = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let sessions = sessions.clone();
|
let sessions = sessions;
|
||||||
Box::pin(async move { sessions.create_session(txn, user.id).await })
|
Box::pin(async move { sessions.create_session(txn, user.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1787,7 +1787,7 @@ mod tests {
|
|||||||
|
|
||||||
let token_for_delete = token.clone();
|
let token_for_delete = token.clone();
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let sessions = sessions.clone();
|
let sessions = sessions;
|
||||||
Box::pin(async move { sessions.delete_session(txn, token_for_delete).await })
|
Box::pin(async move { sessions.delete_session(txn, token_for_delete).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1795,7 +1795,7 @@ mod tests {
|
|||||||
|
|
||||||
let session = db
|
let session = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let sessions = sessions.clone();
|
let sessions = sessions;
|
||||||
Box::pin(async move { sessions.session_user(txn, token).await })
|
Box::pin(async move { sessions.session_user(txn, token).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1825,7 +1825,7 @@ mod tests {
|
|||||||
let lists = SqliteListRepository;
|
let lists = SqliteListRepository;
|
||||||
let summaries = db
|
let summaries = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let lists = lists.clone();
|
let lists = lists;
|
||||||
Box::pin(async move { lists.list_summaries(txn).await })
|
Box::pin(async move { lists.list_summaries(txn).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1843,7 +1843,7 @@ mod tests {
|
|||||||
|
|
||||||
let list_id = list.id;
|
let list_id = list.id;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let lists = lists.clone();
|
let lists = lists;
|
||||||
Box::pin(async move { lists.set_archived(txn, list_id, true).await })
|
Box::pin(async move { lists.set_archived(txn, list_id, true).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1851,7 +1851,7 @@ mod tests {
|
|||||||
|
|
||||||
let summaries = db
|
let summaries = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let lists = lists.clone();
|
let lists = lists;
|
||||||
Box::pin(async move { lists.list_summaries(txn).await })
|
Box::pin(async move { lists.list_summaries(txn).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1860,7 +1860,7 @@ mod tests {
|
|||||||
|
|
||||||
let archived = db
|
let archived = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let lists = lists.clone();
|
let lists = lists;
|
||||||
Box::pin(async move { lists.list_archived_summaries(txn).await })
|
Box::pin(async move { lists.list_archived_summaries(txn).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1878,13 +1878,13 @@ mod tests {
|
|||||||
|
|
||||||
let list_id = list.id;
|
let list_id = list.id;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let lists = lists.clone();
|
let lists = lists;
|
||||||
Box::pin(async move { lists.set_archived(txn, list_id, true).await })
|
Box::pin(async move { lists.set_archived(txn, list_id, true).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let lists = lists.clone();
|
let lists = lists;
|
||||||
Box::pin(async move { lists.set_archived(txn, list_id, false).await })
|
Box::pin(async move { lists.set_archived(txn, list_id, false).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1892,7 +1892,7 @@ mod tests {
|
|||||||
|
|
||||||
let summaries = db
|
let summaries = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let lists = lists.clone();
|
let lists = lists;
|
||||||
Box::pin(async move { lists.list_summaries(txn).await })
|
Box::pin(async move { lists.list_summaries(txn).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1907,7 +1907,7 @@ mod tests {
|
|||||||
let lists = SqliteListRepository;
|
let lists = SqliteListRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let lists = lists.clone();
|
let lists = lists;
|
||||||
Box::pin(async move { lists.set_archived(txn, 9999, true).await })
|
Box::pin(async move { lists.set_archived(txn, 9999, true).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -1921,7 +1921,7 @@ mod tests {
|
|||||||
let lists = SqliteListRepository;
|
let lists = SqliteListRepository;
|
||||||
let found = db
|
let found = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let lists = lists.clone();
|
let lists = lists;
|
||||||
Box::pin(async move { lists.get_list(txn, list.id).await })
|
Box::pin(async move { lists.get_list(txn, list.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1930,7 +1930,7 @@ mod tests {
|
|||||||
|
|
||||||
let missing = db
|
let missing = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let lists = lists.clone();
|
let lists = lists;
|
||||||
Box::pin(async move { lists.get_list(txn, 9999).await })
|
Box::pin(async move { lists.get_list(txn, 9999).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1946,7 +1946,7 @@ mod tests {
|
|||||||
let categories = SqliteCategoryRepository;
|
let categories = SqliteCategoryRepository;
|
||||||
let id = db
|
let id = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let categories = categories.clone();
|
let categories = categories;
|
||||||
Box::pin(async move { categories.create_category(txn, "Bakery".into()).await })
|
Box::pin(async move { categories.create_category(txn, "Bakery".into()).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -1963,7 +1963,7 @@ mod tests {
|
|||||||
let categories = SqliteCategoryRepository;
|
let categories = SqliteCategoryRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let categories = categories.clone();
|
let categories = categories;
|
||||||
Box::pin(async move { categories.create_category(txn, "Produce".into()).await })
|
Box::pin(async move { categories.create_category(txn, "Produce".into()).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -1975,7 +1975,7 @@ mod tests {
|
|||||||
async fn get_meal_categories(db: &SqliteDatabase) -> Vec<MealCategory> {
|
async fn get_meal_categories(db: &SqliteDatabase) -> Vec<MealCategory> {
|
||||||
let categories = SqliteMealCategoryRepository;
|
let categories = SqliteMealCategoryRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let categories = categories.clone();
|
let categories = categories;
|
||||||
Box::pin(async move { categories.meal_categories(txn).await })
|
Box::pin(async move { categories.meal_categories(txn).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2004,7 +2004,7 @@ mod tests {
|
|||||||
let categories = SqliteMealCategoryRepository;
|
let categories = SqliteMealCategoryRepository;
|
||||||
let id = db
|
let id = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let categories = categories.clone();
|
let categories = categories;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
categories
|
categories
|
||||||
.create_meal_category(txn, "Breakfast".into())
|
.create_meal_category(txn, "Breakfast".into())
|
||||||
@@ -2024,7 +2024,7 @@ mod tests {
|
|||||||
let categories = SqliteMealCategoryRepository;
|
let categories = SqliteMealCategoryRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let categories = categories.clone();
|
let categories = categories;
|
||||||
Box::pin(async move { categories.create_meal_category(txn, "Beef".into()).await })
|
Box::pin(async move { categories.create_meal_category(txn, "Beef".into()).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -2037,7 +2037,7 @@ mod tests {
|
|||||||
let categories = SqliteMealCategoryRepository;
|
let categories = SqliteMealCategoryRepository;
|
||||||
let category_id = db
|
let category_id = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let categories = categories.clone();
|
let categories = categories;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
categories
|
categories
|
||||||
.create_meal_category(txn, "Breakfast".into())
|
.create_meal_category(txn, "Breakfast".into())
|
||||||
@@ -2049,7 +2049,7 @@ mod tests {
|
|||||||
let meal = create_meal(&db, "Pancakes").await;
|
let meal = create_meal(&db, "Pancakes").await;
|
||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
meals
|
meals
|
||||||
.update_meal(
|
.update_meal(
|
||||||
@@ -2066,7 +2066,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let categories = categories.clone();
|
let categories = categories;
|
||||||
Box::pin(async move { categories.delete_meal_category(txn, category_id).await })
|
Box::pin(async move { categories.delete_meal_category(txn, category_id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2074,7 +2074,7 @@ mod tests {
|
|||||||
|
|
||||||
let fetched = db
|
let fetched = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move { meals.get_meal(txn, meal.id).await })
|
Box::pin(async move { meals.get_meal(txn, meal.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2092,7 +2092,7 @@ mod tests {
|
|||||||
let items = SqliteItemRepository;
|
let items = SqliteItemRepository;
|
||||||
let revision = db
|
let revision = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
items
|
items
|
||||||
.add_item(
|
.add_item(
|
||||||
@@ -2126,7 +2126,7 @@ mod tests {
|
|||||||
let items = SqliteItemRepository;
|
let items = SqliteItemRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
items
|
items
|
||||||
.add_item(
|
.add_item(
|
||||||
@@ -2167,7 +2167,7 @@ mod tests {
|
|||||||
];
|
];
|
||||||
let revision = db
|
let revision = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move { items.add_items_bulk(txn, list.id, new_items).await })
|
Box::pin(async move { items.add_items_bulk(txn, list.id, new_items).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2188,7 +2188,7 @@ mod tests {
|
|||||||
let items = SqliteItemRepository;
|
let items = SqliteItemRepository;
|
||||||
let revision = db
|
let revision = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
items
|
items
|
||||||
.update_item(
|
.update_item(
|
||||||
@@ -2221,7 +2221,7 @@ mod tests {
|
|||||||
let items = SqliteItemRepository;
|
let items = SqliteItemRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
items
|
items
|
||||||
.update_item(
|
.update_item(
|
||||||
@@ -2248,7 +2248,7 @@ mod tests {
|
|||||||
let items = SqliteItemRepository;
|
let items = SqliteItemRepository;
|
||||||
let revision = db
|
let revision = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move { items.delete_item(txn, list.id, item.id).await })
|
Box::pin(async move { items.delete_item(txn, list.id, item.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2264,7 +2264,7 @@ mod tests {
|
|||||||
let items = SqliteItemRepository;
|
let items = SqliteItemRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move { items.delete_item(txn, list.id, 9999).await })
|
Box::pin(async move { items.delete_item(txn, list.id, 9999).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -2278,7 +2278,7 @@ mod tests {
|
|||||||
let items = SqliteItemRepository;
|
let items = SqliteItemRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move { items.set_item_checked(txn, list.id, 9999, true).await })
|
Box::pin(async move { items.set_item_checked(txn, list.id, 9999, true).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -2294,7 +2294,7 @@ mod tests {
|
|||||||
let invitations = SqliteInvitationRepository;
|
let invitations = SqliteInvitationRepository;
|
||||||
let expires = db
|
let expires = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let invitations = invitations.clone();
|
let invitations = invitations;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
invitations
|
invitations
|
||||||
.create_invitation(txn, user.id, "token-1".into())
|
.create_invitation(txn, user.id, "token-1".into())
|
||||||
@@ -2307,7 +2307,7 @@ mod tests {
|
|||||||
|
|
||||||
let valid = db
|
let valid = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let invitations = invitations.clone();
|
let invitations = invitations;
|
||||||
Box::pin(async move { invitations.invitation(txn, "token-1".into()).await })
|
Box::pin(async move { invitations.invitation(txn, "token-1".into()).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2321,7 +2321,7 @@ mod tests {
|
|||||||
let invitations = SqliteInvitationRepository;
|
let invitations = SqliteInvitationRepository;
|
||||||
let valid = db
|
let valid = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let invitations = invitations.clone();
|
let invitations = invitations;
|
||||||
Box::pin(async move { invitations.invitation(txn, "bogus".into()).await })
|
Box::pin(async move { invitations.invitation(txn, "bogus".into()).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2335,7 +2335,7 @@ mod tests {
|
|||||||
let user = create_user(&db, "alice@example.com").await;
|
let user = create_user(&db, "alice@example.com").await;
|
||||||
let invitations = SqliteInvitationRepository;
|
let invitations = SqliteInvitationRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let invitations = invitations.clone();
|
let invitations = invitations;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
invitations
|
invitations
|
||||||
.create_invitation(txn, user.id, "token-1".into())
|
.create_invitation(txn, user.id, "token-1".into())
|
||||||
@@ -2346,7 +2346,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let invitations = invitations.clone();
|
let invitations = invitations;
|
||||||
Box::pin(async move { invitations.accept_invitation(txn, "token-1".into()).await })
|
Box::pin(async move { invitations.accept_invitation(txn, "token-1".into()).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2354,7 +2354,7 @@ mod tests {
|
|||||||
|
|
||||||
let valid = db
|
let valid = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let invitations = invitations.clone();
|
let invitations = invitations;
|
||||||
Box::pin(async move { invitations.invitation(txn, "token-1".into()).await })
|
Box::pin(async move { invitations.invitation(txn, "token-1".into()).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2368,7 +2368,7 @@ mod tests {
|
|||||||
let invitations = SqliteInvitationRepository;
|
let invitations = SqliteInvitationRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let invitations = invitations.clone();
|
let invitations = invitations;
|
||||||
Box::pin(async move { invitations.accept_invitation(txn, "bogus".into()).await })
|
Box::pin(async move { invitations.accept_invitation(txn, "bogus".into()).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -2384,13 +2384,13 @@ mod tests {
|
|||||||
let item = add_item(&db, list.id, "Coffee").await;
|
let item = add_item(&db, list.id, "Coffee").await;
|
||||||
let items = SqliteItemRepository;
|
let items = SqliteItemRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move { items.set_item_checked(txn, list.id, item.id, true).await })
|
Box::pin(async move { items.set_item_checked(txn, list.id, item.id, true).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move { items.set_item_checked(txn, list.id, item.id, true).await })
|
Box::pin(async move { items.set_item_checked(txn, list.id, item.id, true).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2411,7 +2411,7 @@ mod tests {
|
|||||||
let first_item = get_items(&db, list.id).await.remove(0);
|
let first_item = get_items(&db, list.id).await.remove(0);
|
||||||
|
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
items
|
items
|
||||||
.set_item_checked(txn, list.id, first_item.id, true)
|
.set_item_checked(txn, list.id, first_item.id, true)
|
||||||
@@ -2433,7 +2433,7 @@ mod tests {
|
|||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
let name = name.to_owned();
|
let name = name.to_owned();
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move { meals.create_meal(txn, name, String::new(), None).await })
|
Box::pin(async move { meals.create_meal(txn, name, String::new(), None).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2449,7 +2449,7 @@ mod tests {
|
|||||||
let ingredients = SqliteMealIngredientRepository;
|
let ingredients = SqliteMealIngredientRepository;
|
||||||
let name_for_insert = name.to_owned();
|
let name_for_insert = name.to_owned();
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let ingredients = ingredients.clone();
|
let ingredients = ingredients;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
ingredients
|
ingredients
|
||||||
.add_ingredient(
|
.add_ingredient(
|
||||||
@@ -2467,7 +2467,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let ingredients = SqliteMealIngredientRepository;
|
let ingredients = SqliteMealIngredientRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let ingredients = ingredients.clone();
|
let ingredients = ingredients;
|
||||||
Box::pin(async move { ingredients.ingredients_for_meal(txn, meal_id).await })
|
Box::pin(async move { ingredients.ingredients_for_meal(txn, meal_id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2494,7 +2494,7 @@ mod tests {
|
|||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
let meals = db
|
let meals = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move { meals.list_meals(txn, "").await })
|
Box::pin(async move { meals.list_meals(txn, "").await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2511,12 +2511,8 @@ mod tests {
|
|||||||
create_meal(&db, "Chicken Curry").await;
|
create_meal(&db, "Chicken Curry").await;
|
||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
let names = |posted_query: &str| {
|
let names = |posted_query: &str| {
|
||||||
let meals = meals.clone();
|
|
||||||
let posted_query = posted_query.to_owned();
|
let posted_query = posted_query.to_owned();
|
||||||
db.run(move |txn| {
|
db.run(move |txn| Box::pin(async move { meals.list_meals(txn, &posted_query).await }))
|
||||||
let meals = meals.clone();
|
|
||||||
Box::pin(async move { meals.list_meals(txn, &posted_query).await })
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
let matched = names("pasta").await.unwrap();
|
let matched = names("pasta").await.unwrap();
|
||||||
let matched_names = matched.iter().map(|m| m.name.as_str()).collect::<Vec<_>>();
|
let matched_names = matched.iter().map(|m| m.name.as_str()).collect::<Vec<_>>();
|
||||||
@@ -2531,12 +2527,8 @@ mod tests {
|
|||||||
create_meal(&db, "Salad").await;
|
create_meal(&db, "Salad").await;
|
||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
let names = |posted_query: &str| {
|
let names = |posted_query: &str| {
|
||||||
let meals = meals.clone();
|
|
||||||
let posted_query = posted_query.to_owned();
|
let posted_query = posted_query.to_owned();
|
||||||
db.run(move |txn| {
|
db.run(move |txn| Box::pin(async move { meals.list_meals(txn, &posted_query).await }))
|
||||||
let meals = meals.clone();
|
|
||||||
Box::pin(async move { meals.list_meals(txn, &posted_query).await })
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
// A bare `%` must not act as a wildcard matching every meal: it only
|
// A bare `%` must not act as a wildcard matching every meal: it only
|
||||||
// matches meals that contain a literal `%` character.
|
// matches meals that contain a literal `%` character.
|
||||||
@@ -2558,7 +2550,7 @@ mod tests {
|
|||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
let fetched = db
|
let fetched = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move { meals.get_meal(txn, meal.id).await })
|
Box::pin(async move { meals.get_meal(txn, meal.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2580,7 +2572,7 @@ mod tests {
|
|||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
let found = db
|
let found = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move { meals.get_meal(txn, 9999).await })
|
Box::pin(async move { meals.get_meal(txn, 9999).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2594,7 +2586,7 @@ mod tests {
|
|||||||
let meal = create_meal(&db, "Pasta").await;
|
let meal = create_meal(&db, "Pasta").await;
|
||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
meals
|
meals
|
||||||
.update_meal(
|
.update_meal(
|
||||||
@@ -2611,7 +2603,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let fetched = db
|
let fetched = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move { meals.get_meal(txn, meal.id).await })
|
Box::pin(async move { meals.get_meal(txn, meal.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2627,7 +2619,7 @@ mod tests {
|
|||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
meals
|
meals
|
||||||
.update_meal(txn, 9999, "X".into(), String::new(), None)
|
.update_meal(txn, 9999, "X".into(), String::new(), None)
|
||||||
@@ -2645,14 +2637,14 @@ mod tests {
|
|||||||
add_ingredient(&db, meal.id, "Penne", None).await;
|
add_ingredient(&db, meal.id, "Penne", None).await;
|
||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move { meals.delete_meal(txn, meal.id).await })
|
Box::pin(async move { meals.delete_meal(txn, meal.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let found = db
|
let found = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move { meals.get_meal(txn, meal.id).await })
|
Box::pin(async move { meals.get_meal(txn, meal.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2666,7 +2658,7 @@ mod tests {
|
|||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move { meals.delete_meal(txn, 9999).await })
|
Box::pin(async move { meals.delete_meal(txn, 9999).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -2680,7 +2672,7 @@ mod tests {
|
|||||||
let ingredients = SqliteMealIngredientRepository;
|
let ingredients = SqliteMealIngredientRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let ingredients = ingredients.clone();
|
let ingredients = ingredients;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
ingredients
|
ingredients
|
||||||
.add_ingredient(
|
.add_ingredient(
|
||||||
@@ -2705,7 +2697,7 @@ mod tests {
|
|||||||
let ingredient = add_ingredient(&db, meal.id, "Penne", None).await;
|
let ingredient = add_ingredient(&db, meal.id, "Penne", None).await;
|
||||||
let ingredients = SqliteMealIngredientRepository;
|
let ingredients = SqliteMealIngredientRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let ingredients = ingredients.clone();
|
let ingredients = ingredients;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
ingredients
|
ingredients
|
||||||
.update_ingredient(
|
.update_ingredient(
|
||||||
@@ -2724,7 +2716,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let fetched = db
|
let fetched = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let ingredients = ingredients.clone();
|
let ingredients = ingredients;
|
||||||
Box::pin(async move { ingredients.ingredients_for_meal(txn, meal.id).await })
|
Box::pin(async move { ingredients.ingredients_for_meal(txn, meal.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2740,7 +2732,7 @@ mod tests {
|
|||||||
let ingredient = add_ingredient(&db, meal.id, "Penne", None).await;
|
let ingredient = add_ingredient(&db, meal.id, "Penne", None).await;
|
||||||
let ingredients = SqliteMealIngredientRepository;
|
let ingredients = SqliteMealIngredientRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let ingredients = ingredients.clone();
|
let ingredients = ingredients;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
ingredients
|
ingredients
|
||||||
.delete_ingredient(txn, meal.id, ingredient.id)
|
.delete_ingredient(txn, meal.id, ingredient.id)
|
||||||
@@ -2751,7 +2743,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let remaining = db
|
let remaining = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let ingredients = ingredients.clone();
|
let ingredients = ingredients;
|
||||||
Box::pin(async move { ingredients.ingredients_for_meal(txn, meal.id).await })
|
Box::pin(async move { ingredients.ingredients_for_meal(txn, meal.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2766,7 +2758,7 @@ mod tests {
|
|||||||
let ingredients = SqliteMealIngredientRepository;
|
let ingredients = SqliteMealIngredientRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let ingredients = ingredients.clone();
|
let ingredients = ingredients;
|
||||||
Box::pin(async move { ingredients.delete_ingredient(txn, meal.id, 9999).await })
|
Box::pin(async move { ingredients.delete_ingredient(txn, meal.id, 9999).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -2781,7 +2773,7 @@ mod tests {
|
|||||||
let meal_id = meal.id;
|
let meal_id = meal.id;
|
||||||
let id = db
|
let id = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let list_meals = list_meals.clone();
|
let list_meals = list_meals;
|
||||||
Box::pin(
|
Box::pin(
|
||||||
async move { list_meals.add_meal(txn, list_id, Some(meal_id), name).await },
|
async move { list_meals.add_meal(txn, list_id, Some(meal_id), name).await },
|
||||||
)
|
)
|
||||||
@@ -2806,7 +2798,7 @@ mod tests {
|
|||||||
let list_meals = SqliteListMealRepository;
|
let list_meals = SqliteListMealRepository;
|
||||||
let meals = db
|
let meals = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let list_meals = list_meals.clone();
|
let list_meals = list_meals;
|
||||||
Box::pin(async move { list_meals.list_meals(txn, list.id).await })
|
Box::pin(async move { list_meals.list_meals(txn, list.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2829,7 +2821,7 @@ mod tests {
|
|||||||
let ingredients = SqliteMealIngredientRepository;
|
let ingredients = SqliteMealIngredientRepository;
|
||||||
let ingredient_rows = db
|
let ingredient_rows = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let ingredients = ingredients.clone();
|
let ingredients = ingredients;
|
||||||
Box::pin(async move { ingredients.ingredients_for_meal(txn, meal.id).await })
|
Box::pin(async move { ingredients.ingredients_for_meal(txn, meal.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2845,7 +2837,7 @@ mod tests {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let items = items.clone();
|
let items = items;
|
||||||
Box::pin(async move { items.add_items_bulk(txn, list.id, new_items).await })
|
Box::pin(async move { items.add_items_bulk(txn, list.id, new_items).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2855,7 +2847,7 @@ mod tests {
|
|||||||
let list_meals = SqliteListMealRepository;
|
let list_meals = SqliteListMealRepository;
|
||||||
let revision = db
|
let revision = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let list_meals = list_meals.clone();
|
let list_meals = list_meals;
|
||||||
Box::pin(async move { list_meals.remove_meal(txn, list.id, list_meal.id).await })
|
Box::pin(async move { list_meals.remove_meal(txn, list.id, list_meal.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2864,7 +2856,7 @@ mod tests {
|
|||||||
|
|
||||||
let meals = db
|
let meals = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let list_meals = list_meals.clone();
|
let list_meals = list_meals;
|
||||||
Box::pin(async move { list_meals.list_meals(txn, list.id).await })
|
Box::pin(async move { list_meals.list_meals(txn, list.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2880,7 +2872,7 @@ mod tests {
|
|||||||
let list_meals = SqliteListMealRepository;
|
let list_meals = SqliteListMealRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let list_meals = list_meals.clone();
|
let list_meals = list_meals;
|
||||||
Box::pin(async move { list_meals.remove_meal(txn, list.id, 9999).await })
|
Box::pin(async move { list_meals.remove_meal(txn, list.id, 9999).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -2899,7 +2891,7 @@ mod tests {
|
|||||||
let list_meals = SqliteListMealRepository;
|
let list_meals = SqliteListMealRepository;
|
||||||
let (copied, revision) = db
|
let (copied, revision) = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let list_meals = list_meals.clone();
|
let list_meals = list_meals;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
list_meals
|
list_meals
|
||||||
.copy_meals_to_list(txn, source.id, dest.id, &[list_meal.id])
|
.copy_meals_to_list(txn, source.id, dest.id, &[list_meal.id])
|
||||||
@@ -2919,7 +2911,7 @@ mod tests {
|
|||||||
// The source meal is untouched.
|
// The source meal is untouched.
|
||||||
let source_meals = db
|
let source_meals = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let list_meals = list_meals.clone();
|
let list_meals = list_meals;
|
||||||
Box::pin(async move { list_meals.list_meals(txn, source.id).await })
|
Box::pin(async move { list_meals.list_meals(txn, source.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2939,7 +2931,7 @@ mod tests {
|
|||||||
// becomes NULL.
|
// becomes NULL.
|
||||||
let meals = SqliteMealRepository;
|
let meals = SqliteMealRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let meals = meals.clone();
|
let meals = meals;
|
||||||
Box::pin(async move { meals.delete_meal(txn, meal.id).await })
|
Box::pin(async move { meals.delete_meal(txn, meal.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -2948,7 +2940,7 @@ mod tests {
|
|||||||
let list_meals = SqliteListMealRepository;
|
let list_meals = SqliteListMealRepository;
|
||||||
let (copied, _) = db
|
let (copied, _) = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let list_meals = list_meals.clone();
|
let list_meals = list_meals;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
list_meals
|
list_meals
|
||||||
.copy_meals_to_list(txn, source.id, dest.id, &[list_meal.id])
|
.copy_meals_to_list(txn, source.id, dest.id, &[list_meal.id])
|
||||||
@@ -2970,7 +2962,7 @@ mod tests {
|
|||||||
let list_meals = SqliteListMealRepository;
|
let list_meals = SqliteListMealRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let list_meals = list_meals.clone();
|
let list_meals = list_meals;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
list_meals
|
list_meals
|
||||||
.copy_meals_to_list(txn, source.id, dest.id, &[9999])
|
.copy_meals_to_list(txn, source.id, dest.id, &[9999])
|
||||||
@@ -2991,7 +2983,7 @@ mod tests {
|
|||||||
|
|
||||||
let created = db
|
let created = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let passkeys = passkeys.clone();
|
let passkeys = passkeys;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
passkeys
|
passkeys
|
||||||
.create_passkey(txn, user.id, "cred-1".into(), "{}".into(), 0)
|
.create_passkey(txn, user.id, "cred-1".into(), "{}".into(), 0)
|
||||||
@@ -3006,7 +2998,7 @@ mod tests {
|
|||||||
|
|
||||||
let found = db
|
let found = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let passkeys = passkeys.clone();
|
let passkeys = passkeys;
|
||||||
Box::pin(async move { passkeys.find_by_credential_id(txn, "cred-1".into()).await })
|
Box::pin(async move { passkeys.find_by_credential_id(txn, "cred-1".into()).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -3016,7 +3008,7 @@ mod tests {
|
|||||||
|
|
||||||
let listed = db
|
let listed = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let passkeys = passkeys.clone();
|
let passkeys = passkeys;
|
||||||
Box::pin(async move { passkeys.list_for_user(txn, user.id).await })
|
Box::pin(async move { passkeys.list_for_user(txn, user.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -3024,7 +3016,7 @@ mod tests {
|
|||||||
assert_eq!(listed.len(), 1);
|
assert_eq!(listed.len(), 1);
|
||||||
|
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let passkeys = passkeys.clone();
|
let passkeys = passkeys;
|
||||||
Box::pin(async move { passkeys.delete_passkey(txn, user.id, created.id).await })
|
Box::pin(async move { passkeys.delete_passkey(txn, user.id, created.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -3032,7 +3024,7 @@ mod tests {
|
|||||||
|
|
||||||
let after = db
|
let after = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let passkeys = passkeys.clone();
|
let passkeys = passkeys;
|
||||||
Box::pin(async move { passkeys.list_for_user(txn, user.id).await })
|
Box::pin(async move { passkeys.list_for_user(txn, user.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -3046,7 +3038,7 @@ mod tests {
|
|||||||
let user = create_user(&db, "alice@example.com").await;
|
let user = create_user(&db, "alice@example.com").await;
|
||||||
let passkeys = SqlitePasskeyRepository;
|
let passkeys = SqlitePasskeyRepository;
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let passkeys = passkeys.clone();
|
let passkeys = passkeys;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
passkeys
|
passkeys
|
||||||
.create_passkey(txn, user.id, "cred-1".into(), "{}".into(), 0)
|
.create_passkey(txn, user.id, "cred-1".into(), "{}".into(), 0)
|
||||||
@@ -3058,7 +3050,7 @@ mod tests {
|
|||||||
|
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let passkeys = passkeys.clone();
|
let passkeys = passkeys;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
passkeys
|
passkeys
|
||||||
.create_passkey(txn, user.id, "cred-1".into(), "{}".into(), 0)
|
.create_passkey(txn, user.id, "cred-1".into(), "{}".into(), 0)
|
||||||
@@ -3076,7 +3068,7 @@ mod tests {
|
|||||||
let passkeys = SqlitePasskeyRepository;
|
let passkeys = SqlitePasskeyRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let passkeys = passkeys.clone();
|
let passkeys = passkeys;
|
||||||
Box::pin(async move { passkeys.delete_passkey(txn, user.id, 9999).await })
|
Box::pin(async move { passkeys.delete_passkey(txn, user.id, 9999).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -3093,7 +3085,7 @@ mod tests {
|
|||||||
|
|
||||||
let created = db
|
let created = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
cards
|
cards
|
||||||
.create_card(
|
.create_card(
|
||||||
@@ -3116,7 +3108,7 @@ mod tests {
|
|||||||
|
|
||||||
let listed = db
|
let listed = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move { cards.list_cards(txn, user.id).await })
|
Box::pin(async move { cards.list_cards(txn, user.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -3125,7 +3117,7 @@ mod tests {
|
|||||||
assert_eq!(listed[0].id, created.id);
|
assert_eq!(listed[0].id, created.id);
|
||||||
|
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move { cards.delete_card(txn, user.id, created.id).await })
|
Box::pin(async move { cards.delete_card(txn, user.id, created.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -3133,7 +3125,7 @@ mod tests {
|
|||||||
|
|
||||||
let after = db
|
let after = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move { cards.list_cards(txn, user.id).await })
|
Box::pin(async move { cards.list_cards(txn, user.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -3149,7 +3141,7 @@ mod tests {
|
|||||||
let cards = SqliteRewardsCardRepository;
|
let cards = SqliteRewardsCardRepository;
|
||||||
|
|
||||||
db.run(move |txn| {
|
db.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
cards
|
cards
|
||||||
.create_card(
|
.create_card(
|
||||||
@@ -3167,7 +3159,7 @@ mod tests {
|
|||||||
|
|
||||||
let bobs = db
|
let bobs = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move { cards.list_cards(txn, bob.id).await })
|
Box::pin(async move { cards.list_cards(txn, bob.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -3177,7 +3169,7 @@ mod tests {
|
|||||||
// Bob cannot delete Alice's card.
|
// Bob cannot delete Alice's card.
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move { cards.delete_card(txn, bob.id, 1).await })
|
Box::pin(async move { cards.delete_card(txn, bob.id, 1).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -3191,7 +3183,7 @@ mod tests {
|
|||||||
let cards = SqliteRewardsCardRepository;
|
let cards = SqliteRewardsCardRepository;
|
||||||
let result = db
|
let result = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move { cards.delete_card(txn, user.id, 9999).await })
|
Box::pin(async move { cards.delete_card(txn, user.id, 9999).await })
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -3207,7 +3199,7 @@ mod tests {
|
|||||||
|
|
||||||
let created = db
|
let created = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
cards
|
cards
|
||||||
.create_card(
|
.create_card(
|
||||||
@@ -3226,7 +3218,7 @@ mod tests {
|
|||||||
// The owner can fetch their card.
|
// The owner can fetch their card.
|
||||||
let found = db
|
let found = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move { cards.get_card(txn, alice.id, created.id).await })
|
Box::pin(async move { cards.get_card(txn, alice.id, created.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -3237,7 +3229,7 @@ mod tests {
|
|||||||
// Another user cannot fetch it.
|
// Another user cannot fetch it.
|
||||||
let not_found = db
|
let not_found = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move { cards.get_card(txn, bob.id, created.id).await })
|
Box::pin(async move { cards.get_card(txn, bob.id, created.id).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@@ -3247,7 +3239,7 @@ mod tests {
|
|||||||
// A missing id returns None.
|
// A missing id returns None.
|
||||||
let missing = db
|
let missing = db
|
||||||
.run(move |txn| {
|
.run(move |txn| {
|
||||||
let cards = cards.clone();
|
let cards = cards;
|
||||||
Box::pin(async move { cards.get_card(txn, alice.id, 9999).await })
|
Box::pin(async move { cards.get_card(txn, alice.id, 9999).await })
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
|||||||
+112
-112
@@ -802,116 +802,6 @@ fn render_markdown(source: &str) -> Markup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
/// Extracts the rendered SVG width from `viewBox="0 0 <width> <height>"`.
|
|
||||||
fn svg_width(svg: &str) -> u32 {
|
|
||||||
let viewbox = svg
|
|
||||||
.split("viewBox=\"")
|
|
||||||
.nth(1)
|
|
||||||
.expect("expected viewBox")
|
|
||||||
.split('"')
|
|
||||||
.next()
|
|
||||||
.unwrap();
|
|
||||||
let width = viewbox.split_whitespace().nth(2).expect("expected width");
|
|
||||||
width.parse().expect("expected numeric width")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn render_markdown_turns_bullets_into_list_html() {
|
|
||||||
let html = render_markdown("- one\n- two\n").into_string();
|
|
||||||
assert!(html.contains("<ul>"), "expected <ul>, got: {html}");
|
|
||||||
assert!(html.contains("<li>"), "expected <li>, got: {html}");
|
|
||||||
assert!(!html.contains("* one"), "raw bullet leaked through: {html}");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn render_markdown_renders_emphasis() {
|
|
||||||
let html = render_markdown("**bold** and *italic*").into_string();
|
|
||||||
assert!(html.contains("<strong>"), "expected <strong>, got: {html}");
|
|
||||||
assert!(html.contains("<em>"), "expected <em>, got: {html}");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn format_date_renders_human_readable_date() {
|
|
||||||
// 2026-08-07T00:00:00Z in Unix seconds.
|
|
||||||
let ts = 1_786_060_800;
|
|
||||||
assert_eq!(format_date(ts), "7 Aug 2026");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn barcode_svg_renders_code128_svg() {
|
|
||||||
let html = barcode_svg("code128", "601123456789").into_string();
|
|
||||||
assert!(html.contains("<svg"), "expected svg, got: {html}");
|
|
||||||
assert!(html.contains("</svg>"), "expected closing svg, got: {html}");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn code128_uses_set_c_for_even_digit_numbers() {
|
|
||||||
// Set C (Ć) packs two digits per symbol, so an even-length digit-only
|
|
||||||
// number should be encoded with set C rather than set B.
|
|
||||||
assert_eq!(code128_input("601123456789"), "Ć601123456789");
|
|
||||||
// Non-numeric data falls back to set B.
|
|
||||||
assert_eq!(code128_input("ABC123"), "ƁABC123");
|
|
||||||
assert_eq!(code128_input(""), "Ɓ");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn code128_odd_digit_numbers_lead_with_set_b_then_switch_to_set_c() {
|
|
||||||
// 21-digit number: first digit in set B, then set C for the rest.
|
|
||||||
assert_eq!(
|
|
||||||
code128_input("606171584511340224537"),
|
|
||||||
"Ɓ6Ć06171584511340224537"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn code128_set_c_renders_shorter_than_set_b() {
|
|
||||||
let number = "601123456789";
|
|
||||||
let set_c = barcode_svg("code128", number).into_string();
|
|
||||||
// Force set B by using a non-numeric character so the digit-only
|
|
||||||
// fast path doesn't kick in.
|
|
||||||
let set_b = barcode_svg("code128", &format!("{number} ")).into_string();
|
|
||||||
let width_c = svg_width(&set_c);
|
|
||||||
let width_b = svg_width(&set_b);
|
|
||||||
assert!(
|
|
||||||
width_c < width_b,
|
|
||||||
"expected set C ({width_c}) narrower than set B ({width_b})"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn code128_odd_digit_number_renders_shorter_than_pure_set_b() {
|
|
||||||
let number = "606171584511340224537";
|
|
||||||
let mixed = barcode_svg("code128", number).into_string();
|
|
||||||
// Force pure set B by appending a non-numeric character.
|
|
||||||
let set_b = barcode_svg("code128", &format!("{number} ")).into_string();
|
|
||||||
let width_mixed = svg_width(&mixed);
|
|
||||||
let width_b = svg_width(&set_b);
|
|
||||||
assert!(
|
|
||||||
width_mixed < width_b,
|
|
||||||
"expected mixed ({width_mixed}) narrower than set B ({width_b})"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn barcode_svg_renders_code39_svg() {
|
|
||||||
let html = barcode_svg("code39", "ABC123").into_string();
|
|
||||||
assert!(html.contains("<svg"), "expected svg, got: {html}");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn barcode_svg_falls_back_to_text_for_invalid_number() {
|
|
||||||
// Code 39 only supports uppercase letters and digits, so lowercase
|
|
||||||
// input cannot be encoded and falls back to plain text.
|
|
||||||
let html = barcode_svg("code39", "abc").into_string();
|
|
||||||
assert!(!html.contains("<svg"), "expected no svg, got: {html}");
|
|
||||||
assert!(html.contains("abc"), "expected fallback text, got: {html}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn list_page(
|
pub fn list_page(
|
||||||
user: &User,
|
user: &User,
|
||||||
list: &GroceryList,
|
list: &GroceryList,
|
||||||
@@ -1596,7 +1486,7 @@ fn barcode_svg(symbology: &str, number: &str) -> Markup {
|
|||||||
.generate(&encoded)
|
.generate(&encoded)
|
||||||
.ok()
|
.ok()
|
||||||
}),
|
}),
|
||||||
_ => barcoders::sym::code128::Code128::new(&code128_input(number))
|
_ => barcoders::sym::code128::Code128::new(code128_input(number))
|
||||||
.ok()
|
.ok()
|
||||||
.map(|code| code.encode())
|
.map(|code| code.encode())
|
||||||
.and_then(|encoded| {
|
.and_then(|encoded| {
|
||||||
@@ -1628,7 +1518,7 @@ fn code128_input(number: &str) -> String {
|
|||||||
return format!("Ɓ{number}");
|
return format!("Ɓ{number}");
|
||||||
}
|
}
|
||||||
let len = number.chars().count();
|
let len = number.chars().count();
|
||||||
if len % 2 == 0 {
|
if len.is_multiple_of(2) {
|
||||||
format!("Ć{number}")
|
format!("Ć{number}")
|
||||||
} else {
|
} else {
|
||||||
let (first, rest) = number.split_at(1);
|
let (first, rest) = number.split_at(1);
|
||||||
@@ -1723,3 +1613,113 @@ fn initials(name: &str) -> String {
|
|||||||
.collect::<String>()
|
.collect::<String>()
|
||||||
.to_uppercase()
|
.to_uppercase()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// Extracts the rendered SVG width from `viewBox="0 0 <width> <height>"`.
|
||||||
|
fn svg_width(svg: &str) -> u32 {
|
||||||
|
let viewbox = svg
|
||||||
|
.split("viewBox=\"")
|
||||||
|
.nth(1)
|
||||||
|
.expect("expected viewBox")
|
||||||
|
.split('"')
|
||||||
|
.next()
|
||||||
|
.unwrap();
|
||||||
|
let width = viewbox.split_whitespace().nth(2).expect("expected width");
|
||||||
|
width.parse().expect("expected numeric width")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn render_markdown_turns_bullets_into_list_html() {
|
||||||
|
let html = render_markdown("- one\n- two\n").into_string();
|
||||||
|
assert!(html.contains("<ul>"), "expected <ul>, got: {html}");
|
||||||
|
assert!(html.contains("<li>"), "expected <li>, got: {html}");
|
||||||
|
assert!(!html.contains("* one"), "raw bullet leaked through: {html}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn render_markdown_renders_emphasis() {
|
||||||
|
let html = render_markdown("**bold** and *italic*").into_string();
|
||||||
|
assert!(html.contains("<strong>"), "expected <strong>, got: {html}");
|
||||||
|
assert!(html.contains("<em>"), "expected <em>, got: {html}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn format_date_renders_human_readable_date() {
|
||||||
|
// 2026-08-07T00:00:00Z in Unix seconds.
|
||||||
|
let ts = 1_786_060_800;
|
||||||
|
assert_eq!(format_date(ts), "7 Aug 2026");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn barcode_svg_renders_code128_svg() {
|
||||||
|
let html = barcode_svg("code128", "601123456789").into_string();
|
||||||
|
assert!(html.contains("<svg"), "expected svg, got: {html}");
|
||||||
|
assert!(html.contains("</svg>"), "expected closing svg, got: {html}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn code128_uses_set_c_for_even_digit_numbers() {
|
||||||
|
// Set C (Ć) packs two digits per symbol, so an even-length digit-only
|
||||||
|
// number should be encoded with set C rather than set B.
|
||||||
|
assert_eq!(code128_input("601123456789"), "Ć601123456789");
|
||||||
|
// Non-numeric data falls back to set B.
|
||||||
|
assert_eq!(code128_input("ABC123"), "ƁABC123");
|
||||||
|
assert_eq!(code128_input(""), "Ɓ");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn code128_odd_digit_numbers_lead_with_set_b_then_switch_to_set_c() {
|
||||||
|
// 21-digit number: first digit in set B, then set C for the rest.
|
||||||
|
assert_eq!(
|
||||||
|
code128_input("606171584511340224537"),
|
||||||
|
"Ɓ6Ć06171584511340224537"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn code128_set_c_renders_shorter_than_set_b() {
|
||||||
|
let number = "601123456789";
|
||||||
|
let set_c = barcode_svg("code128", number).into_string();
|
||||||
|
// Force set B by using a non-numeric character so the digit-only
|
||||||
|
// fast path doesn't kick in.
|
||||||
|
let set_b = barcode_svg("code128", &format!("{number} ")).into_string();
|
||||||
|
let width_c = svg_width(&set_c);
|
||||||
|
let width_b = svg_width(&set_b);
|
||||||
|
assert!(
|
||||||
|
width_c < width_b,
|
||||||
|
"expected set C ({width_c}) narrower than set B ({width_b})"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn code128_odd_digit_number_renders_shorter_than_pure_set_b() {
|
||||||
|
let number = "606171584511340224537";
|
||||||
|
let mixed = barcode_svg("code128", number).into_string();
|
||||||
|
// Force pure set B by appending a non-numeric character.
|
||||||
|
let set_b = barcode_svg("code128", &format!("{number} ")).into_string();
|
||||||
|
let width_mixed = svg_width(&mixed);
|
||||||
|
let width_b = svg_width(&set_b);
|
||||||
|
assert!(
|
||||||
|
width_mixed < width_b,
|
||||||
|
"expected mixed ({width_mixed}) narrower than set B ({width_b})"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn barcode_svg_renders_code39_svg() {
|
||||||
|
let html = barcode_svg("code39", "ABC123").into_string();
|
||||||
|
assert!(html.contains("<svg"), "expected svg, got: {html}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn barcode_svg_falls_back_to_text_for_invalid_number() {
|
||||||
|
// Code 39 only supports uppercase letters and digits, so lowercase
|
||||||
|
// input cannot be encoded and falls back to plain text.
|
||||||
|
let html = barcode_svg("code39", "abc").into_string();
|
||||||
|
assert!(!html.contains("<svg"), "expected no svg, got: {html}");
|
||||||
|
assert!(html.contains("abc"), "expected fallback text, got: {html}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user