Zuzu

 view release on metacpan or  search on metacpan

t/integration/cli-zuzuzoo.t  view on Meta::CPAN

use File::Temp qw( tempdir );
use IPC::Run qw( run );
use JSON::PP;

my $repo_root = File::Spec->rel2abs( File::Spec->catdir( File::Spec->curdir ) );
my $zuzu_bin = File::Spec->catfile( $repo_root, 'bin', 'zuzu.pl' );
my $zuzuzoo_bin = _zuzuzoo_script();

ok -x $zuzu_bin, 'bin/zuzu.pl exists and is executable';
ok -x $zuzuzoo_bin, 'zuzuzoo script exists and is executable';

sub _zuzuzoo_script {
	my @candidates = (
		File::Spec->catfile( $repo_root, 'blib', 'script', 'zuzuzoo' ),
		File::Spec->catfile( $repo_root, 'stdlib', 'scripts', 'zuzuzoo' ),
	);
	for my $candidate ( @candidates ) {
		return $candidate if -x $candidate;
	}
	return $candidates[-1];
}

sub run_zuzuzoo {
	my ( $home, $stdin, @args ) = @_;

	my @cmd = ( $zuzuzoo_bin, @args );
	my ( $stdout, $stderr ) = ( '', '' );
	$stdin = '' if ! defined $stdin;

	local $ENV{HOME} = $home;
	local $ENV{PATH} = File::Spec->catdir( $repo_root, 'bin' )
		. $Config::Config{path_sep}
		. File::Spec->catdir( $repo_root, 'blib', 'script' )
		. $Config::Config{path_sep} . $ENV{PATH};
	local $ENV{ZUZULIB} = File::Spec->catdir( $repo_root, 'stdlib', 'modules' )
		. $Config::Config{path_sep}
		. File::Spec->catdir( $repo_root, 'stdlib', 'test-modules' );
	local $ENV{ZUZU_COMMAND} = $zuzu_bin;
	run \@cmd, '<', \$stdin, '>', \$stdout, '2>', \$stderr;

	return {
		exit   => $? >> 8,
		stdout => $stdout,
		stderr => $stderr,
		output => $stdout . $stderr,
	};
}

sub make_dist_tar {
	my ( %args ) = @_;

	my $tmp = $args{tmp};
	my $name = $args{name};
	my $version = $args{version} // '1.0.0';
	my $module = $args{module};
	my $root_name = "$name-$version";
	my $dist_root = File::Spec->catdir( $tmp, $root_name );
	my $module_path = File::Spec->catfile(
		$dist_root,
		'modules',
		split m{/}, "$module.zzm",
	);
	my $meta_path = File::Spec->catfile(
		$dist_root,
		'zuzu-distribution.json',
	);

	make_path( dirname($module_path) );

	open my $mod_fh, '>:encoding(UTF-8)', $module_path
		or die "Could not create $module_path: $!";
	print {$mod_fh} <<"ZZM";
function version () {
\treturn "$version";
}
ZZM
	close $mod_fh;

	open my $meta_fh, '>:encoding(UTF-8)', $meta_path
		or die "Could not create $meta_path: $!";
	print {$meta_fh} <<"JSON";
{
	"name": "$name",
	"version": "$version",
	"author": "Example Author",
	"license": "CC0-1.0"
}
JSON
	close $meta_fh;

	my $tarball = File::Spec->catfile( $tmp, "$root_name.tar" );
	system( 'tar', '-cf', $tarball, '-C', $tmp, $root_name ) == 0
		or die "Could not create tarball $tarball";

	return $tarball;
}

sub installed_meta_path {
	my ( $home, $name, $version ) = @_;
	return File::Spec->catfile(
		$home,
		'.zuzu',
		'meta',
		"$name-$version.json",
	);
}

sub installed_module_path {
	my ( $home, $module ) = @_;
	return File::Spec->catfile(
		$home,
		'.zuzu',
		'modules',
		split m{/}, "$module.zzm",
	);
}

sub decode_json_output {
	my ( $text ) = @_;
	return JSON::PP->new->decode($text);
}

my $tmp = tempdir( CLEANUP => 1 );
my $tar_one = make_dist_tar(
	tmp     => $tmp,
	name    => 'phase-seven-one',
	version => '1.0.0',
	module  => 'phase7/one',
);
my $tar_two = make_dist_tar(
	tmp     => $tmp,
	name    => 'phase-seven-two',
	version => '1.0.0',
	module  => 'phase7/two',
);

my $usage_home = File::Spec->catdir( $tmp, 'home-usage' );
make_path($usage_home);

my $help = run_zuzuzoo( $usage_home, undef, '--help' );
is $help->{exit}, 0, '--help exits successfully';
like $help->{stdout}, qr/Usage:/, '--help prints usage';

my $usage_error = run_zuzuzoo( $usage_home, undef );
is $usage_error->{exit}, 2, 'missing command is a usage error';
like $usage_error->{stderr}, qr/Usage:/, 'usage error prints usage';

my $unknown = run_zuzuzoo( $usage_home, undef, 'bogus-command' );
is $unknown->{exit}, 2, 'unknown command exits with usage status';
like $unknown->{stderr}, qr/Unknown command: bogus-command/,
	'unknown command is reported';

my $bad_version = run_zuzuzoo( $usage_home, undef, '--version' );
is $bad_version->{exit}, 2, '--version is rejected with usage status';
like $bad_version->{stderr}, qr/--version is not supported/,
	'--version rejection is explicit';

my $dry_home = File::Spec->catdir( $tmp, 'home-dry-install' );
make_path($dry_home);
my $dry_install = run_zuzuzoo(
	$dry_home,
	undef,
	'install',
	'--dry-run',
	$tar_one,
	$tar_two,
);
is $dry_install->{exit}, 0, 'multi-target install dry-run succeeds';
like $dry_install->{stdout}, qr/phase-seven-one 1\.0\.0/,
	'install dry-run plans first target';
like $dry_install->{stdout}, qr/phase-seven-two 1\.0\.0/,
	'install dry-run plans second target';
like $dry_install->{stdout}, qr/Dry run complete/,
	'install dry-run reports completion';



( run in 0.532 second using v1.01-cache-2.11-cpan-71847e10f99 )