summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorRuss Allbery <rra@cpan.org>2022-01-15 17:13:04 -0800
committerRuss Allbery <rra@cpan.org>2022-01-15 17:13:04 -0800
commitca30d64285e120b991f994808100ff866d7bdf7a (patch)
tree23f2ade5fa21795c33123ca133cf922c952fbe4c /t
parentd49f4587924e350998178e517b800b7268fa6345 (diff)
parent9c3d2a30bd5f6601805cc4b6c64e0f486ab4ebd2 (diff)
New upstream version 6.01
Diffstat (limited to 't')
-rwxr-xr-xt/cli/errors.t10
-rwxr-xr-xt/cli/spin.t7
-rw-r--r--t/data/generate/docknot/output/thread8
-rw-r--r--t/data/perltidyrc5
-rw-r--r--t/data/spin/input/journal/.rss4
-rw-r--r--t/data/spin/update/input/module.rpod1
-rw-r--r--t/data/spin/update/input/readme.rpod2
-rw-r--r--t/data/spin/update/input/script.rpod3
-rw-r--r--t/data/spin/update/output/module.spin2
-rw-r--r--t/data/spin/update/output/readme.spin6
-rw-r--r--t/data/spin/update/output/script.spin3
-rwxr-xr-xt/dist/basic.t7
-rw-r--r--t/lib/Test/DocKnot/Spin.pm6
-rw-r--r--t/lib/Test/RRA.pm2
-rw-r--r--t/lib/Test/RRA/Config.pm2
-rw-r--r--t/lib/Test/RRA/ModuleVersion.pm12
-rwxr-xr-xt/release/basic.t116
-rwxr-xr-xt/spin/errors.t2
-rwxr-xr-xt/spin/sitemap.t2
-rwxr-xr-xt/spin/tree.t26
-rwxr-xr-xt/spin/versions.t6
-rwxr-xr-xt/update/spin.t65
22 files changed, 260 insertions, 37 deletions
diff --git a/t/cli/errors.t b/t/cli/errors.t
index 2336977..c311d14 100755
--- a/t/cli/errors.t
+++ b/t/cli/errors.t
@@ -10,9 +10,11 @@ use 5.024;
use autodie;
use warnings;
+use POSIX qw(LC_ALL setlocale);
use Test::More tests => 11;
# Isolate from the environment.
+setlocale(LC_ALL, 'C');
local $ENV{XDG_CONFIG_HOME} = '/nonexistent';
local $ENV{XDG_CONFIG_DIRS} = '/nonexistent';
@@ -61,7 +63,13 @@ is_error($@, 'generate-all: too many arguments', 'Too many arguments');
# Trigger an error in a submodule to test error rewriting.
eval { $docknot->run('generate', '-m', '/nonexistent', 'readme') };
-is_error($@, 'generate: metadata path /nonexistent does not exist');
+is_error(
+ $@,
+ (
+ 'generate: can\'t open \'/nonexistent\' for input:'
+ . ' No such file or directory'
+ ),
+);
# Check for a missing required argument.
eval { $docknot->run('dist') };
diff --git a/t/cli/spin.t b/t/cli/spin.t
index ac7894f..2522eda 100755
--- a/t/cli/spin.t
+++ b/t/cli/spin.t
@@ -76,7 +76,11 @@ print_fh($fh, $pointer_path, "format: pod\n");
print_fh($fh, $pointer_path, "path: $pod_source\n");
close($fh);
-# Spin a tree of files.
+# Spin a tree of files. Do this from the temporary directory because 6.00 had
+# a regression where docknot spin would fail if there were no package metadata
+# even though it didn't use it.
+my $cwd = getcwd();
+chdir($tempdir->dirname);
$expected = File::Spec->catfile($datadir, 'output');
capture_stdout {
$docknot->run(
@@ -84,6 +88,7 @@ capture_stdout {
$tempdir->dirname,
);
};
+chdir($cwd);
my $count = is_spin_output_tree($tempdir->dirname, $expected, 'spin');
# Spin a file with warnings. The specific warnings are checked in
diff --git a/t/data/generate/docknot/output/thread b/t/data/generate/docknot/output/thread
index 63e79c3..d1d89a0 100644
--- a/t/data/generate/docknot/output/thread
+++ b/t/data/generate/docknot/output/thread
@@ -117,9 +117,11 @@ The following additional Perl modules are required to use it:
\bullet(packed)[JSON::MaybeXS]
\bullet(packed)[Kwalify]
\bullet(packed)[List::SomeUtils 0.07 or later]
-\bullet(packed)[Path::Tiny]
+\bullet(packed)[Path::Iterator::Rule]
+\bullet(packed)[Path::Tiny 0.101 or later]
\bullet(packed)[Perl6::Slurp]
-\bullet(packed)[Pod::Thread 3.00 or later]
+\bullet(packed)[Pod::Thread 3.01 or later]
+\bullet(packed)[Sort::Versions]
\bullet(packed)[Template (part of Template Toolkit)]
\bullet(packed)[YAML::XS 0.81 or later]
@@ -197,7 +199,7 @@ license:
\block[
- Copyright 1999-2021
+ Copyright 1999-2022
Russ Allbery <rra@cpan.org>
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/t/data/perltidyrc b/t/data/perltidyrc
index 431c311..dc3a2f7 100644
--- a/t/data/perltidyrc
+++ b/t/data/perltidyrc
@@ -6,7 +6,7 @@
# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
-# Copyright 2021 Russ Allbery <eagle@eyrie.org>
+# Copyright 2021-2022 Russ Allbery <eagle@eyrie.org>
# Copyright 2012-2013
# The Board of Trustees of the Leland Stanford Junior University
#
@@ -22,8 +22,9 @@
-boc # do not re-break lists, since perltidy is awful at this
-ce # cuddle braces around else
-l=79 # usually use 78, but don't want 79-long lines reformatted
+-nlop # disable vertical alignment of logical and ternary expressions
-pt=2 # don't add extra whitespace around parentheses
-sbt=2 # ...or square brackets
--sfs # no space before semicolon in for (not that I use this form)
+-nsfs # no space before semicolon in for (not that I use this form)
-nvc # disable vertical alignment of = and similar symbols
-xci # improve indentation of nested structures
diff --git a/t/data/spin/input/journal/.rss b/t/data/spin/input/journal/.rss
index 62f7c63..07c8e82 100644
--- a/t/data/spin/input/journal/.rss
+++ b/t/data/spin/input/journal/.rss
@@ -30,10 +30,10 @@ Index-Suffix:
Date: 2011-08-13 00:09
Title: NPR Top 100 SFF meme
Link: journal/2011-08/006.html
-Journal: journal/2011-08/006.th
+Journal: 2011-08/006.th
Tags: debian
Date: 2007-01-14 21:30
Title: Review: Fermat's Enigma
Link: reviews/books/1-250-30112-2.html
-Review: reviews/books/0-385-49362-2.th
+Review: ../reviews/books/0-385-49362-2.th
diff --git a/t/data/spin/update/input/module.rpod b/t/data/spin/update/input/module.rpod
new file mode 100644
index 0000000..5f75697
--- /dev/null
+++ b/t/data/spin/update/input/module.rpod
@@ -0,0 +1 @@
+/path/Module.pm
diff --git a/t/data/spin/update/input/readme.rpod b/t/data/spin/update/input/readme.rpod
new file mode 100644
index 0000000..042274b
--- /dev/null
+++ b/t/data/spin/update/input/readme.rpod
@@ -0,0 +1,2 @@
+/path/readme.pod
+-c -t 'Basic Information'
diff --git a/t/data/spin/update/input/script.rpod b/t/data/spin/update/input/script.rpod
new file mode 100644
index 0000000..00f79c7
--- /dev/null
+++ b/t/data/spin/update/input/script.rpod
@@ -0,0 +1,3 @@
+/path/script
+
+/~eagle/styles/script.css
diff --git a/t/data/spin/update/output/module.spin b/t/data/spin/update/output/module.spin
new file mode 100644
index 0000000..31b97ce
--- /dev/null
+++ b/t/data/spin/update/output/module.spin
@@ -0,0 +1,2 @@
+format: pod
+path: /path/Module.pm
diff --git a/t/data/spin/update/output/readme.spin b/t/data/spin/update/output/readme.spin
new file mode 100644
index 0000000..c78a5cf
--- /dev/null
+++ b/t/data/spin/update/output/readme.spin
@@ -0,0 +1,6 @@
+format: pod
+options:
+ contents: true
+ navbar: false
+path: /path/readme.pod
+title: Basic Information
diff --git a/t/data/spin/update/output/script.spin b/t/data/spin/update/output/script.spin
new file mode 100644
index 0000000..5be3d64
--- /dev/null
+++ b/t/data/spin/update/output/script.spin
@@ -0,0 +1,3 @@
+format: pod
+path: /path/script
+style: /~eagle/styles/script.css
diff --git a/t/dist/basic.t b/t/dist/basic.t
index 6fcf2bc..dcc6b1b 100755
--- a/t/dist/basic.t
+++ b/t/dist/basic.t
@@ -20,6 +20,7 @@ use File::Temp;
use Git::Repository;
use IPC::Run qw(run);
use IPC::System::Simple qw(capturex systemx);
+use List::Util qw(first);
use Test::More;
@@ -52,9 +53,13 @@ $repo->run(add => '-A', q{.});
$repo->run(commit => '-q', '-m', 'Initial commit');
# Check whether we have all the necessary tools to run the test.
+my @branches = $repo->run(
+ 'for-each-ref' => '--format=%(refname:short)', 'refs/heads/',
+);
+my $head = first { $_ eq 'main' || $_ eq 'master' } @branches;
my $result;
eval {
- my $archive = $repo->command(archive => 'HEAD');
+ my $archive = $repo->command(archive => '--prefix=foo/', $head);
my $out;
$result = run([qw(tar tf -)], '<', $archive->stdout, '>', \$out);
$archive->close();
diff --git a/t/lib/Test/DocKnot/Spin.pm b/t/lib/Test/DocKnot/Spin.pm
index c7c33b8..2c520a2 100644
--- a/t/lib/Test/DocKnot/Spin.pm
+++ b/t/lib/Test/DocKnot/Spin.pm
@@ -82,6 +82,10 @@ sub is_spin_output_tree {
# File::Find on the output directory.
my $check_output = sub {
my $file = $_;
+ if ($file eq '.git') {
+ $File::Find::prune = 1;
+ return;
+ }
return if -d $file;
# Determine the relative path and mark it as seen.
@@ -191,7 +195,7 @@ Russ Allbery <rra@cpan.org>
=head1 COPYRIGHT AND LICENSE
-Copyright 2021 Russ Allbery <rra@cpan.org>
+Copyright 2021-2022 Russ Allbery <rra@cpan.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/t/lib/Test/RRA.pm b/t/lib/Test/RRA.pm
index c432d0c..2e34bf5 100644
--- a/t/lib/Test/RRA.pm
+++ b/t/lib/Test/RRA.pm
@@ -52,7 +52,7 @@ BEGIN {
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '10.01';
+ $VERSION = '10.02';
}
# Compare a string to the contents of a file, similar to the standard is()
diff --git a/t/lib/Test/RRA/Config.pm b/t/lib/Test/RRA/Config.pm
index 75419ea..a2ba32c 100644
--- a/t/lib/Test/RRA/Config.pm
+++ b/t/lib/Test/RRA/Config.pm
@@ -32,7 +32,7 @@ BEGIN {
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '10.01';
+ $VERSION = '10.02';
}
# If C_TAP_BUILD or C_TAP_SOURCE are set in the environment, look for
diff --git a/t/lib/Test/RRA/ModuleVersion.pm b/t/lib/Test/RRA/ModuleVersion.pm
index d01c14b..aed52c1 100644
--- a/t/lib/Test/RRA/ModuleVersion.pm
+++ b/t/lib/Test/RRA/ModuleVersion.pm
@@ -29,7 +29,7 @@ BEGIN {
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '10.01';
+ $VERSION = '10.02';
}
# A regular expression matching the version string for a module using the
@@ -103,9 +103,7 @@ sub _module_version {
my ($file) = @_;
open(my $data, q{<}, $file) or die "$0: cannot open $file: $!\n";
while (defined(my $line = <$data>)) {
- if ( $line =~ $REGEX_VERSION_PACKAGE
- || $line =~ $REGEX_VERSION_OLD)
- {
+ if ($line =~ $REGEX_VERSION_PACKAGE || $line =~ $REGEX_VERSION_OLD) {
my ($prefix, $version, $suffix) = ($1, $2, $3);
close($data) or die "$0: error reading from $file: $!\n";
return $version;
@@ -140,8 +138,8 @@ sub _update_module_version {
or die "$0: cannot create $file.new: $!\n";
SCAN:
while (defined(my $line = <$in>)) {
- if ( $line =~ s{ $REGEX_VERSION_PACKAGE }{$1$version$3}xms
- || $line =~ s{ $REGEX_VERSION_OLD }{$1$old_version$3}xms)
+ if ($line =~ s{ $REGEX_VERSION_PACKAGE }{$1$version$3}xms
+ || $line =~ s{ $REGEX_VERSION_OLD }{$1$old_version$3}xms)
{
print {$out} $line or die "$0: cannot write to $file.new: $!\n";
last SCAN;
@@ -265,7 +263,7 @@ Russ Allbery <eagle@eyrie.org>
=head1 COPYRIGHT AND LICENSE
-Copyright 2016, 2018-2020 Russ Allbery <eagle@eyrie.org>
+Copyright 2016, 2018-2020, 2022 Russ Allbery <eagle@eyrie.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/t/release/basic.t b/t/release/basic.t
new file mode 100755
index 0000000..4379136
--- /dev/null
+++ b/t/release/basic.t
@@ -0,0 +1,116 @@
+#!/usr/bin/perl
+#
+# Tests for the App::DocKnot::Release module API.
+#
+# Copyright 2022 Russ Allbery <rra@cpan.org>
+#
+# SPDX-License-Identifier: MIT
+
+use 5.024;
+use autodie;
+use warnings;
+
+use lib 't/lib';
+
+use Git::Repository ();
+use Path::Tiny qw(path);
+
+use Test::More tests => 30;
+
+# Isolate from the environment.
+local $ENV{XDG_CONFIG_HOME} = '/nonexistent';
+local $ENV{XDG_CONFIG_DIRS} = '/nonexistent';
+
+# Load the module.
+require_ok('App::DocKnot::Release');
+
+# Construct a working area.
+my $tempdir = Path::Tiny->tempdir();
+my $archive_path = $tempdir->child('archive');
+$archive_path->mkpath();
+my $old_path = $archive_path->child('ARCHIVE');
+my $dist_path = $tempdir->child('dist');
+$dist_path->mkpath();
+
+# Make a release when there are no existing files.
+my @extensions = qw(tar.gz tar.gz.asc tar.xz tar.xz.asc);
+for my $ext (@extensions) {
+ $dist_path->child('Empty-1.9.' . $ext)->touch();
+}
+my $metadata = path('t', 'data', 'dist', 'package', 'docs', 'docknot.yaml');
+my %options = (
+ archivedir => $archive_path,
+ distdir => $dist_path,
+ metadata => $metadata,
+);
+my $release = App::DocKnot::Release->new(\%options);
+$release->release();
+
+# Check that the files were copied correctly and the symlinks were created.
+for my $ext (@extensions) {
+ my $file = 'Empty-1.9.' . $ext;
+ ok($archive_path->child('devel', $file)->is_file(), "Copied $file");
+ my $link = 'Empty.' . $ext;
+ is(readlink($archive_path->child('devel', $link)), $file, "Linked $link");
+}
+
+# Build a Git repository and a .versions file.
+my $spin_path = $tempdir->child('spin');
+$spin_path->mkpath();
+my $versions_path = $spin_path->child('.versions');
+$versions_path->spew_utf8(
+ "empty 1.9 2022-01-01 16:00:00 software/empty/index.th\n",
+);
+Git::Repository->run('init', { cwd => "$spin_path", quiet => 1 });
+my $repo = Git::Repository->new(work_tree => "$spin_path");
+$repo->run(config => '--add', 'user.name', 'Test');
+$repo->run(config => '--add', 'user.email', 'test@example.com');
+$repo->run(add => '-A', q{.});
+$repo->run(commit => '-q', '-m', 'Initial commit');
+
+# Construct a configuration file.
+my $config_path = $tempdir->child('docknot', 'config.yaml');
+$config_path->parent()->mkpath();
+my @config = (
+ "archivedir: $archive_path",
+ "distdir: $dist_path",
+ "versions: $versions_path",
+);
+$config_path->spew_utf8(join("\n", @config), "\n");
+local $ENV{XDG_CONFIG_HOME} = "$tempdir";
+
+# Make another release, now relying on the global configuration. Add some
+# other files to distdir to ensure they're ignored.
+for my $ext (@extensions) {
+ $dist_path->child('Empty-1.10.' . $ext)->touch();
+ $dist_path->child('foo-1.0.' . $ext)->touch();
+}
+$release = App::DocKnot::Release->new({ metadata => $metadata });
+$release->release();
+
+# Check that the files were copied correctly, the symlinks were created, and
+# the old files were moved. Check that the old files were copied to the
+# archive directory.
+for my $ext (@extensions) {
+ my $file = 'Empty-1.10.' . $ext;
+ ok($archive_path->child('devel', $file)->is_file(), "Copied $file");
+ my $old = 'Empty-1.9.' . $ext;
+ ok(!$archive_path->child('devel', $old)->is_file(), "Removed $old");
+ ok(
+ $archive_path->child('ARCHIVE', 'Empty', $old)->is_file(),
+ "Archived $old",
+ );
+ my $link = 'Empty.' . $ext;
+ is(readlink($archive_path->child('devel', $link)), $file, "Updated $link");
+}
+
+# Check that the version file was updated.
+my @versions = split(q{ }, $versions_path->slurp_utf8());
+is($versions[0], 'empty', '.versions line');
+is($versions[1], '1.10', '...version updated');
+isnt(join(q{ }, @versions[2, 3]), '2022-01-01 16:00:00', '...date updated');
+is($versions[4], 'software/empty/index.th', '...dependency unchanged');
+
+# Check that the change was staged.
+my $status = $repo->run('status', '-s');
+is($status, ' M .versions', '.versions change was staged');
diff --git a/t/spin/errors.t b/t/spin/errors.t
index d4cc565..c6e1ce6 100755
--- a/t/spin/errors.t
+++ b/t/spin/errors.t
@@ -43,5 +43,5 @@ my ($stdout, $stderr) = capture {
# Simplify the file name, and then check against the expected output.
$stderr =~ s{ ^ [^:]+/errors[.]th: }{errors.th:}xmsg;
-$stderr =~ s{ (cannot [ ] stat [^:]+): .* }{$1\n}xms;
+$stderr =~ s{ (cannot [ ] stat [ ] file [ ]) /[^:]+/([^/:]+) : .* }{$1$2\n}xms;
is($stderr, $EXPECTED_ERRORS, 'errors are correct');
diff --git a/t/spin/sitemap.t b/t/spin/sitemap.t
index 59f8fe3..b51d675 100755
--- a/t/spin/sitemap.t
+++ b/t/spin/sitemap.t
@@ -40,7 +40,7 @@ is_deeply(\@navbar, [], 'navbar for unknown page');
# exercised by the test of spinning a tree of files.
@links = $sitemap->links('/faqs/soundness-inn.html');
my @expected = (
- q{ <link rel="next" href="soundness-cnews.html"}
+ q{ <link rel="next" href="soundness-cnews.html"}
. qq{ title="Soundness for C News" />\n},
qq{ <link rel="up" href="./" title="FAQs and Documentation" />\n},
qq{ <link rel="top" href="../" />\n},
diff --git a/t/spin/tree.t b/t/spin/tree.t
index d2daab1..700f961 100755
--- a/t/spin/tree.t
+++ b/t/spin/tree.t
@@ -35,35 +35,35 @@ Generating RSS file .../changes.rss
Updating .../changes.rss
Spinning .../changes.html
Spinning .../index.html
-Updating .../names.png
-Spinning .../random.html
Creating .../journal
Generating index file .../journal/index.th
Generating RSS file .../journal/index.rss
Generating RSS file .../journal/debian.rss
Generating RSS file .../journal/reviews.rss
+Updating .../names.png
+Spinning .../random.html
+Creating .../reviews
+Creating .../software
+Creating .../usefor
+Creating .../journal/2011-08
Updating .../journal/debian.rss
Updating .../journal/index.rss
Spinning .../journal/index.html
Updating .../journal/reviews.rss
-Creating .../journal/2011-08
-Spinning .../journal/2011-08/006.html
-Creating .../reviews
Creating .../reviews/books
-Spinning .../reviews/books/0-385-49362-2.html
-Creating .../software
-Spinning .../software/index.html
Creating .../software/docknot
-Spinning .../software/docknot/index.html
-Creating .../software/docknot/api
-Converting .../software/docknot/api/app-docknot.html
-Creating .../usefor
-Spinning .../usefor/index.html
+Spinning .../software/index.html
Creating .../usefor/drafts
+Spinning .../usefor/index.html
+Spinning .../journal/2011-08/006.html
+Spinning .../reviews/books/0-385-49362-2.html
+Creating .../software/docknot/api
+Spinning .../software/docknot/index.html
Updating .../usefor/drafts/draft-ietf-usefor-message-id-01.txt
Updating .../usefor/drafts/draft-ietf-usefor-posted-mailed-01.txt
Updating .../usefor/drafts/draft-ietf-usefor-useage-01.txt
Updating .../usefor/drafts/draft-lindsey-usefor-signed-01.txt
+Converting .../software/docknot/api/app-docknot.html
OUTPUT
BEGIN { use_ok('App::DocKnot::Util', qw(print_fh)) }
diff --git a/t/spin/versions.t b/t/spin/versions.t
index 640e143..7f1e62b 100755
--- a/t/spin/versions.t
+++ b/t/spin/versions.t
@@ -19,8 +19,10 @@ use Test::More tests => 20;
require_ok('App::DocKnot::Spin::Versions');
-# All dates in the sample data are in America/Los_Angeles.
-local $ENV{TZ} = 'America/Los_Angeles';
+# All dates in the sample data are in America/Los_Angeles. Specify this in
+# the POSIX format in the hope this will also work on systems without tzinfo
+# installed.
+local $ENV{TZ} = 'PST8PDT,M3.2.0,M11.1.0';
tzset();
# Parse the file.
diff --git a/t/update/spin.t b/t/update/spin.t
new file mode 100755
index 0000000..c692c80
--- /dev/null
+++ b/t/update/spin.t
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+#
+# Tests for the spin part of the App::DocKnot::Update module API.
+#
+# Copyright 2022 Russ Allbery <rra@cpan.org>
+#
+# SPDX-License-Identifier: MIT
+
+use 5.024;
+use autodie;
+use warnings;
+
+use lib 't/lib';
+
+use File::Copy::Recursive qw(dircopy);
+use Git::Repository ();
+use Path::Tiny qw(path);
+use Test::DocKnot::Spin qw(is_spin_output_tree);
+
+use Test::More;
+
+# Isolate from the environment.
+local $ENV{XDG_CONFIG_HOME} = '/nonexistent';
+local $ENV{XDG_CONFIG_DIRS} = '/nonexistent';
+
+# Load the module.
+require_ok('App::DocKnot::Update');
+
+# Construct the source tree. Copy t/data/spin/update/input into a fresh Git
+# repository and commit it so that we can test the Git interaction.
+my $input = path('t', 'data', 'spin', 'update', 'input');
+my $tempdir = Path::Tiny->tempdir();
+Git::Repository->run('init', { cwd => "$tempdir", quiet => 1 });
+dircopy($input, "$tempdir")
+ or die "$0: cannot copy $input to $tempdir: $!\n";
+my $repo = Git::Repository->new(work_tree => "$tempdir");
+$repo->run(config => '--add', 'user.name', 'Test');
+$repo->run(config => '--add', 'user.email', 'test@example.com');
+$repo->run(add => '-A', q{.});
+$repo->run(commit => '-q', '-m', 'Initial commit');
+
+# Update the tree.
+my $update = App::DocKnot::Update->new();
+$update->update_spin($tempdir);
+
+# Check the resulting output.
+my $expected = path('t', 'data', 'spin', 'update', 'output');
+my $count = is_spin_output_tree("$tempdir", "$expected", 'Tree updated');
+my @changes = grep { m{ deleted | new [ ] file }xms } $repo->run('status');
+@changes = map { [split(q{ })] } sort(@changes);
+is_deeply(
+ \@changes,
+ [
+ ['deleted:', 'module.rpod'],
+ ['deleted:', 'readme.rpod'],
+ ['deleted:', 'script.rpod'],
+ ['new', 'file:', 'module.spin'],
+ ['new', 'file:', 'readme.spin'],
+ ['new', 'file:', 'script.spin'],
+ ],
+ 'Git operations',
+);
+
+# Report the end of testing.
+done_testing($count + 2);