summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riki.md15
-rw-r--r--src/error.rs3
-rw-r--r--src/site.rs54
3 files changed, 56 insertions, 16 deletions
diff --git a/riki.md b/riki.md
index 85abe81..14be721 100644
--- a/riki.md
+++ b/riki.md
@@ -381,7 +381,6 @@ then file output/dir/foo.html contains "href="/absolute""
then file output/dir/foo.html contains "href="dir/sibling""
then file output/dir/foo.html contains "href="dir/foo/child""
then file output/dir/foo.html contains "href="dir/foo/child/grandchild""
-then file output/dir/foo.html contains "href="/missing"
~~~
~~~{#foo .file .markdown}
@@ -389,6 +388,20 @@ then file output/dir/foo.html contains "href="/missing"
[[sibling]]
[[child]]
[[child/grandchild]]
+~~~
+
+## Wiki links to pages that don't exist
+
+_Requirement: Linking to a page that doesn't exist is an error._
+
+~~~scenario
+given an installed riki
+given file site/dir/foo.mdwn from badlink
+when I try to run riki build --plain-body site output
+then command fails
+~~~
+
+~~~{#badlink .file .markdown}
[[missing]]
~~~
diff --git a/src/error.rs b/src/error.rs
index faaaaa8..fa8ddf2 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -43,4 +43,7 @@ pub enum SiteError {
#[error("directive {0} is missing required argument {1}")]
DirectiveUnknownArg(String, String),
+
+ #[error("link to missing page {1} on {0}")]
+ PageMissing(PathBuf, PathBuf),
}
diff --git a/src/site.rs b/src/site.rs
index c1c7249..9bfa2bd 100644
--- a/src/site.rs
+++ b/src/site.rs
@@ -128,7 +128,7 @@ impl Site {
pub fn resolve<P: AsRef<Path>>(&self, page: P, target: P) -> Result<PathBuf, SiteError> {
let page = page.as_ref();
let target = target.as_ref();
- let resolved = self.resolve_helper(page, target);
+ let resolved = self.resolve_helper(page, target)?;
trace!(
"resolve: page={}, target={} -> {}",
page.display(),
@@ -138,28 +138,28 @@ impl Site {
Ok(resolved)
}
- fn resolve_helper(&self, page: &Path, target: &Path) -> PathBuf {
+ fn resolve_helper(&self, page: &Path, target: &Path) -> Result<PathBuf, SiteError> {
// Is target absolute?
if target.starts_with("/") {
- return target.to_path_buf();
+ return Ok(target.to_path_buf());
}
// Does a sub-page exist?
let path = page.join(target);
if self.have_page(path.as_path()) {
- return path;
+ return Ok(path);
}
// Does a sibling exist?
if let Some(parent) = page.parent() {
let path = parent.join(target);
if self.have_page(path.as_path()) {
- return path;
+ return Ok(path);
}
}
// Nothing else worked, so make the target absolute.
- PathBuf::from("/").join(target)
+ Err(SiteError::PageMissing(page.into(), target.into()))
}
fn have_page(&self, path: &Path) -> bool {
@@ -169,7 +169,7 @@ impl Site {
#[cfg(test)]
mod test {
- use super::{Site, WikitextPage};
+ use super::{Site, SiteError, WikitextPage};
use crate::page::MetaBuilder;
use std::path::{Path, PathBuf};
@@ -187,13 +187,22 @@ mod test {
#[test]
fn absolute_link_resolves_to_absolute() {
let site = Site::new(".", ".");
- assert_eq!(site.resolve("/foo/bar", "/yo/yoyo").unwrap(), Path::new("/yo/yoyo"));
+ assert_eq!(
+ site.resolve("/foo/bar", "/yo/yoyo").unwrap(),
+ Path::new("/yo/yoyo")
+ );
}
#[test]
- fn link_to_missing_resolves_to_absolute() {
+ fn link_to_missing_is_an_error() {
let site = Site::new(".", ".");
- assert_eq!(site.resolve("/foo/bar", "yo").unwrap(), Path::new("/yo"));
+ match site.resolve("/foo/bar", "yo") {
+ Err(SiteError::PageMissing(page, target)) => {
+ assert_eq!(target, PathBuf::from("yo"));
+ assert_eq!(page, PathBuf::from("/foo/bar"));
+ }
+ _ => panic!("unexpected success"),
+ }
}
#[test]
@@ -201,7 +210,10 @@ mod test {
let mut site = Site::new(".", ".");
site.add_wikitextpage(page("/foo/yo"));
site.process().unwrap();
- assert_eq!(site.resolve("/foo/bar", "yo").unwrap(), Path::new("/foo/yo"));
+ assert_eq!(
+ site.resolve("/foo/bar", "yo").unwrap(),
+ Path::new("/foo/yo")
+ );
}
#[test]
@@ -209,7 +221,10 @@ mod test {
let mut site = Site::new(".", ".");
site.add_wikitextpage(page("/foo/bar/yo"));
site.process().unwrap();
- assert_eq!(site.resolve("/foo/bar", "yo").unwrap(), Path::new("/foo/bar/yo"));
+ assert_eq!(
+ site.resolve("/foo/bar", "yo").unwrap(),
+ Path::new("/foo/bar/yo")
+ );
}
#[test]
@@ -218,14 +233,23 @@ mod test {
site.add_wikitextpage(page("/foo/bar/yo"));
site.add_wikitextpage(page("/foo/yo"));
site.process().unwrap();
- assert_eq!(site.resolve("/foo/bar", "yo").unwrap(), Path::new("/foo/bar/yo"));
+ assert_eq!(
+ site.resolve("/foo/bar", "yo").unwrap(),
+ Path::new("/foo/bar/yo")
+ );
}
#[test]
- fn link_to_unrelated_subpage_resolves_absolute() {
+ fn link_to_unrelated_subpage_is_an_error() {
let mut site = Site::new(".", ".");
site.process().unwrap();
- assert_eq!(site.resolve("/foo/bar", "yo/yoyo").unwrap(), Path::new("/yo/yoyo"));
+ match site.resolve("/foo/bar", "yo/yoyo") {
+ Err(SiteError::PageMissing(page, target)) => {
+ assert_eq!(target, PathBuf::from("yo/yoyo"));
+ assert_eq!(page, PathBuf::from("/foo/bar"));
+ }
+ _ => panic!("unexpected success"),
+ }
}
#[test]