The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# t/83_modulemaker-long.t
# tests of the modulemaker utility
use strict;
use warnings;
use Carp;
use Cwd;
use File::Spec;
use File::Temp qw(tempdir);
use Test::More;
use_ok( 'ExtUtils::ModuleMaker' );
use_ok( 'ExtUtils::ModuleMaker::Auxiliary', qw(
    prepare_mockdirs
    basic_file_and_directory_tests
    license_text_test
    check_MakefilePL
    compact_build_tests
    check_pm_file
    read_file_string
) );
use Capture::Tiny qw( :all );

my $cwd = cwd();
my %reg_def = (
    AUTHOR      => "A\.\\sU\.\\sThor",
    EMAIL       => "a\.u\.thor\@a\.galaxy\.far\.far\.away",
    ABSTRACT    => "Module\\sabstract\\s\\(<=\\s44\\scharacters\\)\\sgoes\\shere",
);

{
    note("Set 1:  test against Testing::Defaults");

    my ($home_dir, $personal_defaults_dir) = prepare_mockdirs();
    local $ENV{HOME} = $home_dir;

    my $tdir = tempdir( CLEANUP => 1);
    ok(chdir $tdir, 'changed to temp directory for testing');

    my (@components, $module_name, $dist_name, $path_str);
    my ($mf);
    @components = ( qw| EU MM Testing Defaults | );
    $module_name = join('::' => @components);
    $dist_name = join('-' => @components);
    $path_str = File::Spec->catdir(@components);
    $mf = join('/' => (
        'lib', @components[0 .. ($#components - 1)], "$components[-1].pm"));

    my ($abstract, $author, $cpanid, $organization, $website, $email);
    $abstract = "Module abstract (<= 44 characters) goes here";
    $author = "Hilton Stallone";
    $cpanid = 'RAMBO';
    $organization = 'Parliamentary Pictures';
    $website = 'http://parliamentarypictures.com';
    $email = 'hiltons\@parliamentarypictures.com';

    my @system_args = (
        $^X, qq{-I$cwd/blib/lib}, qq{$cwd/blib/script/modulemaker},
        '--no-interactive',
        '--name' => $module_name,
        '--abstract' => qq{$abstract},
        '--author' => $author,
        '--cpanid' => $cpanid,
        '--organization' => $organization,
        '--website' => $website,
        '--email' => $email,
    );
    my ($stdout, $stderr, @results);
    ($stdout, $stderr, @results) = capture { system(@system_args); };
    ok(! $results[0], "system call to modulemaker exited successfully");

    basic_file_and_directory_tests($path_str);
    license_text_test($path_str, qr/Terms of Perl itself/);

    my @pred = (
        $module_name,
        quotemeta($mf),
        quotemeta($author),
        quotemeta($email),
        quotemeta($abstract),
    );

    check_MakefilePL($path_str, \@pred);

    ok(chdir $cwd, "Able to change back to starting directory");
}

{
    note("Set 2:  compact build; specify abstract");

    my ($home_dir, $personal_defaults_dir) = prepare_mockdirs();
    local $ENV{HOME} = $home_dir;

    my $tdir = tempdir( CLEANUP => 1);
    ok(chdir $tdir, 'changed to temp directory for testing');

    my (@components, $module_name, $dist_name, $path_str);
    my ($mf);
    @components = ( qw| XYZ ABC | );
    $module_name = join('::' => @components);
    $dist_name = join('-' => @components);
    $path_str = File::Spec->catdir(@components);
    $mf = join('/' => (
        'lib', @components[0 .. ($#components - 1)], "$components[-1].pm"));

    my ($abstract, $author, $cpanid, $organization, $website, $email);
    $abstract = "This is very abstract.";
    my @system_args = (
        $^X, qq{-I$cwd/blib/lib}, qq{$cwd/blib/script/modulemaker},
        '--no-interactive',
        '--compact',
        '--name' => $module_name,
        '--abstract' => qq{$abstract},
    );
    my ($stdout, $stderr, @results);
    ($stdout, $stderr, @results) = capture { system(@system_args); };
    ok(! $results[0], "system call to modulemaker exited successfully");

    my ($module_file, $test_file) = compact_build_tests(\@components);

    my @pred = (
        $module_name,
        quotemeta($mf),
        $reg_def{AUTHOR},
        $reg_def{EMAIL},
        quotemeta($abstract),
    );

    check_MakefilePL($dist_name, \@pred);

    ok(chdir $cwd, "Able to change back to starting directory");
}

{
    note("Set 3:  compact build; specify abstract and author");

    my ($home_dir, $personal_defaults_dir) = prepare_mockdirs();
    local $ENV{HOME} = $home_dir;

    my $tdir = tempdir( CLEANUP => 1);
    ok(chdir $tdir, 'changed to temp directory for testing');

    my (@components, $module_name, $dist_name, $path_str);
    my ($mf);
    @components = ( qw| XYZ ABC | );
    $module_name = join('::' => @components);
    $dist_name = join('-' => @components);
    $path_str = File::Spec->catdir(@components);
    $mf = join('/' => (
        'lib', @components[0 .. ($#components - 1)], "$components[-1].pm"));

    my ($abstract, $author, $cpanid, $organization, $website, $email);
    $abstract = "This is very abstract.";
    $author = "John Q Public";
    my @system_args = (
        $^X, qq{-I$cwd/blib/lib}, qq{$cwd/blib/script/modulemaker},
        '--no-interactive',
        '--compact',
        '--name' => $module_name,
        '--abstract' => qq{$abstract},
        '--author' => $author,
    );
    my ($stdout, $stderr, @results);
    ($stdout, $stderr, @results) = capture { system(@system_args); };
    ok(! $results[0], "system call to modulemaker exited successfully");

    my ($module_file, $test_file) = compact_build_tests(\@components);

    my @pred = (
        $module_name,
        quotemeta($mf),
        quotemeta($author),
        $reg_def{EMAIL},
        quotemeta($abstract),
    );

    check_MakefilePL($dist_name, \@pred);

    ok(chdir $cwd, "Able to change back to starting directory");
}

{
    note("Set 4:  compact build; specify abstract, author and email");

    my ($home_dir, $personal_defaults_dir) = prepare_mockdirs();
    local $ENV{HOME} = $home_dir;

    my $tdir = tempdir( CLEANUP => 1);
    ok(chdir $tdir, 'changed to temp directory for testing');

    my (@components, $module_name, $dist_name, $path_str);
    my ($mf);
    @components = ( qw| XYZ ABC | );
    $module_name = join('::' => @components);
    $dist_name = join('-' => @components);
    $path_str = File::Spec->catdir(@components);
    $mf = join('/' => (
        'lib', @components[0 .. ($#components - 1)], "$components[-1].pm"));

    my ($abstract, $author, $cpanid, $organization, $website, $email);
    $abstract = "This is very abstract.";
    $author = "John Q Public";
    $email = 'jqpublic@calamity.jane.net';
    my @system_args = (
        $^X, qq{-I$cwd/blib/lib}, qq{$cwd/blib/script/modulemaker},
        '--no-interactive',
        '--compact',
        '--name' => $module_name,
        '--abstract' => qq{$abstract},
        '--author' => $author,
        '--email' => $email,
    );
    my ($stdout, $stderr, @results);
    ($stdout, $stderr, @results) = capture { system(@system_args); };
    ok(! $results[0], "system call to modulemaker exited successfully");

    my ($module_file, $test_file) = compact_build_tests(\@components);

    my @pred = (
        $module_name,
        quotemeta($mf),
        quotemeta($author),
        quotemeta($email),
        quotemeta($abstract),
    );

    check_MakefilePL($dist_name, \@pred);

    ok(chdir $cwd, "Able to change back to starting directory");
}

{
    note("Set 5:  compact build; omit POD from .pm file");

    my ($home_dir, $personal_defaults_dir) = prepare_mockdirs();
    local $ENV{HOME} = $home_dir;

    my $tdir = tempdir( CLEANUP => 1);
    ok(chdir $tdir, 'changed to temp directory for testing');

    my (@components, $module_name, $dist_name, $path_str);
    my ($mf);
    @components = ( qw| XYZ ABC | );
    $module_name = join('::' => @components);
    $dist_name = join('-' => @components);
    $path_str = File::Spec->catdir(@components);
    $mf = join('/' => (
        'lib', @components[0 .. ($#components - 1)], "$components[-1].pm"));

    my ($abstract, $author, $cpanid, $organization, $website, $email);
    my @system_args = (
        $^X, qq{-I$cwd/blib/lib}, qq{$cwd/blib/script/modulemaker},
        '--no-interactive',
        '--compact',
        '--no-pod',
        '--name' => $module_name,
    );
    my ($stdout, $stderr, @results);
    ($stdout, $stderr, @results) = capture { system(@system_args); };
    ok(! $results[0], "system call to modulemaker exited successfully");

    my ($module_file, $test_file) = compact_build_tests(\@components);

    my %pred = (
        'pod_present'       => 0,
    );
    check_pm_file($module_file, \%pred);

    ok(chdir $cwd, "Able to change back to starting directory");
}

{
    note("Set 6:  compact build; omit constructor from .pm file");

    my ($home_dir, $personal_defaults_dir) = prepare_mockdirs();
    local $ENV{HOME} = $home_dir;

    my $tdir = tempdir( CLEANUP => 1);
    ok(chdir $tdir, 'changed to temp directory for testing');

    my (@components, $module_name, $dist_name, $path_str);
    my ($mf);
    @components = ( qw| XYZ ABC | );
    $module_name = join('::' => @components);
    $dist_name = join('-' => @components);
    $path_str = File::Spec->catdir(@components);
    $mf = join('/' => (
        'lib', @components[0 .. ($#components - 1)], "$components[-1].pm"));

    my ($abstract, $author, $cpanid, $organization, $website, $email);
    my @system_args = (
        $^X, qq{-I$cwd/blib/lib}, qq{$cwd/blib/script/modulemaker},
        '--no-interactive',
        '--compact',
        '--no-new-method',
        '--name' => $module_name,
    );
    my ($stdout, $stderr, @results);
    ($stdout, $stderr, @results) = capture { system(@system_args); };
    ok(! $results[0], "system call to modulemaker exited successfully");

    my ($module_file, $test_file) = compact_build_tests(\@components);

    my %pred = (
        'constructor_present'       => 0,
    );
    check_pm_file($module_file, \%pred);

    ok(chdir $cwd, "Able to change back to starting directory");
}

{
    note("Set 7:  compact build; set VERSION to number other than 0.01");

    my ($home_dir, $personal_defaults_dir) = prepare_mockdirs();
    local $ENV{HOME} = $home_dir;

    my $tdir = tempdir( CLEANUP => 1);
    ok(chdir $tdir, 'changed to temp directory for testing');

    my (@components, $module_name, $dist_name, $path_str);
    my ($mf);
    @components = ( qw| XYZ ABC | );
    $module_name = join('::' => @components);
    $dist_name = join('-' => @components);
    $path_str = File::Spec->catdir(@components);
    $mf = join('/' => (
        'lib', @components[0 .. ($#components - 1)], "$components[-1].pm"));

    my ($abstract, $author, $cpanid, $organization, $website, $email);
    my $version = '0.3';
    my @system_args = (
        $^X, qq{-I$cwd/blib/lib}, qq{$cwd/blib/script/modulemaker},
        '-cI',
        '--name' => $module_name,
        '--version' => $version,
    );
    my ($stdout, $stderr, @results);
    ($stdout, $stderr, @results) = capture { system(@system_args); };
    ok(! $results[0], "system call to modulemaker exited successfully");

    my ($module_file, $test_file) = compact_build_tests(\@components);

    my $filetext;
    ok($filetext = read_file_string($module_file), "Able to read $module_file");
    like($filetext, qr/\$VERSION\s+=\s+'\Q$version\E'/,
        "VERSION number is correct and properly quoted");

    ok(chdir $cwd, "Able to change back to starting directory");
}

{
    note("Set 8:  test help switch: '-h'");

    my ($home_dir, $personal_defaults_dir) = prepare_mockdirs();
    local $ENV{HOME} = $home_dir;

    my $tdir = tempdir( CLEANUP => 1);
    ok(chdir $tdir, 'changed to temp directory for testing');

    my @system_args = (
        $^X, qq{-I$cwd/blib/lib}, qq{$cwd/blib/script/modulemaker},
        '--help',
    );
    my ($stdout, $stderr, @results);
    ($stdout, $stderr, @results) = capture { system(@system_args); };
    ok(! $results[0], "system call to modulemaker exited successfully");

    like($stdout, qr/^modulemaker \[-CIPVbch\]/s,
        "Got expected start of Usage message");
    like($stdout, qr/Currently Supported Features/s,
        "Got expected middle of Usage message");
    like($stdout, qr/modulemaker\s+ExtUtils::ModuleMaker\sversion:\s+\d\.\d{2}$/s,
        "Got expected end of Usage message");

    ok(chdir $cwd, "Able to change back to starting directory");
}

{
    note("Set 9:  compact build; -b flag sets Module::Build");

    my ($home_dir, $personal_defaults_dir) = prepare_mockdirs();
    local $ENV{HOME} = $home_dir;

    my $tdir = tempdir( CLEANUP => 1);
    ok(chdir $tdir, 'changed to temp directory for testing');

    my (@components, $module_name, $dist_name, $path_str);
    my ($mf);
    @components = ( qw| XYZ ABC | );
    $module_name = join('::' => @components);
    $dist_name = join('-' => @components);
    $path_str = File::Spec->catdir(@components);
    $mf = join('/' => (
        'lib', @components[0 .. ($#components - 1)], "$components[-1].pm"));

    my ($abstract, $author, $cpanid, $organization, $website, $email);
    my @system_args = (
        $^X, qq{-I$cwd/blib/lib}, qq{$cwd/blib/script/modulemaker},
        '--no-interactive',
        '--compact',
        '--name' => $module_name,
        '--build-system',
    );
    my ($stdout, $stderr, @results);
    ($stdout, $stderr, @results) = capture { system(@system_args); };
    ok(! $results[0], "system call to modulemaker exited successfully");

    for my $f ( qw| Changes MANIFEST Build.PL LICENSE README | ) {
        my $ff = File::Spec->catfile($dist_name, $f);
        ok (-e $ff, "$ff exists");
    }
    ok(! -e File::Spec->catfile($dist_name, 'Makefile.PL'),
        "Makefile.PL does not exist");
    for my $d ( qw| lib t | ) {
        my $dd = File::Spec->catdir($dist_name, $d);
        ok(-d $dd, "Directory '$dd' exists");
    }

    ok(chdir $cwd, "Able to change back to starting directory");
}

{
    note("Set 10:  compact build; various other previously untested options");

    my ($home_dir, $personal_defaults_dir) = prepare_mockdirs();
    local $ENV{HOME} = $home_dir;

    my $tdir = tempdir( CLEANUP => 1);
    ok(chdir $tdir, 'changed to temp directory for testing');

    my (@components, $module_name, $dist_name, $path_str);
    my ($mf);
    @components = ( qw| XYZ ABC | );
    $module_name = join('::' => @components);
    $dist_name = join('-' => @components);
    $path_str = File::Spec->catdir(@components);
    $mf = join('/' => (
        'lib', @components[0 .. ($#components - 1)], "$components[-1].pm"));

    my ($abstract, $author, $cpanid, $organization, $website, $email);
    $organization = 'World Wide Web, Inc.';
    $website = 'http://example.com';
    my $license = 'apache_1_1';
    my @system_args = (
        $^X, qq{-I$cwd/blib/lib}, qq{$cwd/blib/script/modulemaker},
        '--no-interactive',
        '--compact',
        '--changes-in-pod',  # Changes in POD
        '--name' => $module_name,
        '--license' => $license,
        '--organization' => $organization,
        '--website' => $website,
    );
    my ($stdout, $stderr, @results);
    ($stdout, $stderr, @results) = capture { system(@system_args); };
    ok(! $results[0], "system call to modulemaker exited successfully");

    for my $f ( qw| MANIFEST Makefile.PL LICENSE README | ) {
        my $ff = File::Spec->catfile($dist_name, $f);
        ok (-e $ff, "$ff exists");
    }
    for my $f ( qw| Build.PL Changes | ) {
        my $ff = File::Spec->catfile($dist_name, $f);
        ok (! -e $ff, "$ff does not exist");
    }
    for my $d ( qw| lib t | ) {
        my $dd = File::Spec->catdir($dist_name, $d);
        ok(-d $dd, "Directory '$dd' exists");
    }
    license_text_test($dist_name, qr/Apache Software License.*Version 1\.1/s);

    my $filetext = read_file_string(File::Spec->catfile($dist_name, $mf));
    ok($filetext, "Able to read $mf");
    like($filetext, qr/=head1 HISTORY/s, "HISTORY section placed in POD");
    like($filetext, qr/original version; created by ExtUtils::ModuleMaker/s,
        "Got expected text in HISTORY");
    like($filetext, qr/=head1 AUTHOR/s, "AUTHOR section placed in POD");
    like($filetext, qr/\Q$organization\E/s, "Got expected ORGANIZATION");
    like($filetext, qr/\Q$website\E/s, "Got expected WEBSITE");
    ok(chdir $cwd, "Able to change back to starting directory");
}


done_testing();