Skip to content

Commit 6f2159e

Browse files
committed
Add test for normalized front matter
1 parent ab98793 commit 6f2159e

File tree

2 files changed

+80
-3
lines changed

2 files changed

+80
-3
lines changed

front_matter/src/lib.rs

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ use serde::{Deserialize, Serialize};
44
/// The front matter of a markdown blog post.
55
#[derive(Debug, PartialEq, Serialize, Deserialize)]
66
pub struct FrontMatter {
7+
pub layout: String,
78
pub title: String,
89
pub author: String,
9-
#[serde(default)]
10-
pub release: bool,
10+
pub description: Option<String>,
1111
pub team: Option<String>,
12-
pub layout: String,
12+
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
13+
pub release: bool,
1314
}
1415

1516
/// Extracts the front matter from a markdown file.
@@ -27,3 +28,78 @@ pub fn parse(markdown: &str) -> eyre::Result<(FrontMatter, &str)> {
2728

2829
Ok((toml::from_str(front_matter)?, content))
2930
}
31+
32+
/// Normalizes the front matter of a markdown file.
33+
pub fn normalize(markdown: &str) -> eyre::Result<String> {
34+
let (front_matter, content) = parse(markdown)?;
35+
36+
Ok(format!(
37+
"\
38+
+++
39+
{}\
40+
+++
41+
{content}",
42+
toml::to_string_pretty(&front_matter)?
43+
))
44+
}
45+
46+
#[cfg(test)]
47+
mod tests {
48+
use std::{env, fs, path::PathBuf};
49+
50+
use super::*;
51+
52+
#[test]
53+
fn front_matter_is_normalized() {
54+
let repo_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..");
55+
56+
let posts = fs::read_dir(repo_root.join("posts"))
57+
.unwrap()
58+
.chain(fs::read_dir(repo_root.join("posts/inside-rust")).unwrap())
59+
.map(|p| p.unwrap().path())
60+
.filter(|p| p.extension() == Some("md".as_ref()));
61+
62+
for post in posts {
63+
let content = fs::read_to_string(&post).unwrap();
64+
let normalized = normalize(&content).unwrap();
65+
66+
if content != normalized {
67+
if env::var("FIX_FRONT_MATTER").is_ok() {
68+
fs::write(post, normalized).unwrap();
69+
continue;
70+
}
71+
72+
let post = post.file_name().unwrap().to_str().unwrap();
73+
let actual = content
74+
.rsplit_once("+++")
75+
.map(|(f, _)| format!("{f}+++"))
76+
.unwrap_or(content);
77+
let expected = normalized
78+
.rsplit_once("+++")
79+
.map(|(f, _)| format!("{f}+++"))
80+
.unwrap_or(normalized);
81+
82+
// better error message than assert_eq!()
83+
panic!(
84+
"
85+
The post {post} has abnormal front matter.
86+
87+
actual:
88+
{actual}
89+
90+
expected:
91+
{expected}
92+
93+
┌──────────────────────────────────────────────────────────────────────────┐
94+
│ │
95+
│ You can fix this automatically by running: │
96+
│ │
97+
│ FIX_FRONT_MATTER=1 cargo test --all front_matter_is_normalized │
98+
│ │
99+
└──────────────────────────────────────────────────────────────────────────┘
100+
",
101+
)
102+
};
103+
}
104+
}
105+
}

src/posts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ impl Post {
5050
release,
5151
team: team_string,
5252
layout,
53+
..
5354
},
5455
contents,
5556
) = front_matter::parse(&contents)?;

0 commit comments

Comments
 (0)