Skip to content

Commit 72f9a1f

Browse files
committed
template macro: generate function for all checks
1 parent 4af582a commit 72f9a1f

File tree

2 files changed

+39
-45
lines changed

2 files changed

+39
-45
lines changed

crates/templates/src/lib.rs

Lines changed: 14 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99

1010
//! Templates rendering
1111
12-
use std::{collections::HashSet, sync::Arc};
12+
use std::{
13+
collections::{BTreeMap, HashSet},
14+
sync::Arc,
15+
};
1316

1417
use anyhow::Context as _;
1518
use arc_swap::ArcSwap;
@@ -383,7 +386,7 @@ register_templates! {
383386
pub fn render_recovery_disabled(WithLanguage<EmptyContext>) { "pages/recovery/disabled.html" }
384387

385388
/// Render the form used by the `form_post` response mode
386-
pub fn render_form_post<T: Serialize>(WithLanguage<FormPostContext<T>>) { "form_post.html" }
389+
pub fn render_form_post<#[sample(EmptyContext)] T: Serialize>(WithLanguage<FormPostContext<T>>) { "form_post.html" }
387390

388391
/// Render the HTML error page
389392
pub fn render_error(ErrorContext) { "pages/error.html" }
@@ -439,7 +442,13 @@ register_templates! {
439442

440443
impl Templates {
441444
/// Render all templates with the generated samples to check if they render
442-
/// properly
445+
/// properly.
446+
///
447+
/// Returns the renders in a map whose keys are template names
448+
/// and the values are lists of renders (according to the list
449+
/// of samples).
450+
/// Samples are stable across re-runs and can be used for
451+
/// acceptance testing.
443452
///
444453
/// # Errors
445454
///
@@ -448,47 +457,8 @@ impl Templates {
448457
&self,
449458
now: chrono::DateTime<chrono::Utc>,
450459
rng: &mut impl Rng,
451-
) -> anyhow::Result<()> {
452-
check::render_not_found(self, now, rng)?;
453-
check::render_app(self, now, rng)?;
454-
check::render_swagger(self, now, rng)?;
455-
check::render_swagger_callback(self, now, rng)?;
456-
check::render_login(self, now, rng)?;
457-
check::render_register(self, now, rng)?;
458-
check::render_password_register(self, now, rng)?;
459-
check::render_register_steps_verify_email(self, now, rng)?;
460-
check::render_register_steps_email_in_use(self, now, rng)?;
461-
check::render_register_steps_display_name(self, now, rng)?;
462-
check::render_register_steps_registration_token(self, now, rng)?;
463-
check::render_consent(self, now, rng)?;
464-
check::render_policy_violation(self, now, rng)?;
465-
check::render_sso_login(self, now, rng)?;
466-
check::render_index(self, now, rng)?;
467-
check::render_recovery_start(self, now, rng)?;
468-
check::render_recovery_progress(self, now, rng)?;
469-
check::render_recovery_finish(self, now, rng)?;
470-
check::render_recovery_expired(self, now, rng)?;
471-
check::render_recovery_consumed(self, now, rng)?;
472-
check::render_recovery_disabled(self, now, rng)?;
473-
check::render_form_post::<EmptyContext>(self, now, rng)?;
474-
check::render_error(self, now, rng)?;
475-
check::render_email_recovery_txt(self, now, rng)?;
476-
check::render_email_recovery_html(self, now, rng)?;
477-
check::render_email_recovery_subject(self, now, rng)?;
478-
check::render_email_verification_txt(self, now, rng)?;
479-
check::render_email_verification_html(self, now, rng)?;
480-
check::render_email_verification_subject(self, now, rng)?;
481-
check::render_upstream_oauth2_link_mismatch(self, now, rng)?;
482-
check::render_upstream_oauth2_login_link(self, now, rng)?;
483-
check::render_upstream_oauth2_suggest_link(self, now, rng)?;
484-
check::render_upstream_oauth2_do_register(self, now, rng)?;
485-
check::render_device_link(self, now, rng)?;
486-
check::render_device_consent(self, now, rng)?;
487-
check::render_account_deactivated(self, now, rng)?;
488-
check::render_account_locked(self, now, rng)?;
489-
check::render_account_logged_out(self, now, rng)?;
490-
check::render_device_name(self, now, rng)?;
491-
Ok(())
460+
) -> anyhow::Result<BTreeMap<&'static str, Vec<String>>> {
461+
check::all(self, now, rng)
492462
}
493463
}
494464

crates/templates/src/macros.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ macro_rules! register_templates {
3131
pub fn $name:ident
3232
// Optional list of generics. Taken from
3333
// https://newbedev.com/rust-macro-accepting-type-with-generic-parameters
34-
$(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
34+
// For sample rendering, we also require a 'sample' generic parameter to be provided,
35+
// using #[sample(Type)] attribute syntax
36+
$(< $( #[sample( $generic_default:tt )] $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
3537
// Type of context taken by the template
3638
( $param:ty )
3739
{
@@ -69,9 +71,31 @@ macro_rules! register_templates {
6971
pub mod check {
7072
use super::*;
7173

74+
/// Check and render all templates with all samples.
75+
///
76+
/// Returns the sample renders. The keys in the map are the template names.
77+
///
78+
/// # Errors
79+
///
80+
/// Returns an error if any template fails to render with any of the sample.
81+
pub(crate) fn all(templates: &Templates, now: chrono::DateTime<chrono::Utc>, rng: &mut impl rand::Rng) -> anyhow::Result<::std::collections::BTreeMap<&'static str, Vec<String>>> {
82+
let mut out = ::std::collections::BTreeMap::new();
83+
// TODO shouldn't the Rng be independent for each render?
84+
$(
85+
out.insert(
86+
$template,
87+
$name $(::< $( $generic_default ),* >)? (templates, now, rng)?
88+
);
89+
)*
90+
91+
Ok(out)
92+
}
93+
7294
$(
7395
#[doc = concat!("Render the `", $template, "` template with sample contexts")]
7496
///
97+
/// Returns the sample renders.
98+
///
7599
/// # Errors
76100
///
77101
/// Returns an error if the template fails to render with any of the sample.

0 commit comments

Comments
 (0)