summaryrefslogtreecommitdiff
path: root/t/spin/tree.t
blob: b794b0490c258d458c85f4fff3480ba4b3dbc7f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/perl
#
# Test running spin on a tree of files.
#
# Copyright 2021 Russ Allbery <rra@cpan.org>
#
# SPDX-License-Identifier: MIT

use 5.024;
use autodie;
use warnings;

use lib 't/lib';

use Capture::Tiny qw(capture_stdout);
use Cwd qw(getcwd);
use File::Copy::Recursive qw(dircopy);
use File::Spec ();
use File::Temp ();
use Perl6::Slurp qw(slurp);
use POSIX qw(strftime);
use Test::DocKnot::Spin qw(is_spin_output_tree);

use Test::More;

# Expected output when spinning our tree of input files.
my $EXPECTED_OUTPUT = <<'OUTPUT';
Generating thread file .../changes.th
Generating RSS file .../changes.rss
Updating .../changes.rss
Spinning .../changes.html
Spinning .../index.html
Updating .../names.png
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 .../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
Running pod2thread for .../software/docknot/api/app-docknot.html
Creating .../usefor
Spinning .../usefor/index.html
Creating .../usefor/drafts
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
OUTPUT

require_ok('App::DocKnot::Spin');

# Copy the input tree to a new temporary directory since .rss files generate
# additional thread files.  Replace the rpod pointer since it points to a
# relative path in the source tree.
my $tmpdir  = File::Temp->newdir();
my $datadir = File::Spec->catfile('t', 'data', 'spin');
my $input   = File::Spec->catfile($datadir, 'input');
dircopy($input, $tmpdir->dirname)
  or die "Cannot copy $input to $tmpdir: $!\n";
my $rpod_source = File::Spec->catfile(getcwd(), 'lib', 'App', 'DocKnot.pm');
my $rpod_path   = File::Spec->catfile(
    $tmpdir->dirname, 'software', 'docknot', 'api',
    'app-docknot.rpod',
);
open(my $fh, '>', $rpod_path);
print {$fh} "$rpod_source\n" or die "Cannot write to $rpod_path: $!\n";
close($fh);

# Spin a tree of files.
my $output   = File::Temp->newdir();
my $expected = File::Spec->catfile($datadir, 'output');
my $spin     = App::DocKnot::Spin->new({ 'style-url' => '/~eagle/styles/' });
my $stdout   = capture_stdout {
    $spin->spin($tmpdir->dirname, $output->dirname);
};
my $count = is_spin_output_tree($output, $expected, 'spin');
is($stdout, $EXPECTED_OUTPUT, 'Expected spin output');

# Create a bogus file in the output tree.
my $bogus      = File::Spec->catfile($output->dirname, 'bogus');
my $bogus_file = File::Spec->catfile($bogus,           'some-file');
mkdir($bogus);
open($fh, '>', $bogus_file);
print {$fh} "Some stuff\n" or die "Cannot write to $bogus_file: $!\n";
close($fh);

# Spinning the same tree of files again should do nothing because of the
# modification timestamps.
$stdout = capture_stdout {
    $spin->spin($tmpdir->dirname, $output->dirname);
};
is($stdout, q{}, 'Spinning again does nothing');

# The extra file shouldn't be deleted.
ok(-d $bogus, 'Stray file and directory not deleted');

# Reconfigure spin to enable deletion, and run it again.  The only action
# taken should be to delete the stray file.
$spin
  = App::DocKnot::Spin->new({ delete => 1, 'style-url' => '/~eagle/styles/' });
$stdout = capture_stdout {
    $spin->spin($tmpdir->dirname, $output->dirname);
};
is(
    $stdout,
    "Deleting .../bogus/some-file\nDeleting .../bogus\n",
    'Spinning with delete option cleans up',
);
ok(!-e $bogus, 'Stray file and directory was deleted');

# Now, update the .versions file at the top of the input tree to change the
# timestamp to a second into the future.  This should force regeneration of
# only the software/docknot/index.html file.
my $versions_path = File::Spec->catfile($tmpdir->dirname, '.versions');
my $versions      = slurp($versions_path);
my $new_date      = strftime('%Y-%m-%d %T', localtime(time() + 1));
$versions =~ s{ \d{4}-\d\d-\d\d [ ] [\d:]+ }{$new_date}xms;
open(my $versions_fh, '>', $versions_path);
print {$versions_fh} $versions or die "Cannot write to $versions_path: $!\n";
close($versions_fh);
$stdout = capture_stdout {
    $spin->spin($tmpdir->dirname, $output->dirname);
};
is(
    $stdout,
    "Spinning .../software/docknot/index.html\n",
    'Spinning again regenerates the DocKnot page',
);

# Report the end of testing.
done_testing($count + 7);