118334Speter#!/usr/bin/perl
218334Speter
318334SpeterBEGIN {
490075Sobrien  if (-f './TestInit.pm') {
5169689Skan    @INC = '.';
618334Speter  } elsif (-f '../TestInit.pm') {
790075Sobrien    @INC = '..';
818334Speter  }
990075Sobrien}
1090075Sobrienuse TestInit qw(T); # T is chdir to the top level
1190075Sobrien
1290075Sobrienuse warnings;
1318334Speteruse strict;
1490075Sobrienuse Config;
1590075Sobrienuse Data::Dumper;
1690075Sobrienrequire './t/test.pl';
1790075Sobrien
1818334Speterplan("no_plan");
1918334Speter
2090075Sobrien# Test that all deprecations in regen/warnings.pl are mentioned in
21169689Skan# pod/perldeprecation.pod and that there is sufficient time between them.
22169689Skan
2318334Spetermy $pod_file = "./pod/perldeprecation.pod";
2418334Spetermy $warnings_file = "./regen/warnings.pl";
25132718Skan
2650397Sobriendo $warnings_file;
27132718Skanour $WARNING_TREE;
28132718Skan
2918334Spetermy $deprecated = $WARNING_TREE->{all}[1]{deprecated}[2];
3090075Sobrien
3190075Sobrienopen my $fh, "<", $pod_file
3218334Speter    or die "failed to open '$pod_file': $!";
3318334Spetermy $removed_in_version;
34132718Skanmy $subject;
3518334Spetermy %category_seen;
36117395Skanmy %subject_has_category;
37117395Skanmy $in_legacy;
38117395Skan
3918334Speterwhile (<$fh>) {
4018334Speter    if (/^=head2 (?|Perl (5\.\d+)(?:\.\d+)?|(Unscheduled))/) { # ignore minor version
4118334Speter        $removed_in_version = lc $1;
4290075Sobrien        if ($removed_in_version eq "5.38") {
43117395Skan            $in_legacy = 1;
44117395Skan        }
45117395Skan    }
46117395Skan    elsif (/^=head3 (.*)/) {
47117395Skan        my $new_subject = $1;
48117395Skan        if (!$in_legacy and $subject) {
4918334Speter            ok($subject_has_category{$subject},
5018334Speter                "Subject '$subject' has a category specified");
5118334Speter        }
52132718Skan        $subject = $new_subject;
5318334Speter    }
5418334Speter    elsif (/^Category: "([::\w]+)"/) {
5518334Speter        my $category = $1;
5690075Sobrien        $category_seen{$category} = $removed_in_version;
5718334Speter        $subject_has_category{$subject} = $category;
58117395Skan        next if $removed_in_version eq "unscheduled";
59117395Skan        my $tuple = $deprecated->{$category};
60117395Skan        ok( $tuple, "Deprecated category '$category' ($subject) exists in $warnings_file")
61117395Skan            or next;
6290075Sobrien        my $added_in_version = $tuple->[0];
6390075Sobrien        $added_in_version =~ s/(5\.\d{3})\d+/$1/;
6418334Speter
6590075Sobrien        my $diff = $removed_in_version - $added_in_version;
6690075Sobrien        cmp_ok($diff, ">=", 0.004, # two production cycles
6790075Sobrien            "Version change for '$category' ($subject) is sufficiently after deprecation date")
6890075Sobrien    }
6990075Sobrien}
7090075Sobrien# make sure that all the deprecated categories have an entry of some sort
7190075Sobrienforeach my $category (sort keys %$deprecated) {
7290075Sobrien    ok($category_seen{$category},"Deprecated category '$category' is documented in $pod_file");
7318334Speter}
7418334Speter# make sure that there arent any new uses of WARN_DEPRECATED,
7518334Speter# note that \< and \> are ERE expressions roughly equivalent to perl regex \b
7618334Speterif (-e ".git") {
7718334Speter    chomp(my @warn_deprecated = `git grep "\<WARN_DEPRECATED\>"`);
7890075Sobrien    my %files;
7990075Sobrien    foreach my $line (@warn_deprecated) {
8090075Sobrien        my ($file, $text) = split /:/, $line, 2;
8190075Sobrien        if ($file =~ m!^dist/Devel-PPPort! ||
8290075Sobrien            $file eq "t/porting/diag.t" ||
8318334Speter            ($file eq "warnings.h" && $text=~/^[=#]/)
8418334Speter        ) {
8518334Speter            next;
86117395Skan        }
8718334Speter        $files{$file}++;
8818334Speter    }
89117395Skan    is(0+keys %files, 0,
9090075Sobrien        "There should not be any new files which mention WARN_DEPRECATED");
9190075Sobrien}
9290075Sobrien
9318334Speter# Test that deprecation warnings are produced under "use warnings"
9490075Sobrien# (set above)
9590075Sobrien{
9618334Speter    my $warning = "nada";
9790075Sobrien    local $SIG{__WARN__} = sub { $warning = $_[0] };
9890075Sobrien    my $count = 0;
99    while ($count<1) {
100        LABEL: $count++;
101        goto DONE if $count>1;
102    }
103    goto LABEL;
104    DONE:
105    like($warning,
106        qr/Use of "goto" to jump into a construct is deprecated/,
107        "Got expected deprecation warning");
108}
109# Test that we can silence deprecation warnings with "no warnings 'deprecated'"
110# as we used to.
111{
112    no warnings 'deprecated';
113    my $warning = "nada";
114    local $SIG{__WARN__} = sub { $warning = $_[0] };
115    my $count = 0;
116    while ($count<1) {
117        LABEL: $count++;
118        goto DONE if $count>1;
119    }
120    goto LABEL;
121    DONE:
122    like($warning, qr/nada/,
123        "no warnings 'deprecated'; silenced deprecation warning as expected");
124}
125
126# Test that we can silence a specific deprecation warnings with "no warnings 'deprecated::$subcategory'"
127# and that by doing so we don't silence any other deprecation warnings.
128{
129    no warnings 'deprecated::goto_construct';
130    my $warning = "nada";
131    local $SIG{__WARN__} = sub { $warning = $_[0] };
132    my $count = 0;
133    while ($count<1) {
134        LABEL: $count++;
135        goto DONE if $count>1;
136    }
137    goto LABEL;
138    DONE:
139    like($warning, qr/nada/,
140        "no warnings 'deprecated::goto_construct'; silenced deprecation warning as expected");
141    @INC = ();
142    do "regen.pl"; # this should produce a deprecation warning
143    like($warning, qr/is no longer in \@INC/,
144        "no warnings 'deprecated::goto_construct'; did not silence deprecated::dot_in_inc warnings");
145}
146