summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rwxr-xr-xt/add_depends.t10
-rwxr-xr-xt/bazaar.t30
-rwxr-xr-xt/calculate_changed_links.t58
-rwxr-xr-xt/cvs.t6
-rwxr-xr-xt/file_pruned.t56
-rwxr-xr-xt/find_src_files.t97
-rwxr-xr-xt/git.t12
-rwxr-xr-xt/index.t29
-rwxr-xr-xt/mercurial.t11
-rwxr-xr-xt/openiduser.t9
-rwxr-xr-xt/pagespec_match.t31
-rwxr-xr-xt/pagespec_match_list.t66
-rwxr-xr-xt/parentlinks.t1
-rwxr-xr-xt/permalink.t2
-rwxr-xr-xt/preprocess.t12
-rwxr-xr-xt/svn.t6
-rwxr-xr-xt/tag.t39
-rwxr-xr-xt/template_syntax.t15
-rwxr-xr-xt/templates_documented.t14
19 files changed, 449 insertions, 55 deletions
diff --git a/t/add_depends.t b/t/add_depends.t
index 9b074818c..aa58fb0ff 100755
--- a/t/add_depends.t
+++ b/t/add_depends.t
@@ -1,7 +1,7 @@
#!/usr/bin/perl
use warnings;
use strict;
-use Test::More tests => 38;
+use Test::More tests => 40;
BEGIN { use_ok("IkiWiki"); }
%config=IkiWiki::defaultconfig();
@@ -60,3 +60,11 @@ ok(! ($IkiWiki::depends{foo0}{"*"} & $IkiWiki::DEPEND_PRESENCE));
ok(add_depends("foo9", "*", deptype("monkey")));
ok($IkiWiki::depends{foo9}{"*"} & $IkiWiki::DEPEND_CONTENT);
ok(! ($IkiWiki::depends{foo9}{"*"} & ($IkiWiki::DEPEND_PRESENCE | $IkiWiki::DEPEND_LINKS)));
+
+# Influences are added for dependencies involving links.
+$pagesources{"foo"}="foo.mdwn";
+$links{foo}=[qw{bar}];
+$pagesources{"bar"}="bar.mdwn";
+$links{bar}=[qw{}];
+ok(add_depends("foo", "link(bar) and backlink(meep)"));
+ok($IkiWiki::depends_simple{foo}{foo} == $IkiWiki::DEPEND_LINKS);
diff --git a/t/bazaar.t b/t/bazaar.t
index 2ca44a65e..3e54ec4dc 100755
--- a/t/bazaar.t
+++ b/t/bazaar.t
@@ -12,7 +12,7 @@ BEGIN {
}
}
}
-use Test::More tests => 16;
+use Test::More tests => 17;
BEGIN { use_ok("IkiWiki"); }
@@ -24,11 +24,19 @@ IkiWiki::checkconfig();
system "bzr init $config{srcdir}";
+use CGI::Session;
+my $session=CGI::Session->new;
+$session->param("name", "Joe User");
+
# Web commit
my $test1 = readfile("t/test1.mdwn");
writefile('test1.mdwn', $config{srcdir}, $test1);
IkiWiki::rcs_add("test1.mdwn");
-IkiWiki::rcs_commit("test1.mdwn", "Added the first page", "moo", "Joe User");
+IkiWiki::rcs_commit(
+ file => "test1.mdwn",
+ message => "Added the first page",
+ token => "moo",
+ session => $session);
my @changes;
@changes = IkiWiki::rcs_recentchanges(3);
@@ -60,10 +68,16 @@ is($changes[1]{pages}[0]{"page"}, "test1");
my $ctime = IkiWiki::rcs_getctime("test2.mdwn");
ok($ctime >= time() - 20);
+my $mtime = IkiWiki::rcs_getmtime("test2.mdwn");
+ok($mtime >= time() - 20);
+
writefile('test3.mdwn', $config{srcdir}, $test1);
IkiWiki::rcs_add("test3.mdwn");
IkiWiki::rcs_rename("test3.mdwn", "test4.mdwn");
-IkiWiki::rcs_commit_staged("Added the 4th page", "moo", "Joe User");
+IkiWiki::rcs_commit_staged(
+ message => "Added the 4th page",
+ session => $session,
+);
@changes = IkiWiki::rcs_recentchanges(4);
@@ -72,7 +86,10 @@ is($changes[0]{pages}[0]{"page"}, "test4");
ok(mkdir($config{srcdir}."/newdir"));
IkiWiki::rcs_rename("test4.mdwn", "newdir/test5.mdwn");
-IkiWiki::rcs_commit_staged("Added the 5th page", "moo", "Joe User");
+IkiWiki::rcs_commit_staged(
+ message => "Added the 5th page",
+ session => $session,
+);
@changes = IkiWiki::rcs_recentchanges(4);
@@ -80,6 +97,9 @@ is($#changes, 3);
is($changes[0]{pages}[0]{"page"}, "newdir/test5");
IkiWiki::rcs_remove("newdir/test5.mdwn");
-IkiWiki::rcs_commit_staged("Remove the 5th page", "moo", "Joe User");
+IkiWiki::rcs_commit_staged(
+ message => "Remove the 5th page",
+ session => $session,
+);
system "rm -rf $dir";
diff --git a/t/calculate_changed_links.t b/t/calculate_changed_links.t
new file mode 100755
index 000000000..bf6e2af45
--- /dev/null
+++ b/t/calculate_changed_links.t
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+package IkiWiki;
+
+use warnings;
+use strict;
+use Test::More tests => 5;
+
+BEGIN { use_ok("IkiWiki"); }
+BEGIN { use_ok("IkiWiki::Render"); }
+%config=IkiWiki::defaultconfig();
+$config{srcdir}=$config{destdir}="/dev/null";
+
+%oldrenderedfiles=%pagectime=();
+%pagesources=%pagemtime=%oldlinks=%links=%depends=%typedlinks=%oldtypedlinks=
+%destsources=%renderedfiles=%pagecase=%pagestate=();
+
+IkiWiki::checkconfig();
+
+foreach my $page (qw(tags/a tags/b Reorder Add Remove TypeAdd TypeRemove)) {
+ $pagesources{$page} = "$page.mdwn";
+ $pagemtime{$page} = $pagectime{$page} = 1000000;
+}
+
+$oldlinks{Reorder} = [qw{tags/a tags/b}];
+$links{Reorder} = [qw{tags/b tags/a}];
+
+$oldlinks{Add} = [qw{tags/b}];
+$links{Add} = [qw{tags/a tags/b}];
+
+$oldlinks{Remove} = [qw{tags/a}];
+$links{Remove} = [];
+
+$oldlinks{TypeAdd} = [qw{tags/a tags/b}];
+$links{TypeAdd} = [qw{tags/a tags/b}];
+# This causes TypeAdd to be rebuilt, but isn't a backlink change, so it doesn't
+# cause tags/b to be rebuilt.
+$oldtypedlinks{TypeAdd}{tag} = { "tags/a" => 1 };
+$typedlinks{TypeAdd}{tag} = { "tags/a" => 1, "tags/b" => 1 };
+
+$oldlinks{TypeRemove} = [qw{tags/a tags/b}];
+$links{TypeRemove} = [qw{tags/a tags/b}];
+# This causes TypeRemove to be rebuilt, but isn't a backlink change, so it
+# doesn't cause tags/b to be rebuilt.
+$oldtypedlinks{TypeRemove}{tag} = { "tags/a" => 1 };
+$typedlinks{TypeRemove}{tag} = { "tags/a" => 1, "tags/b" => 1 };
+
+my $oldlink_targets = calculate_old_links([keys %pagesources], []);
+is_deeply($oldlink_targets, {
+ Reorder => { "tags/a" => "tags/a", "tags/b" => "tags/b" },
+ Add => { "tags/b" => "tags/b" },
+ Remove => { "tags/a" => "tags/a" },
+ TypeAdd => { "tags/a" => "tags/a", "tags/b" => "tags/b" },
+ TypeRemove => { "tags/a" => "tags/a", "tags/b" => "tags/b" },
+ });
+my ($backlinkchanged, $linkchangers) = calculate_changed_links([keys %pagesources], [], $oldlink_targets);
+
+is_deeply($backlinkchanged, { "tags/a" => 1 });
+is_deeply($linkchangers, { add => 1, remove => 1, typeadd => 1, typeremove => 1 });
diff --git a/t/cvs.t b/t/cvs.t
index 2808973be..96359ab6e 100755
--- a/t/cvs.t
+++ b/t/cvs.t
@@ -46,7 +46,11 @@ system "cvs -d $cvsrepo co -d $config{srcdir} ikiwiki >/dev/null";
my $test1 = readfile("t/test1.mdwn");
writefile('test1.mdwn', $config{srcdir}, $test1);
IkiWiki::rcs_add("test1.mdwn");
-IkiWiki::rcs_commit("test1.mdwn", "Added the first page", "moo");
+IkiWiki::rcs_commit(
+ files => "test1.mdwn",
+ message => "Added the first page",
+ token => "moo"
+);
my @changes;
@changes = IkiWiki::rcs_recentchanges(3);
diff --git a/t/file_pruned.t b/t/file_pruned.t
index 00542d580..34f366610 100755
--- a/t/file_pruned.t
+++ b/t/file_pruned.t
@@ -1,40 +1,40 @@
#!/usr/bin/perl
use warnings;
use strict;
-use Test::More tests => 26;
+use Test::More tests => 27;
BEGIN { use_ok("IkiWiki"); }
%config=IkiWiki::defaultconfig();
-ok(IkiWiki::file_pruned("src/.ikiwiki/", "src"));
-ok(IkiWiki::file_pruned("src/.ikiwiki/index", "src"));
-ok(IkiWiki::file_pruned("src/CVS/foo", "src"));
-ok(IkiWiki::file_pruned("src/subdir/CVS/foo", "src"));
-ok(IkiWiki::file_pruned("src/.svn", "src"));
-ok(IkiWiki::file_pruned("src/subdir/.svn", "src"));
-ok(IkiWiki::file_pruned("src/subdir/.svn/foo", "src"));
-ok(IkiWiki::file_pruned("src/.git", "src"));
-ok(IkiWiki::file_pruned("src/subdir/.git", "src"));
-ok(IkiWiki::file_pruned("src/subdir/.git/foo", "src"));
-ok(! IkiWiki::file_pruned("src/svn/fo", "src"));
-ok(! IkiWiki::file_pruned("src/git", "src"));
-ok(! IkiWiki::file_pruned("src/index.mdwn", "src"));
-ok(! IkiWiki::file_pruned("src/index.", "src"));
+ok(IkiWiki::file_pruned(".htaccess"));
+ok(IkiWiki::file_pruned(".ikiwiki/"));
+ok(IkiWiki::file_pruned(".ikiwiki/index"));
+ok(IkiWiki::file_pruned("CVS/foo"));
+ok(IkiWiki::file_pruned("subdir/CVS/foo"));
+ok(IkiWiki::file_pruned(".svn"));
+ok(IkiWiki::file_pruned("subdir/.svn"));
+ok(IkiWiki::file_pruned("subdir/.svn/foo"));
+ok(IkiWiki::file_pruned(".git"));
+ok(IkiWiki::file_pruned("subdir/.git"));
+ok(IkiWiki::file_pruned("subdir/.git/foo"));
+ok(! IkiWiki::file_pruned("svn/fo"));
+ok(! IkiWiki::file_pruned("git"));
+ok(! IkiWiki::file_pruned("index.mdwn"));
+ok(! IkiWiki::file_pruned("index."));
+ok(IkiWiki::file_pruned("."));
+ok(IkiWiki::file_pruned("./"));
-# these are ok because while the filename starts with ".", the canonpathed
-# version does not
-ok(! IkiWiki::file_pruned("src/.", "src"));
-ok(! IkiWiki::file_pruned("src/./", "src"));
+# absolute filenames are not allowed.
+ok(IkiWiki::file_pruned("/etc/passwd"));
+ok(IkiWiki::file_pruned("//etc/passwd"));
+ok(IkiWiki::file_pruned("/"));
+ok(IkiWiki::file_pruned("//"));
+ok(IkiWiki::file_pruned("///"));
-ok(IkiWiki::file_pruned("src/..", "src"));
-ok(IkiWiki::file_pruned("src/../", "src"));
-ok(IkiWiki::file_pruned("src/../", "src"));
-ok(! IkiWiki::file_pruned("src", "src"));
-ok(! IkiWiki::file_pruned("/.foo/src", "/.foo/src"));
-ok(IkiWiki::file_pruned("/.foo/src/.foo/src", "/.foo/src"));
-ok(! IkiWiki::file_pruned("/.foo/src/index.mdwn", "/.foo/src/index.mdwn"));
+ok(IkiWiki::file_pruned(".."));
+ok(IkiWiki::file_pruned("../"));
-ok(IkiWiki::file_pruned("x/y/foo.dpkg-tmp", "src"));
-ok(IkiWiki::file_pruned("x/y/foo.ikiwiki-new", "src"));
+ok(IkiWiki::file_pruned("y/foo.dpkg-tmp"));
+ok(IkiWiki::file_pruned("y/foo.ikiwiki-new"));
diff --git a/t/find_src_files.t b/t/find_src_files.t
new file mode 100755
index 000000000..a3742db75
--- /dev/null
+++ b/t/find_src_files.t
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use Test::More tests => 20;
+
+BEGIN { use_ok("IkiWiki"); }
+BEGIN { use_ok("IkiWiki::Render"); }
+
+%config=IkiWiki::defaultconfig();
+$config{srcdir}="t/tmp/srcdir";
+$config{underlaydir}="t/tmp/underlaydir";
+IkiWiki::checkconfig();
+
+sub cleanup {
+ ok(! system("rm -rf t/tmp"));
+}
+
+sub setup_underlay {
+ foreach my $file (@_) {
+ writefile($file, $config{underlaydir}, "test content");
+ }
+ return @_;
+}
+
+sub setup_srcdir {
+ foreach my $file (@_) {
+ writefile($file, $config{srcdir}, "test content");
+ }
+ return @_;
+}
+
+sub test_src_files {
+ my %expected=map { $_ => 1 } @{shift()}; # the input list may have dups
+ my $desc=shift;
+
+ close STDERR; # find_src_files prints warnings about bad files
+
+ my ($files, $pages)=IkiWiki::find_src_files();
+ is_deeply([sort @$files], [sort keys %expected], $desc);
+}
+
+cleanup();
+
+my @list=setup_underlay(qw{index.mdwn sandbox.mdwn smiley.png ikiwiki.mdwn ikiwiki/directive.mdwn ikiwiki/directive/foo.mdwn});
+push @list, setup_srcdir(qw{index.mdwn foo.mwdn icon.jpeg blog/archive/1/2/3/foo.mdwn blog/archive/1/2/4/bar.mdwn blog/archive.mdwn});
+test_src_files(\@list, "simple test");
+
+setup_srcdir(".badfile");
+test_src_files(\@list, "srcdir dotfile is skipped");
+
+setup_underlay(".badfile");
+test_src_files(\@list, "underlay dotfile is skipped");
+
+setup_srcdir(".ikiwiki/index");
+test_src_files(\@list, "srcdir dotdir is skipped");
+
+setup_underlay(".ikiwiki/index");
+test_src_files(\@list, "underlay dotdir is skipped");
+
+setup_srcdir("foo>.mdwn");
+test_src_files(\@list, "illegal srcdir filename skipped");
+
+setup_underlay("foo>.mdwn");
+test_src_files(\@list, "illegal underlay filename skipped");
+
+system("mkdir -p $config{srcdir}/empty");
+test_src_files(\@list, "empty srcdir directory ignored");
+
+system("mkdir -p $config{underlaydir}/empty");
+test_src_files(\@list, "empty underlay directory ignored");
+
+setup_underlay("bad.mdwn");
+system("ln -sf /etc/passwd $config{srcdir}/bad.mdwn");
+test_src_files(\@list, "underlaydir override attack foiled");
+
+system("ln -sf /etc/passwd $config{srcdir}/symlink.mdwn");
+test_src_files(\@list, "file symlink in srcdir skipped");
+
+system("ln -sf /etc/passwd $config{underlaydir}/symlink.mdwn");
+test_src_files(\@list, "file symlink in underlaydir skipped");
+
+system("ln -sf /etc/ $config{srcdir}/symdir");
+test_src_files(\@list, "dir symlink in srcdir skipped");
+
+system("ln -sf /etc/ $config{underlaydir}/symdir");
+test_src_files(\@list, "dir symlink in underlaydir skipped");
+
+system("ln -sf /etc/ $config{srcdir}/blog/symdir");
+test_src_files(\@list, "deep dir symlink in srcdir skipped");
+
+system("ln -sf /etc/ $config{underlaydir}/ikiwiki/symdir");
+test_src_files(\@list, "deep dir symlink in underlaydir skipped");
+
+
+
+
+cleanup();
diff --git a/t/git.t b/t/git.t
index f1c24b359..ee778ebf0 100755
--- a/t/git.t
+++ b/t/git.t
@@ -38,7 +38,11 @@ is($changes[0]{pages}[0]{"page"}, ".gitignore");
my $test1 = readfile("t/test1.mdwn");
writefile('test1.mdwn', $config{srcdir}, $test1);
IkiWiki::rcs_add("test1.mdwn");
-IkiWiki::rcs_commit("test1.mdwn", "Added the first page", "moo");
+IkiWiki::rcs_commit(
+ file => "test1.mdwn",
+ message => "Added the first page",
+ token => "moo",
+);
@changes = IkiWiki::rcs_recentchanges(3);
@@ -68,7 +72,7 @@ is($changes[1]{pages}[0]{"page"}, "test1");
writefile('test3.mdwn', $config{srcdir}, $test1);
IkiWiki::rcs_add("test3.mdwn");
IkiWiki::rcs_rename("test3.mdwn", "test4.mdwn");
-IkiWiki::rcs_commit_staged("Added the 4th page", "moo", "Joe User");
+IkiWiki::rcs_commit_staged(message => "Added the 4th page");
@changes = IkiWiki::rcs_recentchanges(4);
@@ -77,7 +81,7 @@ is($changes[0]{pages}[0]{"page"}, "test4");
ok(mkdir($config{srcdir}."/newdir"));
IkiWiki::rcs_rename("test4.mdwn", "newdir/test5.mdwn");
-IkiWiki::rcs_commit_staged("Added the 5th page", "moo", "Joe User");
+IkiWiki::rcs_commit_staged(message => "Added the 5th page");
@changes = IkiWiki::rcs_recentchanges(4);
@@ -85,6 +89,6 @@ is($#changes, 3);
is($changes[0]{pages}[0]{"page"}, "newdir/test5");
IkiWiki::rcs_remove("newdir/test5.mdwn");
-IkiWiki::rcs_commit_staged("Remove the 5th page", "moo", "Joe User");
+IkiWiki::rcs_commit_staged(message => "Remove the 5th page");
system "rm -rf $dir";
diff --git a/t/index.t b/t/index.t
index 2f23524a7..392a167e9 100755
--- a/t/index.t
+++ b/t/index.t
@@ -4,7 +4,7 @@ use strict;
use IkiWiki;
package IkiWiki; # use internal variables
-use Test::More tests => 27;
+use Test::More tests => 31;
$config{wikistatedir}="/tmp/ikiwiki-test.$$";
system "rm -rf $config{wikistatedir}";
@@ -31,6 +31,7 @@ $renderedfiles{"bar"}=["bar.html", "bar.rss", "sparkline-foo.gif"];
$renderedfiles{"bar.png"}=["bar.png"];
$links{"Foo"}=["bar.png"];
$links{"bar"}=["Foo", "new-page"];
+$typedlinks{"bar"}={tag => {"Foo" => 1}};
$links{"bar.png"}=[];
$depends{"Foo"}={};
$depends{"bar"}={"foo*" => 1};
@@ -45,7 +46,7 @@ ok(-s "$config{wikistatedir}/indexdb", "index file created");
# Clear state.
%oldrenderedfiles=%pagectime=();
-%pagesources=%pagemtime=%oldlinks=%links=%depends=
+%pagesources=%pagemtime=%oldlinks=%links=%depends=%typedlinks=%oldtypedlinks=
%destsources=%renderedfiles=%pagecase=%pagestate=();
ok(loadindex(), "load index");
@@ -104,17 +105,26 @@ is_deeply(\%destsources, {
"sparkline-foo.gif" => "bar",
"bar.png" => "bar.png",
}, "%destsources generated correctly");
+is_deeply(\%typedlinks, {
+ bar => {tag => {"Foo" => 1}},
+}, "%typedlinks loaded correctly");
+is_deeply(\%oldtypedlinks, {
+ bar => {tag => {"Foo" => 1}},
+}, "%oldtypedlinks loaded correctly");
# Clear state.
%oldrenderedfiles=%pagectime=();
-%pagesources=%pagemtime=%oldlinks=%links=%depends=
+%pagesources=%pagemtime=%oldlinks=%links=%depends=%typedlinks=%oldtypedlinks=
%destsources=%renderedfiles=%pagecase=%pagestate=();
-# When state is loaded for a wiki rebuild, only ctime and oldrenderedfiles
-# are retained.
+# When state is loaded for a wiki rebuild, only ctime, oldrenderedfiles,
+# and pagesources are retained.
$config{rebuild}=1;
ok(loadindex(), "load index");
is_deeply(\%pagesources, {
+ Foo => "Foo.mdwn",
+ bar => "bar.mdwn",
+ "bar.png" => "bar.png",
}, "%pagesources loaded correctly");
is_deeply(\%pagemtime, {
}, "%pagemtime loaded correctly");
@@ -136,9 +146,16 @@ is_deeply(\%depends, {
}, "%depends loaded correctly");
is_deeply(\%pagestate, {
}, "%pagestate loaded correctly");
-is_deeply(\%pagecase, {
+is_deeply(\%pagecase, { # generated implicitly since pagesources is loaded
+ foo => "Foo",
+ bar => "bar",
+ "bar.png" => "bar.png"
}, "%pagecase generated correctly");
is_deeply(\%destsources, {
}, "%destsources generated correctly");
+is_deeply(\%typedlinks, {
+}, "%typedlinks cleared correctly");
+is_deeply(\%oldtypedlinks, {
+}, "%oldtypedlinks cleared correctly");
system "rm -rf $config{wikistatedir}";
diff --git a/t/mercurial.t b/t/mercurial.t
index 954b17526..b64ea8e56 100755
--- a/t/mercurial.t
+++ b/t/mercurial.t
@@ -22,13 +22,22 @@ $config{srcdir} = "$dir/repo";
IkiWiki::loadplugins();
IkiWiki::checkconfig();
+use CGI::Session;
+my $session=CGI::Session->new;
+$session->param("name", "Joe User");
+
system "hg init $config{srcdir}";
# Web commit
my $test1 = readfile("t/test1.mdwn");
writefile('test1.mdwn', $config{srcdir}, $test1);
IkiWiki::rcs_add("test1.mdwn");
-IkiWiki::rcs_commit("test1.mdwn", "Added the first page", "moo", "Joe User");
+IkiWiki::rcs_commit(
+ file => "test1.mdwn",
+ message => "Added the first page",
+ token => "moo",
+ session => $session,
+);
my @changes;
@changes = IkiWiki::rcs_recentchanges(3);
diff --git a/t/openiduser.t b/t/openiduser.t
index 52d879484..746090103 100755
--- a/t/openiduser.t
+++ b/t/openiduser.t
@@ -10,9 +10,9 @@ BEGIN {
eval q{use Test::More skip_all => "Net::OpenID::VerifiedIdentity not available"};
}
else {
- eval q{use Test::More tests => 9};
+ eval q{use Test::More tests => 11};
}
- use_ok("IkiWiki::Plugin::openid");
+ use_ok("IkiWiki");
}
# Some typical examples:
@@ -28,6 +28,11 @@ $^W=1;
is(IkiWiki::openiduser('http://yam655.livejournal.com/'), 'yam655 [livejournal.com]');
is(IkiWiki::openiduser('http://id.mayfirst.org/jamie/'), 'jamie [id.mayfirst.org]');
+# yahoo has an anchor in the url
+is(IkiWiki::openiduser('https://me.yahoo.com/joeyhess#35f22'), 'joeyhess [me.yahoo.com]');
+# google urls are horrendous, but the worst bit is after a ?, so can be dropped
+is(IkiWiki::openiduser('https://www.google.com/accounts/o8/id?id=AItOawm-ebiIfxbKD3KNa-Cu9LvvD9edMLW7BAo'), 'id [www.google.com/accounts/o8]');
+
# and some less typical ones taken from the ikiwiki commit history
is(IkiWiki::openiduser('http://thm.id.fedoraproject.org/'), 'thm [id.fedoraproject.org]');
diff --git a/t/pagespec_match.t b/t/pagespec_match.t
index b96947407..97bcc969c 100755
--- a/t/pagespec_match.t
+++ b/t/pagespec_match.t
@@ -1,7 +1,7 @@
#!/usr/bin/perl
use warnings;
use strict;
-use Test::More tests => 64;
+use Test::More tests => 85;
BEGIN { use_ok("IkiWiki"); }
@@ -40,11 +40,21 @@ ok(! pagespec_match("foo", "foo and bar"), "foo and bar");
ok(pagespec_match("{f}oo", "{*}*"), "curly match");
ok(! pagespec_match("foo", "{*}*"), "curly !match");
+ok(pagespec_match("somepage", "user(frodo)", user => "frodo"));
+ok(pagespec_match("somepage", "user(frodo)", user => "Frodo"));
+ok(! pagespec_match("somepage", "user(frodo)", user => "Sam"));
+ok(pagespec_match("somepage", "user(*o)", user => "Bilbo"));
+ok(pagespec_match("somepage", "user(*o)", user => "frodo"));
+ok(! pagespec_match("somepage", "user(*o)", user => "Sam"));
+ok(pagespec_match("somepage", "user(http://*.myopenid.com/)", user => "http://foo.myopenid.com/"));
+ok(pagespec_match("somepage", "user(*://*)", user => "http://foo.myopenid.com/"));
+
# The link and backlink stuff needs this.
$config{userdir}="";
$links{foo}=[qw{bar baz}];
$links{bar}=[];
$links{baz}=[];
+$links{meh}=[];
$links{"bugs/foo"}=[qw{bugs/done}];
$links{"bugs/done"}=[];
$links{"bugs/bar"}=[qw{done}];
@@ -56,7 +66,21 @@ $links{"ook"}=[qw{/blog/tags/foo}];
foreach my $p (keys %links) {
$pagesources{$p}="$p.mdwn";
}
+$pagesources{"foo.png"}="foo.png";
+$pagesources{"foo"}="foo.mdwn";
+$IkiWiki::hooks{htmlize}{mdwn}={};
+ok(pagespec_match("foo", "foo"), "simple");
+ok(! pagespec_match("foo", "bar"), "simple fail");
+ok(pagespec_match("foo", "foo"), "simple glob");
+ok(pagespec_match("foo", "f*"), "simple glob fail");
+ok(pagespec_match("foo", "page(foo)"), "page()");
+print pagespec_match("foo", "page(foo)")."\n";
+ok(! pagespec_match("foo", "page(bar)"), "page() fail");
+ok(! pagespec_match("foo.png", "page(foo.png)"), "page() fails on non-page");
+ok(! pagespec_match("foo.png", "page(foo*)"), "page() fails on non-page glob");
+ok(pagespec_match("foo", "page(foo)"), "page() glob");
+ok(pagespec_match("foo", "page(f*)"), "page() glob fail");
ok(pagespec_match("foo", "link(bar)"), "link");
ok(pagespec_match("foo", "link(ba?)"), "glob link");
ok(! pagespec_match("foo", "link(quux)"), "failed link");
@@ -73,6 +97,7 @@ ok(! pagespec_match("bar", ""), "empty pagespec should match nothing");
ok(! pagespec_match("bar", " "), "blank pagespec should match nothing");
ok(pagespec_match("ook", "link(blog/tags/foo)"), "link internal absolute success");
ok(pagespec_match("ook", "link(/blog/tags/foo)"), "link explicit absolute success");
+ok(pagespec_match("meh", "!link(done)"), "negated failing match is a success");
$IkiWiki::pagectime{foo}=1154532692; # Wed Aug 2 11:26 EDT 2006
$IkiWiki::pagectime{bar}=1154532695; # after
@@ -113,3 +138,7 @@ $i=pagespec_match("foo", "link(baz) and created_after(bar)")->influences;
is(join(",", sort keys %$i), 'bar,foo', "influences add up over OR");
$i=pagespec_match("foo", "!link(baz) and !created_after(bar)")->influences;
is(join(",", sort keys %$i), 'bar,foo', "influences unaffected by negation");
+$i=pagespec_match("foo", "!link(baz) and !created_after(bar)")->influences;
+is(join(",", sort keys %$i), 'bar,foo', "influences unaffected by negation");
+$i=pagespec_match("meh", "!link(done)")->influences;
+is(join(",", sort keys %$i), 'meh', "a negated, failing link test is successful, so the page is a link influence");
diff --git a/t/pagespec_match_list.t b/t/pagespec_match_list.t
index dd5dcc5b0..244ad9159 100755
--- a/t/pagespec_match_list.t
+++ b/t/pagespec_match_list.t
@@ -1,7 +1,7 @@
#!/usr/bin/perl
use warnings;
use strict;
-use Test::More tests => 88;
+use Test::More tests => 126;
BEGIN { use_ok("IkiWiki"); }
@@ -9,6 +9,12 @@ BEGIN { use_ok("IkiWiki"); }
$config{srcdir}=$config{destdir}="/dev/null";
IkiWiki::checkconfig();
+{
+ package IkiWiki::SortSpec;
+
+ sub cmp_path { $a cmp $b }
+}
+
%pagesources=(
foo => "foo.mdwn",
foo2 => "foo2.mdwn",
@@ -18,6 +24,15 @@ IkiWiki::checkconfig();
"post/2" => "post/2.mdwn",
"post/3" => "post/3.mdwn",
);
+$IkiWiki::pagectime{foo} = 2;
+$IkiWiki::pagectime{foo2} = 2;
+$IkiWiki::pagectime{foo3} = 1;
+$IkiWiki::pagectime{foo4} = 1;
+$IkiWiki::pagectime{foo5} = 1;
+$IkiWiki::pagectime{bar} = 3;
+$IkiWiki::pagectime{"post/1"} = 6;
+$IkiWiki::pagectime{"post/2"} = 6;
+$IkiWiki::pagectime{"post/3"} = 6;
$links{foo}=[qw{post/1 post/2}];
$links{foo2}=[qw{bar}];
$links{foo3}=[qw{bar}];
@@ -25,15 +40,24 @@ $links{foo3}=[qw{bar}];
is_deeply([pagespec_match_list("foo", "bar")], ["bar"]);
is_deeply([sort(pagespec_match_list("foo", "* and !post/*"))], ["bar", "foo", "foo2", "foo3"]);
is_deeply([sort(pagespec_match_list("foo", "post/*"))], ["post/1", "post/2", "post/3"]);
+is_deeply([pagespec_match_list("foo", "post/*", sort => "title")],
+ ["post/1", "post/2", "post/3"]);
is_deeply([pagespec_match_list("foo", "post/*", sort => "title", reverse => 1)],
["post/3", "post/2", "post/1"]);
is_deeply([pagespec_match_list("foo", "post/*", sort => "title", num => 2)],
["post/1", "post/2"]);
is_deeply([pagespec_match_list("foo", "post/*", sort => "title", num => 50)],
["post/1", "post/2", "post/3"]);
+is_deeply([pagespec_match_list("foo", "post/*", sort => "title", num => 50, reverse => 1)],
+ ["post/3", "post/2", "post/1"]);
is_deeply([pagespec_match_list("foo", "post/*", sort => "title",
filter => sub { $_[0] =~ /3/}) ],
["post/1", "post/2"]);
+is_deeply([pagespec_match_list("foo", "*", sort => "path", num => 2)],
+ ["bar", "foo"]);
+is_deeply([pagespec_match_list("foo", "foo* or bar*",
+ sort => "-age title")], # oldest first, break ties by title
+ ["foo3", "foo", "foo2", "bar"]);
my $r=eval { pagespec_match_list("foo", "beep") };
ok(eval { pagespec_match_list("foo", "beep") } == 0);
ok(! $@, "does not fail with error when unable to match anything");
@@ -57,18 +81,44 @@ foreach my $spec ("* and link(bar)", "* or link(bar)") {
%IkiWiki::depends=();
}
+# A link pagespec is influenced by the pages that currently contain the link.
+# It is not influced by pages that do not currently contain the link,
+# because if those pages were changed to contain it, regular dependency
+# handling would be triggered.
+foreach my $spec ("* and link(bar)", "link(bar)", "no_such_page or link(bar)") {
+ pagespec_match_list("foo2", $spec);
+ ok($IkiWiki::depends_simple{foo2}{foo2} == $IkiWiki::DEPEND_LINKS);
+ ok(! exists $IkiWiki::depends_simple{foo2}{foo}, $spec);
+ %IkiWiki::depends_simple=();
+ %IkiWiki::depends=();
+}
+
+# Oppositely, a pagespec that tests for pages that do not have a link
+# is not influenced by pages that currently contain the link, but
+# is instead influenced by pages that currently do not (but that
+# could be changed to have it).
+foreach my $spec ("* and !link(bar)", "* and !(!(!link(bar)))") {
+ pagespec_match_list("foo2", $spec);
+ ok(! exists $IkiWiki::depends_simple{foo2}{foo2});
+ ok($IkiWiki::depends_simple{foo2}{foo} == $IkiWiki::DEPEND_LINKS, $spec);
+ %IkiWiki::depends_simple=();
+ %IkiWiki::depends=();
+}
+
# a pagespec with backlinks() will add as an influence the page with the links
-foreach my $spec ("bar or (backlink(foo) and !*.png)", "backlink(foo)") {
+foreach my $spec ("bar or (backlink(foo) and !*.png)", "backlink(foo)", "!backlink(foo)") {
pagespec_match_list("foo2", $spec, deptype => deptype("presence"));
ok($IkiWiki::depends{foo2}{$spec} & $IkiWiki::DEPEND_PRESENCE);
ok(! ($IkiWiki::depends{foo2}{$spec} & ($IkiWiki::DEPEND_CONTENT | $IkiWiki::DEPEND_LINKS)));
ok($IkiWiki::depends_simple{foo2}{foo} == $IkiWiki::DEPEND_LINKS);
+ ok(! exists $IkiWiki::depends_simple{foo2}{foo2});
%IkiWiki::depends_simple=();
%IkiWiki::depends=();
pagespec_match_list("foo2", $spec, deptype => deptype("links"));
ok($IkiWiki::depends{foo2}{$spec} & $IkiWiki::DEPEND_LINKS);
ok(! ($IkiWiki::depends{foo2}{$spec} & ($IkiWiki::DEPEND_PRESENCE | $IkiWiki::DEPEND_CONTENT)));
ok($IkiWiki::depends_simple{foo2}{foo} == $IkiWiki::DEPEND_LINKS);
+ ok(! exists $IkiWiki::depends_simple{foo2}{foo2});
%IkiWiki::depends_simple=();
%IkiWiki::depends=();
pagespec_match_list("foo2", $spec, deptype => deptype("presence", "links"));
@@ -76,6 +126,7 @@ foreach my $spec ("bar or (backlink(foo) and !*.png)", "backlink(foo)") {
ok($IkiWiki::depends{foo2}{$spec} & $IkiWiki::DEPEND_LINKS);
ok(! ($IkiWiki::depends{foo2}{$spec} & $IkiWiki::DEPEND_CONTENT));
ok($IkiWiki::depends_simple{foo2}{foo} == $IkiWiki::DEPEND_LINKS);
+ ok(! exists $IkiWiki::depends_simple{foo2}{foo2});
%IkiWiki::depends_simple=();
%IkiWiki::depends=();
pagespec_match_list("foo2", $spec);
@@ -110,3 +161,14 @@ foreach my $spec ("nosuchpage or link(bar)", "link(bar) or nosuchpage",
%IkiWiki::depends_simple=();
%IkiWiki::depends=();
}
+
+my @ps;
+foreach my $p (100..500) {
+ $IkiWiki::pagectime{"p/$p"} = $p;
+ $pagesources{"p/$p"} = "p/$p.mdwn";
+ unshift @ps, "p/$p";
+}
+is_deeply([pagespec_match_list("foo", "p/*", sort => "age")],
+ [@ps]);
+is_deeply([pagespec_match_list("foo", "p/*", sort => "age", num => 20)],
+ [@ps[0..19]]);
diff --git a/t/parentlinks.t b/t/parentlinks.t
index 593937a97..9b4654903 100755
--- a/t/parentlinks.t
+++ b/t/parentlinks.t
@@ -21,7 +21,6 @@ IkiWiki::checkconfig();
# Test data
$expected{'parentlinks'} =
{
- "" => [],
"ikiwiki" => [],
"ikiwiki/pagespec" =>
[ {depth => 0, height => 2, },
diff --git a/t/permalink.t b/t/permalink.t
index b49b98338..adb8648b4 100755
--- a/t/permalink.t
+++ b/t/permalink.t
@@ -5,7 +5,7 @@ use Test::More 'no_plan';
ok(! system("mkdir t/tmp"));
ok(! system("make -s ikiwiki.out"));
-ok(! system("perl -I. ./ikiwiki.out -plugin inline -url=http://example.com -cgiurl=http://example.com/ikiwiki.cgi -rss -atom -underlaydir=underlays/basewiki -templatedir=templates t/tinyblog t/tmp/out"));
+ok(! system("perl -I. ./ikiwiki.out -plugin inline -url=http://example.com -cgiurl=http://example.com/ikiwiki.cgi -rss -atom -underlaydir=underlays/basewiki -set underlaydirbase=underlays -templatedir=templates t/tinyblog t/tmp/out"));
# This guid should never, ever change, for any reason whatsoever!
my $guid="http://example.com/post/";
ok(length `grep '<guid>$guid</guid>' t/tmp/out/index.rss`);
diff --git a/t/preprocess.t b/t/preprocess.t
index e5026ed64..7bb9878d0 100755
--- a/t/preprocess.t
+++ b/t/preprocess.t
@@ -1,7 +1,7 @@
#!/usr/bin/perl
use warnings;
use strict;
-use Test::More tests => 21;
+use Test::More tests => 31;
BEGIN { use_ok("IkiWiki"); }
@@ -26,6 +26,16 @@ is(IkiWiki::preprocess("foo", "foo", "[[foo ]]", 0, 0), "foo()", "simple");
is(IkiWiki::preprocess("foo", "foo", "[[!foo ]]", 0, 0), "foo()", "prefixed");
is(IkiWiki::preprocess("foo", "foo", "[[!foo]]", 0, 0), "[[!foo]]", "prefixed, no space");
is(IkiWiki::preprocess("foo", "foo", "[[foo a=1]]", 0, 0), "foo(a => 1)");
+is(IkiWiki::preprocess("foo", "foo", q{[[foo a="1"]]}, 0, 0), "foo(a => 1)");
+is(IkiWiki::preprocess("foo", "foo", q{[[foo a="""1"""]]}, 0, 0), "foo(a => 1)");
+is(IkiWiki::preprocess("foo", "foo", q{[[foo a=""]]}, 0, 0), "foo(a)");
+is(IkiWiki::preprocess("foo", "foo", q{[[foo a="" b="1"]]}, 0, 0), "foo(a, b => 1)");
+is(IkiWiki::preprocess("foo", "foo", q{[[foo a=""""""]]}, 0, 0), "foo(a)");
+is(IkiWiki::preprocess("foo", "foo", q{[[foo a="""""" b="1"]]}, 0, 0), "foo(a, b => 1)");
+is(IkiWiki::preprocess("foo", "foo", q{[[foo a="""""" b="""1"""]]}, 0, 0), "foo(a, b => 1)");
+is(IkiWiki::preprocess("foo", "foo", q{[[foo a="""""" b=""""""]]}, 0, 0), "foo(a, b)");
+is(IkiWiki::preprocess("foo", "foo", q{[[foo a="" b=""""""]]}, 0, 0), "foo(a, b)");
+is(IkiWiki::preprocess("foo", "foo", q{[[foo a="" b="""1"""]]}, 0, 0), "foo(a, b => 1)");
is(IkiWiki::preprocess("foo", "foo", "[[foo a=\"1 2 3 4\"]]", 0, 0), "foo(a => 1 2 3 4)");
is(IkiWiki::preprocess("foo", "foo", "[[foo ]] then [[foo a=2]]", 0, 0),
"foo() then foo(a => 2)");
diff --git a/t/svn.t b/t/svn.t
index 5223b4409..82b71b5fc 100755
--- a/t/svn.t
+++ b/t/svn.t
@@ -36,7 +36,11 @@ system "svn co file://$svnrepo/trunk $config{srcdir} >/dev/null";
my $test1 = readfile("t/test1.mdwn");
writefile('test1.mdwn', $config{srcdir}, $test1);
IkiWiki::rcs_add("test1.mdwn");
-IkiWiki::rcs_commit("test1.mdwn", "Added the first page", "moo");
+IkiWiki::rcs_commit(
+ file => "test1.mdwn",
+ message => "Added the first page",
+ token => "moo",
+);
my @changes;
@changes = IkiWiki::rcs_recentchanges(3);
diff --git a/t/tag.t b/t/tag.t
new file mode 100755
index 000000000..fe547d85b
--- /dev/null
+++ b/t/tag.t
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+package IkiWiki;
+
+use warnings;
+use strict;
+use Test::More tests => 7;
+
+BEGIN { use_ok("IkiWiki"); }
+BEGIN { use_ok("IkiWiki::Plugin::tag"); }
+
+ok(! system("rm -rf t/tmp; mkdir t/tmp"));
+
+$config{userdir} = "users";
+$config{tagbase} = "tags";
+
+%oldrenderedfiles=%pagectime=();
+%pagesources=%pagemtime=%oldlinks=%links=%depends=%typedlinks=%oldtypedlinks=
+%destsources=%renderedfiles=%pagecase=%pagestate=();
+
+foreach my $page (qw(tags/numbers tags/letters one two alpha beta)) {
+ $pagesources{$page} = "$page.mdwn";
+ $pagemtime{$page} = $pagectime{$page} = 1000000;
+}
+
+$links{one}=[qw(tags/numbers alpha tags/letters)];
+$links{two}=[qw(tags/numbers)];
+$links{alpha}=[qw(tags/letters one)];
+$links{beta}=[qw(tags/letters)];
+$typedlinks{one}={tag => {"tags/numbers" => 1 }};
+$typedlinks{two}={tag => {"tags/numbers" => 1 }};
+$typedlinks{alpha}={tag => {"tags/letters" => 1 }};
+$typedlinks{beta}={tag => {"tags/letters" => 1 }};
+
+ok(pagespec_match("one", "tagged(numbers)"));
+ok(!pagespec_match("two", "tagged(alpha)"));
+ok(pagespec_match("one", "link(tags/numbers)"));
+ok(pagespec_match("one", "link(alpha)"));
+
+1;
diff --git a/t/template_syntax.t b/t/template_syntax.t
new file mode 100755
index 000000000..1e156eed8
--- /dev/null
+++ b/t/template_syntax.t
@@ -0,0 +1,15 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use Test::More;
+
+my @templates=glob("templates/*.tmpl"), glob("doc/templates/*.mdwn");
+plan(tests => 2*@templates);
+
+use HTML::Template;
+
+foreach my $template (@templates) {
+ my $obj=eval {HTML::Template->new(filename => $template)};
+ ok(! $@, $template." $@");
+ ok($obj, $template);
+}
diff --git a/t/templates_documented.t b/t/templates_documented.t
new file mode 100755
index 000000000..826c51d36
--- /dev/null
+++ b/t/templates_documented.t
@@ -0,0 +1,14 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use Test::More 'no_plan';
+
+$/=undef;
+open(IN, "doc/templates.mdwn") || die "doc/templates.mdwn: $!";
+my $page=<IN>;
+close IN;
+
+foreach my $file (glob("templates/*.tmpl")) {
+ $file=~s/templates\///;
+ ok($page =~ /\Q$file\E/, "$file documented on doc/templates.mdwn");
+}