App-makefilepl2cpanfile

 view release on metacpan or  search on metacpan

t/integration.t  view on Meta::CPAN


	ok exists $parsed->{runtime}{requires}{'Carp'},
		'PREREQ_PM entry extracted';
	ok exists $parsed->{runtime}{recommends}{'Cpanel::JSON::XS'},
		'META_MERGE recommends extracted';
	is $parsed->{runtime}{recommends}{'Cpanel::JSON::XS'}{version}, '4.00',
		'META_MERGE recommends version correct';

	my $out = App::makefilepl2cpanfile::generate(
		makefile     => "$mf",
		with_develop => 0,
	);
	like $out, qr/requires\s+'Carp'/,                       'Carp in output';
	like $out, qr/recommends\s+'Cpanel::JSON::XS', '4\.00'/, 'META_MERGE recommends in output';

	diag "Output:\n$out" if $ENV{TEST_VERBOSE};
};

# -----------------------------------------------------------------------
# 6. First-occurrence-wins for duplicate module declarations
#
# Strategy: when the same module appears in both PREREQ_PM (version 0)
# and a structured requires block (version 2.00), parse_prereqs() and
# generate() must honour the first occurrence (PREREQ_PM, version 0).
# -----------------------------------------------------------------------

subtest 'pipeline: first-occurrence-wins for duplicate module declarations' => sub {
	my $g = empty_home();
	my $mf = make_mf($MF_DUPLICATE);

	my $content = $mf->slurp_utf8;
	my $parsed  = App::makefilepl2cpanfile::parse_prereqs($content);

	# PREREQ_PM is parsed first; its version (0) must win over structured (2.00).
	is $parsed->{runtime}{requires}{'Moo'}{version}, 0,
		'first-occurrence-wins: PREREQ_PM version 0 takes precedence';

	my $out = App::makefilepl2cpanfile::generate(
		makefile     => "$mf",
		with_develop => 0,
	);

	# Version 0 → no version constraint in output (just "requires 'Moo';").
	like   $out, qr/requires 'Moo';/,     'Moo present without version (version 0 wins)';
	unlike $out, qr/requires 'Moo', '2\.00'/, 'version 2.00 from structured block NOT used';

	# Moo must appear exactly once.
	my @hits = ( $out =~ /\bMoo\b/g );
	is scalar @hits, 1, 'Moo appears exactly once in output';

	diag "Output:\n$out" if $ENV{TEST_VERBOSE};
};

# -----------------------------------------------------------------------
# 7. Idempotency: feeding generate() output back as 'existing'
#
# Strategy: generate a cpanfile from a Makefile.PL, then call generate()
# again with that output as the 'existing' argument.  The second output
# must equal the first — regeneration must be stable.
# This verifies that the develop-merge logic does not accumulate duplicates
# or otherwise mutate the output across iterations.
# -----------------------------------------------------------------------

subtest 'pipeline: generate() is idempotent when output fed back as existing' => sub {
	my $g = empty_home();
	my $mf = make_mf($MF_ALL_PHASES);

	my $first = App::makefilepl2cpanfile::generate(
		makefile     => "$mf",
		with_develop => 0,
	);

	my $second = App::makefilepl2cpanfile::generate(
		makefile     => "$mf",
		existing     => $first,
		with_develop => 0,
	);

	is $second, $first,
		'generate() is idempotent: second call with own output yields identical result';

	diag "First:\n$first\nSecond:\n$second" if $ENV{TEST_VERBOSE};
};

# -----------------------------------------------------------------------
# 8. Config file interaction: absent config → default develop tools
#
# Strategy: when no config file exists in the (mocked) home dir,
# generate() with with_develop => 1 must inject the built-in defaults
# (Devel::Cover, Perl::Critic, Test::Pod, Test::Pod::Coverage) into the
# develop block.
# -----------------------------------------------------------------------

subtest 'optional config: absent config -> default develop tools injected' => sub {
	my $g = empty_home();    # no config file in fake home
	my $mf  = make_mf($MF_SIMPLE);
	my $out = App::makefilepl2cpanfile::generate(
		makefile     => "$mf",
		with_develop => 1,
	);

	like $out, qr/on 'develop' => sub/,    'develop block present';
	like $out, qr/Perl::Critic/,           'default Perl::Critic injected';
	like $out, qr/Devel::Cover/,           'default Devel::Cover injected';
	like $out, qr/Test::Pod\b/,            'default Test::Pod injected';
	like $out, qr/Test::Pod::Coverage/,    'default Test::Pod::Coverage injected';

	diag "Output:\n$out" if $ENV{TEST_VERBOSE};
};

# -----------------------------------------------------------------------
# 9. Config file interaction: present config with custom tools
#
# Strategy: when a config file with a 'develop' section is present, those
# tools replace the built-in defaults entirely.  Default tools that are NOT
# listed in the config must NOT appear in the output.
# -----------------------------------------------------------------------

subtest 'optional config: present config -> custom tools replace defaults' => sub {
	my $g = home_with_config( {
		develop => {



( run in 3.153 seconds using v1.01-cache-2.11-cpan-f03e8824b8d )