NAME
App::FuguWeb::Check - what a built site must be true of
SYNOPSIS
use App::FuguWeb::Check;
my $check = App::FuguWeb::Check->new(
config => $config,
out => 'web/build',
);
my @problems = $check->run;
warn "$_\n" for @problems;
note("external link: $_") for $check->external;
DESCRIPTION
The checks are generic, so every project that uses the tool gets them. A project keeps only the assertions that are about its own content.
The class never fetches a link. It collects the external ones and reports them, because the build and its checks touch no network.
The class reads each attribute of a page through "edit_attributes" in App::FuguWeb, the reader that App::FuguWeb::Fragment reads too. The text of a value, such as title="see href=x", is therefore no reference, and a name such as data-id is no id.
METHODS
new
App::FuguWeb::Check->new(
config => $config, # required
out => $dir, # required: the built site
)
pages, generated_pages
pages names each page of each language tree, as <path>/<page>, where the path is that of the tree of the language: for each language, the pages of the description, then one page for each manual of each group. generated_pages names the human page of each key directory, which the build writes itself and which no block names. The pages of the top level sit outside every tree as well, and "top_pages" in App::FuguWeb::Config names them.
A generated page takes the checks of a page. It takes no reachability check: a site links the key directory when it chooses to. The pages of the top level take none either.
The full expectation, assets and the pages of the top level included, comes from "inventory" in App::FuguWeb::Config, so the build and the checks can never disagree about what the site is.
run
Check the site and return the problems, each one a sentence that names the page. An empty list means the site is good.
The checks are:
every expected page and asset exists and is not empty;
on every page but the top-level index.html, the check finds a title. The place of the path of the page decides its chrome, as it does in App::FuguWeb::Page: a tree page, a page of the top level, or the human page of a key directory;
every page of a language tree carries the tag of its tree as
langon its<html>element, anddir="rtl"when the language of the tree is right to left, per WEB-LANGUAGE-13;the head of a tree page names the page itself, the same page in each language, and the forward page, per WEB-CHROME-6. The head of the forward names the bare
urlas its canonical link and asx-default, and the entry page of each language, per WEB-TOP-2. The head of any other page names none. Each such href is theurlof the description, then the path of a page of the inventory, or the bareurl, per WEB-LINKS-5. None of them is an external link;the header links the entry page of the tree, and the
navholds one item for eachnaventry, in the order of the description. A page outside every tree takes the words and the links of the default tree. The check resolves each link of the chrome from the path of its page, and reads its target and not its form. A link can carry the marks of its language after itshref;on a site of more than one language, the header of a tree page and of the top-level 404.html, and the body of the forward, hold one item for each language, in the order of the declaration. On a tree page, each link goes to the same page in that language. On a page of the top level, each link goes to the entry page of that language, per WEB-TOP-2 and WEB-TOP-4. Its text is the name of the language, and the tag is its
langand itshreflang. The key page, and each page of a site of one language, holds no such item;the link of the language of the page, and the
navlink of the page, carryaria-current="page", and no other link of the chrome does;the chrome holds no class, no
<hr>and no text separator, per WEB-CHROME-5. Each word of the chrome of the body is the text of a link. The body fragment and the footer fragment are the writer's own;a relative
navhref of the description names a page of each tree, as it resolves from the path of that tree, per WEB-LINKS-2;no reference starts with
/, because the host may serve the site from a path below the root. The<base>of a page of the top level is the one exception, per WEB-LINKS-4. Its href is "url_path" in App::FuguWeb::Config, and that page must carry it;the top-level index.html is a page of the default language, per WEB-TOP-1. Its head holds the charset, a meta refresh to the entry page of the default tree, the title and the links of WEB-CHROME-6, in that order, and nothing else. Its title is the site name. On a site of one language, its body holds one link to the entry page, with the site name as its text. The body holds no other reference, so the page loads nothing, and it carries no navigation;
the top-level 404.html is a page of the default language, with the title of the 404.html of the default tree, per WEB-TOP-4. Its head holds the charset, the viewport, the base, the title and the stylesheet link, in that order, and nothing else, per WEB-TOP-3. Its
<main>carries no mark. It holds one<section>for each language, in the order of the declaration, and nothing else, per WEB-TOP-5. Each section carries the marks of the language of its text. It holds the body of the 404.html of the tree of its language, as "not_found" in App::FuguWeb::Fragment fits it: with no id, and with each relative link from the site root, per WEB-TOP-6;no reference uses a
file:URL;every relative reference resolves to a file of the inventory, a manual cross-reference included. A directory and a stray file are no file of the inventory. A reference with a query passes when its path names a file of the inventory, per WEB-LINKS-3;
a reference of a page resolves against the directory of that page: a language tree, a key directory, or the top level. A page with a
<base>resolves each reference against the site root, and a fragment alone names no page there, per WEB-LINKS-3;every fragment resolves to an
idon the target page;each heading of the
mainelement of a tree page of another language than the default takes the id of the heading at the same position of its namesake in the default tree, per WEB-OUTLINE-3. It takes no id when that heading has none, and the page holds the same count of headings. The check reads each outline through "outline" in App::FuguWeb::Fragment, as the build does;no relative href reads as a URL scheme, so every local link keeps its
./;every page of a language tree is reachable from the entry page of that tree, except a page that the description marks
unlinked. The walk stays inside the tree, per WEB-LANGUAGE-13;the output holds the site and nothing else, at any depth: no staging directory, no editor backup, no stray source, no tree of a language that the description does not declare, and no empty directory.
A description with a keys block adds the checks of "THE CHECKS" in App::FuguWeb::Keys. They read the source key directory and not the output. A stray key file and a stale digest are therefore found whether or not a build has run.
external
The external links that the last run collected, sorted.
SEE ALSO
App::FuguWeb, App::FuguWeb::Config, App::FuguWeb::Fragment, App::FuguWeb::Keys, App::FuguWeb::Site, fuguweb(1)
AUTHOR
Dick Olsson <hi@senzilla.io>