Start adding some tests for building multilingual sites

This commit is contained in:
Vincent Prouillet 2018-12-28 17:30:47 +01:00
parent 779511ae43
commit 7313b41f4d
5 changed files with 176 additions and 157 deletions

View file

@ -861,6 +861,11 @@ impl Site {
pub fn render_section(&self, section: &Section, render_pages: bool) -> Result<()> { pub fn render_section(&self, section: &Section, render_pages: bool) -> Result<()> {
ensure_directory_exists(&self.output_path)?; ensure_directory_exists(&self.output_path)?;
let mut output_path = self.output_path.clone(); let mut output_path = self.output_path.clone();
if let Some(ref lang) = section.lang {
output_path.push(lang);
}
for component in &section.file.components { for component in &section.file.components {
output_path.push(component); output_path.push(component);

View file

@ -0,0 +1,66 @@
extern crate tempfile;
extern crate site;
use std::env;
use std::path::PathBuf;
use self::site::Site;
use self::tempfile::{tempdir, TempDir};
// 2 helper macros to make all the build testing more bearable
#[macro_export]
macro_rules! file_exists {
($root: expr, $path: expr) => {{
let mut path = $root.clone();
for component in $path.split("/") {
path = path.join(component);
}
std::path::Path::new(&path).exists()
}};
}
#[macro_export]
macro_rules! file_contains {
($root: expr, $path: expr, $text: expr) => {{
use std::io::prelude::*;
let mut path = $root.clone();
for component in $path.split("/") {
path = path.join(component);
}
let mut file = std::fs::File::open(&path).unwrap();
let mut s = String::new();
file.read_to_string(&mut s).unwrap();
println!("{}", s);
s.contains($text)
}};
}
/// We return the tmpdir otherwise it would get out of scope and be deleted
/// The tests can ignore it if they dont need it by prefixing it with a `_`
pub fn build_site(name: &str) -> (Site, TempDir, PathBuf) {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf();
path.push(name);
let mut site = Site::new(&path, "config.toml").unwrap();
site.load().unwrap();
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.build().unwrap();
(site, tmp_dir, public.clone())
}
/// Same as `build_site` but has a hook to setup some config options
pub fn build_site_with_setup<F>(name: &str, mut setup_cb: F) -> (Site, TempDir, PathBuf) where F: FnMut(Site) -> (Site, bool) {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf();
path.push(name);
let site = Site::new(&path, "config.toml").unwrap();
let (mut site, needs_loading) = setup_cb(site);
if needs_loading {
site.load().unwrap();
}
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.build().unwrap();
(site, tmp_dir, public.clone())
}

View file

@ -1,16 +1,14 @@
extern crate config; extern crate config;
extern crate site; extern crate site;
extern crate tempfile; mod common;
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path; use std::path::Path;
use config::Taxonomy; use config::Taxonomy;
use site::Site; use site::Site;
use tempfile::tempdir; use common::{build_site, build_site_with_setup};
#[test] #[test]
fn can_parse_site() { fn can_parse_site() {
@ -92,41 +90,9 @@ fn can_parse_site() {
assert_eq!(prog_section.pages.len(), 2); assert_eq!(prog_section.pages.len(), 2);
} }
// 2 helper macros to make all the build testing more bearable
macro_rules! file_exists {
($root: expr, $path: expr) => {{
let mut path = $root.clone();
for component in $path.split("/") {
path = path.join(component);
}
Path::new(&path).exists()
}};
}
macro_rules! file_contains {
($root: expr, $path: expr, $text: expr) => {{
let mut path = $root.clone();
for component in $path.split("/") {
path = path.join(component);
}
let mut file = File::open(&path).unwrap();
let mut s = String::new();
file.read_to_string(&mut s).unwrap();
println!("{}", s);
s.contains($text)
}};
}
#[test] #[test]
fn can_build_site_without_live_reload() { fn can_build_site_without_live_reload() {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); let (_, _tmp_dir, public) = build_site("test_site");
path.push("test_site");
let mut site = Site::new(&path, "config.toml").unwrap();
site.load().unwrap();
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.build().unwrap();
assert!(&public.exists()); assert!(&public.exists());
assert!(file_exists!(public, "index.html")); assert!(file_exists!(public, "index.html"));
@ -222,17 +188,12 @@ fn can_build_site_without_live_reload() {
#[test] #[test]
fn can_build_site_with_live_reload() { fn can_build_site_with_live_reload() {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
path.push("test_site"); site.enable_live_reload(1000);
let mut site = Site::new(&path, "config.toml").unwrap(); (site, true)
site.load().unwrap(); });
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.enable_live_reload(1000);
site.build().unwrap();
assert!(Path::new(&public).exists()); assert!(&public.exists());
assert!(file_exists!(public, "index.html")); assert!(file_exists!(public, "index.html"));
assert!(file_exists!(public, "sitemap.xml")); assert!(file_exists!(public, "sitemap.xml"));
@ -271,28 +232,23 @@ fn can_build_site_with_live_reload() {
#[test] #[test]
fn can_build_site_with_taxonomies() { fn can_build_site_with_taxonomies() {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); let (site, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
path.push("test_site"); site.load().unwrap();
let mut site = Site::new(&path, "config.toml").unwrap(); for (i, (_, page)) in site.library.pages_mut().iter_mut().enumerate() {
site.load().unwrap(); page.meta.taxonomies = {
let mut taxonomies = HashMap::new();
taxonomies.insert(
"categories".to_string(),
vec![if i % 2 == 0 { "A" } else { "B" }.to_string()],
);
taxonomies
};
}
site.populate_taxonomies().unwrap();
(site, false)
});
for (i, (_, page)) in site.library.pages_mut().iter_mut().enumerate() { assert!(&public.exists());
page.meta.taxonomies = {
let mut taxonomies = HashMap::new();
taxonomies.insert(
"categories".to_string(),
vec![if i % 2 == 0 { "A" } else { "B" }.to_string()],
);
taxonomies
};
}
site.populate_taxonomies().unwrap();
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.build().unwrap();
assert!(Path::new(&public).exists());
assert_eq!(site.taxonomies.len(), 1); assert_eq!(site.taxonomies.len(), 1);
assert!(file_exists!(public, "index.html")); assert!(file_exists!(public, "index.html"));
@ -340,15 +296,7 @@ fn can_build_site_with_taxonomies() {
#[test] #[test]
fn can_build_site_and_insert_anchor_links() { fn can_build_site_and_insert_anchor_links() {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); let (_, _tmp_dir, public) = build_site("test_site");
path.push("test_site");
let mut site = Site::new(&path, "config.toml").unwrap();
site.load().unwrap();
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.build().unwrap();
assert!(Path::new(&public).exists()); assert!(Path::new(&public).exists());
// anchor link inserted // anchor link inserted
@ -361,23 +309,19 @@ fn can_build_site_and_insert_anchor_links() {
#[test] #[test]
fn can_build_site_with_pagination_for_section() { fn can_build_site_with_pagination_for_section() {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
path.push("test_site"); site.load().unwrap();
let mut site = Site::new(&path, "config.toml").unwrap(); for (_, section) in site.library.sections_mut() {
site.load().unwrap(); if section.is_index() {
for (_, section) in site.library.sections_mut() { continue;
if section.is_index() { }
continue; section.meta.paginate_by = Some(2);
section.meta.template = Some("section_paginated.html".to_string());
} }
section.meta.paginate_by = Some(2); (site, false)
section.meta.template = Some("section_paginated.html".to_string()); });
}
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.build().unwrap();
assert!(Path::new(&public).exists()); assert!(&public.exists());
assert!(file_exists!(public, "index.html")); assert!(file_exists!(public, "index.html"));
assert!(file_exists!(public, "sitemap.xml")); assert!(file_exists!(public, "sitemap.xml"));
@ -478,21 +422,17 @@ fn can_build_site_with_pagination_for_section() {
#[test] #[test]
fn can_build_site_with_pagination_for_index() { fn can_build_site_with_pagination_for_index() {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
path.push("test_site"); site.load().unwrap();
let mut site = Site::new(&path, "config.toml").unwrap(); {
site.load().unwrap(); let index = site.library.get_section_mut(&site.base_path.join("content").join("_index.md")).unwrap();
{ index.meta.paginate_by = Some(2);
let index = site.library.get_section_mut(&path.join("content").join("_index.md")).unwrap(); index.meta.template = Some("index_paginated.html".to_string());
index.meta.paginate_by = Some(2); }
index.meta.template = Some("index_paginated.html".to_string()); (site, false)
} });
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.build().unwrap();
assert!(Path::new(&public).exists()); assert!(&public.exists());
assert!(file_exists!(public, "index.html")); assert!(file_exists!(public, "index.html"));
assert!(file_exists!(public, "sitemap.xml")); assert!(file_exists!(public, "sitemap.xml"));
@ -530,33 +470,28 @@ fn can_build_site_with_pagination_for_index() {
#[test] #[test]
fn can_build_site_with_pagination_for_taxonomy() { fn can_build_site_with_pagination_for_taxonomy() {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
path.push("test_site"); site.config.taxonomies.push(Taxonomy {
let mut site = Site::new(&path, "config.toml").unwrap(); name: "tags".to_string(),
site.config.taxonomies.push(Taxonomy { paginate_by: Some(2),
name: "tags".to_string(), paginate_path: None,
paginate_by: Some(2), rss: true,
paginate_path: None, });
rss: true, site.load().unwrap();
for (i, (_, page)) in site.library.pages_mut().iter_mut().enumerate() {
page.meta.taxonomies = {
let mut taxonomies = HashMap::new();
taxonomies
.insert("tags".to_string(), vec![if i % 2 == 0 { "A" } else { "B" }.to_string()]);
taxonomies
};
}
site.populate_taxonomies().unwrap();
(site, false)
}); });
site.load().unwrap();
for (i, (_, page)) in site.library.pages_mut().iter_mut().enumerate() { assert!(&public.exists());
page.meta.taxonomies = {
let mut taxonomies = HashMap::new();
taxonomies
.insert("tags".to_string(), vec![if i % 2 == 0 { "A" } else { "B" }.to_string()]);
taxonomies
};
}
site.populate_taxonomies().unwrap();
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.build().unwrap();
assert!(Path::new(&public).exists());
assert!(file_exists!(public, "index.html")); assert!(file_exists!(public, "index.html"));
assert!(file_exists!(public, "sitemap.xml")); assert!(file_exists!(public, "sitemap.xml"));
@ -610,16 +545,9 @@ fn can_build_site_with_pagination_for_taxonomy() {
#[test] #[test]
fn can_build_rss_feed() { fn can_build_rss_feed() {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); let (_, _tmp_dir, public) = build_site("test_site");
path.push("test_site");
let mut site = Site::new(&path, "config.toml").unwrap();
site.load().unwrap();
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.build().unwrap();
assert!(Path::new(&public).exists()); assert!(&public.exists());
assert!(file_exists!(public, "rss.xml")); assert!(file_exists!(public, "rss.xml"));
// latest article is posts/extra-syntax.md // latest article is posts/extra-syntax.md
assert!(file_contains!(public, "rss.xml", "Extra Syntax")); assert!(file_contains!(public, "rss.xml", "Extra Syntax"));
@ -629,15 +557,10 @@ fn can_build_rss_feed() {
#[test] #[test]
fn can_build_search_index() { fn can_build_search_index() {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
path.push("test_site"); site.config.build_search_index = true;
let mut site = Site::new(&path, "config.toml").unwrap(); (site, true)
site.load().unwrap(); });
site.config.build_search_index = true;
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.build().unwrap();
assert!(Path::new(&public).exists()); assert!(Path::new(&public).exists());
assert!(file_exists!(public, "elasticlunr.min.js")); assert!(file_exists!(public, "elasticlunr.min.js"));
@ -646,14 +569,7 @@ fn can_build_search_index() {
#[test] #[test]
fn can_build_with_extra_syntaxes() { fn can_build_with_extra_syntaxes() {
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); let (_, _tmp_dir, public) = build_site("test_site");
path.push("test_site");
let mut site = Site::new(&path, "config.toml").unwrap();
site.load().unwrap();
let tmp_dir = tempdir().expect("create temp dir");
let public = &tmp_dir.path().join("public");
site.set_output_path(&public);
site.build().unwrap();
assert!(&public.exists()); assert!(&public.exists());
assert!(file_exists!(public, "posts/extra-syntax/index.html")); assert!(file_exists!(public, "posts/extra-syntax/index.html"));

View file

@ -1,8 +1,10 @@
extern crate site; extern crate site;
mod common;
use std::env; use std::env;
use site::Site; use site::Site;
use common::build_site;
#[test] #[test]
fn can_parse_multilingual_site() { fn can_parse_multilingual_site() {
@ -44,3 +46,29 @@ fn can_parse_multilingual_site() {
assert_eq!(page.lang, Some("fr".to_string())); assert_eq!(page.lang, Some("fr".to_string()));
} }
} }
#[test]
fn can_build_multilingual_site() {
let (_, _tmp_dir, public) = build_site("test_site_i18n");
assert!(public.exists());
// Index pages
assert!(file_exists!(public, "index.html"));
assert!(file_exists!(public, "fr/index.html"));
assert!(file_contains!(public, "fr/index.html", "Une page"));
assert!(file_contains!(public, "fr/index.html", "Language: fr"));
assert!(file_exists!(public, "base/index.html"));
assert!(file_exists!(public, "fr/base/index.html"));
// Sections are there as well
assert!(file_exists!(public, "blog/index.html"));
assert!(file_exists!(public, "fr/blog/index.html"));
assert!(file_contains!(public, "fr/blog/index.html", "Language: fr"));
// sitemap contains all languages
assert!(file_exists!(public, "sitemap.xml"));
assert!(file_contains!(public, "sitemap.xml", "https://example.com/blog/something-else/"));
assert!(file_contains!(public, "sitemap.xml", "https://example.com/fr/blog/something-else/"));
}

View file

@ -0,0 +1,4 @@
{% for page in section.pages %}
{{page.title}}
{% endfor %}
Language: {{lang}}