[svn-inject] Installing original source of libcpan-meta-yaml-perl (0.003)
Nicholas Bamber
13 years ago
0 | Revision history for CPAN-Meta-YAML | |
1 | ||
2 | 0.003 2011-01-02 17:32:05 EST5EDT | |
3 | ||
4 | - Generated from ADAMK/YAML-Tiny-1.46.tar.gz | |
5 | ||
6 | - Updated SEE ALSO documentation at Ingy's request | |
7 | ||
8 | - Remove CompileTests plugin from dist.ini | |
9 | ||
10 | 0.002 2010-12-17 12:31:12 EST5EDT | |
11 | ||
12 | - Generated from ADAMK/YAML-Tiny-1.46.tar.gz | |
13 | ||
14 | - Removed source $VERSION and replaced with our own | |
15 | ||
16 | - Added a SYNOPSIS to the generated Pod | |
17 | ||
18 | - Omits the dist.ini from the distribution | |
19 | ||
20 | 0.001 2010-12-17 08:53:42 EST5EDT | |
21 | ||
22 | - Generated from ADAMK/YAML-Tiny-1.46.tar.gz | |
23 | ||
24 | ||
25 |
0 | This software is copyright (c) 2010 by Adam Kennedy. | |
1 | ||
2 | This is free software; you can redistribute it and/or modify it under | |
3 | the same terms as the Perl 5 programming language system itself. | |
4 | ||
5 | Terms of the Perl programming language system itself | |
6 | ||
7 | a) the GNU General Public License as published by the Free | |
8 | Software Foundation; either version 1, or (at your option) any | |
9 | later version, or | |
10 | b) the "Artistic License" | |
11 | ||
12 | --- The GNU General Public License, Version 1, February 1989 --- | |
13 | ||
14 | This software is Copyright (c) 2010 by Adam Kennedy. | |
15 | ||
16 | This is free software, licensed under: | |
17 | ||
18 | The GNU General Public License, Version 1, February 1989 | |
19 | ||
20 | GNU GENERAL PUBLIC LICENSE | |
21 | Version 1, February 1989 | |
22 | ||
23 | Copyright (C) 1989 Free Software Foundation, Inc. | |
24 | 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA | |
25 | Everyone is permitted to copy and distribute verbatim copies | |
26 | of this license document, but changing it is not allowed. | |
27 | ||
28 | Preamble | |
29 | ||
30 | The license agreements of most software companies try to keep users | |
31 | at the mercy of those companies. By contrast, our General Public | |
32 | License is intended to guarantee your freedom to share and change free | |
33 | software--to make sure the software is free for all its users. The | |
34 | General Public License applies to the Free Software Foundation's | |
35 | software and to any other program whose authors commit to using it. | |
36 | You can use it for your programs, too. | |
37 | ||
38 | When we speak of free software, we are referring to freedom, not | |
39 | price. Specifically, the General Public License is designed to make | |
40 | sure that you have the freedom to give away or sell copies of free | |
41 | software, that you receive source code or can get it if you want it, | |
42 | that you can change the software or use pieces of it in new free | |
43 | programs; and that you know you can do these things. | |
44 | ||
45 | To protect your rights, we need to make restrictions that forbid | |
46 | anyone to deny you these rights or to ask you to surrender the rights. | |
47 | These restrictions translate to certain responsibilities for you if you | |
48 | distribute copies of the software, or if you modify it. | |
49 | ||
50 | For example, if you distribute copies of a such a program, whether | |
51 | gratis or for a fee, you must give the recipients all the rights that | |
52 | you have. You must make sure that they, too, receive or can get the | |
53 | source code. And you must tell them their rights. | |
54 | ||
55 | We protect your rights with two steps: (1) copyright the software, and | |
56 | (2) offer you this license which gives you legal permission to copy, | |
57 | distribute and/or modify the software. | |
58 | ||
59 | Also, for each author's protection and ours, we want to make certain | |
60 | that everyone understands that there is no warranty for this free | |
61 | software. If the software is modified by someone else and passed on, we | |
62 | want its recipients to know that what they have is not the original, so | |
63 | that any problems introduced by others will not reflect on the original | |
64 | authors' reputations. | |
65 | ||
66 | The precise terms and conditions for copying, distribution and | |
67 | modification follow. | |
68 | ||
69 | GNU GENERAL PUBLIC LICENSE | |
70 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
71 | ||
72 | 0. This License Agreement applies to any program or other work which | |
73 | contains a notice placed by the copyright holder saying it may be | |
74 | distributed under the terms of this General Public License. The | |
75 | "Program", below, refers to any such program or work, and a "work based | |
76 | on the Program" means either the Program or any work containing the | |
77 | Program or a portion of it, either verbatim or with modifications. Each | |
78 | licensee is addressed as "you". | |
79 | ||
80 | 1. You may copy and distribute verbatim copies of the Program's source | |
81 | code as you receive it, in any medium, provided that you conspicuously and | |
82 | appropriately publish on each copy an appropriate copyright notice and | |
83 | disclaimer of warranty; keep intact all the notices that refer to this | |
84 | General Public License and to the absence of any warranty; and give any | |
85 | other recipients of the Program a copy of this General Public License | |
86 | along with the Program. You may charge a fee for the physical act of | |
87 | transferring a copy. | |
88 | ||
89 | 2. You may modify your copy or copies of the Program or any portion of | |
90 | it, and copy and distribute such modifications under the terms of Paragraph | |
91 | 1 above, provided that you also do the following: | |
92 | ||
93 | a) cause the modified files to carry prominent notices stating that | |
94 | you changed the files and the date of any change; and | |
95 | ||
96 | b) cause the whole of any work that you distribute or publish, that | |
97 | in whole or in part contains the Program or any part thereof, either | |
98 | with or without modifications, to be licensed at no charge to all | |
99 | third parties under the terms of this General Public License (except | |
100 | that you may choose to grant warranty protection to some or all | |
101 | third parties, at your option). | |
102 | ||
103 | c) If the modified program normally reads commands interactively when | |
104 | run, you must cause it, when started running for such interactive use | |
105 | in the simplest and most usual way, to print or display an | |
106 | announcement including an appropriate copyright notice and a notice | |
107 | that there is no warranty (or else, saying that you provide a | |
108 | warranty) and that users may redistribute the program under these | |
109 | conditions, and telling the user how to view a copy of this General | |
110 | Public License. | |
111 | ||
112 | d) You may charge a fee for the physical act of transferring a | |
113 | copy, and you may at your option offer warranty protection in | |
114 | exchange for a fee. | |
115 | ||
116 | Mere aggregation of another independent work with the Program (or its | |
117 | derivative) on a volume of a storage or distribution medium does not bring | |
118 | the other work under the scope of these terms. | |
119 | ||
120 | 3. You may copy and distribute the Program (or a portion or derivative of | |
121 | it, under Paragraph 2) in object code or executable form under the terms of | |
122 | Paragraphs 1 and 2 above provided that you also do one of the following: | |
123 | ||
124 | a) accompany it with the complete corresponding machine-readable | |
125 | source code, which must be distributed under the terms of | |
126 | Paragraphs 1 and 2 above; or, | |
127 | ||
128 | b) accompany it with a written offer, valid for at least three | |
129 | years, to give any third party free (except for a nominal charge | |
130 | for the cost of distribution) a complete machine-readable copy of the | |
131 | corresponding source code, to be distributed under the terms of | |
132 | Paragraphs 1 and 2 above; or, | |
133 | ||
134 | c) accompany it with the information you received as to where the | |
135 | corresponding source code may be obtained. (This alternative is | |
136 | allowed only for noncommercial distribution and only if you | |
137 | received the program in object code or executable form alone.) | |
138 | ||
139 | Source code for a work means the preferred form of the work for making | |
140 | modifications to it. For an executable file, complete source code means | |
141 | all the source code for all modules it contains; but, as a special | |
142 | exception, it need not include source code for modules which are standard | |
143 | libraries that accompany the operating system on which the executable | |
144 | file runs, or for standard header files or definitions files that | |
145 | accompany that operating system. | |
146 | ||
147 | 4. You may not copy, modify, sublicense, distribute or transfer the | |
148 | Program except as expressly provided under this General Public License. | |
149 | Any attempt otherwise to copy, modify, sublicense, distribute or transfer | |
150 | the Program is void, and will automatically terminate your rights to use | |
151 | the Program under this License. However, parties who have received | |
152 | copies, or rights to use copies, from you under this General Public | |
153 | License will not have their licenses terminated so long as such parties | |
154 | remain in full compliance. | |
155 | ||
156 | 5. By copying, distributing or modifying the Program (or any work based | |
157 | on the Program) you indicate your acceptance of this license to do so, | |
158 | and all its terms and conditions. | |
159 | ||
160 | 6. Each time you redistribute the Program (or any work based on the | |
161 | Program), the recipient automatically receives a license from the original | |
162 | licensor to copy, distribute or modify the Program subject to these | |
163 | terms and conditions. You may not impose any further restrictions on the | |
164 | recipients' exercise of the rights granted herein. | |
165 | ||
166 | 7. The Free Software Foundation may publish revised and/or new versions | |
167 | of the General Public License from time to time. Such new versions will | |
168 | be similar in spirit to the present version, but may differ in detail to | |
169 | address new problems or concerns. | |
170 | ||
171 | Each version is given a distinguishing version number. If the Program | |
172 | specifies a version number of the license which applies to it and "any | |
173 | later version", you have the option of following the terms and conditions | |
174 | either of that version or of any later version published by the Free | |
175 | Software Foundation. If the Program does not specify a version number of | |
176 | the license, you may choose any version ever published by the Free Software | |
177 | Foundation. | |
178 | ||
179 | 8. If you wish to incorporate parts of the Program into other free | |
180 | programs whose distribution conditions are different, write to the author | |
181 | to ask for permission. For software which is copyrighted by the Free | |
182 | Software Foundation, write to the Free Software Foundation; we sometimes | |
183 | make exceptions for this. Our decision will be guided by the two goals | |
184 | of preserving the free status of all derivatives of our free software and | |
185 | of promoting the sharing and reuse of software generally. | |
186 | ||
187 | NO WARRANTY | |
188 | ||
189 | 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | |
190 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | |
191 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | |
192 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | |
193 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
194 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | |
195 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | |
196 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | |
197 | REPAIR OR CORRECTION. | |
198 | ||
199 | 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |
200 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | |
201 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | |
202 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | |
203 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | |
204 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | |
205 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | |
206 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | |
207 | POSSIBILITY OF SUCH DAMAGES. | |
208 | ||
209 | END OF TERMS AND CONDITIONS | |
210 | ||
211 | Appendix: How to Apply These Terms to Your New Programs | |
212 | ||
213 | If you develop a new program, and you want it to be of the greatest | |
214 | possible use to humanity, the best way to achieve this is to make it | |
215 | free software which everyone can redistribute and change under these | |
216 | terms. | |
217 | ||
218 | To do so, attach the following notices to the program. It is safest to | |
219 | attach them to the start of each source file to most effectively convey | |
220 | the exclusion of warranty; and each file should have at least the | |
221 | "copyright" line and a pointer to where the full notice is found. | |
222 | ||
223 | <one line to give the program's name and a brief idea of what it does.> | |
224 | Copyright (C) 19yy <name of author> | |
225 | ||
226 | This program is free software; you can redistribute it and/or modify | |
227 | it under the terms of the GNU General Public License as published by | |
228 | the Free Software Foundation; either version 1, or (at your option) | |
229 | any later version. | |
230 | ||
231 | This program is distributed in the hope that it will be useful, | |
232 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
233 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
234 | GNU General Public License for more details. | |
235 | ||
236 | You should have received a copy of the GNU General Public License | |
237 | along with this program; if not, write to the Free Software Foundation, | |
238 | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | |
239 | ||
240 | Also add information on how to contact you by electronic and paper mail. | |
241 | ||
242 | If the program is interactive, make it output a short notice like this | |
243 | when it starts in an interactive mode: | |
244 | ||
245 | Gnomovision version 69, Copyright (C) 19xx name of author | |
246 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |
247 | This is free software, and you are welcome to redistribute it | |
248 | under certain conditions; type `show c' for details. | |
249 | ||
250 | The hypothetical commands `show w' and `show c' should show the | |
251 | appropriate parts of the General Public License. Of course, the | |
252 | commands you use may be called something other than `show w' and `show | |
253 | c'; they could even be mouse-clicks or menu items--whatever suits your | |
254 | program. | |
255 | ||
256 | You should also get your employer (if you work as a programmer) or your | |
257 | school, if any, to sign a "copyright disclaimer" for the program, if | |
258 | necessary. Here a sample; alter the names: | |
259 | ||
260 | Yoyodyne, Inc., hereby disclaims all copyright interest in the | |
261 | program `Gnomovision' (a program to direct compilers to make passes | |
262 | at assemblers) written by James Hacker. | |
263 | ||
264 | <signature of Ty Coon>, 1 April 1989 | |
265 | Ty Coon, President of Vice | |
266 | ||
267 | That's all there is to it! | |
268 | ||
269 | ||
270 | --- The Artistic License 1.0 --- | |
271 | ||
272 | This software is Copyright (c) 2010 by Adam Kennedy. | |
273 | ||
274 | This is free software, licensed under: | |
275 | ||
276 | The Artistic License 1.0 | |
277 | ||
278 | The Artistic License | |
279 | ||
280 | Preamble | |
281 | ||
282 | The intent of this document is to state the conditions under which a Package | |
283 | may be copied, such that the Copyright Holder maintains some semblance of | |
284 | artistic control over the development of the package, while giving the users of | |
285 | the package the right to use and distribute the Package in a more-or-less | |
286 | customary fashion, plus the right to make reasonable modifications. | |
287 | ||
288 | Definitions: | |
289 | ||
290 | - "Package" refers to the collection of files distributed by the Copyright | |
291 | Holder, and derivatives of that collection of files created through | |
292 | textual modification. | |
293 | - "Standard Version" refers to such a Package if it has not been modified, | |
294 | or has been modified in accordance with the wishes of the Copyright | |
295 | Holder. | |
296 | - "Copyright Holder" is whoever is named in the copyright or copyrights for | |
297 | the package. | |
298 | - "You" is you, if you're thinking about copying or distributing this Package. | |
299 | - "Reasonable copying fee" is whatever you can justify on the basis of media | |
300 | cost, duplication charges, time of people involved, and so on. (You will | |
301 | not be required to justify it to the Copyright Holder, but only to the | |
302 | computing community at large as a market that must bear the fee.) | |
303 | - "Freely Available" means that no fee is charged for the item itself, though | |
304 | there may be fees involved in handling the item. It also means that | |
305 | recipients of the item may redistribute it under the same conditions they | |
306 | received it. | |
307 | ||
308 | 1. You may make and give away verbatim copies of the source form of the | |
309 | Standard Version of this Package without restriction, provided that you | |
310 | duplicate all of the original copyright notices and associated disclaimers. | |
311 | ||
312 | 2. You may apply bug fixes, portability fixes and other modifications derived | |
313 | from the Public Domain or from the Copyright Holder. A Package modified in such | |
314 | a way shall still be considered the Standard Version. | |
315 | ||
316 | 3. You may otherwise modify your copy of this Package in any way, provided that | |
317 | you insert a prominent notice in each changed file stating how and when you | |
318 | changed that file, and provided that you do at least ONE of the following: | |
319 | ||
320 | a) place your modifications in the Public Domain or otherwise make them | |
321 | Freely Available, such as by posting said modifications to Usenet or an | |
322 | equivalent medium, or placing the modifications on a major archive site | |
323 | such as ftp.uu.net, or by allowing the Copyright Holder to include your | |
324 | modifications in the Standard Version of the Package. | |
325 | ||
326 | b) use the modified Package only within your corporation or organization. | |
327 | ||
328 | c) rename any non-standard executables so the names do not conflict with | |
329 | standard executables, which must also be provided, and provide a separate | |
330 | manual page for each non-standard executable that clearly documents how it | |
331 | differs from the Standard Version. | |
332 | ||
333 | d) make other distribution arrangements with the Copyright Holder. | |
334 | ||
335 | 4. You may distribute the programs of this Package in object code or executable | |
336 | form, provided that you do at least ONE of the following: | |
337 | ||
338 | a) distribute a Standard Version of the executables and library files, | |
339 | together with instructions (in the manual page or equivalent) on where to | |
340 | get the Standard Version. | |
341 | ||
342 | b) accompany the distribution with the machine-readable source of the Package | |
343 | with your modifications. | |
344 | ||
345 | c) accompany any non-standard executables with their corresponding Standard | |
346 | Version executables, giving the non-standard executables non-standard | |
347 | names, and clearly documenting the differences in manual pages (or | |
348 | equivalent), together with instructions on where to get the Standard | |
349 | Version. | |
350 | ||
351 | d) make other distribution arrangements with the Copyright Holder. | |
352 | ||
353 | 5. You may charge a reasonable copying fee for any distribution of this | |
354 | Package. You may charge any fee you choose for support of this Package. You | |
355 | may not charge a fee for this Package itself. However, you may distribute this | |
356 | Package in aggregate with other (possibly commercial) programs as part of a | |
357 | larger (possibly commercial) software distribution provided that you do not | |
358 | advertise this Package as a product of your own. | |
359 | ||
360 | 6. The scripts and library files supplied as input to or produced as output | |
361 | from the programs of this Package do not automatically fall under the copyright | |
362 | of this Package, but belong to whomever generated them, and may be sold | |
363 | commercially, and may be aggregated with this Package. | |
364 | ||
365 | 7. C or perl subroutines supplied by you and linked into this Package shall not | |
366 | be considered part of this Package. | |
367 | ||
368 | 8. The name of the Copyright Holder may not be used to endorse or promote | |
369 | products derived from this software without specific prior written permission. | |
370 | ||
371 | 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED | |
372 | WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF | |
373 | MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
374 | ||
375 | The End | |
376 |
0 | Changes | |
1 | LICENSE | |
2 | MANIFEST | |
3 | MANIFEST.SKIP | |
4 | META.json | |
5 | META.yml | |
6 | Makefile.PL | |
7 | README | |
8 | lib/CPAN/Meta/YAML.pm | |
9 | t/01_compile.t | |
10 | t/02_basic.t | |
11 | t/03_regression.t | |
12 | t/04_scalar.t | |
13 | t/05_export.t | |
14 | t/11_meta_yml.t | |
15 | t/12_plagger.t | |
16 | t/13_perl_smith.t | |
17 | t/14_yaml_org.t | |
18 | t/15_multibyte.t | |
19 | t/16_nullrefs.t | |
20 | t/17_toolbar.t | |
21 | t/18_tap.t | |
22 | t/19_errors.t | |
23 | t/20_subclass.t | |
24 | t/21_bom.t | |
25 | t/22_comments.t | |
26 | t/data/HTML-WebDAO.yml | |
27 | t/data/Spreadsheet-Read.yml | |
28 | t/data/Template-Provider-Unicode-Japanese.yml | |
29 | t/data/multibyte.yml | |
30 | t/data/one.yml | |
31 | t/data/sample.yml | |
32 | t/data/toolbar.yml | |
33 | t/data/two.yml | |
34 | t/data/utf_16_le_bom.yml | |
35 | t/data/vanilla.yml | |
36 | t/lib/Test.pm | |
37 | xt/release/distmeta.t | |
38 | xt/release/pod-syntax.t |
0 | ^dist\.ini |
0 | { | |
1 | "abstract" : "Read and write a subset of YAML for CPAN Meta files", | |
2 | "author" : [ | |
3 | "Adam Kennedy <adamk@cpan.org>", | |
4 | "David Golden <dagolden@cpan.org>" | |
5 | ], | |
6 | "dynamic_config" : 0, | |
7 | "generated_by" : "Dist::Zilla version 4.200001, CPAN::Meta::Converter version 2.102400", | |
8 | "license" : [ | |
9 | "perl_5" | |
10 | ], | |
11 | "meta-spec" : { | |
12 | "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", | |
13 | "version" : "2" | |
14 | }, | |
15 | "name" : "CPAN-Meta-YAML", | |
16 | "no_index" : { | |
17 | "directory" : [ | |
18 | "t", | |
19 | "xt", | |
20 | "examples", | |
21 | "corpus" | |
22 | ], | |
23 | "package" : [ | |
24 | "DB" | |
25 | ] | |
26 | }, | |
27 | "prereqs" : { | |
28 | "configure" : { | |
29 | "requires" : { | |
30 | "ExtUtils::MakeMaker" : "6.31" | |
31 | } | |
32 | }, | |
33 | "runtime" : { | |
34 | "requires" : { | |
35 | "Carp" : 0, | |
36 | "Exporter" : 0, | |
37 | "Scalar::Util" : 0, | |
38 | "perl" : "5.004" | |
39 | } | |
40 | }, | |
41 | "test" : { | |
42 | "requires" : { | |
43 | "File::Spec" : 0, | |
44 | "File::Spec::Functions" : 0, | |
45 | "Test::More" : 0, | |
46 | "vars" : 0 | |
47 | } | |
48 | } | |
49 | }, | |
50 | "provides" : { | |
51 | "CPAN::Meta::YAML" : { | |
52 | "file" : "lib/CPAN/Meta/YAML.pm", | |
53 | "version" : "0.003" | |
54 | } | |
55 | }, | |
56 | "release_status" : "stable", | |
57 | "resources" : { | |
58 | "homepage" : "http://github.com/dagolden/cpan-meta-yaml/tree", | |
59 | "repository" : { | |
60 | "type" : "git", | |
61 | "url" : "git://github.com/dagolden/cpan-meta-yaml.git", | |
62 | "web" : "http://github.com/dagolden/cpan-meta-yaml/tree" | |
63 | } | |
64 | }, | |
65 | "version" : "0.003" | |
66 | } | |
67 |
0 | --- | |
1 | abstract: 'Read and write a subset of YAML for CPAN Meta files' | |
2 | author: | |
3 | - 'Adam Kennedy <adamk@cpan.org>' | |
4 | - 'David Golden <dagolden@cpan.org>' | |
5 | build_requires: | |
6 | File::Spec: 0 | |
7 | File::Spec::Functions: 0 | |
8 | Test::More: 0 | |
9 | vars: 0 | |
10 | configure_requires: | |
11 | ExtUtils::MakeMaker: 6.31 | |
12 | dynamic_config: 0 | |
13 | generated_by: 'Dist::Zilla version 4.200001, CPAN::Meta::Converter version 2.102400' | |
14 | license: perl | |
15 | meta-spec: | |
16 | url: http://module-build.sourceforge.net/META-spec-v1.4.html | |
17 | version: 1.4 | |
18 | name: CPAN-Meta-YAML | |
19 | no_index: | |
20 | directory: | |
21 | - t | |
22 | - xt | |
23 | - examples | |
24 | - corpus | |
25 | package: | |
26 | - DB | |
27 | provides: | |
28 | CPAN::Meta::YAML: | |
29 | file: lib/CPAN/Meta/YAML.pm | |
30 | version: 0.003 | |
31 | requires: | |
32 | Carp: 0 | |
33 | Exporter: 0 | |
34 | Scalar::Util: 0 | |
35 | perl: 5.004 | |
36 | resources: | |
37 | homepage: http://github.com/dagolden/cpan-meta-yaml/tree | |
38 | repository: git://github.com/dagolden/cpan-meta-yaml.git | |
39 | version: 0.003 |
0 | ||
1 | use strict; | |
2 | use warnings; | |
3 | ||
4 | BEGIN { require 5.004; } | |
5 | ||
6 | use ExtUtils::MakeMaker 6.31; | |
7 | ||
8 | ||
9 | ||
10 | my %WriteMakefileArgs = ( | |
11 | 'ABSTRACT' => 'Read and write a subset of YAML for CPAN Meta files', | |
12 | 'AUTHOR' => 'Adam Kennedy <adamk@cpan.org>, David Golden <dagolden@cpan.org>', | |
13 | 'BUILD_REQUIRES' => { | |
14 | 'File::Spec' => '0', | |
15 | 'File::Spec::Functions' => '0', | |
16 | 'Test::More' => '0', | |
17 | 'vars' => '0' | |
18 | }, | |
19 | 'CONFIGURE_REQUIRES' => { | |
20 | 'ExtUtils::MakeMaker' => '6.31' | |
21 | }, | |
22 | 'DISTNAME' => 'CPAN-Meta-YAML', | |
23 | 'EXE_FILES' => [], | |
24 | 'LICENSE' => 'perl', | |
25 | 'NAME' => 'CPAN::Meta::YAML', | |
26 | 'PREREQ_PM' => { | |
27 | 'Carp' => '0', | |
28 | 'Exporter' => '0', | |
29 | 'Scalar::Util' => '0' | |
30 | }, | |
31 | 'VERSION' => '0.003', | |
32 | 'test' => { | |
33 | 'TESTS' => 't/*.t' | |
34 | } | |
35 | ); | |
36 | ||
37 | ||
38 | unless ( eval { ExtUtils::MakeMaker->VERSION(6.56) } ) { | |
39 | my $br = delete $WriteMakefileArgs{BUILD_REQUIRES}; | |
40 | my $pp = $WriteMakefileArgs{PREREQ_PM}; | |
41 | for my $mod ( keys %$br ) { | |
42 | if ( exists $pp->{$mod} ) { | |
43 | $pp->{$mod} = $br->{$mod} if $br->{$mod} > $pp->{$mod}; | |
44 | } | |
45 | else { | |
46 | $pp->{$mod} = $br->{$mod}; | |
47 | } | |
48 | } | |
49 | } | |
50 | ||
51 | delete $WriteMakefileArgs{CONFIGURE_REQUIRES} | |
52 | unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; | |
53 | ||
54 | WriteMakefile(%WriteMakefileArgs); | |
55 | ||
56 | ||
57 |
0 | NAME | |
1 | CPAN::Meta::YAML - Read and write a subset of YAML for CPAN Meta files | |
2 | ||
3 | VERSION | |
4 | version 0.003 | |
5 | ||
6 | SYNOPSIS | |
7 | use CPAN::Meta::YAML; | |
8 | ||
9 | # methods for files | |
10 | $yaml = CPAN::Meta::YAML->read('META.yml'); | |
11 | $yaml->write('MYMETA.yml'); | |
12 | ||
13 | # methods for strings | |
14 | $yaml_text = $yaml->write_string; | |
15 | $yaml = CPAN::Meta::YAML->read_string($yaml_text); | |
16 | ||
17 | # finding the metadata | |
18 | my $meta = $yaml->[0]; | |
19 | ||
20 | # handling errors | |
21 | $yaml->write($file) | |
22 | or die CPAN::Meta::YAML->errstr; | |
23 | ||
24 | DESCRIPTION | |
25 | This module implements a subset of the YAML specification for use in | |
26 | reading and writing CPAN metadata files like META.yml and MYMETA.yml. It | |
27 | should not be used for any other general YAML parsing or generation | |
28 | task. | |
29 | ||
30 | SUPPORT | |
31 | This module is currently derived from YAML::Tiny by Adam Kennedy. If | |
32 | there are bugs in how it parses a particular META.yml file, please file | |
33 | a bug report in the YAML::Tiny bugtracker: | |
34 | <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=YAML-Tiny> | |
35 | ||
36 | SEE ALSO | |
37 | YAML::Tiny, YAML, YAML::XS | |
38 | ||
39 | AUTHORS | |
40 | * Adam Kennedy <adamk@cpan.org> | |
41 | ||
42 | * David Golden <dagolden@cpan.org> | |
43 | ||
44 | COPYRIGHT AND LICENSE | |
45 | This software is copyright (c) 2010 by Adam Kennedy. | |
46 | ||
47 | This is free software; you can redistribute it and/or modify it under | |
48 | the same terms as the Perl 5 programming language system itself. | |
49 |
0 | package CPAN::Meta::YAML; | |
1 | BEGIN { | |
2 | $CPAN::Meta::YAML::VERSION = '0.003'; | |
3 | } | |
4 | ||
5 | use strict; | |
6 | ||
7 | # UTF Support? | |
8 | sub HAVE_UTF8 () { $] >= 5.007003 } | |
9 | BEGIN { | |
10 | if ( HAVE_UTF8 ) { | |
11 | # The string eval helps hide this from Test::MinimumVersion | |
12 | eval "require utf8;"; | |
13 | die "Failed to load UTF-8 support" if $@; | |
14 | } | |
15 | ||
16 | # Class structure | |
17 | require 5.004; | |
18 | require Exporter; | |
19 | require Carp; | |
20 | @CPAN::Meta::YAML::ISA = qw{ Exporter }; | |
21 | @CPAN::Meta::YAML::EXPORT = qw{ Load Dump }; | |
22 | @CPAN::Meta::YAML::EXPORT_OK = qw{ LoadFile DumpFile freeze thaw }; | |
23 | ||
24 | # Error storage | |
25 | $CPAN::Meta::YAML::errstr = ''; | |
26 | } | |
27 | ||
28 | # The character class of all characters we need to escape | |
29 | # NOTE: Inlined, since it's only used once | |
30 | # my $RE_ESCAPE = '[\\x00-\\x08\\x0b-\\x0d\\x0e-\\x1f\"\n]'; | |
31 | ||
32 | # Printed form of the unprintable characters in the lowest range | |
33 | # of ASCII characters, listed by ASCII ordinal position. | |
34 | my @UNPRINTABLE = qw( | |
35 | z x01 x02 x03 x04 x05 x06 a | |
36 | x08 t n v f r x0e x0f | |
37 | x10 x11 x12 x13 x14 x15 x16 x17 | |
38 | x18 x19 x1a e x1c x1d x1e x1f | |
39 | ); | |
40 | ||
41 | # Printable characters for escapes | |
42 | my %UNESCAPES = ( | |
43 | z => "\x00", a => "\x07", t => "\x09", | |
44 | n => "\x0a", v => "\x0b", f => "\x0c", | |
45 | r => "\x0d", e => "\x1b", '\\' => '\\', | |
46 | ); | |
47 | ||
48 | # Special magic boolean words | |
49 | my %QUOTE = map { $_ => 1 } qw{ | |
50 | null Null NULL | |
51 | y Y yes Yes YES n N no No NO | |
52 | true True TRUE false False FALSE | |
53 | on On ON off Off OFF | |
54 | }; | |
55 | ||
56 | ||
57 | ||
58 | ||
59 | ||
60 | ##################################################################### | |
61 | # Implementation | |
62 | ||
63 | # Create an empty CPAN::Meta::YAML object | |
64 | sub new { | |
65 | my $class = shift; | |
66 | bless [ @_ ], $class; | |
67 | } | |
68 | ||
69 | # Create an object from a file | |
70 | sub read { | |
71 | my $class = ref $_[0] ? ref shift : shift; | |
72 | ||
73 | # Check the file | |
74 | my $file = shift or return $class->_error( 'You did not specify a file name' ); | |
75 | return $class->_error( "File '$file' does not exist" ) unless -e $file; | |
76 | return $class->_error( "'$file' is a directory, not a file" ) unless -f _; | |
77 | return $class->_error( "Insufficient permissions to read '$file'" ) unless -r _; | |
78 | ||
79 | # Slurp in the file | |
80 | local $/ = undef; | |
81 | local *CFG; | |
82 | unless ( open(CFG, $file) ) { | |
83 | return $class->_error("Failed to open file '$file': $!"); | |
84 | } | |
85 | my $contents = <CFG>; | |
86 | unless ( close(CFG) ) { | |
87 | return $class->_error("Failed to close file '$file': $!"); | |
88 | } | |
89 | ||
90 | $class->read_string( $contents ); | |
91 | } | |
92 | ||
93 | # Create an object from a string | |
94 | sub read_string { | |
95 | my $class = ref $_[0] ? ref shift : shift; | |
96 | my $self = bless [], $class; | |
97 | my $string = $_[0]; | |
98 | eval { | |
99 | unless ( defined $string ) { | |
100 | die \"Did not provide a string to load"; | |
101 | } | |
102 | ||
103 | # Byte order marks | |
104 | # NOTE: Keeping this here to educate maintainers | |
105 | # my %BOM = ( | |
106 | # "\357\273\277" => 'UTF-8', | |
107 | # "\376\377" => 'UTF-16BE', | |
108 | # "\377\376" => 'UTF-16LE', | |
109 | # "\377\376\0\0" => 'UTF-32LE' | |
110 | # "\0\0\376\377" => 'UTF-32BE', | |
111 | # ); | |
112 | if ( $string =~ /^(?:\376\377|\377\376|\377\376\0\0|\0\0\376\377)/ ) { | |
113 | die \"Stream has a non UTF-8 BOM"; | |
114 | } else { | |
115 | # Strip UTF-8 bom if found, we'll just ignore it | |
116 | $string =~ s/^\357\273\277//; | |
117 | } | |
118 | ||
119 | # Try to decode as utf8 | |
120 | utf8::decode($string) if HAVE_UTF8; | |
121 | ||
122 | # Check for some special cases | |
123 | return $self unless length $string; | |
124 | unless ( $string =~ /[\012\015]+\z/ ) { | |
125 | die \"Stream does not end with newline character"; | |
126 | } | |
127 | ||
128 | # Split the file into lines | |
129 | my @lines = grep { ! /^\s*(?:\#.*)?\z/ } | |
130 | split /(?:\015{1,2}\012|\015|\012)/, $string; | |
131 | ||
132 | # Strip the initial YAML header | |
133 | @lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines; | |
134 | ||
135 | # A nibbling parser | |
136 | while ( @lines ) { | |
137 | # Do we have a document header? | |
138 | if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?\z/ ) { | |
139 | # Handle scalar documents | |
140 | shift @lines; | |
141 | if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML[: ][\d\.]+)\z/ ) { | |
142 | push @$self, $self->_read_scalar( "$1", [ undef ], \@lines ); | |
143 | next; | |
144 | } | |
145 | } | |
146 | ||
147 | if ( ! @lines or $lines[0] =~ /^(?:---|\.\.\.)/ ) { | |
148 | # A naked document | |
149 | push @$self, undef; | |
150 | while ( @lines and $lines[0] !~ /^---/ ) { | |
151 | shift @lines; | |
152 | } | |
153 | ||
154 | } elsif ( $lines[0] =~ /^\s*\-/ ) { | |
155 | # An array at the root | |
156 | my $document = [ ]; | |
157 | push @$self, $document; | |
158 | $self->_read_array( $document, [ 0 ], \@lines ); | |
159 | ||
160 | } elsif ( $lines[0] =~ /^(\s*)\S/ ) { | |
161 | # A hash at the root | |
162 | my $document = { }; | |
163 | push @$self, $document; | |
164 | $self->_read_hash( $document, [ length($1) ], \@lines ); | |
165 | ||
166 | } else { | |
167 | die \"CPAN::Meta::YAML failed to classify the line '$lines[0]'"; | |
168 | } | |
169 | } | |
170 | }; | |
171 | if ( ref $@ eq 'SCALAR' ) { | |
172 | return $self->_error(${$@}); | |
173 | } elsif ( $@ ) { | |
174 | require Carp; | |
175 | Carp::croak($@); | |
176 | } | |
177 | ||
178 | return $self; | |
179 | } | |
180 | ||
181 | # Deparse a scalar string to the actual scalar | |
182 | sub _read_scalar { | |
183 | my ($self, $string, $indent, $lines) = @_; | |
184 | ||
185 | # Trim trailing whitespace | |
186 | $string =~ s/\s*\z//; | |
187 | ||
188 | # Explitic null/undef | |
189 | return undef if $string eq '~'; | |
190 | ||
191 | # Single quote | |
192 | if ( $string =~ /^\'(.*?)\'(?:\s+\#.*)?\z/ ) { | |
193 | return '' unless defined $1; | |
194 | $string = $1; | |
195 | $string =~ s/\'\'/\'/g; | |
196 | return $string; | |
197 | } | |
198 | ||
199 | # Double quote. | |
200 | # The commented out form is simpler, but overloaded the Perl regex | |
201 | # engine due to recursion and backtracking problems on strings | |
202 | # larger than 32,000ish characters. Keep it for reference purposes. | |
203 | # if ( $string =~ /^\"((?:\\.|[^\"])*)\"\z/ ) { | |
204 | if ( $string =~ /^\"([^\\"]*(?:\\.[^\\"]*)*)\"(?:\s+\#.*)?\z/ ) { | |
205 | # Reusing the variable is a little ugly, | |
206 | # but avoids a new variable and a string copy. | |
207 | $string = $1; | |
208 | $string =~ s/\\"/"/g; | |
209 | $string =~ s/\\([never\\fartz]|x([0-9a-fA-F]{2}))/(length($1)>1)?pack("H2",$2):$UNESCAPES{$1}/gex; | |
210 | return $string; | |
211 | } | |
212 | ||
213 | # Special cases | |
214 | if ( $string =~ /^[\'\"!&]/ ) { | |
215 | die \"CPAN::Meta::YAML does not support a feature in line '$string'"; | |
216 | } | |
217 | return {} if $string =~ /^{}(?:\s+\#.*)?\z/; | |
218 | return [] if $string =~ /^\[\](?:\s+\#.*)?\z/; | |
219 | ||
220 | # Regular unquoted string | |
221 | if ( $string !~ /^[>|]/ ) { | |
222 | if ( | |
223 | $string =~ /^(?:-(?:\s|$)|[\@\%\`])/ | |
224 | or | |
225 | $string =~ /:(?:\s|$)/ | |
226 | ) { | |
227 | die \"CPAN::Meta::YAML found illegal characters in plain scalar: '$string'"; | |
228 | } | |
229 | $string =~ s/\s+#.*\z//; | |
230 | return $string; | |
231 | } | |
232 | ||
233 | # Error | |
234 | die \"CPAN::Meta::YAML failed to find multi-line scalar content" unless @$lines; | |
235 | ||
236 | # Check the indent depth | |
237 | $lines->[0] =~ /^(\s*)/; | |
238 | $indent->[-1] = length("$1"); | |
239 | if ( defined $indent->[-2] and $indent->[-1] <= $indent->[-2] ) { | |
240 | die \"CPAN::Meta::YAML found bad indenting in line '$lines->[0]'"; | |
241 | } | |
242 | ||
243 | # Pull the lines | |
244 | my @multiline = (); | |
245 | while ( @$lines ) { | |
246 | $lines->[0] =~ /^(\s*)/; | |
247 | last unless length($1) >= $indent->[-1]; | |
248 | push @multiline, substr(shift(@$lines), length($1)); | |
249 | } | |
250 | ||
251 | my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n"; | |
252 | my $t = (substr($string, 1, 1) eq '-') ? '' : "\n"; | |
253 | return join( $j, @multiline ) . $t; | |
254 | } | |
255 | ||
256 | # Parse an array | |
257 | sub _read_array { | |
258 | my ($self, $array, $indent, $lines) = @_; | |
259 | ||
260 | while ( @$lines ) { | |
261 | # Check for a new document | |
262 | if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) { | |
263 | while ( @$lines and $lines->[0] !~ /^---/ ) { | |
264 | shift @$lines; | |
265 | } | |
266 | return 1; | |
267 | } | |
268 | ||
269 | # Check the indent level | |
270 | $lines->[0] =~ /^(\s*)/; | |
271 | if ( length($1) < $indent->[-1] ) { | |
272 | return 1; | |
273 | } elsif ( length($1) > $indent->[-1] ) { | |
274 | die \"CPAN::Meta::YAML found bad indenting in line '$lines->[0]'"; | |
275 | } | |
276 | ||
277 | if ( $lines->[0] =~ /^(\s*\-\s+)[^\'\"]\S*\s*:(?:\s+|$)/ ) { | |
278 | # Inline nested hash | |
279 | my $indent2 = length("$1"); | |
280 | $lines->[0] =~ s/-/ /; | |
281 | push @$array, { }; | |
282 | $self->_read_hash( $array->[-1], [ @$indent, $indent2 ], $lines ); | |
283 | ||
284 | } elsif ( $lines->[0] =~ /^\s*\-(\s*)(.+?)\s*\z/ ) { | |
285 | # Array entry with a value | |
286 | shift @$lines; | |
287 | push @$array, $self->_read_scalar( "$2", [ @$indent, undef ], $lines ); | |
288 | ||
289 | } elsif ( $lines->[0] =~ /^\s*\-\s*\z/ ) { | |
290 | shift @$lines; | |
291 | unless ( @$lines ) { | |
292 | push @$array, undef; | |
293 | return 1; | |
294 | } | |
295 | if ( $lines->[0] =~ /^(\s*)\-/ ) { | |
296 | my $indent2 = length("$1"); | |
297 | if ( $indent->[-1] == $indent2 ) { | |
298 | # Null array entry | |
299 | push @$array, undef; | |
300 | } else { | |
301 | # Naked indenter | |
302 | push @$array, [ ]; | |
303 | $self->_read_array( $array->[-1], [ @$indent, $indent2 ], $lines ); | |
304 | } | |
305 | ||
306 | } elsif ( $lines->[0] =~ /^(\s*)\S/ ) { | |
307 | push @$array, { }; | |
308 | $self->_read_hash( $array->[-1], [ @$indent, length("$1") ], $lines ); | |
309 | ||
310 | } else { | |
311 | die \"CPAN::Meta::YAML failed to classify line '$lines->[0]'"; | |
312 | } | |
313 | ||
314 | } elsif ( defined $indent->[-2] and $indent->[-1] == $indent->[-2] ) { | |
315 | # This is probably a structure like the following... | |
316 | # --- | |
317 | # foo: | |
318 | # - list | |
319 | # bar: value | |
320 | # | |
321 | # ... so lets return and let the hash parser handle it | |
322 | return 1; | |
323 | ||
324 | } else { | |
325 | die \"CPAN::Meta::YAML failed to classify line '$lines->[0]'"; | |
326 | } | |
327 | } | |
328 | ||
329 | return 1; | |
330 | } | |
331 | ||
332 | # Parse an array | |
333 | sub _read_hash { | |
334 | my ($self, $hash, $indent, $lines) = @_; | |
335 | ||
336 | while ( @$lines ) { | |
337 | # Check for a new document | |
338 | if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) { | |
339 | while ( @$lines and $lines->[0] !~ /^---/ ) { | |
340 | shift @$lines; | |
341 | } | |
342 | return 1; | |
343 | } | |
344 | ||
345 | # Check the indent level | |
346 | $lines->[0] =~ /^(\s*)/; | |
347 | if ( length($1) < $indent->[-1] ) { | |
348 | return 1; | |
349 | } elsif ( length($1) > $indent->[-1] ) { | |
350 | die \"CPAN::Meta::YAML found bad indenting in line '$lines->[0]'"; | |
351 | } | |
352 | ||
353 | # Get the key | |
354 | unless ( $lines->[0] =~ s/^\s*([^\'\" ][^\n]*?)\s*:(\s+(?:\#.*)?|$)// ) { | |
355 | if ( $lines->[0] =~ /^\s*[?\'\"]/ ) { | |
356 | die \"CPAN::Meta::YAML does not support a feature in line '$lines->[0]'"; | |
357 | } | |
358 | die \"CPAN::Meta::YAML failed to classify line '$lines->[0]'"; | |
359 | } | |
360 | my $key = $1; | |
361 | ||
362 | # Do we have a value? | |
363 | if ( length $lines->[0] ) { | |
364 | # Yes | |
365 | $hash->{$key} = $self->_read_scalar( shift(@$lines), [ @$indent, undef ], $lines ); | |
366 | } else { | |
367 | # An indent | |
368 | shift @$lines; | |
369 | unless ( @$lines ) { | |
370 | $hash->{$key} = undef; | |
371 | return 1; | |
372 | } | |
373 | if ( $lines->[0] =~ /^(\s*)-/ ) { | |
374 | $hash->{$key} = []; | |
375 | $self->_read_array( $hash->{$key}, [ @$indent, length($1) ], $lines ); | |
376 | } elsif ( $lines->[0] =~ /^(\s*)./ ) { | |
377 | my $indent2 = length("$1"); | |
378 | if ( $indent->[-1] >= $indent2 ) { | |
379 | # Null hash entry | |
380 | $hash->{$key} = undef; | |
381 | } else { | |
382 | $hash->{$key} = {}; | |
383 | $self->_read_hash( $hash->{$key}, [ @$indent, length($1) ], $lines ); | |
384 | } | |
385 | } | |
386 | } | |
387 | } | |
388 | ||
389 | return 1; | |
390 | } | |
391 | ||
392 | # Save an object to a file | |
393 | sub write { | |
394 | my $self = shift; | |
395 | my $file = shift or return $self->_error('No file name provided'); | |
396 | ||
397 | # Write it to the file | |
398 | open( CFG, '>' . $file ) or return $self->_error( | |
399 | "Failed to open file '$file' for writing: $!" | |
400 | ); | |
401 | print CFG $self->write_string; | |
402 | close CFG; | |
403 | ||
404 | return 1; | |
405 | } | |
406 | ||
407 | # Save an object to a string | |
408 | sub write_string { | |
409 | my $self = shift; | |
410 | return '' unless @$self; | |
411 | ||
412 | # Iterate over the documents | |
413 | my $indent = 0; | |
414 | my @lines = (); | |
415 | foreach my $cursor ( @$self ) { | |
416 | push @lines, '---'; | |
417 | ||
418 | # An empty document | |
419 | if ( ! defined $cursor ) { | |
420 | # Do nothing | |
421 | ||
422 | # A scalar document | |
423 | } elsif ( ! ref $cursor ) { | |
424 | $lines[-1] .= ' ' . $self->_write_scalar( $cursor, $indent ); | |
425 | ||
426 | # A list at the root | |
427 | } elsif ( ref $cursor eq 'ARRAY' ) { | |
428 | unless ( @$cursor ) { | |
429 | $lines[-1] .= ' []'; | |
430 | next; | |
431 | } | |
432 | push @lines, $self->_write_array( $cursor, $indent, {} ); | |
433 | ||
434 | # A hash at the root | |
435 | } elsif ( ref $cursor eq 'HASH' ) { | |
436 | unless ( %$cursor ) { | |
437 | $lines[-1] .= ' {}'; | |
438 | next; | |
439 | } | |
440 | push @lines, $self->_write_hash( $cursor, $indent, {} ); | |
441 | ||
442 | } else { | |
443 | Carp::croak("Cannot serialize " . ref($cursor)); | |
444 | } | |
445 | } | |
446 | ||
447 | join '', map { "$_\n" } @lines; | |
448 | } | |
449 | ||
450 | sub _write_scalar { | |
451 | my $string = $_[1]; | |
452 | return '~' unless defined $string; | |
453 | return "''" unless length $string; | |
454 | if ( $string =~ /[\x00-\x08\x0b-\x0d\x0e-\x1f\"\'\n]/ ) { | |
455 | $string =~ s/\\/\\\\/g; | |
456 | $string =~ s/"/\\"/g; | |
457 | $string =~ s/\n/\\n/g; | |
458 | $string =~ s/([\x00-\x1f])/\\$UNPRINTABLE[ord($1)]/g; | |
459 | return qq|"$string"|; | |
460 | } | |
461 | if ( $string =~ /(?:^\W|\s)/ or $QUOTE{$string} ) { | |
462 | return "'$string'"; | |
463 | } | |
464 | return $string; | |
465 | } | |
466 | ||
467 | sub _write_array { | |
468 | my ($self, $array, $indent, $seen) = @_; | |
469 | if ( $seen->{refaddr($array)}++ ) { | |
470 | die "CPAN::Meta::YAML does not support circular references"; | |
471 | } | |
472 | my @lines = (); | |
473 | foreach my $el ( @$array ) { | |
474 | my $line = (' ' x $indent) . '-'; | |
475 | my $type = ref $el; | |
476 | if ( ! $type ) { | |
477 | $line .= ' ' . $self->_write_scalar( $el, $indent + 1 ); | |
478 | push @lines, $line; | |
479 | ||
480 | } elsif ( $type eq 'ARRAY' ) { | |
481 | if ( @$el ) { | |
482 | push @lines, $line; | |
483 | push @lines, $self->_write_array( $el, $indent + 1, $seen ); | |
484 | } else { | |
485 | $line .= ' []'; | |
486 | push @lines, $line; | |
487 | } | |
488 | ||
489 | } elsif ( $type eq 'HASH' ) { | |
490 | if ( keys %$el ) { | |
491 | push @lines, $line; | |
492 | push @lines, $self->_write_hash( $el, $indent + 1, $seen ); | |
493 | } else { | |
494 | $line .= ' {}'; | |
495 | push @lines, $line; | |
496 | } | |
497 | ||
498 | } else { | |
499 | die "CPAN::Meta::YAML does not support $type references"; | |
500 | } | |
501 | } | |
502 | ||
503 | @lines; | |
504 | } | |
505 | ||
506 | sub _write_hash { | |
507 | my ($self, $hash, $indent, $seen) = @_; | |
508 | if ( $seen->{refaddr($hash)}++ ) { | |
509 | die "CPAN::Meta::YAML does not support circular references"; | |
510 | } | |
511 | my @lines = (); | |
512 | foreach my $name ( sort keys %$hash ) { | |
513 | my $el = $hash->{$name}; | |
514 | my $line = (' ' x $indent) . "$name:"; | |
515 | my $type = ref $el; | |
516 | if ( ! $type ) { | |
517 | $line .= ' ' . $self->_write_scalar( $el, $indent + 1 ); | |
518 | push @lines, $line; | |
519 | ||
520 | } elsif ( $type eq 'ARRAY' ) { | |
521 | if ( @$el ) { | |
522 | push @lines, $line; | |
523 | push @lines, $self->_write_array( $el, $indent + 1, $seen ); | |
524 | } else { | |
525 | $line .= ' []'; | |
526 | push @lines, $line; | |
527 | } | |
528 | ||
529 | } elsif ( $type eq 'HASH' ) { | |
530 | if ( keys %$el ) { | |
531 | push @lines, $line; | |
532 | push @lines, $self->_write_hash( $el, $indent + 1, $seen ); | |
533 | } else { | |
534 | $line .= ' {}'; | |
535 | push @lines, $line; | |
536 | } | |
537 | ||
538 | } else { | |
539 | die "CPAN::Meta::YAML does not support $type references"; | |
540 | } | |
541 | } | |
542 | ||
543 | @lines; | |
544 | } | |
545 | ||
546 | # Set error | |
547 | sub _error { | |
548 | $CPAN::Meta::YAML::errstr = $_[1]; | |
549 | undef; | |
550 | } | |
551 | ||
552 | # Retrieve error | |
553 | sub errstr { | |
554 | $CPAN::Meta::YAML::errstr; | |
555 | } | |
556 | ||
557 | ||
558 | ||
559 | ||
560 | ||
561 | ##################################################################### | |
562 | # YAML Compatibility | |
563 | ||
564 | sub Dump { | |
565 | CPAN::Meta::YAML->new(@_)->write_string; | |
566 | } | |
567 | ||
568 | sub Load { | |
569 | my $self = CPAN::Meta::YAML->read_string(@_); | |
570 | unless ( $self ) { | |
571 | Carp::croak("Failed to load YAML document from string"); | |
572 | } | |
573 | if ( wantarray ) { | |
574 | return @$self; | |
575 | } else { | |
576 | # To match YAML.pm, return the last document | |
577 | return $self->[-1]; | |
578 | } | |
579 | } | |
580 | ||
581 | BEGIN { | |
582 | *freeze = *Dump; | |
583 | *thaw = *Load; | |
584 | } | |
585 | ||
586 | sub DumpFile { | |
587 | my $file = shift; | |
588 | CPAN::Meta::YAML->new(@_)->write($file); | |
589 | } | |
590 | ||
591 | sub LoadFile { | |
592 | my $self = CPAN::Meta::YAML->read($_[0]); | |
593 | unless ( $self ) { | |
594 | Carp::croak("Failed to load YAML document from '" . ($_[0] || '') . "'"); | |
595 | } | |
596 | if ( wantarray ) { | |
597 | return @$self; | |
598 | } else { | |
599 | # Return only the last document to match YAML.pm, | |
600 | return $self->[-1]; | |
601 | } | |
602 | } | |
603 | ||
604 | ||
605 | ||
606 | ||
607 | ||
608 | ##################################################################### | |
609 | # Use Scalar::Util if possible, otherwise emulate it | |
610 | ||
611 | BEGIN { | |
612 | eval { | |
613 | require Scalar::Util; | |
614 | *refaddr = *Scalar::Util::refaddr; | |
615 | }; | |
616 | eval <<'END_PERL' if $@; | |
617 | # Failed to load Scalar::Util | |
618 | sub refaddr { | |
619 | my $pkg = ref($_[0]) or return undef; | |
620 | if ( !! UNIVERSAL::can($_[0], 'can') ) { | |
621 | bless $_[0], 'Scalar::Util::Fake'; | |
622 | } else { | |
623 | $pkg = undef; | |
624 | } | |
625 | "$_[0]" =~ /0x(\w+)/; | |
626 | my $i = do { local $^W; hex $1 }; | |
627 | bless $_[0], $pkg if defined $pkg; | |
628 | $i; | |
629 | } | |
630 | END_PERL | |
631 | ||
632 | } | |
633 | ||
634 | 1; | |
635 | ||
636 | ||
637 | ||
638 | =pod | |
639 | ||
640 | =head1 NAME | |
641 | ||
642 | CPAN::Meta::YAML - Read and write a subset of YAML for CPAN Meta files | |
643 | ||
644 | =head1 VERSION | |
645 | ||
646 | version 0.003 | |
647 | ||
648 | =head1 SYNOPSIS | |
649 | ||
650 | use CPAN::Meta::YAML; | |
651 | ||
652 | # methods for files | |
653 | $yaml = CPAN::Meta::YAML->read('META.yml'); | |
654 | $yaml->write('MYMETA.yml'); | |
655 | ||
656 | # methods for strings | |
657 | $yaml_text = $yaml->write_string; | |
658 | $yaml = CPAN::Meta::YAML->read_string($yaml_text); | |
659 | ||
660 | # finding the metadata | |
661 | my $meta = $yaml->[0]; | |
662 | ||
663 | # handling errors | |
664 | $yaml->write($file) | |
665 | or die CPAN::Meta::YAML->errstr; | |
666 | ||
667 | =head1 DESCRIPTION | |
668 | ||
669 | This module implements a subset of the YAML specification for use in reading | |
670 | and writing CPAN metadata files like F<META.yml> and F<MYMETA.yml>. It should | |
671 | not be used for any other general YAML parsing or generation task. | |
672 | ||
673 | =head1 SUPPORT | |
674 | ||
675 | This module is currently derived from L<YAML::Tiny> by Adam Kennedy. If | |
676 | there are bugs in how it parses a particular META.yml file, please file | |
677 | a bug report in the YAML::Tiny bugtracker: | |
678 | L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=YAML-Tiny> | |
679 | ||
680 | =head1 SEE ALSO | |
681 | ||
682 | L<YAML::Tiny>, L<YAML>, L<YAML::XS> | |
683 | ||
684 | =head1 AUTHORS | |
685 | ||
686 | =over 4 | |
687 | ||
688 | =item * | |
689 | ||
690 | Adam Kennedy <adamk@cpan.org> | |
691 | ||
692 | =item * | |
693 | ||
694 | David Golden <dagolden@cpan.org> | |
695 | ||
696 | =back | |
697 | ||
698 | =head1 COPYRIGHT AND LICENSE | |
699 | ||
700 | This software is copyright (c) 2010 by Adam Kennedy. | |
701 | ||
702 | This is free software; you can redistribute it and/or modify it under | |
703 | the same terms as the Perl 5 programming language system itself. | |
704 | ||
705 | =cut | |
706 | ||
707 | ||
708 | __END__ | |
709 | ||
710 | ||
711 | # ABSTRACT: Read and write a subset of YAML for CPAN Meta files | |
712 | ||
713 |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Load testing for CPAN::Meta::YAML | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use Test::More tests => 3; | |
12 | ||
13 | # Check their perl version | |
14 | ok( $] >= 5.004, "Your perl is new enough" ); | |
15 | ||
16 | # Does the module load | |
17 | use_ok( 'CPAN::Meta::YAML' ); | |
18 | use_ok( 't::lib::Test' ); |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing of basic document structures | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More tests(30); | |
13 | use CPAN::Meta::YAML; | |
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ##################################################################### | |
20 | # Sample Testing | |
21 | ||
22 | # Test a completely empty document | |
23 | yaml_ok( | |
24 | '', | |
25 | [ ], | |
26 | 'empty', | |
27 | ); | |
28 | ||
29 | # Just a newline | |
30 | ### YAML.pm has a bug where it dies on a single newline | |
31 | yaml_ok( | |
32 | "\n\n", | |
33 | [ ], | |
34 | 'only_newlines', | |
35 | ); | |
36 | ||
37 | # Just a comment | |
38 | yaml_ok( | |
39 | "# comment\n", | |
40 | [ ], | |
41 | 'only_comment', | |
42 | ); | |
43 | ||
44 | # Empty documents | |
45 | yaml_ok( | |
46 | "---\n", | |
47 | [ undef ], | |
48 | 'only_header', | |
49 | noyamlperl => 1, | |
50 | ); | |
51 | yaml_ok( | |
52 | "---\n---\n", | |
53 | [ undef, undef ], | |
54 | 'two_header', | |
55 | noyamlperl => 1, | |
56 | ); | |
57 | yaml_ok( | |
58 | "--- ~\n", | |
59 | [ undef ], | |
60 | 'one_undef', | |
61 | noyamlperl => 1, | |
62 | ); | |
63 | yaml_ok( | |
64 | "--- ~\n", | |
65 | [ undef ], | |
66 | 'one_undef2', | |
67 | noyamlperl => 1, | |
68 | ); | |
69 | yaml_ok( | |
70 | "--- ~\n---\n", | |
71 | [ undef, undef ], | |
72 | 'two_undef', | |
73 | noyamlperl => 1, | |
74 | ); | |
75 | ||
76 | # Just a scalar | |
77 | yaml_ok( | |
78 | "--- foo\n", | |
79 | [ 'foo' ], | |
80 | 'one_scalar', | |
81 | ); | |
82 | yaml_ok( | |
83 | "--- foo\n", | |
84 | [ 'foo' ], | |
85 | 'one_scalar2', | |
86 | ); | |
87 | yaml_ok( | |
88 | "--- foo\n--- bar\n", | |
89 | [ 'foo', 'bar' ], | |
90 | 'two_scalar', | |
91 | noyamlperl => 1, | |
92 | ); | |
93 | ||
94 | # Simple lists | |
95 | yaml_ok( | |
96 | "---\n- foo\n", | |
97 | [ [ 'foo' ] ], | |
98 | 'one_list1', | |
99 | ); | |
100 | yaml_ok( | |
101 | "---\n- foo\n- bar\n", | |
102 | [ [ 'foo', 'bar' ] ], | |
103 | 'one_list2', | |
104 | ); | |
105 | yaml_ok( | |
106 | "---\n- ~\n- bar\n", | |
107 | [ [ undef, 'bar' ] ], | |
108 | 'one_listundef', | |
109 | noyamlperl => 1, | |
110 | ); | |
111 | ||
112 | # Simple hashs | |
113 | yaml_ok( | |
114 | "---\nfoo: bar\n", | |
115 | [ { foo => 'bar' } ], | |
116 | 'one_hash1', | |
117 | ); | |
118 | ||
119 | yaml_ok( | |
120 | "---\nfoo: bar\nthis: ~\n", | |
121 | [ { this => undef, foo => 'bar' } ], | |
122 | 'one_hash2', | |
123 | noyamlperl => 1, | |
124 | ); | |
125 | ||
126 | # Simple array inside a hash with an undef | |
127 | yaml_ok( | |
128 | <<'END_YAML', | |
129 | --- | |
130 | foo: | |
131 | - bar | |
132 | - ~ | |
133 | - baz | |
134 | END_YAML | |
135 | [ { foo => [ 'bar', undef, 'baz' ] } ], | |
136 | 'array_in_hash', | |
137 | noyamlperl => 1, | |
138 | ); | |
139 | ||
140 | # Simple hash inside a hash with an undef | |
141 | yaml_ok( | |
142 | <<'END_YAML', | |
143 | --- | |
144 | foo: ~ | |
145 | bar: | |
146 | foo: bar | |
147 | END_YAML | |
148 | [ { foo => undef, bar => { foo => 'bar' } } ], | |
149 | 'hash_in_hash', | |
150 | noyamlperl => 1, | |
151 | ); | |
152 | ||
153 | # Mixed hash and scalars inside an array | |
154 | yaml_ok( | |
155 | <<'END_YAML', | |
156 | --- | |
157 | - | |
158 | foo: ~ | |
159 | this: that | |
160 | - foo | |
161 | - ~ | |
162 | - | |
163 | foo: bar | |
164 | this: that | |
165 | END_YAML | |
166 | [ [ | |
167 | { foo => undef, this => 'that' }, | |
168 | 'foo', | |
169 | undef, | |
170 | { foo => 'bar', this => 'that' }, | |
171 | ] ], | |
172 | 'hash_in_array', | |
173 | noyamlperl => 1, | |
174 | ); | |
175 | ||
176 | # Simple single quote | |
177 | yaml_ok( | |
178 | "---\n- 'foo'\n", | |
179 | [ [ 'foo' ] ], | |
180 | 'single_quote1', | |
181 | ); | |
182 | yaml_ok( | |
183 | "---\n- ' '\n", | |
184 | [ [ ' ' ] ], | |
185 | 'single_spaces', | |
186 | ); | |
187 | yaml_ok( | |
188 | "---\n- ''\n", | |
189 | [ [ '' ] ], | |
190 | 'single_null', | |
191 | ); | |
192 | ||
193 | # Double quotes | |
194 | yaml_ok( | |
195 | "--- \" \"\n", | |
196 | [ ' ' ], | |
197 | "only_spaces", | |
198 | noyamlpm => 1, | |
199 | noyamlperl => 1, | |
200 | ); | |
201 | ||
202 | yaml_ok( | |
203 | "--- \" foo\"\n--- \"bar \"\n", | |
204 | [ " foo", "bar " ], | |
205 | "leading_trailing_spaces", | |
206 | noyamlpm => 1, | |
207 | noyamlperl => 1, | |
208 | ); | |
209 | ||
210 | # Implicit document start | |
211 | yaml_ok( | |
212 | "foo: bar\n", | |
213 | [ { foo => 'bar' } ], | |
214 | 'implicit_hash', | |
215 | ); | |
216 | yaml_ok( | |
217 | "- foo\n", | |
218 | [ [ 'foo' ] ], | |
219 | 'implicit_array', | |
220 | ); | |
221 | ||
222 | # Inline nested hash | |
223 | yaml_ok( | |
224 | <<'END_YAML', | |
225 | --- | |
226 | - ~ | |
227 | - foo: bar | |
228 | this: that | |
229 | - baz | |
230 | END_YAML | |
231 | [ [ undef, { foo => 'bar', this => 'that' }, 'baz' ] ], | |
232 | 'inline_nested_hash', | |
233 | noyamlperl => 1, | |
234 | ); | |
235 | ||
236 | # Empty comments | |
237 | yaml_ok( | |
238 | "---\n- foo\n#\n- bar\n", | |
239 | [ [ 'foo', 'bar' ] ], | |
240 | 'empty_comment_in_list', | |
241 | ); | |
242 | ||
243 | yaml_ok( | |
244 | "---\nfoo: bar\n# foo\none: two\n", | |
245 | [ { foo => 'bar', one => 'two' } ], | |
246 | 'empty_comment_in_hash', | |
247 | ); | |
248 | ||
249 | # Complex keys | |
250 | yaml_ok( | |
251 | "---\na b: c d\n", | |
252 | [ { 'a b' => 'c d' } ], | |
253 | 'key_with_whitespace', | |
254 | ); |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing of common META.yml examples | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More tests(37, 0, 12); | |
13 | use CPAN::Meta::YAML qw{ | |
14 | Load Dump | |
15 | LoadFile DumpFile | |
16 | freeze thaw | |
17 | }; | |
18 | ||
19 | ||
20 | ||
21 | ||
22 | ||
23 | ##################################################################### | |
24 | # Check Exports | |
25 | ||
26 | ok( defined(&Load), 'Found exported Load function' ); | |
27 | ok( defined(&Dump), 'Found exported Dump function' ); | |
28 | ok( defined(&LoadFile), 'Found exported LoadFile function' ); | |
29 | ok( defined(&DumpFile), 'Found exported DumpFile function' ); | |
30 | ok( defined(&freeze), 'Found exported freeze function' ); | |
31 | ok( defined(&thaw), 'Found exported thaw functiona' ); | |
32 | ||
33 | ||
34 | ||
35 | ||
36 | ||
37 | ##################################################################### | |
38 | # In META.yml files, some hash keys contain module names | |
39 | ||
40 | # Hash key legally containing a colon | |
41 | yaml_ok( | |
42 | "---\nFoo::Bar: 1\n", | |
43 | [ { 'Foo::Bar' => 1 } ], | |
44 | 'module_hash_key', | |
45 | ); | |
46 | ||
47 | # Hash indented | |
48 | yaml_ok( | |
49 | "---\n" | |
50 | . " foo: bar\n", | |
51 | [ { foo => "bar" } ], | |
52 | 'hash_indented', | |
53 | ); | |
54 | ||
55 | ||
56 | ||
57 | ||
58 | ||
59 | ##################################################################### | |
60 | # Support for literal multi-line scalars | |
61 | ||
62 | # Declarative multi-line scalar | |
63 | yaml_ok( | |
64 | "---\n" | |
65 | . " foo: >\n" | |
66 | . " bar\n" | |
67 | . " baz\n", | |
68 | [ { foo => "bar baz\n" } ], | |
69 | 'simple_multiline', | |
70 | ); | |
71 | ||
72 | # Piped multi-line scalar | |
73 | yaml_ok( | |
74 | <<'END_YAML', | |
75 | --- | |
76 | - | | |
77 | foo | |
78 | bar | |
79 | - 1 | |
80 | END_YAML | |
81 | [ [ "foo\nbar\n", 1 ] ], | |
82 | 'indented', | |
83 | ); | |
84 | ||
85 | # ... with a pointless hyphen | |
86 | yaml_ok( <<'END_YAML', | |
87 | --- | |
88 | - |- | |
89 | foo | |
90 | bar | |
91 | - 1 | |
92 | END_YAML | |
93 | [ [ "foo\nbar", 1 ] ], | |
94 | 'indented', | |
95 | ); | |
96 | ||
97 | ||
98 | ||
99 | ||
100 | ||
101 | ##################################################################### | |
102 | # Support for YAML version directives | |
103 | ||
104 | # Simple inline case (comment variant) | |
105 | yaml_ok( | |
106 | <<'END_YAML', | |
107 | --- #YAML:1.0 | |
108 | foo: bar | |
109 | END_YAML | |
110 | [ { foo => 'bar' } ], | |
111 | 'simple_doctype_comment', | |
112 | nosyck => 1, | |
113 | ); | |
114 | ||
115 | # Simple inline case (percent variant) | |
116 | yaml_ok( | |
117 | <<'END_YAML', | |
118 | --- %YAML:1.0 | |
119 | foo: bar | |
120 | END_YAML | |
121 | [ { foo => 'bar' } ], | |
122 | 'simple_doctype_percent', | |
123 | noyamlpm => 1, | |
124 | noxs => 1, | |
125 | noyamlperl => 1, | |
126 | ); | |
127 | ||
128 | # Simple header (comment variant) | |
129 | yaml_ok( | |
130 | <<'END_YAML', | |
131 | %YAML:1.0 | |
132 | --- | |
133 | foo: bar | |
134 | END_YAML | |
135 | [ { foo => 'bar' } ], | |
136 | 'predocument_1_0', | |
137 | noyamlpm => 1, | |
138 | nosyck => 1, | |
139 | noxs => 1, | |
140 | noyamlperl => 1, | |
141 | ); | |
142 | ||
143 | # Simple inline case (comment variant) | |
144 | yaml_ok( | |
145 | <<'END_YAML', | |
146 | %YAML 1.1 | |
147 | --- | |
148 | foo: bar | |
149 | END_YAML | |
150 | [ { foo => 'bar' } ], | |
151 | 'predocument_1_1', | |
152 | noyamlpm => 1, | |
153 | nosyck => 1, | |
154 | noyamlperl => 1, | |
155 | ); | |
156 | ||
157 | # Multiple inline documents (comment variant) | |
158 | yaml_ok( | |
159 | <<'END_YAML', | |
160 | --- #YAML:1.0 | |
161 | foo: bar | |
162 | --- #YAML:1.0 | |
163 | - 1 | |
164 | --- #YAML:1.0 | |
165 | foo: bar | |
166 | END_YAML | |
167 | [ { foo => 'bar' }, [ 1 ], { foo => 'bar' } ], | |
168 | 'multi_doctype_comment', | |
169 | ); | |
170 | ||
171 | # Simple pre-document case (comment variant) | |
172 | yaml_ok( | |
173 | <<'END_YAML', | |
174 | %YAML 1.1 | |
175 | --- | |
176 | foo: bar | |
177 | END_YAML | |
178 | [ { foo => 'bar' } ], | |
179 | 'predocument_percent', | |
180 | noyamlpm => 1, | |
181 | nosyck => 1, | |
182 | noyamlperl => 1, | |
183 | ); | |
184 | ||
185 | # Simple pre-document case (comment variant) | |
186 | yaml_ok( | |
187 | <<'END_YAML', | |
188 | #YAML 1.1 | |
189 | --- | |
190 | foo: bar | |
191 | END_YAML | |
192 | [ { foo => 'bar' } ], | |
193 | 'predocument_comment', | |
194 | ); | |
195 | ||
196 | ||
197 | ||
198 | ||
199 | ||
200 | ##################################################################### | |
201 | # Hitchhiker Scalar | |
202 | ||
203 | yaml_ok( | |
204 | <<'END_YAML', | |
205 | --- 42 | |
206 | END_YAML | |
207 | [ 42 ], | |
208 | 'hitchhiker scalar', | |
209 | serializes => 1, | |
210 | ); | |
211 | ||
212 | ||
213 | ||
214 | ||
215 | ||
216 | ##################################################################### | |
217 | # Null HASH/ARRAY | |
218 | ||
219 | yaml_ok( | |
220 | <<'END_YAML', | |
221 | --- | |
222 | - foo | |
223 | - {} | |
224 | - bar | |
225 | END_YAML | |
226 | [ [ 'foo', {}, 'bar' ] ], | |
227 | 'null hash in array', | |
228 | ); | |
229 | ||
230 | yaml_ok( | |
231 | <<'END_YAML', | |
232 | --- | |
233 | - foo | |
234 | - [] | |
235 | - bar | |
236 | END_YAML | |
237 | [ [ 'foo', [], 'bar' ] ], | |
238 | 'null array in array', | |
239 | ); | |
240 | ||
241 | yaml_ok( | |
242 | <<'END_YAML', | |
243 | --- | |
244 | foo: {} | |
245 | bar: 1 | |
246 | END_YAML | |
247 | [ { foo => {}, bar => 1 } ], | |
248 | 'null hash in hash', | |
249 | ); | |
250 | ||
251 | yaml_ok( | |
252 | <<'END_YAML', | |
253 | --- | |
254 | foo: [] | |
255 | bar: 1 | |
256 | END_YAML | |
257 | [ { foo => [], bar => 1 } ], | |
258 | 'null array in hash', | |
259 | ); | |
260 | ||
261 | ||
262 | ||
263 | ||
264 | ##################################################################### | |
265 | # Trailing Whitespace | |
266 | ||
267 | yaml_ok( | |
268 | <<'END_YAML', | |
269 | --- | |
270 | abstract: Generate fractal curves | |
271 | foo: ~ | |
272 | arr: | |
273 | - foo | |
274 | - ~ | |
275 | - 'bar' | |
276 | END_YAML | |
277 | [ { | |
278 | abstract => 'Generate fractal curves', | |
279 | foo => undef, | |
280 | arr => [ 'foo', undef, 'bar' ], | |
281 | } ], | |
282 | 'trailing whitespace', | |
283 | noyamlperl => 1, | |
284 | ); | |
285 | ||
286 | ||
287 | ||
288 | ||
289 | ||
290 | ##################################################################### | |
291 | # Quote vs Hash | |
292 | ||
293 | yaml_ok( | |
294 | <<'END_YAML', | |
295 | --- | |
296 | author: | |
297 | - 'mst: Matt S. Trout <mst@shadowcatsystems.co.uk>' | |
298 | END_YAML | |
299 | [ { author => [ 'mst: Matt S. Trout <mst@shadowcatsystems.co.uk>' ] } ], | |
300 | 'hash-like quote', | |
301 | ); | |
302 | ||
303 | ||
304 | ||
305 | ||
306 | ||
307 | ##################################################################### | |
308 | # Quote and Escaping Idiosyncracies | |
309 | ||
310 | yaml_ok( | |
311 | <<'END_YAML', | |
312 | --- | |
313 | name1: 'O''Reilly' | |
314 | name2: 'O''Reilly O''Tool' | |
315 | name3: 'Double '''' Quote' | |
316 | END_YAML | |
317 | [ { | |
318 | name1 => "O'Reilly", | |
319 | name2 => "O'Reilly O'Tool", | |
320 | name3 => "Double '' Quote", | |
321 | } ], | |
322 | 'single quote subtleties', | |
323 | ); | |
324 | ||
325 | yaml_ok( | |
326 | <<'END_YAML', | |
327 | --- | |
328 | slash1: '\\' | |
329 | slash2: '\\foo' | |
330 | slash3: '\\foo\\\\' | |
331 | END_YAML | |
332 | [ { | |
333 | slash1 => "\\\\", | |
334 | slash2 => "\\\\foo", | |
335 | slash3 => "\\\\foo\\\\\\\\", | |
336 | } ], | |
337 | 'single quote subtleties', | |
338 | ); | |
339 | ||
340 | ||
341 | ||
342 | ||
343 | ||
344 | ##################################################################### | |
345 | # Empty Values and Premature EOF | |
346 | ||
347 | yaml_ok( | |
348 | <<'END_YAML', | |
349 | --- | |
350 | foo: 0 | |
351 | requires: | |
352 | build_requires: | |
353 | END_YAML | |
354 | [ { foo => 0, requires => undef, build_requires => undef } ], | |
355 | 'empty hash keys', | |
356 | noyamlpm => 1, | |
357 | noyamlperl => 1, | |
358 | ); | |
359 | ||
360 | yaml_ok( | |
361 | <<'END_YAML', | |
362 | --- | |
363 | - foo | |
364 | - | |
365 | - | |
366 | END_YAML | |
367 | [ [ 'foo', undef, undef ] ], | |
368 | 'empty array keys', | |
369 | noyamlpm => 1, | |
370 | noyamlperl => 1, | |
371 | ); | |
372 | ||
373 | ||
374 | ||
375 | ||
376 | ||
377 | ##################################################################### | |
378 | # Comment on the Document Line | |
379 | ||
380 | yaml_ok( | |
381 | <<'END_YAML', | |
382 | --- # Comment | |
383 | foo: bar | |
384 | END_YAML | |
385 | [ { foo => 'bar' } ], | |
386 | 'comment header', | |
387 | noyamlpm => 1, | |
388 | noyamlperl => 1, | |
389 | ); | |
390 | ||
391 | ||
392 | ||
393 | ||
394 | ||
395 | ||
396 | ##################################################################### | |
397 | # Newlines and tabs | |
398 | ||
399 | yaml_ok( | |
400 | <<'END_YAML', | |
401 | foo: "foo\\\n\tbar" | |
402 | END_YAML | |
403 | [ { foo => "foo\\\n\tbar" } ], | |
404 | 'special characters', | |
405 | ); | |
406 | ||
407 | ||
408 | ||
409 | ||
410 | ||
411 | ##################################################################### | |
412 | # Circular Reference Protection | |
413 | ||
414 | SCOPE: { | |
415 | my $foo = { a => 'b' }; | |
416 | my $bar = [ $foo, 2 ]; | |
417 | $foo->{c} = $bar; | |
418 | my $circ = CPAN::Meta::YAML->new( [ $foo, $bar ] ); | |
419 | isa_ok( $circ, 'CPAN::Meta::YAML' ); | |
420 | ||
421 | # When we try to serialize, it should NOT infinite loop | |
422 | my $string = undef; | |
423 | $string = eval { $circ->write_string; }; | |
424 | is( $string, undef, '->write_string does not return a value' ); | |
425 | ok( $@, 'Error string is defined' ); | |
426 | ok( | |
427 | $@ =~ /does not support circular references/, | |
428 | 'Got the expected error message', | |
429 | ); | |
430 | } | |
431 | ||
432 | ||
433 | ||
434 | ||
435 | ||
436 | ##################################################################### | |
437 | # Confirm we can read the synopsis | |
438 | ||
439 | yaml_ok( | |
440 | <<'END_YAML', | |
441 | --- | |
442 | rootproperty: blah | |
443 | section: | |
444 | one: two | |
445 | three: four | |
446 | Foo: Bar | |
447 | empty: ~ | |
448 | END_YAML | |
449 | [ { | |
450 | rootproperty => 'blah', | |
451 | section => { | |
452 | one => 'two', | |
453 | three => 'four', | |
454 | Foo => 'Bar', | |
455 | empty => undef, | |
456 | }, | |
457 | } ], | |
458 | 'synopsis', | |
459 | noyamlperl => 1, | |
460 | ); | |
461 | ||
462 | ||
463 | ||
464 | ||
465 | ||
466 | ##################################################################### | |
467 | # Unprintable Characters | |
468 | ||
469 | yaml_ok( | |
470 | "--- \"foo\\n\\x00\"\n", | |
471 | [ "foo\n\0" ], | |
472 | 'unprintable', | |
473 | ); | |
474 | ||
475 | ||
476 | ||
477 | ||
478 | ||
479 | ##################################################################### | |
480 | # Empty Quote Line | |
481 | ||
482 | yaml_ok( | |
483 | <<'END_YAML', | |
484 | --- | |
485 | - foo | |
486 | # | |
487 | - bar | |
488 | END_YAML | |
489 | [ [ "foo", "bar" ] ], | |
490 | ); | |
491 | ||
492 | ||
493 | ||
494 | ||
495 | ||
496 | ##################################################################### | |
497 | # Indentation after empty hash value | |
498 | ||
499 | yaml_ok( | |
500 | <<'END_YAML', | |
501 | --- | |
502 | Test: | |
503 | optmods: | |
504 | Bad: 0 | |
505 | Foo: 1 | |
506 | Long: 0 | |
507 | version: 5 | |
508 | Test_IncludeA: | |
509 | optmods: | |
510 | Test_IncludeB: | |
511 | optmods: | |
512 | _meta: | |
513 | name: 'test profile' | |
514 | note: 'note this test profile' | |
515 | END_YAML | |
516 | [ { | |
517 | Test => { | |
518 | optmods => { | |
519 | Bad => 0, | |
520 | Foo => 1, | |
521 | Long => 0, | |
522 | }, | |
523 | version => 5, | |
524 | }, | |
525 | Test_IncludeA => { | |
526 | optmods => undef, | |
527 | }, | |
528 | Test_IncludeB => { | |
529 | optmods => undef, | |
530 | }, | |
531 | _meta => { | |
532 | name => 'test profile', | |
533 | note => 'note this test profile', | |
534 | }, | |
535 | } ], | |
536 | 'Indentation after empty hash value', | |
537 | noyamlperl => 1, | |
538 | ); | |
539 | ||
540 | ||
541 | ||
542 | ||
543 | ||
544 | ##################################################################### | |
545 | # Spaces in the Key | |
546 | ||
547 | yaml_ok( | |
548 | <<'END_YAML', | |
549 | --- | |
550 | the key: the value | |
551 | END_YAML | |
552 | [ { 'the key' => 'the value' } ], | |
553 | ); | |
554 | ||
555 | ||
556 | ||
557 | ||
558 | ||
559 | ##################################################################### | |
560 | # Ticker #32402 | |
561 | ||
562 | # Tests a particular pathological case | |
563 | ||
564 | yaml_ok( | |
565 | <<'END_YAML', | |
566 | --- | |
567 | - value | |
568 | - '><' | |
569 | END_YAML | |
570 | [ [ 'value', '><' ] ], | |
571 | 'Pathological >< case', | |
572 | ); | |
573 | ||
574 | ||
575 | ||
576 | ||
577 | ||
578 | ##################################################################### | |
579 | # Special Characters | |
580 | ||
581 | #yaml_ok( | |
582 | # <<'END_YAML', | |
583 | #--- | |
584 | #- "Ingy d\xC3\xB6t Net" | |
585 | #END_YAML | |
586 | # [ [ "Ingy d\xC3\xB6t Net" ] ], | |
587 | #); | |
588 | ||
589 | ||
590 | ||
591 | ||
592 | ||
593 | ||
594 | ###################################################################### | |
595 | # Non-Indenting Sub-List | |
596 | ||
597 | yaml_ok( | |
598 | <<'END_YAML', | |
599 | --- | |
600 | foo: | |
601 | - list | |
602 | bar: value | |
603 | END_YAML | |
604 | [ { foo => [ 'list' ], bar => 'value' } ], | |
605 | 'Non-indenting sub-list', | |
606 | noyamlpm => 1, | |
607 | noyamlperl => 1, | |
608 | ); | |
609 | ||
610 | ||
611 | ||
612 | ||
613 | ||
614 | ||
615 | ##################################################################### | |
616 | # Check Multiple-Escaping | |
617 | ||
618 | # RT #42119: write of two single quotes | |
619 | yaml_ok( | |
620 | "--- \"A'B'C\"\n", | |
621 | [ "A'B'C" ], | |
622 | 'Multiple escaping of quote ok', | |
623 | ); | |
624 | ||
625 | # Escapes without whitespace | |
626 | yaml_ok( | |
627 | "--- A\\B\\C\n", | |
628 | [ "A\\B\\C" ], | |
629 | 'Multiple escaping of escape ok', | |
630 | ); | |
631 | ||
632 | # Escapes with whitespace | |
633 | yaml_ok( | |
634 | "--- 'A\\B \\C'\n", | |
635 | [ "A\\B \\C" ], | |
636 | 'Multiple escaping of escape with whitespace ok', | |
637 | ); | |
638 | ||
639 | ||
640 | ||
641 | ||
642 | ||
643 | ###################################################################### | |
644 | # Check illegal characters that are in legal places | |
645 | ||
646 | yaml_ok( | |
647 | "--- 'Wow!'\n", | |
648 | [ "Wow!" ], | |
649 | 'Bang in a quote', | |
650 | ); | |
651 | yaml_ok( | |
652 | "--- 'This&that'\n", | |
653 | [ "This&that" ], | |
654 | 'Ampersand in a quote', | |
655 | ); | |
656 | ||
657 | ||
658 | ||
659 | ||
660 | ||
661 | ###################################################################### | |
662 | # Check for unescaped boolean keywords | |
663 | ||
664 | is_deeply( | |
665 | CPAN::Meta::YAML->new( 'True' )->write_string, | |
666 | "--- 'True'\n", | |
667 | 'Idiomatic trivial boolean string is escaped', | |
668 | ); | |
669 | ||
670 | is_deeply( CPAN::Meta::YAML->new( [ qw{ | |
671 | null Null NULL | |
672 | y Y yes Yes YES n N no No NO | |
673 | true True TRUE false False FALSE | |
674 | on On ON off Off OFF | |
675 | } ] )->write_string, <<'END_YAML' ); | |
676 | --- | |
677 | - 'null' | |
678 | - 'Null' | |
679 | - 'NULL' | |
680 | - 'y' | |
681 | - 'Y' | |
682 | - 'yes' | |
683 | - 'Yes' | |
684 | - 'YES' | |
685 | - 'n' | |
686 | - 'N' | |
687 | - 'no' | |
688 | - 'No' | |
689 | - 'NO' | |
690 | - 'true' | |
691 | - 'True' | |
692 | - 'TRUE' | |
693 | - 'false' | |
694 | - 'False' | |
695 | - 'FALSE' | |
696 | - 'on' | |
697 | - 'On' | |
698 | - 'ON' | |
699 | - 'off' | |
700 | - 'Off' | |
701 | - 'OFF' | |
702 | END_YAML |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing of scalar-context calls to the compatibility functions | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More; | |
13 | BEGIN { | |
14 | if ( t::lib::Test->have_yamlpm ) { | |
15 | plan( tests => 18 ); | |
16 | } else { | |
17 | plan( skip_all => 'Requires YAML.pm' ); | |
18 | exit(0); | |
19 | } | |
20 | } | |
21 | ||
22 | use YAML (); | |
23 | use CPAN::Meta::YAML (); | |
24 | ||
25 | ||
26 | ||
27 | ||
28 | ||
29 | ##################################################################### | |
30 | # Sample documents | |
31 | ||
32 | my $one = <<'END_YAML'; | |
33 | --- | |
34 | - foo | |
35 | END_YAML | |
36 | ||
37 | my $two = <<'END_YAML'; | |
38 | --- | |
39 | - foo | |
40 | --- | |
41 | - bar | |
42 | END_YAML | |
43 | ||
44 | ||
45 | ||
46 | ||
47 | ||
48 | ##################################################################### | |
49 | # Match Listwise Behaviour | |
50 | ||
51 | SCOPE: { | |
52 | my $one_list_pm = [ YAML::Load( $one ) ]; | |
53 | my $two_list_pm = [ YAML::Load( $two ) ]; | |
54 | my $one_list_tiny = [ CPAN::Meta::YAML::Load( $one ) ]; | |
55 | my $two_list_tiny = [ CPAN::Meta::YAML::Load( $two ) ]; | |
56 | ||
57 | is_deeply( $one_list_pm, [ [ 'foo' ] ], 'one: Parsed correctly' ); | |
58 | is_deeply( $one_list_pm, $one_list_tiny, 'one: List context matches' ); | |
59 | ||
60 | is_deeply( $two_list_pm, [ [ 'foo' ], [ 'bar' ] ], 'two: Parsed correctly' ); | |
61 | is_deeply( $two_list_pm, $two_list_tiny, 'two: List context matches' ); | |
62 | } | |
63 | ||
64 | ||
65 | ||
66 | ||
67 | ||
68 | ##################################################################### | |
69 | # Match Scalar Behaviour | |
70 | ||
71 | SCOPE: { | |
72 | my $one_scalar_pm = YAML::Load( $one ); | |
73 | my $two_scalar_pm = YAML::Load( $two ); | |
74 | my $one_scalar_tiny = CPAN::Meta::YAML::Load( $one ); | |
75 | my $two_scalar_tiny = CPAN::Meta::YAML::Load( $two ); | |
76 | ||
77 | is_deeply( $one_scalar_pm, [ 'foo' ], 'one: Parsed correctly' ); | |
78 | is_deeply( $one_scalar_pm, $one_scalar_tiny, 'one: Scalar context matches' ); | |
79 | ||
80 | is_deeply( $two_scalar_pm, [ 'bar' ], 'two: Parsed correctly' ); | |
81 | is_deeply( $two_scalar_pm, $two_scalar_tiny, 'two: Scalar context matches' ); | |
82 | } | |
83 | ||
84 | ||
85 | ||
86 | ||
87 | ||
88 | ##################################################################### | |
89 | # Repeat for LoadFile | |
90 | ||
91 | my $one_file = catfile(qw{ t data one.yml }); | |
92 | my $two_file = catfile(qw{ t data two.yml }); | |
93 | ok( -f $one_file, "Found $one_file" ); | |
94 | ok( -f $two_file, "Found $two_file" ); | |
95 | SCOPE: { | |
96 | my $one_list_pm = [ YAML::LoadFile( $one_file ) ]; | |
97 | my $two_list_pm = [ YAML::LoadFile( $two_file ) ]; | |
98 | my $one_list_tiny = [ CPAN::Meta::YAML::LoadFile( $one_file ) ]; | |
99 | my $two_list_tiny = [ CPAN::Meta::YAML::LoadFile( $two_file ) ]; | |
100 | ||
101 | is_deeply( $one_list_pm, [ [ 'foo' ] ], 'one: Parsed correctly' ); | |
102 | is_deeply( $one_list_pm, $one_list_tiny, 'one: List context matches' ); | |
103 | ||
104 | is_deeply( $two_list_pm, [ [ 'foo' ], [ 'bar' ] ], 'two: Parsed correctly' ); | |
105 | is_deeply( $two_list_pm, $two_list_tiny, 'two: List context matches' ); | |
106 | } | |
107 | ||
108 | SCOPE: { | |
109 | my $one_scalar_pm = YAML::LoadFile( $one_file ); | |
110 | my $two_scalar_pm = YAML::LoadFile( $two_file ); | |
111 | my $one_scalar_tiny = CPAN::Meta::YAML::LoadFile( $one_file ); | |
112 | my $two_scalar_tiny = CPAN::Meta::YAML::LoadFile( $two_file ); | |
113 | ||
114 | is_deeply( $one_scalar_pm, [ 'foo' ], 'one: Parsed correctly' ); | |
115 | is_deeply( $one_scalar_pm, $one_scalar_tiny, 'one: Scalar context matches' ); | |
116 | ||
117 | is_deeply( $two_scalar_pm, [ 'bar' ], 'two: Parsed correctly' ); | |
118 | is_deeply( $two_scalar_pm, $two_scalar_tiny, 'two: Scalar context matches' ); | |
119 | } |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing of basic document structures | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use Test::More tests => 6; | |
11 | use CPAN::Meta::YAML; | |
12 | ||
13 | ||
14 | ||
15 | ok defined &main::Load, 'Load is exported'; | |
16 | ok defined &main::Dump, 'Dump is exported'; | |
17 | ok not(defined &main::LoadFile), 'Load is exported'; | |
18 | ok not(defined &main::DumpFile), 'Dump is exported'; | |
19 | ||
20 | ok \&main::Load == \&CPAN::Meta::YAML::Load, 'Load is CPAN::Meta::YAML'; | |
21 | ok \&main::Dump == \&CPAN::Meta::YAML::Dump, 'Dump is CPAN::Meta::YAML'; |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing of common META.yml examples | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More tests(8, 3); | |
13 | use CPAN::Meta::YAML; | |
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ##################################################################### | |
20 | # Testing CPAN::Meta::YAML's own META.yml file | |
21 | ||
22 | yaml_ok( | |
23 | <<'END_YAML', | |
24 | abstract: Read/Write YAML files with as little code as possible | |
25 | author: 'Adam Kennedy <cpan@ali.as>' | |
26 | build_requires: | |
27 | File::Spec: 0.80 | |
28 | Test::More: 0.47 | |
29 | distribution_type: module | |
30 | generated_by: Module::Install version 0.63 | |
31 | license: perl | |
32 | name: YAML-Tiny | |
33 | no_index: | |
34 | directory: | |
35 | - inc | |
36 | - t | |
37 | requires: | |
38 | perl: 5.005 | |
39 | version: 0.03 | |
40 | END_YAML | |
41 | [ { | |
42 | abstract => 'Read/Write YAML files with as little code as possible', | |
43 | author => 'Adam Kennedy <cpan@ali.as>', | |
44 | build_requires => { | |
45 | 'File::Spec' => '0.80', | |
46 | 'Test::More' => '0.47', | |
47 | }, | |
48 | distribution_type => 'module', | |
49 | generated_by => 'Module::Install version 0.63', | |
50 | license => 'perl', | |
51 | name => 'YAML-Tiny', | |
52 | no_index => { | |
53 | directory => [ qw{inc t} ], | |
54 | }, | |
55 | requires => { | |
56 | perl => '5.005', | |
57 | }, | |
58 | version => '0.03', | |
59 | } ], | |
60 | 'CPAN::Meta::YAML', | |
61 | ); | |
62 | ||
63 | ||
64 | ||
65 | ||
66 | ||
67 | ||
68 | ##################################################################### | |
69 | # Testing a META.yml from a commercial project that crashed | |
70 | ||
71 | yaml_ok( | |
72 | <<'END_YAML', | |
73 | # http://module-build.sourceforge.net/META-spec.html | |
74 | #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# | |
75 | name: ITS-SIN-FIDS-Content-XML | |
76 | version: 0.01 | |
77 | version_from: lib/ITS/SIN/FIDS/Content/XML.pm | |
78 | installdirs: site | |
79 | requires: | |
80 | Test::More: 0.45 | |
81 | XML::Simple: 2 | |
82 | ||
83 | distribution_type: module | |
84 | generated_by: ExtUtils::MakeMaker version 6.30 | |
85 | END_YAML | |
86 | [ { | |
87 | name => 'ITS-SIN-FIDS-Content-XML', | |
88 | version => "0.01", # this kludge is to prevent floating point comparison errors | |
89 | version_from => 'lib/ITS/SIN/FIDS/Content/XML.pm', | |
90 | installdirs => 'site', | |
91 | requires => { | |
92 | 'Test::More' => 0.45, | |
93 | 'XML::Simple' => 2, | |
94 | }, | |
95 | distribution_type => 'module', | |
96 | generated_by => 'ExtUtils::MakeMaker version 6.30', | |
97 | } ], | |
98 | 'CPAN::Meta::YAML', | |
99 | ); | |
100 | ||
101 | ||
102 | ||
103 | ||
104 | ||
105 | ||
106 | ##################################################################### | |
107 | # Testing various failing META.yml files from CPAN | |
108 | ||
109 | yaml_ok( | |
110 | <<'END_YAML', | |
111 | --- | |
112 | abstract: Mii in Nintendo Wii data parser and builder | |
113 | author: Toru Yamaguchi <zigorou@cpan.org> | |
114 | distribution_type: module | |
115 | generated_by: Module::Install version 0.65 | |
116 | license: perl | |
117 | meta-spec: | |
118 | url: http://module-build.sourceforge.net/META-spec-v1.3.html | |
119 | version: 1.3 | |
120 | name: Games-Nintendo-Wii-Mii | |
121 | no_index: | |
122 | directory: | |
123 | - inc | |
124 | - t | |
125 | requires: | |
126 | Carp: 1.03 | |
127 | Class::Accessor::Fast: 0.3 | |
128 | File::Slurp: 9999.12 | |
129 | IO::File: 1.1 | |
130 | Readonly: 0 | |
131 | Tie::IxHash: 1.21 | |
132 | URI: 1.35 | |
133 | XML::LibXML: 1.62 | |
134 | version: 0.02 | |
135 | END_YAML | |
136 | [ { | |
137 | abstract => 'Mii in Nintendo Wii data parser and builder', | |
138 | author => 'Toru Yamaguchi <zigorou@cpan.org>', | |
139 | distribution_type => 'module', | |
140 | generated_by => 'Module::Install version 0.65', | |
141 | license => 'perl', | |
142 | 'meta-spec' => { | |
143 | url => 'http://module-build.sourceforge.net/META-spec-v1.3.html', | |
144 | version => '1.3', | |
145 | }, | |
146 | name => 'Games-Nintendo-Wii-Mii', | |
147 | no_index => { | |
148 | directory => [ qw{ inc t } ], | |
149 | }, | |
150 | requires => { | |
151 | 'Carp' => '1.03', | |
152 | 'Class::Accessor::Fast' => '0.3', | |
153 | 'File::Slurp' => '9999.12', | |
154 | 'IO::File' => '1.1', | |
155 | 'Readonly' => '0', | |
156 | 'Tie::IxHash' => '1.21', | |
157 | 'URI' => '1.35', | |
158 | 'XML::LibXML' => '1.62', | |
159 | }, | |
160 | version => '0.02', | |
161 | } ], | |
162 | 'Games-Nintendo-Wii-Mii', | |
163 | ); | |
164 | ||
165 | yaml_ok( | |
166 | <<'END_YAML', | |
167 | # http://module-build.sourceforge.net/META-spec.html | |
168 | #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# | |
169 | name: Acme-Time-Baby | |
170 | version: 2.106 | |
171 | version_from: Baby.pm | |
172 | installdirs: site | |
173 | requires: | |
174 | warnings: | |
175 | ||
176 | distribution_type: module | |
177 | generated_by: ExtUtils::MakeMaker version 6.17 | |
178 | END_YAML | |
179 | [ { | |
180 | name => 'Acme-Time-Baby', | |
181 | version => '2.106', | |
182 | version_from => 'Baby.pm', | |
183 | installdirs => 'site', | |
184 | requires => { | |
185 | warnings => undef, | |
186 | }, | |
187 | distribution_type => 'module', | |
188 | generated_by => 'ExtUtils::MakeMaker version 6.17', | |
189 | } ], | |
190 | 'Acme-Time-Baby', | |
191 | noyamlperl => 1, | |
192 | ); | |
193 | ||
194 | ||
195 | ||
196 | ||
197 | ||
198 | ##################################################################### | |
199 | # File with a YAML header | |
200 | ||
201 | yaml_ok( | |
202 | <<'END_YAML', | |
203 | --- #YAML:1.0 | |
204 | name: Data-Swap | |
205 | version: 0.05 | |
206 | license: perl | |
207 | distribution_type: module | |
208 | requires: | |
209 | perl: 5.6.0 | |
210 | dynamic_config: 0 | |
211 | END_YAML | |
212 | [ { | |
213 | name => 'Data-Swap', | |
214 | version => '0.05', | |
215 | license => 'perl', | |
216 | distribution_type => 'module', | |
217 | requires => { | |
218 | perl => '5.6.0', | |
219 | }, | |
220 | dynamic_config => '0', | |
221 | } ], | |
222 | 'Data-Swap', | |
223 | nosyck => 1, | |
224 | ); | |
225 | ||
226 | ||
227 | ||
228 | ||
229 | ||
230 | ##################################################################### | |
231 | # Various files that fail for unknown reasons | |
232 | ||
233 | SCOPE: { | |
234 | my $content = load_ok( | |
235 | 'Template-Provider-Unicode-Japanese.yml', | |
236 | catfile( test_data_directory(), 'Template-Provider-Unicode-Japanese.yml' ), | |
237 | 100 | |
238 | ); | |
239 | yaml_ok( | |
240 | $content, | |
241 | [ { | |
242 | abstract => 'Decode all templates by Unicode::Japanese', | |
243 | author => 'Hironori Yoshida C<< <yoshida@cpan.org> >>', | |
244 | distribution_type => 'module', | |
245 | generated_by => 'Module::Install version 0.65', | |
246 | license => 'perl', | |
247 | 'meta-spec' => { | |
248 | url => 'http://module-build.sourceforge.net/META-spec-v1.3.html', | |
249 | version => '1.3', | |
250 | }, | |
251 | name => 'Template-Provider-Unicode-Japanese', | |
252 | no_index => { | |
253 | directory => [ qw{ inc t } ], | |
254 | }, | |
255 | requires => { | |
256 | 'Template::Config' => 0, | |
257 | 'Unicode::Japanese' => 0, | |
258 | perl => '5.6.0', | |
259 | version => '0', | |
260 | }, | |
261 | version => '1.2.1', | |
262 | } ], | |
263 | 'Template-Provider-Unicode-Japanese', | |
264 | noyamlperl => 1, | |
265 | ); | |
266 | } | |
267 | ||
268 | SCOPE: { | |
269 | my $content = load_ok( | |
270 | 'HTML-WebDAO.yml', | |
271 | catfile( test_data_directory(), 'HTML-WebDAO.yml' ), | |
272 | 100 | |
273 | ); | |
274 | yaml_ok( | |
275 | $content, | |
276 | [ { | |
277 | abstract => 'Perl extension for create complex web application', | |
278 | author => [ | |
279 | 'Zahatski Aliaksandr, E<lt>zagap@users.sourceforge.netE<gt>', | |
280 | ], | |
281 | license => 'perl', | |
282 | name => 'HTML-WebDAO', | |
283 | version => '0.04', | |
284 | } ], | |
285 | 'HTML-WebDAO', | |
286 | nosyck => 1, | |
287 | ); | |
288 | } | |
289 | ||
290 | SCOPE: { | |
291 | my $content = load_ok( | |
292 | 'Spreadsheet-Read.yml', | |
293 | catfile( test_data_directory(), 'Spreadsheet-Read.yml' ), | |
294 | 100 | |
295 | ); | |
296 | yaml_ok( | |
297 | $content, | |
298 | [ { | |
299 | 'resources' => { | |
300 | 'license' => 'http://dev.perl.org/licenses/' | |
301 | }, | |
302 | 'meta-spec' => { | |
303 | 'version' => '1.4', | |
304 | 'url' => 'http://module-build.sourceforge.net/META-spec-v1.4.html' | |
305 | }, | |
306 | 'distribution_type' => 'module', | |
307 | 'generated_by' => 'Author', | |
308 | 'version' => 'VERSION', | |
309 | 'name' => 'Read', | |
310 | 'author' => [ | |
311 | 'H.Merijn Brand <h.m.brand@xs4all.nl>' | |
312 | ], | |
313 | 'license' => 'perl', | |
314 | 'build_requires' => { | |
315 | 'Test::More' => '0', | |
316 | 'Test::Harness' => '0', | |
317 | 'perl' => '5.006' | |
318 | }, | |
319 | 'provides' => { | |
320 | 'Spreadsheet::Read' => { | |
321 | 'version' => 'VERSION', | |
322 | 'file' => 'Read.pm' | |
323 | } | |
324 | }, | |
325 | 'optional_features' => [ | |
326 | { | |
327 | 'opt_csv' => { | |
328 | 'requires' => { | |
329 | 'Text::CSV_XS' => '0.23' | |
330 | }, | |
331 | 'recommends' => { | |
332 | 'Text::CSV_PP' => '1.10', | |
333 | 'Text::CSV_XS' => '0.58', | |
334 | 'Text::CSV' => '1.10' | |
335 | }, | |
336 | 'description' => 'Provides parsing of CSV streams' | |
337 | } | |
338 | }, | |
339 | { | |
340 | 'opt_excel' => { | |
341 | 'requires' => { | |
342 | 'Spreadsheet::ParseExcel' => '0.26', | |
343 | 'Spreadsheet::ParseExcel::FmtDefault' => '0' | |
344 | }, | |
345 | 'recommends' => { | |
346 | 'Spreadsheet::ParseExcel' => '0.42' | |
347 | }, | |
348 | 'description' => 'Provides parsing of Microsoft Excel files' | |
349 | } | |
350 | }, | |
351 | { | |
352 | 'opt_excelx' => { | |
353 | 'requires' => { | |
354 | 'Spreadsheet::XLSX' => '0.07' | |
355 | }, | |
356 | 'description' => 'Provides parsing of Microsoft Excel 2007 files' | |
357 | } | |
358 | }, | |
359 | { | |
360 | 'opt_oo' => { | |
361 | 'requires' => { | |
362 | 'Spreadsheet::ReadSXC' => '0.2' | |
363 | }, | |
364 | 'description' => 'Provides parsing of OpenOffice spreadsheets' | |
365 | } | |
366 | }, | |
367 | { | |
368 | 'opt_tools' => { | |
369 | 'recommends' => { | |
370 | 'Tk::TableMatrix::Spreadsheet' => '0', | |
371 | 'Tk::NoteBook' => '0', | |
372 | 'Tk' => '0' | |
373 | }, | |
374 | 'description' => 'Spreadsheet tools' | |
375 | } | |
376 | } | |
377 | ], | |
378 | 'requires' => { | |
379 | 'perl' => '5.006', | |
380 | 'Data::Dumper' => '0', | |
381 | 'Exporter' => '0', | |
382 | 'Carp' => '0' | |
383 | }, | |
384 | 'recommends' => { | |
385 | 'perl' => '5.008005', | |
386 | 'IO::Scalar' => '0', | |
387 | 'File::Temp' => '0.14' | |
388 | }, | |
389 | 'abstract' => 'Meta-Wrapper for reading spreadsheet data' | |
390 | } ], | |
391 | 'Spreadsheet-Read', | |
392 | noyamlpm => 1, | |
393 | noyamlperl => 1, | |
394 | ); | |
395 | } |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing Plagger config samples from Miyagawa-san's YAPC::NA 2006 talk | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More tests(2); | |
13 | use CPAN::Meta::YAML; | |
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ##################################################################### | |
20 | # Example Plagger Configuration 1 | |
21 | ||
22 | yaml_ok( | |
23 | <<'END_YAML', | |
24 | plugins: | |
25 | - module: Subscription::Bloglines | |
26 | config: | |
27 | username: you@example.pl | |
28 | password: foobar | |
29 | mark_read: 1 | |
30 | ||
31 | - module: Publish::Gmail | |
32 | config: | |
33 | mailto: example@gmail.com | |
34 | mailfrom: miyagawa@example.com | |
35 | mailroute: | |
36 | via: smtp | |
37 | host: smtp.example.com | |
38 | END_YAML | |
39 | [ { plugins => [ | |
40 | { | |
41 | module => 'Subscription::Bloglines', | |
42 | config => { | |
43 | username => 'you@example.pl', | |
44 | password => 'foobar', | |
45 | mark_read => 1, | |
46 | }, | |
47 | }, | |
48 | { | |
49 | module => 'Publish::Gmail', | |
50 | config => { | |
51 | mailto => 'example@gmail.com', | |
52 | mailfrom => 'miyagawa@example.com', | |
53 | mailroute => { | |
54 | via => 'smtp', | |
55 | host => 'smtp.example.com', | |
56 | }, | |
57 | }, | |
58 | }, | |
59 | ] } ], | |
60 | 'Plagger', | |
61 | ); | |
62 | ||
63 | ||
64 | ||
65 | ||
66 | ||
67 | ##################################################################### | |
68 | # Example Plagger Configuration 2 | |
69 | ||
70 | yaml_ok( | |
71 | <<'END_YAML', | |
72 | plugins: | |
73 | - module: Subscription::Config | |
74 | config: | |
75 | feed: | |
76 | # Trac's feed for changesets | |
77 | - http://plagger.org/.../rss | |
78 | ||
79 | # I don't like to be notified of the same items | |
80 | # more than once | |
81 | - module: Filter::Rule | |
82 | rule: | |
83 | module: Fresh | |
84 | mtime: | |
85 | path: /tmp/rssbot.time | |
86 | autoupdate: 1 | |
87 | ||
88 | - module: Notify::IRC | |
89 | config: | |
90 | daemon_port: 9999 | |
91 | nickname: plaggerbot | |
92 | server_host: chat.freenode.net | |
93 | server_channels: | |
94 | - '#plagger-ja' | |
95 | - '#plagger' | |
96 | ||
97 | ||
98 | END_YAML | |
99 | [ { plugins => [ { | |
100 | module => 'Subscription::Config', | |
101 | config => { | |
102 | feed => [ 'http://plagger.org/.../rss' ], | |
103 | }, | |
104 | }, { | |
105 | module => 'Filter::Rule', | |
106 | rule => { | |
107 | module => 'Fresh', | |
108 | mtime => { | |
109 | path => '/tmp/rssbot.time', | |
110 | autoupdate => 1, | |
111 | }, | |
112 | }, | |
113 | }, { | |
114 | module => 'Notify::IRC', | |
115 | config => { | |
116 | daemon_port => 9999, | |
117 | nickname => 'plaggerbot', | |
118 | server_host => 'chat.freenode.net', | |
119 | server_channels => [ | |
120 | '#plagger-ja', | |
121 | '#plagger', | |
122 | ], | |
123 | }, | |
124 | } ] } ], | |
125 | 'plagger2', | |
126 | ); |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing of common META.yml examples | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More tests(1, 1); | |
13 | use CPAN::Meta::YAML; | |
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ##################################################################### | |
20 | # Testing that Perl::Smith config files work | |
21 | ||
22 | my $vanilla_file = catfile( test_data_directory(), 'vanilla.yml' ); | |
23 | my $vanilla = load_ok( 'yanilla.yml', $vanilla_file, 1000 ); | |
24 | ||
25 | yaml_ok( | |
26 | $vanilla, | |
27 | [ { | |
28 | package_name => 'VanillaPerl', | |
29 | package_version => 5, | |
30 | download_dir => 'c:\temp\vp_sources', | |
31 | build_dir => 'c:\temp\vp_build', | |
32 | image_dir => 'c:\vanilla-perl', | |
33 | binary => [ | |
34 | { | |
35 | name => 'dmake', | |
36 | url => 'http://search.cpan.org/CPAN/authors/id/S/SH/SHAY/dmake-4.5-20060619-SHAY.zip', | |
37 | license => { | |
38 | 'dmake/COPYING' => 'dmake/COPYING', | |
39 | 'dmake/readme/license.txt' => 'dmake/license.txt', | |
40 | }, | |
41 | install_to => { | |
42 | 'dmake/dmake.exe' => 'dmake/bin/dmake.exe', | |
43 | 'dmake/startup' => 'dmake/bin/startup', | |
44 | }, | |
45 | }, | |
46 | { | |
47 | name => 'gcc-core', | |
48 | url => 'http://umn.dl.sourceforge.net/mingw/gcc-core-3.4.5-20060117-1.tar.gz', | |
49 | license => { | |
50 | 'COPYING' => 'gcc/COPYING', | |
51 | 'COPYING.lib' => 'gcc/COPYING.lib', | |
52 | }, | |
53 | install_to => 'mingw', | |
54 | }, | |
55 | { | |
56 | name => 'gcc-g++', | |
57 | url => 'http://umn.dl.sourceforge.net/mingw/gcc-g++-3.4.5-20060117-1.tar.gz', | |
58 | license => undef, | |
59 | install_to => 'mingw', | |
60 | }, | |
61 | { | |
62 | name => 'binutils', | |
63 | url => 'http://umn.dl.sourceforge.net/mingw/binutils-2.16.91-20060119-1.tar.gz', | |
64 | license => { | |
65 | 'Copying' => 'binutils/Copying', | |
66 | 'Copying.lib' => 'binutils/Copying.lib', | |
67 | }, | |
68 | install_to => 'mingw', | |
69 | }, | |
70 | { | |
71 | name => 'mingw-runtime', | |
72 | url => 'http://umn.dl.sourceforge.net/mingw/mingw-runtime-3.10.tar.gz', | |
73 | license => { | |
74 | 'doc/mingw-runtime/Contributors' => 'mingw/Contributors', | |
75 | 'doc/mingw-runtime/Disclaimer' => 'mingw/Disclaimer', | |
76 | }, | |
77 | install_to => 'mingw', | |
78 | }, | |
79 | { | |
80 | name => 'w32api', | |
81 | url => 'http://umn.dl.sourceforge.net/mingw/w32api-3.6.tar.gz', | |
82 | license => undef, | |
83 | install_to => 'mingw', | |
84 | extra => { | |
85 | 'extra\README.w32api' => 'licenses\win32api\README.w32api', | |
86 | }, | |
87 | } | |
88 | ], | |
89 | source => [ | |
90 | { | |
91 | name => 'perl', | |
92 | url => 'http://mirrors.kernel.org/CPAN/src/perl-5.8.8.tar.gz', | |
93 | license => { | |
94 | 'perl-5.8.8/Readme' => 'perl/Readme', | |
95 | 'perl-5.8.8/Artistic' => 'perl/Artistic', | |
96 | 'perl-5.8.8/Copying' => 'perl/Copying', | |
97 | }, | |
98 | unpack_to => 'perl', | |
99 | install_to => 'perl', | |
100 | after => { | |
101 | 'extra\Config.pm' => 'lib\CPAN\Config.pm', | |
102 | }, | |
103 | } | |
104 | ], | |
105 | modules => [ | |
106 | { | |
107 | name => 'Win32::Job', | |
108 | unpack_to => { | |
109 | APIFile => 'Win32API-File', | |
110 | }, | |
111 | }, | |
112 | { | |
113 | name => 'IO', | |
114 | force => 1, | |
115 | }, | |
116 | { | |
117 | name => 'Compress::Zlib', | |
118 | }, | |
119 | { | |
120 | name => 'IO::Zlib', | |
121 | }, | |
122 | { | |
123 | name => 'Archive::Tar', | |
124 | }, | |
125 | { | |
126 | name => 'Net::FTP', | |
127 | extra => { | |
128 | 'extra\libnet.cfg' => 'libnet.cfg', | |
129 | }, | |
130 | }, | |
131 | ], | |
132 | extra => { | |
133 | 'README' => 'README.txt', | |
134 | 'LICENSE.txt' => 'LICENSE.txt', | |
135 | 'Changes' => 'Release-Notes.txt', | |
136 | 'extra\Config.pm' => 'perl\lib\CPAN\Config.pm', | |
137 | 'extra\links\Perl-Documentation.url' => 'links\Perl Documentation.url', | |
138 | 'extra\links\Perl-Homepage.url' => 'links\Perl Homepage.url', | |
139 | 'extra\links\Perl-Mailing-Lists.url' => 'links\Perl Mailing Lists.url', | |
140 | 'extra\links\Perlmonks-Community-Forum.url' => 'links\Perlmonks Community Forum.url', | |
141 | 'extra\links\Search-CPAN-Modules.url' => 'links\Search CPAN Modules.url', | |
142 | 'extra\links\Vanilla-Perl-Homepage.url' => 'links\Vanilla Perl Homepage.url', | |
143 | }, | |
144 | } ], | |
145 | 'vanilla.yml', | |
146 | nosyck => 1, | |
147 | noyamlperl => 1, | |
148 | ); |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing of common META.yml examples | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More tests(1, 1); | |
13 | use CPAN::Meta::YAML; | |
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ##################################################################### | |
20 | # Testing that Perl::Smith config files work | |
21 | ||
22 | my $sample_file = catfile( test_data_directory(), 'sample.yml' ); | |
23 | my $sample = load_ok( 'sample.yml', $sample_file, 500 ); | |
24 | ||
25 | yaml_ok( | |
26 | $sample, | |
27 | [ { | |
28 | invoice => 34843, | |
29 | date => '2001-01-23', | |
30 | 'bill-to' => { | |
31 | given => 'Chris', | |
32 | family => 'Dumars', | |
33 | address => { | |
34 | lines => "458 Walkman Dr.\nSuite #292\n", | |
35 | city => 'Royal Oak', | |
36 | state => 'MI', | |
37 | postal => 48046, | |
38 | }, | |
39 | }, | |
40 | product => [ | |
41 | { | |
42 | sku => 'BL394D', | |
43 | quantity => '4', | |
44 | description => 'Basketball', | |
45 | price => '450.00', | |
46 | }, | |
47 | { | |
48 | sku => 'BL4438H', | |
49 | quantity => '1', | |
50 | description => 'Super Hoop', | |
51 | price => '2392.00', | |
52 | }, | |
53 | ], | |
54 | tax => '251.42', | |
55 | total => '4443.52', | |
56 | comments => <<'END_TEXT', | |
57 | Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338. | |
58 | END_TEXT | |
59 | } ], | |
60 | 'sample.yml', | |
61 | # nosyck => 1, | |
62 | ); |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing of META.yml containing AVAR's name | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More tests(0, 1, 5); | |
13 | use CPAN::Meta::YAML; | |
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ##################################################################### | |
20 | # Testing that Perl::Smith config files work | |
21 | ||
22 | my $sample_file = catfile( test_data_directory(), 'multibyte.yml' ); | |
23 | my $sample = load_ok( 'multibyte.yml', $sample_file, 450 ); | |
24 | ||
25 | # Does the string parse to the structure | |
26 | my $name = "multibyte"; | |
27 | my $yaml_copy = $sample; | |
28 | my $yaml = eval { CPAN::Meta::YAML->read_string( $yaml_copy ); }; | |
29 | is( $@, '', "$name: CPAN::Meta::YAML parses without error" ); | |
30 | is( $yaml_copy, $sample, "$name: CPAN::Meta::YAML does not modify the input string" ); | |
31 | SKIP: { | |
32 | skip( "Shortcutting after failure", 2 ) if $@; | |
33 | isa_ok( $yaml, 'CPAN::Meta::YAML' ); | |
34 | is_deeply( $yaml->[0]->{build_requires}, { | |
35 | 'Config' => 0, | |
36 | 'Test::More' => 0, | |
37 | 'XSLoader' => 0, | |
38 | }, 'build_requires ok' ); | |
39 | } | |
40 | ||
41 | SKIP: { | |
42 | unless ( CPAN::Meta::YAML::HAVE_UTF8() ) { | |
43 | skip("no utf8 support", 1 ); | |
44 | } | |
45 | eval { utf8::is_utf8('') }; | |
46 | if ( $@ ) { | |
47 | skip("no is_utf8 to test with until 5.8.1", 1); | |
48 | } | |
49 | ok( utf8::is_utf8($yaml->[0]->{author}), "utf8 decoded" ); | |
50 | } |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing for null references | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More tests(1); | |
13 | use CPAN::Meta::YAML; | |
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ##################################################################### | |
20 | # Example Empty References | |
21 | ||
22 | yaml_ok( | |
23 | <<'END_YAML', | |
24 | --- [] | |
25 | --- {} | |
26 | END_YAML | |
27 | [ [], {} ], | |
28 | 'Empty references', | |
29 | ); |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing of a known-bad file from an editor | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | # use Test::More skip_all => 'Temporarily ignoring failing test'; | |
13 | use Test::More tests(1, 1); | |
14 | use CPAN::Meta::YAML; | |
15 | ||
16 | ||
17 | ||
18 | ||
19 | ||
20 | ##################################################################### | |
21 | # Testing that Perl::Smith config files work | |
22 | ||
23 | my $toolbar_file = catfile( test_data_directory(), 'toolbar.yml' ); | |
24 | my $toolbar = load_ok( 'toolbar.yml', $toolbar_file, 100 ); | |
25 | ||
26 | yaml_ok( | |
27 | $toolbar, | |
28 | [ { | |
29 | main_toolbar => [ | |
30 | 'item file-new', | |
31 | 'item file-open', | |
32 | 'item file-print#', | |
33 | 'item file-close#', | |
34 | 'item file-save-all', | |
35 | 'item file-save', | |
36 | undef, | |
37 | 'item edit-changes-undo', | |
38 | 'item edit-changes-redo', | |
39 | undef, | |
40 | 'item edit-cut', | |
41 | 'item edit-copy', | |
42 | 'item edit-paste', | |
43 | 'item edit-replace', | |
44 | 'item edit-delete', | |
45 | ] | |
46 | } ], | |
47 | 'toolbar.yml', | |
48 | noyamlperl => 1, | |
49 | ); |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing relating to functionality in the Test Anything Protocol | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More tests(5, 0, 0); | |
13 | use CPAN::Meta::YAML (); | |
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ##################################################################### | |
20 | # TAP Tests | |
21 | ||
22 | # Make sure we support x-foo keys | |
23 | yaml_ok( | |
24 | "---\nx-foo: 1\n", | |
25 | [ { 'x-foo' => 1 } ], | |
26 | 'x-foo key', | |
27 | ); | |
28 | ||
29 | # Document ending (hash) | |
30 | yaml_ok( | |
31 | "---\n" | |
32 | . " foo: bar\n" | |
33 | . "...\n", | |
34 | [ { foo => "bar" } ], | |
35 | 'document_end_hash', | |
36 | noyamlpm => 1, | |
37 | nosyck => 1, | |
38 | noyamlperl => 1, | |
39 | ); | |
40 | ||
41 | # Document ending (array) | |
42 | yaml_ok( | |
43 | "---\n" | |
44 | . "- foo\n" | |
45 | . "...\n", | |
46 | [ [ 'foo' ] ], | |
47 | 'document_end_array', | |
48 | noyamlpm => 1, | |
49 | noyamlperl => 1, | |
50 | ); | |
51 | ||
52 | # Multiple documents (simple) | |
53 | yaml_ok( | |
54 | "---\n" | |
55 | . "- foo\n" | |
56 | . "...\n" | |
57 | . "---\n" | |
58 | . "- foo\n" | |
59 | . "...\n", | |
60 | [ [ 'foo' ], [ 'foo' ] ], | |
61 | 'multi_document_simple', | |
62 | noyamlpm => 1, | |
63 | noyamlperl => 1, | |
64 | ); | |
65 | ||
66 | # Multiple documents (whitespace-separated) | |
67 | yaml_ok( | |
68 | "---\n" | |
69 | . "- foo\n" | |
70 | . "...\n" | |
71 | . "\n" | |
72 | . "---\n" | |
73 | . "- foo\n" | |
74 | . "...\n", | |
75 | [ [ 'foo' ], [ 'foo' ] ], | |
76 | 'multi_document_space', | |
77 | noyamlpm => 1, | |
78 | noyamlperl => 1, | |
79 | ); |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing documents that should fail | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More tests => 20; | |
13 | use CPAN::Meta::YAML (); | |
14 | ||
15 | my $FEATURE = 'does not support a feature'; | |
16 | my $PLAIN = 'illegal characters in plain scalar'; | |
17 | ||
18 | ||
19 | ||
20 | ||
21 | ||
22 | ##################################################################### | |
23 | # Syntactic Errors | |
24 | ||
25 | yaml_error( <<'END_YAML', $FEATURE ); | |
26 | - 'Multiline | |
27 | quote' | |
28 | END_YAML | |
29 | ||
30 | yaml_error( <<'END_YAML', $FEATURE ); | |
31 | - "Multiline | |
32 | quote" | |
33 | END_YAML | |
34 | ||
35 | yaml_error( <<'END_YAML', $FEATURE ); | |
36 | --- | |
37 | version: !!perl/hash:version | |
38 | original: v2.0.2 | |
39 | qv: 1 | |
40 | version: | |
41 | - 2 | |
42 | - 0 | |
43 | - 2 | |
44 | END_YAML | |
45 | ||
46 | yaml_error( <<'END_YAML', $PLAIN ); | |
47 | - - 2 | |
48 | END_YAML | |
49 | ||
50 | yaml_error( <<'END_YAML', $PLAIN ); | |
51 | foo: - | |
52 | END_YAML | |
53 | ||
54 | yaml_error( <<'END_YAML', $PLAIN ); | |
55 | foo: @INC | |
56 | END_YAML | |
57 | ||
58 | yaml_error( <<'END_YAML', $PLAIN ); | |
59 | foo: %INC | |
60 | END_YAML | |
61 | ||
62 | yaml_error( <<'END_YAML', $PLAIN ); | |
63 | foo: bar: | |
64 | END_YAML | |
65 | ||
66 | yaml_error( <<'END_YAML', $PLAIN ); | |
67 | foo: bar: baz | |
68 | END_YAML | |
69 | ||
70 | yaml_error( <<'END_YAML', $PLAIN ); | |
71 | foo: `perl -V` | |
72 | END_YAML |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing documents that should fail | |
3 | ||
4 | use strict; | |
5 | BEGIN { | |
6 | $| = 1; | |
7 | $^W = 1; | |
8 | } | |
9 | ||
10 | use File::Spec::Functions ':ALL'; | |
11 | use t::lib::Test; | |
12 | use Test::More tests => 1; | |
13 | ||
14 | ||
15 | ||
16 | ||
17 | ||
18 | ##################################################################### | |
19 | # Customized Class | |
20 | ||
21 | SCOPE: { | |
22 | package Foo; | |
23 | ||
24 | use CPAN::Meta::YAML; | |
25 | ||
26 | use vars qw{@ISA}; | |
27 | BEGIN { | |
28 | @ISA = 'CPAN::Meta::YAML'; | |
29 | } | |
30 | ||
31 | sub _write_scalar { | |
32 | my $self = shift; | |
33 | my $string = shift; | |
34 | my $indent = shift; | |
35 | if ( defined $indent ) { | |
36 | return "'$indent'"; | |
37 | } else { | |
38 | return 'undef'; | |
39 | } | |
40 | } | |
41 | ||
42 | 1; | |
43 | } | |
44 | ||
45 | ||
46 | ||
47 | ||
48 | ||
49 | ##################################################################### | |
50 | # Generate the value | |
51 | ||
52 | my $object = Foo->new( | |
53 | { foo => 'bar' } | |
54 | ); | |
55 | is( $object->write_string, "---\nfoo: '1'\n", 'Subclassing works' ); |
0 | #!/usr/bin/perl | |
1 | ||
2 | use strict; | |
3 | BEGIN { | |
4 | $| = 1; | |
5 | $^W = 1; | |
6 | } | |
7 | ||
8 | use File::Spec::Functions ':ALL'; | |
9 | use t::lib::Test; | |
10 | use Test::More tests(0, 1, 4); | |
11 | use CPAN::Meta::YAML; | |
12 | ||
13 | ||
14 | ||
15 | ||
16 | ||
17 | ##################################################################### | |
18 | # Testing that Perl::Smith config files work | |
19 | ||
20 | my $sample_file = catfile( 't', 'data', 'utf_16_le_bom.yml' ); | |
21 | my $sample = load_ok( 'utf_16_le_bom.yml', $sample_file, 3 ); | |
22 | ||
23 | # Does the string parse to the structure | |
24 | my $name = "utf-16"; | |
25 | my $yaml_copy = $sample; | |
26 | my $yaml = eval { CPAN::Meta::YAML->read_string( $yaml_copy ); }; | |
27 | is( $@, '', "$name: CPAN::Meta::YAML parses without error" ); | |
28 | is( $yaml_copy, $sample, "$name: CPAN::Meta::YAML does not modify the input string" ); | |
29 | SKIP: { | |
30 | skip( "Shortcutting after failure", 2 ) if $@; | |
31 | is( $yaml, undef, "file not parsed" ); | |
32 | is( CPAN::Meta::YAML->errstr, "Stream has a non UTF-8 BOM", "correct error" ); | |
33 | } |
0 | #!/usr/bin/perl | |
1 | ||
2 | # Testing of inline comments. These comments can be quite useful in config | |
3 | # files and people will expect them to work. | |
4 | ||
5 | use strict; | |
6 | BEGIN { | |
7 | $| = 1; | |
8 | $^W = 1; | |
9 | } | |
10 | ||
11 | use File::Spec::Functions ':ALL'; | |
12 | use t::lib::Test; | |
13 | use Test::More tests(2); | |
14 | use CPAN::Meta::YAML; | |
15 | ||
16 | ||
17 | ||
18 | ||
19 | ||
20 | ##################################################################### | |
21 | # Main Tests | |
22 | ||
23 | yaml_ok( | |
24 | <<'END_YAML', | |
25 | --- | |
26 | a: b#content | |
27 | c: d #comment | |
28 | e: | |
29 | - f #comment | |
30 | - g# content | |
31 | h: 'single' # comment | |
32 | h2: 'single # content' # comment | |
33 | i: "double" # comment | |
34 | i2: "double # content" # comment | |
35 | j: | # comment | |
36 | literal # content | |
37 | block # content | |
38 | k: {} # comment | |
39 | l: [] # comment | |
40 | m: # comment | |
41 | n: o | |
42 | END_YAML | |
43 | [ | |
44 | { | |
45 | a => 'b#content', | |
46 | c => 'd', | |
47 | e => [ | |
48 | 'f', | |
49 | 'g# content', | |
50 | ], | |
51 | h => 'single', | |
52 | h2 => 'single # content', | |
53 | i => 'double', | |
54 | i2 => 'double # content', | |
55 | j => "literal # content\nblock # content\n", | |
56 | k => {}, | |
57 | l => [], | |
58 | m => { | |
59 | n => 'o', | |
60 | }, | |
61 | }, | |
62 | ], | |
63 | 'Properly ignore comments', | |
64 | noyamlpm => 1, | |
65 | ); | |
66 | ||
67 | # Repeat, with otherwise illegal characters in the comments | |
68 | yaml_ok( | |
69 | <<'END_YAML', | |
70 | --- | |
71 | a: b#content | |
72 | c: d #comment '"!&@%` | |
73 | e: | |
74 | - f #comment '"!&@%` | |
75 | - g# content | |
76 | h: 'single' # comment '"!&@%` | |
77 | h2: 'single # content' # comment '"!&@%` | |
78 | i: "double" # comment '"!&@%` | |
79 | i2: "double # content" # comment '"!&@%` | |
80 | j: | # comment '"!&@%` | |
81 | literal # content | |
82 | block # content | |
83 | k: {} # comment '"!&@%` | |
84 | l: [] # comment '"!&@%` | |
85 | m: # comment '"!&@%` | |
86 | n: o | |
87 | END_YAML | |
88 | [ | |
89 | { | |
90 | a => 'b#content', | |
91 | c => 'd', | |
92 | e => [ | |
93 | 'f', | |
94 | 'g# content', | |
95 | ], | |
96 | h => 'single', | |
97 | h2 => 'single # content', | |
98 | i => 'double', | |
99 | i2 => 'double # content', | |
100 | j => "literal # content\nblock # content\n", | |
101 | k => {}, | |
102 | l => [], | |
103 | m => { | |
104 | n => 'o', | |
105 | }, | |
106 | }, | |
107 | ], | |
108 | 'Properly ignore comments (with otherwise illegal characters)', | |
109 | noyamlpm => 1, | |
110 | ); |
0 | --- #YAML:1.0 | |
1 | name: HTML-WebDAO | |
2 | version: 0.04 | |
3 | author: | |
4 | - |- | |
5 | Zahatski Aliaksandr, E<lt>zagap@users.sourceforge.netE<gt> | |
6 | abstract: Perl extension for create complex web application | |
7 | license: perl |
0 | --- #YAML:1.1 | |
1 | name: Read | |
2 | version: VERSION | |
3 | abstract: Meta-Wrapper for reading spreadsheet data | |
4 | license: perl | |
5 | author: | |
6 | - H.Merijn Brand <h.m.brand@xs4all.nl> | |
7 | generated_by: Author | |
8 | distribution_type: module | |
9 | provides: | |
10 | Spreadsheet::Read: | |
11 | file: Read.pm | |
12 | version: VERSION | |
13 | requires: | |
14 | perl: 5.006 | |
15 | Exporter: 0 | |
16 | Carp: 0 | |
17 | Data::Dumper: 0 | |
18 | recommends: | |
19 | perl: 5.008005 | |
20 | File::Temp: 0.14 | |
21 | IO::Scalar: 0 | |
22 | build_requires: | |
23 | perl: 5.006 | |
24 | Test::Harness: 0 | |
25 | Test::More: 0 | |
26 | optional_features: | |
27 | - opt_csv: | |
28 | description: Provides parsing of CSV streams | |
29 | requires: | |
30 | Text::CSV_XS: 0.23 | |
31 | recommends: | |
32 | Text::CSV: 1.10 | |
33 | Text::CSV_PP: 1.10 | |
34 | Text::CSV_XS: 0.58 | |
35 | - opt_excel: | |
36 | description: Provides parsing of Microsoft Excel files | |
37 | requires: | |
38 | Spreadsheet::ParseExcel: 0.26 | |
39 | Spreadsheet::ParseExcel::FmtDefault: 0 | |
40 | recommends: | |
41 | Spreadsheet::ParseExcel: 0.42 | |
42 | - opt_excelx: | |
43 | description: Provides parsing of Microsoft Excel 2007 files | |
44 | requires: | |
45 | Spreadsheet::XLSX: 0.07 | |
46 | - opt_oo: | |
47 | description: Provides parsing of OpenOffice spreadsheets | |
48 | requires: | |
49 | Spreadsheet::ReadSXC: 0.2 | |
50 | - opt_tools: | |
51 | description: Spreadsheet tools | |
52 | recommends: | |
53 | Tk: 0 | |
54 | Tk::NoteBook: 0 | |
55 | Tk::TableMatrix::Spreadsheet: 0 | |
56 | resources: | |
57 | license: http://dev.perl.org/licenses/ | |
58 | meta-spec: | |
59 | version: 1.4 | |
60 | url: http://module-build.sourceforge.net/META-spec-v1.4.html |
0 | --- | |
1 | abstract: Decode all templates by Unicode::Japanese | |
2 | author: Hironori Yoshida C<< <yoshida@cpan.org> >> | |
3 | distribution_type: module | |
4 | generated_by: Module::Install version 0.65 | |
5 | license: perl | |
6 | meta-spec: | |
7 | url: http://module-build.sourceforge.net/META-spec-v1.3.html | |
8 | version: 1.3 | |
9 | name: Template-Provider-Unicode-Japanese | |
10 | no_index: | |
11 | directory: | |
12 | - inc | |
13 | - t | |
14 | requires: | |
15 | Template::Config: 0 | |
16 | Unicode::Japanese: 0 | |
17 | perl: 5.6.0 | |
18 | version: 0 | |
19 | version: 1.2.1 |
0 | --- | |
1 | abstract: Perl-compatible regular expression engine | |
2 | author: "Ævar Arnfjörð Bjarmason <avar@cpan.org>" | |
3 | build_requires: | |
4 | Config: 0 | |
5 | Test::More: 0 | |
6 | XSLoader: 0 | |
7 | distribution_type: module | |
8 | generated_by: Module::Install version 0.65 | |
9 | license: perl | |
10 | meta-spec: | |
11 | url: http://module-build.sourceforge.net/META-spec-v1.3.html | |
12 | version: 1.3 | |
13 | name: re-engine-PCRE | |
14 | no_index: | |
15 | directory: | |
16 | - inc | |
17 | - t | |
18 | requires: | |
19 | perl: 5.9.5 | |
20 | tests: t/*.t t/*/*.t | |
21 | version: 0.10 |
0 | --- | |
1 | invoice: 34843 | |
2 | date : 2001-01-23 | |
3 | bill-to: | |
4 | given : Chris | |
5 | family : Dumars | |
6 | address: | |
7 | lines: | | |
8 | 458 Walkman Dr. | |
9 | Suite #292 | |
10 | city : Royal Oak | |
11 | state : MI | |
12 | postal : 48046 | |
13 | product: | |
14 | - sku : BL394D | |
15 | quantity : 4 | |
16 | description : Basketball | |
17 | price : 450.00 | |
18 | - sku : BL4438H | |
19 | quantity : 1 | |
20 | description : Super Hoop | |
21 | price : 2392.00 | |
22 | tax : 251.42 | |
23 | total: 4443.52 | |
24 | comments: > | |
25 | Late afternoon is best. | |
26 | Backup contact is Nancy | |
27 | Billsmer @ 338-4338. |
0 | main_toolbar: | |
1 | - item file-new | |
2 | - item file-open | |
3 | - item file-print# | |
4 | - item file-close# | |
5 | - item file-save-all | |
6 | - item file-save | |
7 | - | |
8 | - item edit-changes-undo | |
9 | - item edit-changes-redo | |
10 | - | |
11 | - item edit-cut | |
12 | - item edit-copy | |
13 | - item edit-paste | |
14 | - item edit-replace | |
15 | - item edit-delete |
Binary diff not shown
0 | # VanillaPerl YAML config file | |
1 | --- | |
2 | # package info | |
3 | package_name: VanillaPerl | |
4 | package_version: 5 | |
5 | ||
6 | # directories | |
7 | download_dir: c:\temp\vp_sources | |
8 | build_dir: c:\temp\vp_build | |
9 | image_dir: c:\vanilla-perl | |
10 | ||
11 | # Binary components | |
12 | binary: | |
13 | - name: dmake | |
14 | url: http://search.cpan.org/CPAN/authors/id/S/SH/SHAY/dmake-4.5-20060619-SHAY.zip | |
15 | license: | |
16 | dmake/COPYING : dmake/COPYING | |
17 | dmake/readme/license.txt: dmake/license.txt | |
18 | install_to: | |
19 | dmake/dmake.exe: dmake/bin/dmake.exe | |
20 | dmake/startup: dmake/bin/startup | |
21 | ||
22 | - name: gcc-core | |
23 | url: http://umn.dl.sourceforge.net/mingw/gcc-core-3.4.5-20060117-1.tar.gz | |
24 | license: | |
25 | COPYING: gcc/COPYING | |
26 | COPYING.lib: gcc/COPYING.lib | |
27 | install_to: mingw | |
28 | ||
29 | - name: gcc-g++ | |
30 | url: http://umn.dl.sourceforge.net/mingw/gcc-g++-3.4.5-20060117-1.tar.gz | |
31 | license: | |
32 | install_to: mingw | |
33 | ||
34 | - name: binutils | |
35 | url: http://umn.dl.sourceforge.net/mingw/binutils-2.16.91-20060119-1.tar.gz | |
36 | license: | |
37 | Copying: binutils/Copying | |
38 | Copying.lib: binutils/Copying.lib | |
39 | install_to: mingw | |
40 | ||
41 | - name: mingw-runtime | |
42 | url: http://umn.dl.sourceforge.net/mingw/mingw-runtime-3.10.tar.gz | |
43 | license: | |
44 | doc/mingw-runtime/Contributors: mingw/Contributors | |
45 | doc/mingw-runtime/Disclaimer: mingw/Disclaimer | |
46 | install_to: mingw | |
47 | ||
48 | - name: w32api | |
49 | url: http://umn.dl.sourceforge.net/mingw/w32api-3.6.tar.gz | |
50 | license: | |
51 | install_to: mingw | |
52 | extra: | |
53 | extra\README.w32api: licenses\win32api\README.w32api | |
54 | ||
55 | # Source components | |
56 | source: | |
57 | - name: perl | |
58 | url: http://mirrors.kernel.org/CPAN/src/perl-5.8.8.tar.gz | |
59 | license: | |
60 | perl-5.8.8/Readme: perl/Readme | |
61 | perl-5.8.8/Artistic: perl/Artistic | |
62 | perl-5.8.8/Copying: perl/Copying | |
63 | unpack_to: perl | |
64 | install_to: perl | |
65 | after: | |
66 | extra\Config.pm: lib\CPAN\Config.pm | |
67 | ||
68 | # Additional modules to bundle in site\lib | |
69 | modules: | |
70 | # i.e. not used, but gets us the libwin32 dist | |
71 | - name: Win32::Job | |
72 | unpack_to: | |
73 | APIFile: Win32API-File | |
74 | - name: IO | |
75 | force: 1 | |
76 | - name: Compress::Zlib | |
77 | - name: IO::Zlib | |
78 | - name: Archive::Tar | |
79 | - name: Net::FTP | |
80 | extra: | |
81 | extra\libnet.cfg: libnet.cfg | |
82 | ||
83 | # Extra files to be placed | |
84 | # Signature.pm: perl\site\lib\Module\Signature.pm | |
85 | extra: | |
86 | README: README.txt | |
87 | LICENSE.txt: LICENSE.txt | |
88 | Changes: Release-Notes.txt | |
89 | extra\Config.pm: perl\lib\CPAN\Config.pm | |
90 | # reset this again | |
91 | ||
92 | extra\links\Perl-Documentation.url: links\Perl Documentation.url | |
93 | extra\links\Perl-Homepage.url: links\Perl Homepage.url | |
94 | extra\links\Perl-Mailing-Lists.url: links\Perl Mailing Lists.url | |
95 | extra\links\Perlmonks-Community-Forum.url: links\Perlmonks Community Forum.url | |
96 | extra\links\Search-CPAN-Modules.url: links\Search CPAN Modules.url | |
97 | extra\links\Vanilla-Perl-Homepage.url: links\Vanilla Perl Homepage.url |
0 | package t::lib::Test; | |
1 | ||
2 | use strict; | |
3 | use Exporter (); | |
4 | use File::Spec (); | |
5 | use Test::More (); | |
6 | ||
7 | use vars qw{@ISA @EXPORT}; | |
8 | BEGIN { | |
9 | @ISA = qw{ Exporter }; | |
10 | @EXPORT = qw{ | |
11 | tests yaml_ok yaml_error slurp load_ok | |
12 | test_data_directory | |
13 | }; | |
14 | } | |
15 | ||
16 | # Do we have the authorative YAML to test against | |
17 | eval { | |
18 | require YAML; | |
19 | ||
20 | # This doesn't currently work, but is documented to. | |
21 | # So if it ever turns up, use it. | |
22 | $YAML::UseVersion = 1; | |
23 | }; | |
24 | my $HAVE_YAMLPM = !! ( | |
25 | $YAML::VERSION | |
26 | and | |
27 | $YAML::VERSION >= 0.66 | |
28 | ); | |
29 | sub have_yamlpm { $HAVE_YAMLPM } | |
30 | ||
31 | # Do we have YAML::Perl to test against? | |
32 | eval { | |
33 | require YAML::Perl; | |
34 | }; | |
35 | my $HAVE_YAMLPERL = !! ( | |
36 | $YAML::Perl::VERSION | |
37 | and | |
38 | $YAML::Perl::VERSION >= 0.02 | |
39 | ); | |
40 | sub have_yamlperl { $HAVE_YAMLPERL } | |
41 | ||
42 | # Do we have YAML::Syck to test against? | |
43 | eval { | |
44 | require YAML::Syck; | |
45 | }; | |
46 | my $HAVE_SYCK = !! ( | |
47 | $YAML::Syck::VERSION | |
48 | and | |
49 | $YAML::Syck::VERSION >= 1.05 | |
50 | ); | |
51 | sub have_syck { $HAVE_SYCK } | |
52 | ||
53 | # Do we have YAML::XS to test against? | |
54 | eval { | |
55 | require YAML::XS; | |
56 | }; | |
57 | my $HAVE_XS = !! ( | |
58 | $YAML::XS::VERSION | |
59 | and | |
60 | $YAML::XS::VERSION >= 0.29 | |
61 | ); | |
62 | sub have_xs{ $HAVE_XS } | |
63 | ||
64 | # 22 tests per call to yaml_ok | |
65 | # 4 tests per call to load_ok | |
66 | sub tests { | |
67 | return ( tests => count(@_) ); | |
68 | } | |
69 | ||
70 | sub test_data_directory { | |
71 | return File::Spec->catdir( 't', 'data' ); | |
72 | } | |
73 | ||
74 | sub count { | |
75 | my $yaml_ok = shift || 0; | |
76 | my $load_ok = shift || 0; | |
77 | my $single = shift || 0; | |
78 | my $count = $yaml_ok * 38 + $load_ok * 4 + $single; | |
79 | return $count; | |
80 | } | |
81 | ||
82 | sub yaml_ok { | |
83 | my $string = shift; | |
84 | my $object = shift; | |
85 | my $name = shift || 'unnamed'; | |
86 | my %options = ( @_ ); | |
87 | bless $object, 'CPAN::Meta::YAML'; | |
88 | ||
89 | # If YAML itself is available, test with it | |
90 | SKIP: { | |
91 | unless ( $HAVE_YAMLPM ) { | |
92 | Test::More::skip( "Skipping YAML.pm, not available for testing", 7 ); | |
93 | } | |
94 | if ( $options{noyamlpm} ) { | |
95 | Test::More::skip( "Skipping YAML.pm for known-broken feature", 7 ); | |
96 | } | |
97 | ||
98 | # Test writing with YAML.pm | |
99 | my $yamlpm_out = eval { YAML::Dump( @$object ) }; | |
100 | Test::More::is( $@, '', "$name: YAML.pm saves without error" ); | |
101 | SKIP: { | |
102 | Test::More::skip( "Shortcutting after failure", 4 ) if $@; | |
103 | Test::More::ok( | |
104 | !!(defined $yamlpm_out and ! ref $yamlpm_out), | |
105 | "$name: YAML.pm serializes correctly", | |
106 | ); | |
107 | my @yamlpm_round = eval { YAML::Load( $yamlpm_out ) }; | |
108 | Test::More::is( $@, '', "$name: YAML.pm round-trips without error" ); | |
109 | Test::More::skip( "Shortcutting after failure", 2 ) if $@; | |
110 | my $round = bless [ @yamlpm_round ], 'CPAN::Meta::YAML'; | |
111 | Test::More::is_deeply( $round, $object, "$name: YAML.pm round-trips correctly" ); | |
112 | } | |
113 | ||
114 | # Test reading with YAML.pm | |
115 | my $yamlpm_copy = $string; | |
116 | my @yamlpm_in = eval { YAML::Load( $yamlpm_copy ) }; | |
117 | Test::More::is( $@, '', "$name: YAML.pm loads without error" ); | |
118 | Test::More::is( $yamlpm_copy, $string, "$name: YAML.pm does not modify the input string" ); | |
119 | SKIP: { | |
120 | Test::More::skip( "Shortcutting after failure", 1 ) if $@; | |
121 | Test::More::is_deeply( \@yamlpm_in, $object, "$name: YAML.pm parses correctly" ); | |
122 | } | |
123 | } | |
124 | ||
125 | # If YAML::Syck itself is available, test with it | |
126 | SKIP: { | |
127 | unless ( $HAVE_SYCK ) { | |
128 | Test::More::skip( "Skipping YAML::Syck, not available for testing", 7 ); | |
129 | } | |
130 | if ( $options{nosyck} ) { | |
131 | Test::More::skip( "Skipping YAML::Syck for known-broken feature", 7 ); | |
132 | } | |
133 | unless ( @$object == 1 ) { | |
134 | Test::More::skip( "Skipping YAML::Syck for unsupported feature", 7 ); | |
135 | } | |
136 | ||
137 | # Test writing with YAML::Syck | |
138 | my $syck_out = eval { YAML::Syck::Dump( @$object ) }; | |
139 | Test::More::is( $@, '', "$name: YAML::Syck saves without error" ); | |
140 | SKIP: { | |
141 | Test::More::skip( "Shortcutting after failure", 4 ) if $@; | |
142 | Test::More::ok( | |
143 | !!(defined $syck_out and ! ref $syck_out), | |
144 | "$name: YAML::Syck serializes correctly", | |
145 | ); | |
146 | my @syck_round = eval { YAML::Syck::Load( $syck_out ) }; | |
147 | Test::More::is( $@, '', "$name: YAML::Syck round-trips without error" ); | |
148 | Test::More::skip( "Shortcutting after failure", 2 ) if $@; | |
149 | my $round = bless [ @syck_round ], 'CPAN::Meta::YAML'; | |
150 | Test::More::is_deeply( $round, $object, "$name: YAML::Syck round-trips correctly" ); | |
151 | } | |
152 | ||
153 | # Test reading with YAML::Syck | |
154 | my $syck_copy = $string; | |
155 | my @syck_in = eval { YAML::Syck::Load( $syck_copy ) }; | |
156 | Test::More::is( $@, '', "$name: YAML::Syck loads without error" ); | |
157 | Test::More::is( $syck_copy, $string, "$name: YAML::Syck does not modify the input string" ); | |
158 | SKIP: { | |
159 | Test::More::skip( "Shortcutting after failure", 1 ) if $@; | |
160 | Test::More::is_deeply( \@syck_in, $object, "$name: YAML::Syck parses correctly" ); | |
161 | } | |
162 | } | |
163 | ||
164 | # If YAML::XS itself is available, test with it | |
165 | SKIP: { | |
166 | unless ( $HAVE_XS ) { | |
167 | Test::More::skip( "Skipping YAML::XS, not available for testing", 7 ); | |
168 | } | |
169 | if ( $options{noxs} ) { | |
170 | Test::More::skip( "Skipping YAML::XS for known-broken feature", 7 ); | |
171 | } | |
172 | ||
173 | # Test writing with YAML::XS | |
174 | my $xs_out = eval { YAML::XS::Dump( @$object ) }; | |
175 | Test::More::is( $@, '', "$name: YAML::XS saves without error" ); | |
176 | SKIP: { | |
177 | Test::More::skip( "Shortcutting after failure", 4 ) if $@; | |
178 | Test::More::ok( | |
179 | !!(defined $xs_out and ! ref $xs_out), | |
180 | "$name: YAML::XS serializes correctly", | |
181 | ); | |
182 | my @xs_round = eval { YAML::XS::Load( $xs_out ) }; | |
183 | Test::More::is( $@, '', "$name: YAML::XS round-trips without error" ); | |
184 | Test::More::skip( "Shortcutting after failure", 2 ) if $@; | |
185 | my $round = bless [ @xs_round ], 'CPAN::Meta::YAML'; | |
186 | Test::More::is_deeply( $round, $object, "$name: YAML::XS round-trips correctly" ); | |
187 | } | |
188 | ||
189 | # Test reading with YAML::XS | |
190 | my $xs_copy = $string; | |
191 | my @xs_in = eval { YAML::XS::Load( $xs_copy ) }; | |
192 | Test::More::is( $@, '', "$name: YAML::XS loads without error" ); | |
193 | Test::More::is( $xs_copy, $string, "$name: YAML::XS does not modify the input string" ); | |
194 | SKIP: { | |
195 | Test::More::skip( "Shortcutting after failure", 1 ) if $@; | |
196 | Test::More::is_deeply( \@xs_in, $object, "$name: YAML::XS parses correctly" ); | |
197 | } | |
198 | } | |
199 | ||
200 | # If YAML::Perl is available, test with it | |
201 | SKIP: { | |
202 | unless ( $HAVE_YAMLPERL ) { | |
203 | Test::More::skip( "Skipping YAML::Perl, not available for testing", 7 ); | |
204 | } | |
205 | if ( $options{noyamlperl} ) { | |
206 | Test::More::skip( "Skipping YAML::Perl for known-broken feature", 7 ); | |
207 | } | |
208 | ||
209 | # Test writing with YAML.pm | |
210 | my $yamlperl_out = eval { YAML::Perl::Dump( @$object ) }; | |
211 | Test::More::is( $@, '', "$name: YAML::Perl saves without error" ); | |
212 | SKIP: { | |
213 | Test::More::skip( "Shortcutting after failure", 4 ) if $@; | |
214 | Test::More::ok( | |
215 | !!(defined $yamlperl_out and ! ref $yamlperl_out), | |
216 | "$name: YAML::Perl serializes correctly", | |
217 | ); | |
218 | my @yamlperl_round = eval { YAML::Perl::Load( $yamlperl_out ) }; | |
219 | Test::More::is( $@, '', "$name: YAML::Perl round-trips without error" ); | |
220 | Test::More::skip( "Shortcutting after failure", 2 ) if $@; | |
221 | my $round = bless [ @yamlperl_round ], 'CPAN::Meta::YAML'; | |
222 | Test::More::is_deeply( $round, $object, "$name: YAML::Perl round-trips correctly" ); | |
223 | } | |
224 | ||
225 | # Test reading with YAML::Perl | |
226 | my $yamlperl_copy = $string; | |
227 | my @yamlperl_in = eval { YAML::Perl::Load( $yamlperl_copy ) }; | |
228 | Test::More::is( $@, '', "$name: YAML::Perl loads without error" ); | |
229 | Test::More::is( $yamlperl_copy, $string, "$name: YAML::Perl does not modify the input string" ); | |
230 | SKIP: { | |
231 | Test::More::skip( "Shortcutting after failure", 1 ) if $@; | |
232 | Test::More::is_deeply( \@yamlperl_in, $object, "$name: YAML::Perl parses correctly" ); | |
233 | } | |
234 | } | |
235 | ||
236 | # Does the string parse to the structure | |
237 | my $yaml_copy = $string; | |
238 | my $yaml = eval { CPAN::Meta::YAML->read_string( $yaml_copy ); }; | |
239 | Test::More::is( $@, '', "$name: CPAN::Meta::YAML parses without error" ); | |
240 | Test::More::is( $yaml_copy, $string, "$name: CPAN::Meta::YAML does not modify the input string" ); | |
241 | SKIP: { | |
242 | Test::More::skip( "Shortcutting after failure", 2 ) if $@; | |
243 | Test::More::isa_ok( $yaml, 'CPAN::Meta::YAML' ); | |
244 | Test::More::is_deeply( $yaml, $object, "$name: CPAN::Meta::YAML parses correctly" ); | |
245 | } | |
246 | ||
247 | # Does the structure serialize to the string. | |
248 | # We can't test this by direct comparison, because any | |
249 | # whitespace or comments would be lost. | |
250 | # So instead we parse back in. | |
251 | my $output = eval { $object->write_string }; | |
252 | Test::More::is( $@, '', "$name: CPAN::Meta::YAML serializes without error" ); | |
253 | SKIP: { | |
254 | Test::More::skip( "Shortcutting after failure", 5 ) if $@; | |
255 | Test::More::ok( | |
256 | !!(defined $output and ! ref $output), | |
257 | "$name: CPAN::Meta::YAML serializes correctly", | |
258 | ); | |
259 | my $roundtrip = eval { CPAN::Meta::YAML->read_string( $output ) }; | |
260 | Test::More::is( $@, '', "$name: CPAN::Meta::YAML round-trips without error" ); | |
261 | Test::More::skip( "Shortcutting after failure", 2 ) if $@; | |
262 | Test::More::isa_ok( $roundtrip, 'CPAN::Meta::YAML' ); | |
263 | Test::More::is_deeply( $roundtrip, $object, "$name: CPAN::Meta::YAML round-trips correctly" ); | |
264 | ||
265 | # Testing the serialization | |
266 | Test::More::skip( "Shortcutting perfect serialization tests", 1 ) unless $options{serializes}; | |
267 | Test::More::is( $output, $string, 'Serializes ok' ); | |
268 | } | |
269 | ||
270 | # Return true as a convenience | |
271 | return 1; | |
272 | } | |
273 | ||
274 | sub yaml_error { | |
275 | my $string = shift; | |
276 | my $like = shift; | |
277 | my $yaml = CPAN::Meta::YAML->read_string( $string ); | |
278 | Test::More::is( $yaml, undef, '->read_string returns undef' ); | |
279 | Test::More::ok( CPAN::Meta::YAML->errstr =~ /$like/, "Got expected error" ); | |
280 | # NOTE: like() gives better diagnostics (but requires 5.005) | |
281 | # Test::More::like( $@, qr/$_[0]/, "CPAN::Meta::YAML throws expected error" ); | |
282 | } | |
283 | ||
284 | sub slurp { | |
285 | my $file = shift; | |
286 | local $/ = undef; | |
287 | open( FILE, " $file" ) or die "open($file) failed: $!"; | |
288 | binmode( FILE, $_[0] ) if @_ > 0 && $] > 5.006; | |
289 | # binmode(FILE); # disable perl's BOM interpretation | |
290 | my $source = <FILE>; | |
291 | close( FILE ) or die "close($file) failed: $!"; | |
292 | $source; | |
293 | } | |
294 | ||
295 | sub load_ok { | |
296 | my $name = shift; | |
297 | my $file = shift; | |
298 | my $size = shift; | |
299 | Test::More::ok( -f $file, "Found $name" ); | |
300 | Test::More::ok( -r $file, "Can read $name" ); | |
301 | my $content = slurp( $file ); | |
302 | Test::More::ok( (defined $content and ! ref $content), "Loaded $name" ); | |
303 | Test::More::ok( ($size < length $content), "Content of $name larger than $size bytes" ); | |
304 | return $content; | |
305 | } | |
306 | ||
307 | 1; |