xref: /openbsd-src/gnu/usr.bin/perl/cpan/CPAN-Meta/t/merge.t (revision 9f11ffb7133c203312a01e4b986886bc88c7d74b)
1use strict;
2use warnings;
3
4use Test::More;
5use CPAN::Meta;
6use CPAN::Meta::Merge;
7
8delete $ENV{PERL_YAML_BACKEND};
9delete $ENV{PERL_JSON_BACKEND};
10delete $ENV{CPAN_META_JSON_BACKEND};
11delete $ENV{CPAN_META_JSON_DECODER};
12
13my %base = (
14	abstract => 'This is a test',
15	author => ['A.U. Thor'],
16	generated_by => 'Myself',
17	license => [ 'perl_5' ],
18	resources => {
19		license => [ 'http://dev.perl.org/licenses/' ],
20                bugtracker => { web => 'https://rt.cpan.org/Dist/Display.html?Foo-Bar' },
21	},
22	prereqs => {
23		runtime => {
24			requires => {
25				Foo => '0',
26			},
27		},
28	},
29	dynamic_config => 0,
30	provides => {
31		Baz => {
32			file => 'lib/Baz.pm',
33		},
34	},
35	'meta-spec' => {
36		url => "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
37		version => 2,
38	},
39);
40
41my %first = (
42	author => [ 'I.M. Poster' ],
43	generated_by => 'Some other guy',
44	license => [ 'bsd' ],
45	resources => {
46		license => [ 'http://opensource.org/licenses/bsd-license.php' ],
47	},
48	prereqs => {
49		runtime => {
50			requires => {
51				Foo => '< 1',
52			},
53			recommends => {
54				Bar => '3.14',
55			},
56		},
57		test => {
58			requires => {
59				'Test::Bar' => 0,
60			},
61		},
62	},
63	dynamic_config => 1,
64	provides => {
65		Quz => {
66			file => 'lib/Quz.pm',
67		},
68	},
69);
70my %first_expected = (
71	abstract => 'This is a test',
72	author => [ 'A.U. Thor', 'I.M. Poster' ],
73	generated_by => 'Myself, Some other guy',
74	license => [ 'perl_5', 'bsd' ],
75	resources => {
76		license => [ 'http://dev.perl.org/licenses/', 'http://opensource.org/licenses/bsd-license.php' ],
77                bugtracker => { web => 'https://rt.cpan.org/Dist/Display.html?Foo-Bar' },
78	},
79	prereqs => {
80		runtime => {
81			requires => {
82				Foo => '>= 0, < 1',
83			},
84			recommends => {
85				Bar => '3.14',
86			},
87		},
88		test => {
89			requires => {
90				'Test::Bar' => 0,
91			},
92		},
93	},
94	provides => {
95		Baz => {
96			file => 'lib/Baz.pm',
97		},
98		Quz => {
99			file => 'lib/Quz.pm',
100		},
101	},
102	dynamic_config => 1,
103	'meta-spec' => {
104		url => "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
105		version => 2,
106	},
107);
108my %provides_merge_expected = (
109	abstract => 'This is a test',
110	author => ['A.U. Thor'],
111	generated_by => 'Myself',
112	license => [ 'perl_5' ],
113	resources => {
114		license => [ 'http://dev.perl.org/licenses/' ],
115		bugtracker => { web => 'https://rt.cpan.org/Dist/Display.html?Foo-Bar' },
116	},
117	prereqs => {
118		runtime => {
119			requires => {
120				Foo => '0',
121			},
122		},
123	},
124	dynamic_config => 0,
125	provides => {
126		Baz => {
127			file => 'lib/Baz.pm',
128			version => '0.001',         # same as %base, but for this extra key
129		},
130	},
131	'meta-spec' => {
132		url => "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
133		version => 2,
134	},
135);
136
137my $merger = CPAN::Meta::Merge->new(default_version => '2');
138
139my $first_result = $merger->merge(\%base, \%first);
140
141is_deeply($first_result, \%first_expected, 'First result is as expected');
142
143is_deeply($merger->merge(\%base, { abstract => 'This is a test' }), \%base, 'Can merge in identical abstract');
144is(
145    eval { $merger->merge(\%base, { abstract => 'And now for something else' }) },
146    undef,
147    'Trying to merge different abstract gives an exception',
148);
149like $@, qr/^Can't merge attribute abstract/, 'Exception looks right';
150
151is(
152    eval { $merger->merge(\%base, { resources => { bugtracker => { web => 'http://foo.com' } } } ) },
153    undef,
154    'Trying to merge a different bugtracker URL gives an exception',
155);
156like $@, qr/^Duplication of element resources\.bugtracker\.web /, 'Exception looks right';
157
158is(
159    eval { $merger->merge(\%base, { provides => { Baz => { file => 'Baz.pm' } } }) },
160    undef,
161    'Trying to merge different provides.$module.file gives an exception',
162);
163like $@, qr/^Duplication of element provides\.Baz\.file /, 'Exception looks right';
164
165my $provides_result = $merger->merge(\%base, { provides => { Baz => { file => 'lib/Baz.pm', version => '0.001' } } });
166is_deeply(
167	$provides_result,
168	\%provides_merge_expected,
169	'Trying to merge a new key for provides.$module is permitted; identical values are preserved',
170);
171
172my $extra_merger = CPAN::Meta::Merge->new(
173	default_version => '2',
174	extra_mappings => {
175		'x_toolkit' => 'set_addition',
176		'x_meta_meta' => {
177			name => 'identical',
178			tags => 'set_addition',
179		}
180	}
181);
182
183my $extra_results = $extra_merger->merge(\%base, {
184		x_toolkit => [ 'marble' ],
185		x_meta_meta => {
186			name => 'Test',
187			tags => [ 'Testing' ],
188		}
189	},
190	{ x_toolkit => [ 'trike'],
191		x_meta_meta => {
192			name => 'Test',
193			tags => [ 'TDD' ],
194		}
195	}
196);
197
198my $expected_nested_extra = {
199	name => 'Test',
200	tags => [ 'Testing', 'TDD' ],
201};
202is_deeply($extra_results->{x_toolkit}, [ 'marble', 'trike' ], 'Extra mapping fields are merged');
203is_deeply($extra_results->{x_meta_meta}, $expected_nested_extra, 'Nested extra mapping fields are merged' );
204
205my $adds_to = sub {
206  my ($left, $right, $path) = @_;
207  if ($right !~ /^\Q$left\E/) {
208    die sprintf "Can't merge attribute %s: '%s' does not start with '%s'", join('.', @{$path}), $right, $left;
209  }
210  return $right;
211};
212
213$extra_merger = CPAN::Meta::Merge->new(default_version => '2', extra_mappings => { 'abstract' => \&$adds_to } );
214my $extra_results2 = $extra_merger->merge({ abstract => 'This is a test.'}, { abstract => 'This is a test.  Includes more detail..' } );
215is($extra_results2->{abstract}, 'This is a test.  Includes more detail..', 'Extra mapping fields overwrite existing mappings');
216my $extra_failure = eval { $extra_merger->merge({ abstract => 'This is a test.'}, { abstract => 'This is a better test.' } ) };
217is($extra_failure, undef, 'Extra mapping produces a failure');
218like $@, qr/does not start with/, 'Exception looks right';
219
220
221
222# issue 67
223@base{qw/name version release_status/} = qw/Foo-Bar 0.01 testing/;
224my $base_obj = CPAN::Meta->create(\%base);
225ok my $first_result_obj = $merger->merge($base_obj, \%first), 'merging CPAN::Meta objects succeeds';
226
227done_testing();
228# vim: ts=4 sts=4 sw=4 tw=78 noet :
229