Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
coke committed Mar 16, 2023
1 parent 1f2bd60 commit 771a223
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 20 deletions.
2 changes: 1 addition & 1 deletion doc/Type/Bool.rakudoc
Expand Up @@ -70,7 +70,7 @@ the "lowest" Bool enum value, its own predecessor is also C<False>.

method enums(--> Hash:D)

Returns a L<Hash|/type/Hash> of enum-pairs. Works on both the L<C<Bool>|/type/Bool> type
Returns a L<Hash|/type/Hash> of enum-pairs. Works on both the C<Bool> type
and any key.

say Bool.enums; # OUTPUT: «{False => 0, True => 1}␤»
Expand Down
90 changes: 71 additions & 19 deletions xt/rakudoc-types.rakutest
Expand Up @@ -8,7 +8,12 @@ When referring to items that are types, the required format is:
Any other formatting code that refers to a type will fail the test; any C<>
that isn't inside of an L<> will fail, and any L<> that doesn't have a C<>
will fail.
will fail. Links may end with an optional #id.
Exceptions:
=item Referring to a type on its own page should only use C<>.
=item It's Ok to refer to a routine page with the same name instead.
=end overview

Expand All @@ -26,56 +31,103 @@ if @files {
plan :skip-all<No rakudoc files specified>
}

# TODO: Renders #tags oddly.
sub render-node($node) {
my $type = $node.contents.join('');
my $result = $node.type ~ '<' ~ $type;
if $node.type eq 'L' {
$result ~= '|' ~ $node.meta
$result ~= '|' ~ $node.meta.join('');
}
$result ~= '>';

$result;
}

sub is-valid-type($node, $parent) {
# given a slashy type, see if that file exists on disk
# To work on case-insensitive file systems, we grep the dir listing
# rather than check a preconstructed path.

sub file-exists($type) {
next if $type.fc eq 'raku'|'perl'; # Too common

my @parts = $type.split('/');


my $path = "doc/Type".IO;
while @parts {
my $part = @parts.shift;
$part ~= '.rakudoc' unless @parts.elems;
return False unless $path.dir.grep(*.basename eq $part);
$path = $path.child($part);
}
return True;
}

sub is-valid-type($node, $parent, $file) {
# only care about I<>, C<>, L<>, etc.
return unless $node ~~ Pod::FormattingCode;
return if $node.type eq 'X'; # These are OK as is, and not user-visible

# Does this match a type?
my $type = $node.contents.join('').subst('::','/', :g);
return unless "doc/Type/$type.rakudoc".IO.f;
# Does this match a documented type?
my $type = $node.contents.join('');
my $type-slash = $type.subst('::', '/', :g);
my $type-colon = $type.subst('/', '::', :g);

return unless file-exists($type-slash);

if $file eq "doc/Type/$type-slash.rakudoc" {
# We are on the same page as this type. Don't link it, only C<> it.
if $node.type ne 'C' or $type ne $type-colon {
flunk "{render-node($node)} should be C<$type-colon> - self reference";
} elsif $parent ~~ Pod::FormattingCode {
flunk "{$parent.type}<{render-node($node)}> should be C<$type> - bad parent FormattingCode - self reference";
} else {
pass "{render-node($node)} OK - self reference";
}
return;
}

# Might be nested but we only report on the innermost here.
if $node.type ne 'C' {
flunk "{render-node($node)} should be L<C<$type>|/type/$type>";
flunk "{render-node($node)} should be L<C<$type>|/type/$type-colon>";
return;
}

# Probably in a paragraph
if $parent === Nil or ! ($parent ~~ Pod::FormattingCode) {
flunk "{render-node($node)} should be L<C<$type>|/type/$type>";
flunk "{render-node($node)} should be L<C<$type>|/type/$type-colon>";
return;
}

# Wrapped, but not in an L<>
if $parent.type ne 'L' {
flunk "$parent.type<{render-node($node)}> should be L<C<$type>|/type/$type> - bad parent FormattingCode";
flunk "$parent.type<{render-node($node)}> should be L<C<$type>|/type/$type-colon> - bad parent FormattingCode";
return;
} elsif $parent.meta ne "/type/$type" {
# Wrapped in an L<> but wrong URL
flunk "L<{render-node($node)}|$parent.meta> should be L<C<$type>|/type/$type> - bad link";
} else {
}

my $meta = $parent.meta.join('');
if $meta eq "/type/$type-colon" or
$meta.starts-with: "/type/{$type-colon}#" {
# \o/
pass "$type reference correctly formatted.";
pass "L<{render-node($node)}|$meta>";
} else {
if $meta.starts-with('/routine/') {
# Is this pointing to an routine page? /routine is generated, so we cannot verify
# the existence of an actual file; trust if present.
pass "L<{render-node($node)}|$meta> - routine";
} else {
# Wrapped in an L<> with wrong URL
flunk "L<{render-node($node)}|$meta> should be L<C<$type>|/type/$type-colon> - bad link";
}
}
}

sub walk-content($item, $parent) {
is-valid-type($item, $parent);
sub walk-content($item, $parent, $file) {
is-valid-type($item, $parent, $file);

next unless $item.can('contents');
for @($item.contents) -> $child {
walk-content($child, $item);
walk-content($child, $item, $file);
}
}

Expand All @@ -85,6 +137,6 @@ for @files -> $file {

# This emits pass or flunk for each local L<> found.
subtest $file => {
walk-content($_, Nil) for @chunks;
walk-content($_, Nil, $file) for @chunks;
}
}

0 comments on commit 771a223

Please sign in to comment.