├── .gitignore ├── .mailmap ├── CONTRIBUTING ├── Changes ├── INSTALL ├── LICENSE ├── README.pod ├── dist.ini ├── lib └── YAML │ └── Tiny.pm ├── t ├── 01_api.t ├── 01_compile.t ├── 10_read.t ├── 11_read_string.t ├── 12_write.t ├── 13_write_string.t ├── 20_subclass.t ├── 21_yamlpm_compat.t ├── 30_yaml_spec_tml.t ├── 31_local_tml.t ├── 32_world_tml.t ├── 86_fail.t ├── README.md ├── data │ ├── ascii.yml │ ├── latin1.yml │ ├── multibyte.yml │ ├── utf_16_le_bom.yml │ └── utf_8_bom.yml ├── lib │ ├── SubtestCompat.pm │ ├── TestBridge.pm │ ├── TestML │ │ └── Tiny.pm │ └── TestUtils.pm ├── tml ├── tml-local │ ├── dump-error │ │ └── circular.tml │ ├── load-error │ │ ├── document.tml │ │ ├── scalar.tml │ │ └── tag.tml │ ├── load-warning │ │ └── document.tml │ ├── perl-to-yaml │ │ └── quoting.tml │ └── yaml-roundtrip │ │ ├── collection.tml │ │ ├── comment.tml │ │ ├── document.tml │ │ ├── mapping.tml │ │ ├── quoting.tml │ │ ├── scalar.tml │ │ └── sequence.tml ├── tml-spec │ ├── basic-data.tml │ ├── multiline.tml │ └── unicode.tml └── tml-world │ ├── Acme-Time-Baby.tml │ ├── Data-Swap.tml │ ├── Games-Nintendo-Wii-Mii.tml │ ├── HTML-WebDAO.tml │ ├── ITS-SIN-FIDS-Content-XML.tml │ ├── Plagger.tml │ ├── Spreadsheet-Read.tml │ ├── Template-Provider-Unicode-Japanese.tml │ ├── Vanilla-Perl.tml │ ├── YAML-Tiny-META.tml │ ├── toolbar.tml │ └── yaml_org.tml └── xt ├── compare └── roundtrip.t └── lib └── ExtraTest.pm /.gitignore: -------------------------------------------------------------------------------- 1 | /.ackrc 2 | /.build/ 3 | !/.gitignore 4 | /.latest 5 | /YAML-Tiny-*/ 6 | /YAML-Tiny-*.tar.gz 7 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | # https://www.kernel.org/pub/software/scm/git/docs/git-shortlog.html#_mapping_authors 2 | Neil Bowers neilbowers 3 | Adam Kennedy adam 4 | Adam Kennedy adamk@cpan.org 5 | Alexandr Ciornii chorny@cpan.org 6 | Olivier Mengué dolmen@cpan.org 7 | Ingy döt Net ingy@cpan.org 8 | Ingy döt Net ingy@ingy.net 9 | James E Keenan jkeenan 10 | James E Keenan Jim Keenan 11 | Neil Bowers neilbowers 12 | יובל קוג'מן (Yuval Kogman) nuffin@cpan.org 13 | Steffen Müller smueller@cpan.org 14 | Karen Etheridge Karen Etheridge 15 | David Golden 16 | -------------------------------------------------------------------------------- /CONTRIBUTING: -------------------------------------------------------------------------------- 1 | 2 | CONTRIBUTING 3 | 4 | Thank you for considering contributing to this distribution. This file 5 | contains instructions that will help you work with the source code. 6 | 7 | PLEASE NOTE that if you have any questions or difficulties, you can reach the 8 | maintainer(s) through the bug queue described later in this document 9 | (preferred), or by emailing the releaser directly. You are not required to 10 | follow any of the steps in this document to submit a patch or bug report; 11 | these are just recommendations, intended to help you (and help us help you 12 | faster). 13 | 14 | The distribution is managed with Dist::Zilla (https://metacpan.org/release/Dist-Zilla). 15 | This means than many of the usual files you might expect are not in the 16 | repository, but are generated at release time (e.g. Makefile.PL). 17 | 18 | However, you can run tests directly using the 'prove' tool: 19 | 20 | $ prove -l 21 | $ prove -lv t/some_test_file.t 22 | $ prove -lvr t/ 23 | 24 | In most cases, 'prove' is entirely sufficient for you to test any patches you 25 | have. 26 | 27 | You may need to satisfy some dependencies. The easiest way to satisfy 28 | dependencies is to install the last release -- this is available at 29 | https://metacpan.org/release/YAML-Tiny 30 | 31 | If you use cpanminus, you can do it without downloading the tarball first: 32 | 33 | $ cpanm --reinstall --installdeps --with-recommends YAML::Tiny 34 | 35 | Dist::Zilla is a very powerful authoring tool, but requires a number of 36 | author-specific plugins. If you would like to use it for contributing, 37 | install it from CPAN, then run one of the following commands, depending on 38 | your CPAN client: 39 | 40 | $ cpan `dzil authordeps --missing` 41 | or 42 | $ dzil authordeps --missing | cpanm 43 | 44 | You should then also install any additional requirements not needed by the 45 | dzil build but may be needed by tests or other development: 46 | 47 | $ cpan `dzil listdeps --author --missing` 48 | or 49 | $ dzil listdeps --author --missing | cpanm 50 | 51 | Or, you can use the 'dzil stale' command to install all requirements at once: 52 | 53 | $ cpan Dist::Zilla::App::Command::stale 54 | $ cpan `dzil stale --all` 55 | or 56 | $ cpanm Dist::Zilla::App::Command::stale 57 | $ dzil stale --all | cpanm 58 | 59 | You can also do this via cpanm directly: 60 | 61 | $ cpanm --reinstall --installdeps --with-develop --with-recommends YAML::Tiny 62 | 63 | Once installed, here are some dzil commands you might try: 64 | 65 | $ dzil build 66 | $ dzil test 67 | $ dzil test --release 68 | $ dzil xtest 69 | $ dzil listdeps --json 70 | $ dzil build --notgz 71 | 72 | You can learn more about Dist::Zilla at http://dzil.org/. 73 | 74 | The code for this distribution is hosted at GitHub. The repository is: 75 | 76 | https://github.com/Perl-Toolchain-Gang/YAML-Tiny 77 | 78 | You can submit code changes by forking the repository, pushing your code 79 | changes to your clone, and then submitting a pull request. Please include a 80 | suitable end-user-oriented entry in the Changes file describing your change. 81 | Detailed instructions for doing that is available here: 82 | 83 | https://help.github.com/articles/creating-a-pull-request 84 | 85 | Generated files such as README, CONTRIBUTING, Makefile.PL, LICENSE etc should 86 | *not* be included in your pull request, as they will be updated automatically 87 | during the next release. 88 | 89 | If you have found a bug, but do not have an accompanying patch to fix it, you 90 | can submit an issue report here: 91 | https://rt.cpan.org/Public/Dist/Display.html?Name=YAML-Tiny 92 | or via email: bug-YAML-Tiny@rt.cpan.org 93 | 94 | There is also an irc channel available for users of this distribution, at 95 | irc://irc.perl.org/#yaml 96 | 97 | If you send me a patch or pull request, your name and email address will be 98 | included in the documentation as a contributor (using the attribution on the 99 | commit or patch), unless you specifically request for it not to be. If you 100 | wish to be listed under a different name or address, you should submit a pull 101 | request to the .mailmap file to contain the correct mapping. 102 | 103 | 104 | This file was generated via Dist::Zilla::Plugin::GenerateFile::FromShareDir 0.015 105 | from a template file originating in Dist-Zilla-PluginBundle-Author-ETHER-0.164. 106 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | Revision history for YAML-Tiny 2 | 3 | {{$NEXT}} 4 | 5 | 1.76 2024-12-16 18:59:46Z 6 | [FIXED] 7 | 8 | - revert change from #60: "yes", "y" etc are not actually booleans. 9 | (see issue #66). 10 | 11 | 1.75 2024-12-15 21:24:54Z 12 | 13 | [FIXED] 14 | 15 | - fixed regression in %QUOTE (Nathan Monfils, PR#60) [later reverted 16 | in release 1.76, see above) 17 | - fix version comparison logic for forward compatibility (BooK, PR#63) 18 | 19 | 1.74 2023-03-23 03:19:08Z 20 | 21 | [FIXED] 22 | 23 | - a few documentation tweaks (thanks, Giovanni Los and Richlv!) 24 | 25 | 1.73 2018-02-21 21:07:59Z 26 | 27 | - shipping 1.72 as stable, with no changes. 28 | 29 | 1.72 2017-02-12 23:17:26Z (TRIAL RELEASE) 30 | 31 | [FIXED] 32 | 33 | - fix compatibility with Test::Builder 0.94 in test shim 34 | 35 | 1.71 2017-02-04 05:44:07Z (TRIAL RELEASE) 36 | 37 | [FIXED] 38 | 39 | - Perform correct stripping of leading white space in literal/folded 40 | text blocks (Flavio Poletti, GitHub #44, fixes RT#56045). 41 | 42 | 1.70 2017-01-22 08:59:54Z 43 | 44 | [FIXED] 45 | 46 | - Some errors writing to a file were incorrectly reported. 47 | 48 | 1.69 2015-07-26 00:51:03Z 49 | - No changes since 1.68-TRIAL. 50 | 51 | 1.68 2015-07-09 23:39:49Z (TRIAL RELEASE) 52 | 53 | [FIXED] 54 | 55 | - tests no longer print to stderr unnecessarily; this makes core perl 56 | builds (where this distribution is included as CPAN-Meta-YAML) a 57 | little quieter. 58 | 59 | [CHANGED] 60 | 61 | - the Test::More dependency has been reduced to 0.88 by emulating 62 | 'subtest' for those tests that need it 63 | 64 | 1.67 2015-05-12 00:10:24Z 65 | 66 | [FIXED] 67 | 68 | - instead of erroring on duplicate keys found in a hash (introduced in 69 | version 1.63), now we only warn. This fixes an issue in Strawberry Perl 70 | (via CPAN::Meta::YAML) when parsing a configuration file. 71 | 72 | [CHANGED] 73 | 74 | - Updated File::Temp test prereq to 0.19 for 'newdir' 75 | 76 | 1.66 2015-03-16 22:26:30Z 77 | 78 | [CHANGED] 79 | 80 | - removed bundled Test::TempDir::Tiny to rely on File::Temp 81 | for temporary directories during testing 82 | 83 | 1.65 2015-03-13 23:02:34Z 84 | 85 | [CHANGED] 86 | 87 | - artifacts left behind from testing are now cleaned up (GH#34) 88 | 89 | 1.64 2014-10-08 02:56:30Z 90 | 91 | [CHANGED] 92 | 93 | - remove silencing of any errors encountered while loading 94 | Scalar::Util (GH#33, Graham Knop) 95 | - now using JSON::MaybeXS in tests instead of JSON.pm 96 | 97 | 1.63 2014-06-11 21:58:18Z 98 | 99 | [FIXED] 100 | 101 | - incorrect error messages fixed, when $@ is clobbered when Carp 102 | wasn't loaded (GH#30, GH#31, Hilko Bengen) 103 | 104 | [CHANGED] 105 | 106 | - now checking for, and erroring on, duplicate keys found in a hash 107 | (GH#32, Hilko Bengen) 108 | 109 | 1.62 2014-03-16 12:28:44Z 110 | 111 | [FIXED] 112 | 113 | - fix handling of trailing colon in key name (RT#92916, H.Merijn 114 | Brand) 115 | 116 | 1.61 2014-02-24 16:59:49Z 117 | 118 | [FIXED] 119 | 120 | - fixed a test for VMS (RT#93297, Craig Berry) 121 | 122 | 1.60 2014-02-13 20:31:56Z 123 | 124 | - shipping 1.59 as stable, with no changes. 125 | 126 | 1.59 2014-02-06 03:10:35Z (TRIAL RELEASE) 127 | 128 | [CHANGED] 129 | 130 | - numeric values are now quoted whenever they've been used as a string 131 | (fixes inconsistent behaviour seen with numeric values, due to 132 | differences between the XS and pure-perl variants of Data::Dumper). 133 | (github issue #24) 134 | - numeric hash keys are now always quoted. 135 | 136 | 1.58 2014-02-04 18:01:58Z 137 | 138 | [INCOMPATIBLE CHANGE] 139 | 140 | - 1.57 omitted a change entry for the following change: 141 | 142 | - Previously, YAML::Tiny was sloppy about file encodings. It is 143 | now strict. The 'read' method and 'LoadFile' function expect 144 | UTF-8 encoded files. The 'write' method and 'DumpFile' function 145 | produce UTF-8 encoded files. The 'read_string' and 146 | 'write_string' methods and the 'Load' and 'Dump' functions 147 | expect or generate (decoded) character data. 148 | 149 | 1.57 2014-01-30 22:12:38Z 150 | 151 | [INCOMPATIBLE CHANGE] 152 | 153 | - Previously, some errors would throw exceptions and some would 154 | return the error condition in $YAML::Tiny::errstr. Now all 155 | errors throw exceptions. Use of $errstr and the errstr method 156 | are deprecated. (David Golden) 157 | 158 | [FIXED] 159 | 160 | - Fixed write method to encode YAML file with UTF-8 (David Golden) 161 | - Improved SYNOPSIS and documentation of new (David Golden) 162 | 163 | [TESTING] 164 | 165 | - Tests have been cleaned up and reorganized. Test coverage 166 | has been significnatly improved. (Ingy döt Net, David Golden, 167 | Jim Keenan, Karen Etheridge) 168 | 169 | 1.56 2013-09-25 02:38:19Z 170 | - read_string documentation error fixed (RT#74409, thanks Tim Heaney!) 171 | - re-release with fixed compile test 172 | 173 | 1.55 2013-09-19 04:07:32Z 174 | - again packaging with ExtUtils::MakeMaker 175 | 176 | 1.54 2013-08-22 03:55:41Z 177 | - convert to Dist::Zilla 178 | - Updated format to conform to CPAN::Changes::Spec 179 | 180 | 1.53 2013-08-20 181 | - really fixed metadata 182 | 183 | 1.52 2013-08-20 184 | - updated repository metadata to reflect move to github 185 | 186 | 1.51 2012-03-11 187 | - The fix described in 1.48 was incorrect. Removing an additional 188 | if $@ to fix it properly. 189 | - Make the Scalar::Util version check resistant to bugs caused by 190 | development versions. 191 | 192 | 1.50 2011-06-23 193 | - Major bug fix, all code that writes arbitrary data should upgrade. 194 | - Simple scalars with no whitespace but ending in a colon like ABC: were 195 | not being quoted, which results in the parser confusing it with a 196 | mapping key and crashing. 197 | 198 | 1.49 2011-03-08 199 | - No functional changes. 200 | - Don't depend on the YAML modules in RELEASE_TESTING, as it can 201 | pollute the advisory META.yml. 202 | 203 | 1.48 2011-02-01 204 | - Fix to the refaddr compatibility where Scalar::Util is installed 205 | but is older than 1.18. 206 | 207 | 1.47 2011-01-31 208 | - No functional changes 209 | - Only depend on the YAML implementations when we are release testing 210 | 211 | 1.46 2010-12-16 212 | - No functional changes 213 | - Moving to a production release now CPAN Testers is green again 214 | 215 | 1.45_02 2010-12-07 216 | - Adding experimental support for exception->errstr conversion 217 | - Updating test suite yaml_error to not expect exceptions 218 | 219 | 1.45_01 2010-12-07 220 | - Added support for trailing line comments (INGY) 221 | - Added checks for some characters that are illegal or reserved 222 | in plain scalars (INGY) 223 | - Minor cleaning up of some out of date POD (ADAMK) 224 | - Updated AUTOMATED_TESTING dependencies to new versions (ADAMK) 225 | 226 | 1.44 2010-08-08 227 | - No functional changes, upgrading is not required 228 | - Minor tweaks to Makefile.PL 229 | - Minor cleanup around the refaddr emulation code 230 | 231 | 1.43 2010-07-10 232 | - No functional changes, upgrading is not required 233 | - Don't import Carp 'croak' any more, saving a few K 234 | 235 | 1.42 2010-06-25 236 | - No functional changes, upgrading is not required 237 | - Clarified documation to explain that YAML::Tiny escapes "bool" 238 | keywords when it writes them as strings so that YAML parsers in 239 | other languages won't get confused, but this does not mean that 240 | YAML::Tiny actually supports boolean types itself. 241 | - Added an extra test case for boolean keyword escaping. 242 | - YAML::Perl comparison tests were loading the file back in with 243 | YAML.pm by mistake. Corrected this and added an additional case 244 | that YAML::Perl doesn't support that I wasn't catching. 245 | - Author tests updated and moved into xt/ 246 | - Updated the versions of the other YAML parsers we test ourselves 247 | against to the most recent versions of each. 248 | 249 | 1.41 2009-12-11 250 | - Fixes a performance bug reported by Apocalypse. 251 | Single line double-quoted strings longer than 32,000ish characters 252 | resulted in the regular expression engine crashing due to 253 | excessive recursion. Changed to a different regex that will most 254 | likely only crash after 32,000 ESCAPED characters. If I could use 255 | negative look-behind assertions (I can't because I need 5.004) 256 | this whole issue would be MUCH simpler to fix. 257 | 258 | 1.40 2009-07-31 259 | - Dear Ruby Community. 260 | Thank you so much for your bug report to the "Ruby Talk" mailing list 261 | regarding the lack of true/false support in Perl YAML modules. 262 | http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/169943 263 | This flaw has now been resolved, around 2 hours after we 264 | were made aware of it. Next time, we recommend you report these bugs 265 | to the people who can actually fix your problem. 266 | 267 | 1.39 2009-05-21 268 | - Even though utf8 starts at 5.7+ there's no is_utf till 269 | 5.8.1 so skip in the tests if needed (ADAMK) 270 | 271 | 1.38 2009-05-16 272 | - Moving the test suite style closer to Parse::CPAN::Meta 273 | - Changed exceptions closer to Parse::CPAN::Meta 274 | - Fixed Changes file date for 1.37 :) 275 | 276 | 1.37 2009-05-16 277 | - Call $self->_error instead of $class->_error when we can 278 | - Refactoring away some of the code other people have been 279 | contributing lately that most certainly NOT ::Tiny style. 280 | - Avoid the need to do '' escaping by moving it to "'" 281 | - Added comparative testing with YAML::Perl 282 | 283 | 1.36 2009-01-07 284 | - Fixing missing feature reported by H.Merijn Brand 285 | 286 | 1.35 2008-12-17 287 | - Production release for changes in 1.34_01 288 | - No other changes 289 | 290 | 1.34_01 2008-11-19 291 | - Improving sub-classability by passing the indent level through 292 | to the ->_write_scalar method. 293 | 294 | 1.33 2008-07-24 295 | - Export Load and Dump functions by default. 296 | 297 | 1.32 2008-05-14 298 | - Adding a test to check for correct exceptions 299 | - ONLY do comparative tests when the modules to compare to are current. 300 | (Prevents false failures in some cases) 301 | 302 | 1.31 2008-05-08 303 | - Emergency bugfix release 304 | 305 | 1.30 2008-05-04 306 | - Better error reporting of unsupported features 307 | - Heavily bump automated testing deps to remove false errors 308 | 309 | 1.29 2008-04-12 310 | - CPAN Testers passes ok, moving to production version 311 | 312 | 1.28_01 2008-04-05 313 | - Adding support for document terminators 314 | (To support YAML embedded in TAP streams) 315 | 316 | 1.27 2008-03-31 317 | - Skip 04_scalar.t if no YAML.pm 318 | - Implement YAML compatibility + tests for LoadFile 319 | - Remove the LICENSE key from Makefile.PL 320 | (Which failed on some CPAN Testers setups) 321 | 322 | 1.26 2008-03-20 323 | - Added extra test cases to validate RT bugs that were fixed 324 | previous, but not closed at the time. 325 | - Always quote when serialising anything that starts with a non-word 326 | - YAML::Tiny::Load is now fully compatible with YAML.pm in scalar 327 | context (returns the LAST parsed document). 328 | 329 | 1.25 2008-01-14 330 | - Wrote the specification section 331 | 332 | 1.24_01 2008-01-11 333 | - Adding additional test cases 334 | - Adding support for YAML header for META.yml 335 | - Adding support for YAML header for YAML 1.0 336 | - Adding support for YAML header for YAML 1.1 337 | 338 | 1.23 2008-01-10 339 | - Identical to 1.22_01 340 | - CPAN Testers results positive, pushing to production version 341 | 342 | 1.22_01 2008-01-09 343 | - Correcting handling of single quote escaping 344 | - Adding protection for infinite loops caused by circular 345 | references during serializing. 346 | - Confirmed support for toolbar.yml sample 347 | 348 | 1.21 2007-12-06 349 | - Fixing support for unprintable characters 350 | 351 | 1.20 2007-11-19 352 | - Correcting class name in @EXPORT_OK declaration 353 | (Demetrios Biskinis) 354 | 355 | 1.19 2007-11-16 356 | - Removing the invalid perl dep 357 | 358 | 1.18 2007-11-05 359 | - Adding a new test file 360 | 361 | 1.17 2007-11-01 362 | - Updating from Module::Install to the tinier ExtUtils::MakeMaker 363 | 364 | 1.16 2007-10-22 365 | - Updating to newer AUTOMATED_TESTING tests 366 | 367 | 1.15 2007-08-25 368 | - Incremental release to include an updated version of 99_author.t 369 | - Replace a few CODE INCOMPLETE errors with real errors 370 | (those parts of the module are now complete) 371 | 372 | 1.14 2007-08-16 373 | - Adding support for empty reference documents 374 | 375 | 1.13 2007-07-09 376 | - Adding a test case for support of multi-byte characters 377 | 378 | 1.12 2007-06-05 379 | - Adding support for open hash/array at EOF 380 | 381 | 1.11 2007-06-05 382 | - Forgot to string trailing whitespace in a few cases 383 | - 'hashkey: This was mistaken as a hash entry, not a string' 384 | - Adding explicit tests from #yaml for single quote escaping 385 | 386 | 1.10 2007-06-05 387 | - Adding support for null hash/arrays 388 | 389 | 1.09 2007-05-21 390 | - Fixing a bug in the trivial scalar case 391 | 392 | 1.08 2007-05-16 393 | - Adding support for |- trimming multiline scalars 394 | 395 | 1.07 2007-05-15 396 | - Adding support for whitespace after document headers 397 | 398 | 1.06 2007-05-14 399 | - Bug fix to support an additional variant of null hashes 400 | 401 | 1.05 2007-05-02 402 | - Bug fix to allow support for keys with spaces 403 | - Bug fix to allow empty comments 404 | 405 | 1.04 2007-02-21 406 | - Adding support for LoadFile, DumpFile, freeze and thaw 407 | 408 | 1.03 2007-01-14 409 | - Removing the forward-looking part of the preamble 410 | 411 | 1.02 2007-01-14 412 | - Fixing exporting 413 | 414 | 1.01 2007-01-14 415 | - Removed the ugly bold warning 416 | 417 | 1.00 2007-01-14 418 | - What the hell, I'm as close as is needed I think 419 | 420 | 0.90 2007-01-13 421 | - Adding support for inline multi-lines 422 | 423 | 0.11 2006-09-25 424 | - Fixed bug in regex that detects unheadered ARRAY|HASH 425 | 426 | 0.10 2006-08-24 427 | - Added double-quote support, making YAML::Tiny a lot more usable 428 | - Added Load and Dump for YAML.pm compatibility 429 | - Added tests for verifying compatibility with YAML::Syck 430 | 431 | 0.06 2006-07-09 432 | - Added more tests 433 | 434 | 0.05 2006-07-08 435 | - Added support for nested inline hashes (parse only) 436 | - Added support for naked undef array and hash entries 437 | - Can now handle sample Plagger configs from Miyagawa-san's talk 438 | - Can now handle vanilla.yml from Perl::Dist::Vanilla 439 | 440 | 0.04 2006-07-08 441 | - Added support for implicit document start for array/hash types 442 | - Added support for colons in hash keys 443 | - Added support for simple single quotes 444 | - Can now handle our own META.yml file 445 | 446 | 0.03 2006-07-08 447 | - Got all of the trivial test cases to pass 448 | - Good enough for an initial usable release, 449 | but still expected to fail a lot 450 | 451 | 0.02 2006-04-26 452 | - Added support for a single root-level hash 453 | - Correcting POD bugs 454 | 455 | 0.01 2006-04-26 456 | - Initial version 457 | - Handles only document headers and non-wrapping scalar documents 458 | 459 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | This is the Perl distribution YAML-Tiny. 2 | 3 | Installing YAML-Tiny is straightforward. 4 | 5 | ## Installation with cpanm 6 | 7 | If you have cpanm, you only need one line: 8 | 9 | % cpanm YAML::Tiny 10 | 11 | If it does not have permission to install modules to the current perl, cpanm 12 | will automatically set up and install to a local::lib in your home directory. 13 | See the local::lib documentation (https://metacpan.org/pod/local::lib) for 14 | details on enabling it in your environment. 15 | 16 | ## Installing with the CPAN shell 17 | 18 | Alternatively, if your CPAN shell is set up, you should just be able to do: 19 | 20 | % cpan YAML::Tiny 21 | 22 | ## Manual installation 23 | 24 | As a last resort, you can manually install it. If you have not already 25 | downloaded the release tarball, you can find the download link on the module's 26 | MetaCPAN page: https://metacpan.org/pod/YAML::Tiny 27 | 28 | Untar the tarball, install configure prerequisites (see below), then build it: 29 | 30 | % perl Makefile.PL 31 | % make && make test 32 | 33 | Then install it: 34 | 35 | % make install 36 | 37 | On Windows platforms, you should use `dmake` or `nmake`, instead of `make`. 38 | 39 | If your perl is system-managed, you can create a local::lib in your home 40 | directory to install modules to. For details, see the local::lib documentation: 41 | https://metacpan.org/pod/local::lib 42 | 43 | The prerequisites of this distribution will also have to be installed manually. The 44 | prerequisites are listed in one of the files: `MYMETA.yml` or `MYMETA.json` generated 45 | by running the manual build process described above. 46 | 47 | ## Configure Prerequisites 48 | 49 | This distribution requires other modules to be installed before this 50 | distribution's installer can be run. They can be found under the 51 | "configure_requires" key of META.yml or the 52 | "{prereqs}{configure}{requires}" key of META.json. 53 | 54 | ## Other Prerequisites 55 | 56 | This distribution may require additional modules to be installed after running 57 | Makefile.PL. 58 | Look for prerequisites in the following phases: 59 | 60 | * to run make, PHASE = build 61 | * to use the module code itself, PHASE = runtime 62 | * to run tests, PHASE = test 63 | 64 | They can all be found in the "PHASE_requires" key of MYMETA.yml or the 65 | "{prereqs}{PHASE}{requires}" key of MYMETA.json. 66 | 67 | ## Documentation 68 | 69 | YAML-Tiny documentation is available as POD. 70 | You can run `perldoc` from a shell to read the documentation: 71 | 72 | % perldoc YAML::Tiny 73 | 74 | For more information on installing Perl modules via CPAN, please see: 75 | https://www.cpan.org/modules/INSTALL.html 76 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This software is copyright (c) 2006 by Adam Kennedy. 2 | 3 | This is free software; you can redistribute it and/or modify it under 4 | the same terms as the Perl 5 programming language system itself. 5 | 6 | Terms of the Perl programming language system itself 7 | 8 | a) the GNU General Public License as published by the Free 9 | Software Foundation; either version 1, or (at your option) any 10 | later version, or 11 | b) the "Artistic License" 12 | 13 | --- The GNU General Public License, Version 1, February 1989 --- 14 | 15 | This software is Copyright (c) 2006 by Adam Kennedy. 16 | 17 | This is free software, licensed under: 18 | 19 | The GNU General Public License, Version 1, February 1989 20 | 21 | GNU GENERAL PUBLIC LICENSE 22 | Version 1, February 1989 23 | 24 | Copyright (C) 1989 Free Software Foundation, Inc. 25 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26 | 27 | Everyone is permitted to copy and distribute verbatim copies 28 | of this license document, but changing it is not allowed. 29 | 30 | Preamble 31 | 32 | The license agreements of most software companies try to keep users 33 | at the mercy of those companies. By contrast, our General Public 34 | License is intended to guarantee your freedom to share and change free 35 | software--to make sure the software is free for all its users. The 36 | General Public License applies to the Free Software Foundation's 37 | software and to any other program whose authors commit to using it. 38 | You can use it for your programs, too. 39 | 40 | When we speak of free software, we are referring to freedom, not 41 | price. Specifically, the General Public License is designed to make 42 | sure that you have the freedom to give away or sell copies of free 43 | software, that you receive source code or can get it if you want it, 44 | that you can change the software or use pieces of it in new free 45 | programs; and that you know you can do these things. 46 | 47 | To protect your rights, we need to make restrictions that forbid 48 | anyone to deny you these rights or to ask you to surrender the rights. 49 | These restrictions translate to certain responsibilities for you if you 50 | distribute copies of the software, or if you modify it. 51 | 52 | For example, if you distribute copies of a such a program, whether 53 | gratis or for a fee, you must give the recipients all the rights that 54 | you have. You must make sure that they, too, receive or can get the 55 | source code. And you must tell them their rights. 56 | 57 | We protect your rights with two steps: (1) copyright the software, and 58 | (2) offer you this license which gives you legal permission to copy, 59 | distribute and/or modify the software. 60 | 61 | Also, for each author's protection and ours, we want to make certain 62 | that everyone understands that there is no warranty for this free 63 | software. If the software is modified by someone else and passed on, we 64 | want its recipients to know that what they have is not the original, so 65 | that any problems introduced by others will not reflect on the original 66 | authors' reputations. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | GNU GENERAL PUBLIC LICENSE 72 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 73 | 74 | 0. This License Agreement applies to any program or other work which 75 | contains a notice placed by the copyright holder saying it may be 76 | distributed under the terms of this General Public License. The 77 | "Program", below, refers to any such program or work, and a "work based 78 | on the Program" means either the Program or any work containing the 79 | Program or a portion of it, either verbatim or with modifications. Each 80 | licensee is addressed as "you". 81 | 82 | 1. You may copy and distribute verbatim copies of the Program's source 83 | code as you receive it, in any medium, provided that you conspicuously and 84 | appropriately publish on each copy an appropriate copyright notice and 85 | disclaimer of warranty; keep intact all the notices that refer to this 86 | General Public License and to the absence of any warranty; and give any 87 | other recipients of the Program a copy of this General Public License 88 | along with the Program. You may charge a fee for the physical act of 89 | transferring a copy. 90 | 91 | 2. You may modify your copy or copies of the Program or any portion of 92 | it, and copy and distribute such modifications under the terms of Paragraph 93 | 1 above, provided that you also do the following: 94 | 95 | a) cause the modified files to carry prominent notices stating that 96 | you changed the files and the date of any change; and 97 | 98 | b) cause the whole of any work that you distribute or publish, that 99 | in whole or in part contains the Program or any part thereof, either 100 | with or without modifications, to be licensed at no charge to all 101 | third parties under the terms of this General Public License (except 102 | that you may choose to grant warranty protection to some or all 103 | third parties, at your option). 104 | 105 | c) If the modified program normally reads commands interactively when 106 | run, you must cause it, when started running for such interactive use 107 | in the simplest and most usual way, to print or display an 108 | announcement including an appropriate copyright notice and a notice 109 | that there is no warranty (or else, saying that you provide a 110 | warranty) and that users may redistribute the program under these 111 | conditions, and telling the user how to view a copy of this General 112 | Public License. 113 | 114 | d) You may charge a fee for the physical act of transferring a 115 | copy, and you may at your option offer warranty protection in 116 | exchange for a fee. 117 | 118 | Mere aggregation of another independent work with the Program (or its 119 | derivative) on a volume of a storage or distribution medium does not bring 120 | the other work under the scope of these terms. 121 | 122 | 3. You may copy and distribute the Program (or a portion or derivative of 123 | it, under Paragraph 2) in object code or executable form under the terms of 124 | Paragraphs 1 and 2 above provided that you also do one of the following: 125 | 126 | a) accompany it with the complete corresponding machine-readable 127 | source code, which must be distributed under the terms of 128 | Paragraphs 1 and 2 above; or, 129 | 130 | b) accompany it with a written offer, valid for at least three 131 | years, to give any third party free (except for a nominal charge 132 | for the cost of distribution) a complete machine-readable copy of the 133 | corresponding source code, to be distributed under the terms of 134 | Paragraphs 1 and 2 above; or, 135 | 136 | c) accompany it with the information you received as to where the 137 | corresponding source code may be obtained. (This alternative is 138 | allowed only for noncommercial distribution and only if you 139 | received the program in object code or executable form alone.) 140 | 141 | Source code for a work means the preferred form of the work for making 142 | modifications to it. For an executable file, complete source code means 143 | all the source code for all modules it contains; but, as a special 144 | exception, it need not include source code for modules which are standard 145 | libraries that accompany the operating system on which the executable 146 | file runs, or for standard header files or definitions files that 147 | accompany that operating system. 148 | 149 | 4. You may not copy, modify, sublicense, distribute or transfer the 150 | Program except as expressly provided under this General Public License. 151 | Any attempt otherwise to copy, modify, sublicense, distribute or transfer 152 | the Program is void, and will automatically terminate your rights to use 153 | the Program under this License. However, parties who have received 154 | copies, or rights to use copies, from you under this General Public 155 | License will not have their licenses terminated so long as such parties 156 | remain in full compliance. 157 | 158 | 5. By copying, distributing or modifying the Program (or any work based 159 | on the Program) you indicate your acceptance of this license to do so, 160 | and all its terms and conditions. 161 | 162 | 6. Each time you redistribute the Program (or any work based on the 163 | Program), the recipient automatically receives a license from the original 164 | licensor to copy, distribute or modify the Program subject to these 165 | terms and conditions. You may not impose any further restrictions on the 166 | recipients' exercise of the rights granted herein. 167 | 168 | 7. The Free Software Foundation may publish revised and/or new versions 169 | of the General Public License from time to time. Such new versions will 170 | be similar in spirit to the present version, but may differ in detail to 171 | address new problems or concerns. 172 | 173 | Each version is given a distinguishing version number. If the Program 174 | specifies a version number of the license which applies to it and "any 175 | later version", you have the option of following the terms and conditions 176 | either of that version or of any later version published by the Free 177 | Software Foundation. If the Program does not specify a version number of 178 | the license, you may choose any version ever published by the Free Software 179 | Foundation. 180 | 181 | 8. If you wish to incorporate parts of the Program into other free 182 | programs whose distribution conditions are different, write to the author 183 | to ask for permission. For software which is copyrighted by the Free 184 | Software Foundation, write to the Free Software Foundation; we sometimes 185 | make exceptions for this. Our decision will be guided by the two goals 186 | of preserving the free status of all derivatives of our free software and 187 | of promoting the sharing and reuse of software generally. 188 | 189 | NO WARRANTY 190 | 191 | 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 192 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 193 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 194 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 195 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 196 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 197 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 198 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 199 | REPAIR OR CORRECTION. 200 | 201 | 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 202 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 203 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 204 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 205 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 206 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 207 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 208 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 209 | POSSIBILITY OF SUCH DAMAGES. 210 | 211 | END OF TERMS AND CONDITIONS 212 | 213 | Appendix: How to Apply These Terms to Your New Programs 214 | 215 | If you develop a new program, and you want it to be of the greatest 216 | possible use to humanity, the best way to achieve this is to make it 217 | free software which everyone can redistribute and change under these 218 | terms. 219 | 220 | To do so, attach the following notices to the program. It is safest to 221 | attach them to the start of each source file to most effectively convey 222 | the exclusion of warranty; and each file should have at least the 223 | "copyright" line and a pointer to where the full notice is found. 224 | 225 | 226 | Copyright (C) 19yy 227 | 228 | This program is free software; you can redistribute it and/or modify 229 | it under the terms of the GNU General Public License as published by 230 | the Free Software Foundation; either version 1, or (at your option) 231 | any later version. 232 | 233 | This program is distributed in the hope that it will be useful, 234 | but WITHOUT ANY WARRANTY; without even the implied warranty of 235 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 236 | GNU General Public License for more details. 237 | 238 | You should have received a copy of the GNU General Public License 239 | along with this program; if not, write to the Free Software 240 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA 241 | 242 | 243 | Also add information on how to contact you by electronic and paper mail. 244 | 245 | If the program is interactive, make it output a short notice like this 246 | when it starts in an interactive mode: 247 | 248 | Gnomovision version 69, Copyright (C) 19xx name of author 249 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 250 | This is free software, and you are welcome to redistribute it 251 | under certain conditions; type `show c' for details. 252 | 253 | The hypothetical commands `show w' and `show c' should show the 254 | appropriate parts of the General Public License. Of course, the 255 | commands you use may be called something other than `show w' and `show 256 | c'; they could even be mouse-clicks or menu items--whatever suits your 257 | program. 258 | 259 | You should also get your employer (if you work as a programmer) or your 260 | school, if any, to sign a "copyright disclaimer" for the program, if 261 | necessary. Here a sample; alter the names: 262 | 263 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 264 | program `Gnomovision' (a program to direct compilers to make passes 265 | at assemblers) written by James Hacker. 266 | 267 | , 1 April 1989 268 | Ty Coon, President of Vice 269 | 270 | That's all there is to it! 271 | 272 | 273 | --- The Perl Artistic License 1.0 --- 274 | 275 | This software is Copyright (c) 2006 by Adam Kennedy. 276 | 277 | This is free software, licensed under: 278 | 279 | The Perl Artistic License 1.0 280 | 281 | 282 | 283 | 284 | 285 | The "Artistic License" 286 | 287 | Preamble 288 | 289 | The intent of this document is to state the conditions under which a 290 | Package may be copied, such that the Copyright Holder maintains some 291 | semblance of artistic control over the development of the package, 292 | while giving the users of the package the right to use and distribute 293 | the Package in a more-or-less customary fashion, plus the right to make 294 | reasonable modifications. 295 | 296 | Definitions: 297 | 298 | "Package" refers to the collection of files distributed by the 299 | Copyright Holder, and derivatives of that collection of files 300 | created through textual modification. 301 | 302 | "Standard Version" refers to such a Package if it has not been 303 | modified, or has been modified in accordance with the wishes 304 | of the Copyright Holder as specified below. 305 | 306 | "Copyright Holder" is whoever is named in the copyright or 307 | copyrights for the package. 308 | 309 | "You" is you, if you're thinking about copying or distributing 310 | this Package. 311 | 312 | "Reasonable copying fee" is whatever you can justify on the 313 | basis of media cost, duplication charges, time of people involved, 314 | and so on. (You will not be required to justify it to the 315 | Copyright Holder, but only to the computing community at large 316 | as a market that must bear the fee.) 317 | 318 | "Freely Available" means that no fee is charged for the item 319 | itself, though there may be fees involved in handling the item. 320 | It also means that recipients of the item may redistribute it 321 | under the same conditions they received it. 322 | 323 | 1. You may make and give away verbatim copies of the source form of the 324 | Standard Version of this Package without restriction, provided that you 325 | duplicate all of the original copyright notices and associated disclaimers. 326 | 327 | 2. You may apply bug fixes, portability fixes and other modifications 328 | derived from the Public Domain or from the Copyright Holder. A Package 329 | modified in such a way shall still be considered the Standard Version. 330 | 331 | 3. You may otherwise modify your copy of this Package in any way, provided 332 | that you insert a prominent notice in each changed file stating how and 333 | when you changed that file, and provided that you do at least ONE of the 334 | following: 335 | 336 | a) place your modifications in the Public Domain or otherwise make them 337 | Freely Available, such as by posting said modifications to Usenet or 338 | an equivalent medium, or placing the modifications on a major archive 339 | site such as uunet.uu.net, or by allowing the Copyright Holder to include 340 | your modifications in the Standard Version of the Package. 341 | 342 | b) use the modified Package only within your corporation or organization. 343 | 344 | c) rename any non-standard executables so the names do not conflict 345 | with standard executables, which must also be provided, and provide 346 | a separate manual page for each non-standard executable that clearly 347 | documents how it differs from the Standard Version. 348 | 349 | d) make other distribution arrangements with the Copyright Holder. 350 | 351 | 4. You may distribute the programs of this Package in object code or 352 | executable form, provided that you do at least ONE of the following: 353 | 354 | a) distribute a Standard Version of the executables and library files, 355 | together with instructions (in the manual page or equivalent) on where 356 | to get the Standard Version. 357 | 358 | b) accompany the distribution with the machine-readable source of 359 | the Package with your modifications. 360 | 361 | c) give non-standard executables non-standard names, and clearly 362 | document the differences in manual pages (or equivalent), together 363 | with instructions on where to get the Standard Version. 364 | 365 | d) make other distribution arrangements with the Copyright Holder. 366 | 367 | 5. You may charge a reasonable copying fee for any distribution of this 368 | Package. You may charge any fee you choose for support of this 369 | Package. You may not charge a fee for this Package itself. However, 370 | you may distribute this Package in aggregate with other (possibly 371 | commercial) programs as part of a larger (possibly commercial) software 372 | distribution provided that you do not advertise this Package as a 373 | product of your own. You may embed this Package's interpreter within 374 | an executable of yours (by linking); this shall be construed as a mere 375 | form of aggregation, provided that the complete Standard Version of the 376 | interpreter is so embedded. 377 | 378 | 6. The scripts and library files supplied as input to or produced as 379 | output from the programs of this Package do not automatically fall 380 | under the copyright of this Package, but belong to whoever generated 381 | them, and may be sold commercially, and may be aggregated with this 382 | Package. If such scripts or library files are aggregated with this 383 | Package via the so-called "undump" or "unexec" methods of producing a 384 | binary executable image, then distribution of such an image shall 385 | neither be construed as a distribution of this Package nor shall it 386 | fall under the restrictions of Paragraphs 3 and 4, provided that you do 387 | not represent such an executable image as a Standard Version of this 388 | Package. 389 | 390 | 7. C subroutines (or comparably compiled subroutines in other 391 | languages) supplied by you and linked into this Package in order to 392 | emulate subroutines and variables of the language defined by this 393 | Package shall not be considered part of this Package, but are the 394 | equivalent of input as in Paragraph 6, provided these subroutines do 395 | not change the language in any way that would cause it to fail the 396 | regression tests for the language. 397 | 398 | 8. Aggregation of this Package with a commercial distribution is always 399 | permitted provided that the use of this Package is embedded; that is, 400 | when no overt attempt is made to make this Package's interfaces visible 401 | to the end user of the commercial distribution. Such use shall not be 402 | construed as a distribution of this Package. 403 | 404 | 9. The name of the Copyright Holder may not be used to endorse or promote 405 | products derived from this software without specific prior written permission. 406 | 407 | 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR 408 | IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 409 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 410 | 411 | The End 412 | 413 | -------------------------------------------------------------------------------- /README.pod: -------------------------------------------------------------------------------- 1 | =pod 2 | 3 | =head1 NAME 4 | 5 | YAML::Tiny - Read/Write YAML files with as little code as possible 6 | 7 | =head1 VERSION 8 | 9 | version 1.76 10 | 11 | =head1 PREAMBLE 12 | 13 | The YAML specification is huge. Really, B huge. It contains all the 14 | functionality of XML, except with flexibility and choice, which makes it 15 | easier to read, but with a formal specification that is more complex than 16 | XML. 17 | 18 | The original pure-Perl implementation L costs just over 4 megabytes 19 | of memory to load. Just like with Windows F<.ini> files (3 meg to load) and 20 | CSS (3.5 meg to load) the situation is just asking for a B 21 | module, an incomplete but correct and usable subset of the functionality, 22 | in as little code as possible. 23 | 24 | Like the other C<::Tiny> modules, YAML::Tiny has no non-core dependencies, 25 | does not require a compiler to install, is back-compatible to Perl v5.8.1, 26 | and can be inlined into other modules if needed. 27 | 28 | In exchange for adding this extreme flexibility, it provides support 29 | for only a limited subset of YAML. But the subset supported contains most 30 | of the features for the more common uses of YAML. 31 | 32 | =head1 SYNOPSIS 33 | 34 | Assuming F like this: 35 | 36 | --- 37 | rootproperty: blah 38 | section: 39 | one: two 40 | three: four 41 | Foo: Bar 42 | empty: ~ 43 | 44 | 45 | Read and write F like this: 46 | 47 | use YAML::Tiny; 48 | 49 | # Open the config 50 | my $yaml = YAML::Tiny->read( 'file.yml' ); 51 | 52 | # Get a reference to the first document 53 | my $config = $yaml->[0]; 54 | 55 | # Or read properties directly 56 | my $root = $yaml->[0]->{rootproperty}; 57 | my $one = $yaml->[0]->{section}->{one}; 58 | my $Foo = $yaml->[0]->{section}->{Foo}; 59 | 60 | # Change data directly 61 | $yaml->[0]->{newsection} = { this => 'that' }; # Add a section 62 | $yaml->[0]->{section}->{Foo} = 'Not Bar!'; # Change a value 63 | delete $yaml->[0]->{section}; # Delete a value 64 | 65 | # Save the document back to the file 66 | $yaml->write( 'file.yml' ); 67 | 68 | To create a new YAML file from scratch: 69 | 70 | # Create a new object with a single hashref document 71 | my $yaml = YAML::Tiny->new( { wibble => "wobble" } ); 72 | 73 | # Add an arrayref document 74 | push @$yaml, [ 'foo', 'bar', 'baz' ]; 75 | 76 | # Save both documents to a file 77 | $yaml->write( 'data.yml' ); 78 | 79 | Then F will contain: 80 | 81 | --- 82 | wibble: wobble 83 | --- 84 | - foo 85 | - bar 86 | - baz 87 | 88 | =head1 DESCRIPTION 89 | 90 | B is a perl class for reading and writing YAML-style files, 91 | written with as little code as possible, reducing load time and memory 92 | overhead. 93 | 94 | Most of the time it is accepted that Perl applications use a lot 95 | of memory and modules. The B<::Tiny> family of modules is specifically 96 | intended to provide an ultralight and zero-dependency alternative to 97 | many more-thorough standard modules. 98 | 99 | This module is primarily for reading human-written files (like simple 100 | config files) and generating very simple human-readable files. Note that 101 | I said B and not B. The sort of files that 102 | your average manager or secretary should be able to look at and make 103 | sense of. 104 | 105 | =for stopwords normalise 106 | 107 | L does not generate comments, it won't necessarily preserve the 108 | order of your hashes, and it will normalise if reading in and writing out 109 | again. 110 | 111 | It only supports a very basic subset of the full YAML specification. 112 | 113 | =for stopwords embeddable 114 | 115 | Usage is targeted at files like Perl's META.yml, for which a small and 116 | easily-embeddable module is extremely attractive. 117 | 118 | Features will only be added if they are human readable, and can be written 119 | in a few lines of code. Please don't be offended if your request is 120 | refused. Someone has to draw the line, and for YAML::Tiny that someone 121 | is me. 122 | 123 | If you need something with more power move up to L (7 megabytes of 124 | memory overhead) or L (6 megabytes memory overhead and requires 125 | a C compiler). 126 | 127 | To restate, L does B preserve your comments, whitespace, 128 | or the order of your YAML data. But it should round-trip from Perl 129 | structure to file and back again just fine. 130 | 131 | =head1 METHODS 132 | 133 | =for Pod::Coverage HAVE_UTF8 refaddr 134 | 135 | =head2 new 136 | 137 | The constructor C creates a C object as a blessed array 138 | reference. Any arguments provided are taken as separate documents 139 | to be serialized. 140 | 141 | =head2 read $filename 142 | 143 | The C constructor reads a YAML file from a file name, 144 | and returns a new C object containing the parsed content. 145 | 146 | Returns the object on success or throws an error on failure. 147 | 148 | =head2 read_string $string; 149 | 150 | The C constructor reads YAML data from a character string, and 151 | returns a new C object containing the parsed content. If you have 152 | read the string from a file yourself, be sure that you have correctly decoded 153 | it into characters first. 154 | 155 | Returns the object on success or throws an error on failure. 156 | 157 | =head2 write $filename 158 | 159 | The C method generates the file content for the properties, and 160 | writes it to disk using UTF-8 encoding to the filename specified. 161 | 162 | Returns true on success or throws an error on failure. 163 | 164 | =head2 write_string 165 | 166 | Generates the file content for the object and returns it as a character 167 | string. This may contain non-ASCII characters and should be encoded 168 | before writing it to a file. 169 | 170 | Returns true on success or throws an error on failure. 171 | 172 | =for stopwords errstr 173 | 174 | =head2 errstr (DEPRECATED) 175 | 176 | Prior to version 1.57, some errors were fatal and others were available only 177 | via the C<$YAML::Tiny::errstr> variable, which could be accessed via the 178 | C method. 179 | 180 | Starting with version 1.57, all errors are fatal and throw exceptions. 181 | 182 | The C<$errstr> variable is still set when exceptions are thrown, but 183 | C<$errstr> and the C method are deprecated and may be removed in a 184 | future release. The first use of C will issue a deprecation 185 | warning. 186 | 187 | =head1 FUNCTIONS 188 | 189 | YAML::Tiny implements a number of functions to add compatibility with 190 | the L API. These should be a drop-in replacement. 191 | 192 | =head2 Dump 193 | 194 | my $string = Dump(list-of-Perl-data-structures); 195 | 196 | Turn Perl data into YAML. This function works very much like 197 | Data::Dumper::Dumper(). 198 | 199 | It takes a list of Perl data structures and dumps them into a serialized 200 | form. 201 | 202 | It returns a character string containing the YAML stream. Be sure to encode 203 | it as UTF-8 before serializing to a file or socket. 204 | 205 | The structures can be references or plain scalars. 206 | 207 | Dies on any error. 208 | 209 | =head2 Load 210 | 211 | my @data_structures = Load(string-containing-a-YAML-stream); 212 | 213 | Turn YAML into Perl data. This is the opposite of Dump. 214 | 215 | Just like L's thaw() function or the eval() function in relation 216 | to L. 217 | 218 | It parses a character string containing a valid YAML stream into a list of 219 | Perl data structures representing the individual YAML documents. Be sure to 220 | decode the character string correctly if the string came from a file or 221 | socket. 222 | 223 | my $last_data_structure = Load(string-containing-a-YAML-stream); 224 | 225 | For consistency with YAML.pm, when Load is called in scalar context, it 226 | returns the data structure corresponding to the last of the YAML documents 227 | found in the input stream. 228 | 229 | Dies on any error. 230 | 231 | =head2 freeze() and thaw() 232 | 233 | Aliases to Dump() and Load() for L fans. This will also allow 234 | YAML::Tiny to be plugged directly into modules like POE.pm, that use the 235 | freeze/thaw API for internal serialization. 236 | 237 | =head2 DumpFile(filepath, list) 238 | 239 | Writes the YAML stream to a file with UTF-8 encoding instead of just 240 | returning a string. 241 | 242 | Dies on any error. 243 | 244 | =head2 LoadFile(filepath) 245 | 246 | Reads the YAML stream from a UTF-8 encoded file instead of a string. 247 | 248 | Dies on any error. 249 | 250 | =head1 YAML TINY SPECIFICATION 251 | 252 | This section of the documentation provides a specification for "YAML Tiny", 253 | a subset of the YAML specification. 254 | 255 | It is based on and described comparatively to the YAML 1.1 Working Draft 256 | 2004-12-28 specification, located at L. 257 | 258 | Terminology and chapter numbers are based on that specification. 259 | 260 | =head2 1. Introduction and Goals 261 | 262 | The purpose of the YAML Tiny specification is to describe a useful subset 263 | of the YAML specification that can be used for typical document-oriented 264 | use cases such as configuration files and simple data structure dumps. 265 | 266 | =for stopwords extensibility 267 | 268 | Many specification elements that add flexibility or extensibility are 269 | intentionally removed, as is support for complex data structures, class 270 | and object-orientation. 271 | 272 | In general, the YAML Tiny language targets only those data structures 273 | available in JSON, with the additional limitation that only simple keys 274 | are supported. 275 | 276 | As a result, all possible YAML Tiny documents should be able to be 277 | transformed into an equivalent JSON document, although the reverse is 278 | not necessarily true (but will be true in simple cases). 279 | 280 | =for stopwords PCRE 281 | 282 | As a result of these simplifications the YAML Tiny specification should 283 | be implementable in a (relatively) small amount of code in any language 284 | that supports Perl Compatible Regular Expressions (PCRE). 285 | 286 | =head2 2. Introduction 287 | 288 | YAML Tiny supports three data structures. These are scalars (in a variety 289 | of forms), block-form sequences and block-form mappings. Flow-style 290 | sequences and mappings are not supported, with some minor exceptions 291 | detailed later. 292 | 293 | The use of three dashes "---" to indicate the start of a new document is 294 | supported, and multiple documents per file/stream is allowed. 295 | 296 | Both line and inline comments are supported. 297 | 298 | Scalars are supported via the plain style, single quote and double quote, 299 | as well as literal-style and folded-style multi-line scalars. 300 | 301 | The use of explicit tags is not supported. 302 | 303 | The use of "null" type scalars is supported via the ~ character. 304 | 305 | The use of "bool" type scalars is not supported. 306 | 307 | =for stopwords serializer 308 | 309 | However, serializer implementations should take care to explicitly escape 310 | strings that match a "bool" keyword in the following set to prevent other 311 | implementations that do support "bool" accidentally reading a string as a 312 | boolean 313 | 314 | y|Y|yes|Yes|YES|n|N|no|No|NO 315 | |true|True|TRUE|false|False|FALSE 316 | |on|On|ON|off|Off|OFF 317 | 318 | The use of anchors and aliases is not supported. 319 | 320 | The use of directives is supported only for the %YAML directive. 321 | 322 | =head2 3. Processing YAML Tiny Information 323 | 324 | B 325 | 326 | =for stopwords deserialization 327 | 328 | The YAML specification dictates three-phase serialization and three-phase 329 | deserialization. 330 | 331 | The YAML Tiny specification does not mandate any particular methodology 332 | or mechanism for parsing. 333 | 334 | Any compliant parser is only required to parse a single document at a 335 | time. The ability to support streaming documents is optional and most 336 | likely non-typical. 337 | 338 | =for stopwords acyclic 339 | 340 | Because anchors and aliases are not supported, the resulting representation 341 | graph is thus directed but (unlike the main YAML specification) B. 342 | 343 | Circular references/pointers are not possible, and any YAML Tiny serializer 344 | detecting a circular reference should error with an appropriate message. 345 | 346 | B 347 | 348 | =for stopwords unicode 349 | 350 | YAML Tiny reads and write UTF-8 encoded files. Operations on strings expect 351 | or produce Unicode characters not UTF-8 encoded bytes. 352 | 353 | B 354 | 355 | =for stopwords modality 356 | 357 | =for stopwords parsers 358 | 359 | YAML Tiny parsers and emitters are not expected to recover from, or 360 | adapt to, errors. The specific error modality of any implementation is 361 | not dictated (return codes, exceptions, etc.) but is expected to be 362 | consistent. 363 | 364 | =head2 4. Syntax 365 | 366 | B 367 | 368 | YAML Tiny streams are processed in memory as Unicode characters and 369 | read/written with UTF-8 encoding. 370 | 371 | The escaping and unescaping of the 8-bit YAML escapes is required. 372 | 373 | The escaping and unescaping of 16-bit and 32-bit YAML escapes is not 374 | required. 375 | 376 | B 377 | 378 | Support for the "~" null/undefined indicator is required. 379 | 380 | Implementations may represent this as appropriate for the underlying 381 | language. 382 | 383 | Support for the "-" block sequence indicator is required. 384 | 385 | Support for the "?" mapping key indicator is B required. 386 | 387 | Support for the ":" mapping value indicator is required. 388 | 389 | Support for the "," flow collection indicator is B required. 390 | 391 | Support for the "[" flow sequence indicator is B required, with 392 | one exception (detailed below). 393 | 394 | Support for the "]" flow sequence indicator is B required, with 395 | one exception (detailed below). 396 | 397 | Support for the "{" flow mapping indicator is B required, with 398 | one exception (detailed below). 399 | 400 | Support for the "}" flow mapping indicator is B required, with 401 | one exception (detailed below). 402 | 403 | Support for the "#" comment indicator is required. 404 | 405 | Support for the "&" anchor indicator is B required. 406 | 407 | Support for the "*" alias indicator is B required. 408 | 409 | Support for the "!" tag indicator is B required. 410 | 411 | Support for the "|" literal block indicator is required. 412 | 413 | Support for the ">" folded block indicator is required. 414 | 415 | Support for the "'" single quote indicator is required. 416 | 417 | Support for the """ double quote indicator is required. 418 | 419 | Support for the "%" directive indicator is required, but only 420 | for the special case of a %YAML version directive before the 421 | "---" document header, or on the same line as the document header. 422 | 423 | For example: 424 | 425 | %YAML 1.1 426 | --- 427 | - A sequence with a single element 428 | 429 | Special Exception: 430 | 431 | To provide the ability to support empty sequences 432 | and mappings, support for the constructs [] (empty sequence) and {} 433 | (empty mapping) are required. 434 | 435 | For example, 436 | 437 | %YAML 1.1 438 | # A document consisting of only an empty mapping 439 | --- {} 440 | # A document consisting of only an empty sequence 441 | --- [] 442 | # A document consisting of an empty mapping within a sequence 443 | - foo 444 | - {} 445 | - bar 446 | 447 | B 448 | 449 | Other than the empty sequence and mapping cases described above, YAML Tiny 450 | supports only the indentation-based block-style group of contexts. 451 | 452 | All five scalar contexts are supported. 453 | 454 | Indentation spaces work as per the YAML specification in all cases. 455 | 456 | Comments work as per the YAML specification in all simple cases. 457 | Support for indented multi-line comments is B required. 458 | 459 | Separation spaces work as per the YAML specification in all cases. 460 | 461 | B 462 | 463 | The only directive supported by the YAML Tiny specification is the 464 | %YAML language/version identifier. Although detected, this directive 465 | will have no control over the parsing itself. 466 | 467 | =for stopwords recognise 468 | 469 | The parser must recognise both the YAML 1.0 and YAML 1.1+ formatting 470 | of this directive (as well as the commented form, although no explicit 471 | code should be needed to deal with this case, being a comment anyway) 472 | 473 | That is, all of the following should be supported. 474 | 475 | --- #YAML:1.0 476 | - foo 477 | 478 | %YAML:1.0 479 | --- 480 | - foo 481 | 482 | % YAML 1.1 483 | --- 484 | - foo 485 | 486 | Support for the %TAG directive is B required. 487 | 488 | Support for additional directives is B required. 489 | 490 | Support for the document boundary marker "---" is required. 491 | 492 | Support for the document boundary market "..." is B required. 493 | 494 | If necessary, a document boundary should simply be indicated with a 495 | "---" marker, with no preceding "..." marker. 496 | 497 | Support for empty streams (containing no documents) is required. 498 | 499 | Support for implicit document starts is required. 500 | 501 | That is, the following must be equivalent. 502 | 503 | # Full form 504 | %YAML 1.1 505 | --- 506 | foo: bar 507 | 508 | # Implicit form 509 | foo: bar 510 | 511 | B 512 | 513 | Support for nodes optional anchor and tag properties is B required. 514 | 515 | Support for node anchors is B required. 516 | 517 | Support for node tags is B required. 518 | 519 | Support for alias nodes is B required. 520 | 521 | Support for flow nodes is B required. 522 | 523 | Support for block nodes is required. 524 | 525 | B 526 | 527 | Support for all five scalar styles is required as per the YAML 528 | specification, although support for quoted scalars spanning more 529 | than one line is B required. 530 | 531 | Support for multi-line scalar documents starting on the header 532 | is not required. 533 | 534 | Support for the chomping indicators on multi-line scalar styles 535 | is required. 536 | 537 | B 538 | 539 | Support for block-style sequences is required. 540 | 541 | Support for flow-style sequences is B required. 542 | 543 | Support for block-style mappings is required. 544 | 545 | Support for flow-style mappings is B required. 546 | 547 | Both sequences and mappings should be able to be arbitrarily 548 | nested. 549 | 550 | Support for plain-style mapping keys is required. 551 | 552 | Support for quoted keys in mappings is B required. 553 | 554 | Support for "?"-indicated explicit keys is B required. 555 | 556 | =for stopwords endeth 557 | 558 | Here endeth the specification. 559 | 560 | =head2 Additional Perl-Specific Notes 561 | 562 | For some Perl applications, it's important to know if you really have a 563 | number and not a string. 564 | 565 | That is, in some contexts is important that 3 the number is distinctive 566 | from "3" the string. 567 | 568 | Because even Perl itself is not trivially able to understand the difference 569 | (certainly without XS-based modules) Perl implementations of the YAML Tiny 570 | specification are not required to retain the distinctiveness of 3 vs "3". 571 | 572 | =head1 SUPPORT 573 | 574 | Bugs should be reported via the CPAN bug tracker at 575 | 576 | L 577 | 578 | =begin html 579 | 580 | For other issues, or commercial enhancement or support, please contact 581 | Adam Kennedy directly. 582 | 583 | =end html 584 | 585 | =head1 AUTHOR 586 | 587 | Adam Kennedy Eadamk@cpan.orgE 588 | 589 | =head1 SEE ALSO 590 | 591 | =over 4 592 | 593 | =item * L 594 | 595 | =item * L 596 | 597 | =item * L 598 | 599 | =item * L 600 | 601 | =item * L 602 | 603 | =item * L 604 | 605 | =back 606 | 607 | =head1 COPYRIGHT 608 | 609 | Copyright 2006 - 2013 Adam Kennedy. 610 | 611 | This program is free software; you can redistribute 612 | it and/or modify it under the same terms as Perl itself. 613 | 614 | The full text of the license can be found in the 615 | LICENSE file included with this module. 616 | 617 | =cut 618 | -------------------------------------------------------------------------------- /dist.ini: -------------------------------------------------------------------------------- 1 | name = YAML-Tiny 2 | author = Adam Kennedy 3 | copyright_holder = Adam Kennedy 4 | copyright_year = 2006 5 | license = Perl_5 6 | abstract = Read/Write YAML files with as little code as possible 7 | 8 | [PodVersion] 9 | 10 | ; version is determined from lib/YAML/Tiny.pm and is bumped automatically 11 | ; after each release 12 | [@Author::ETHER] 13 | :version = 0.151 14 | installer = MakeMaker 15 | changes_version_columns = 8 16 | -remove = PodWeaver 17 | authority = cpan:ADAMK 18 | Test::MinimumVersion.max_target_perl = 5.008001 19 | Keywords.keywords = YAML markup language serializer serialiser string data 20 | -remove = Test::Pod::No404s ; RIP use.perl.org 21 | 22 | [Prereqs / DevelopRequires] 23 | YAML = 0.66 24 | YAML::Syck = 1.05 25 | YAML::XS = 0.29 26 | 27 | [Prereqs::Soften] 28 | module = JSON::MaybeXS 29 | 30 | [Prereqs / TestRequires] 31 | File::Spec = 0.80 32 | 33 | [MetaResources] 34 | x_IRC = irc://irc.perl.org/#yaml 35 | ; x_MailingList = ??? 36 | 37 | [Encoding / data] 38 | encoding = bytes 39 | matches = ^t/data/ 40 | matches = ^t/tml- 41 | matches = ^t/README\.md$ 42 | 43 | [OnlyCorePrereqs] 44 | :version = 0.008 45 | check_dual_life_versions = 0 46 | starting_version = 5.007003 ; when Scalar::Util was first cored 47 | -------------------------------------------------------------------------------- /t/01_api.t: -------------------------------------------------------------------------------- 1 | # Testing of some API methods; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use lib 't/lib/'; 7 | use Test::More 0.88; 8 | use SubtestCompat; 9 | use TestBridge; 10 | use YAML::Tiny; 11 | 12 | subtest "default exports" => sub { 13 | ok( defined(&Load), 'Found exported Load function' ); 14 | ok( defined(&Dump), 'Found exported Dump function' ); 15 | ok( \&main::Load == \&YAML::Tiny::Load, 'Load is YAML::Tiny' ); 16 | ok( \&main::Dump == \&YAML::Tiny::Dump, 'Dump is YAML::Tiny' ); 17 | ok( !defined(&LoadFile), 'LoadFile function not exported' ); 18 | ok( !defined(&DumpFile), 'DumpFile function not exported' ); 19 | ok( !defined(&freeze), 'freeze function not exported' ); 20 | ok( !defined(&thaw), 'thaw functiona not exported' ); 21 | }; 22 | 23 | subtest "all exports" => sub { 24 | package main::all_exports; 25 | use Test::More 0.88; 26 | use YAML::Tiny qw/Load Dump LoadFile DumpFile freeze thaw/; 27 | ok( defined(&Load), 'Found exported Load function' ); 28 | ok( defined(&Dump), 'Found exported Dump function' ); 29 | ok( defined(&LoadFile), 'Found exported LoadFile function' ); 30 | ok( defined(&DumpFile), 'Found exported DumpFile function' ); 31 | ok( defined(&freeze), 'Found exported freeze function' ); 32 | ok( defined(&thaw), 'Found exported thaw functiona' ); 33 | }; 34 | 35 | subtest "constructor and documents" => sub { 36 | my @docs = ( { one => 'two' }, { three => 'four' } ); 37 | ok( my $yaml = YAML::Tiny->new( @docs ), "constructor" ); 38 | cmp_deeply( [ @$yaml ], \@docs, "the object is an arrayref of documents" ); 39 | }; 40 | 41 | done_testing; 42 | -------------------------------------------------------------------------------- /t/01_compile.t: -------------------------------------------------------------------------------- 1 | # Load testing for YAML::Tiny 2 | 3 | use strict; 4 | use warnings; 5 | use lib 't/lib'; 6 | 7 | BEGIN { 8 | $| = 1; 9 | } 10 | 11 | use Test::More 0.88; 12 | 13 | # Check their perl version 14 | ok( "$]" >= 5.008001, "Your perl is new enough" ); 15 | 16 | # Does the module load 17 | require_ok( 'YAML::Tiny' ); 18 | require_ok( 'TestUtils' ); 19 | require_ok( 'TestBridge' ); 20 | require_ok( 'TestML::Tiny' ); 21 | 22 | done_testing; 23 | -------------------------------------------------------------------------------- /t/10_read.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use utf8; 4 | use lib 't/lib/'; 5 | use Test::More 0.88; 6 | use SubtestCompat; 7 | use TestUtils; 8 | use TestBridge; 9 | 10 | use YAML::Tiny; 11 | 12 | #--------------------------------------------------------------------------# 13 | # read() should read these files without error 14 | #--------------------------------------------------------------------------# 15 | 16 | my %passes = ( 17 | array => { 18 | file => 'ascii.yml', 19 | perl => [ 20 | [ 'foo' ] 21 | ], 22 | }, 23 | 'multibyte UTF-8' => { 24 | file => 'multibyte.yml', 25 | perl => [ 26 | { author => 'Ævar Arnfjörð Bjarmason ' } 27 | ], 28 | utf8 => 'author', 29 | }, 30 | 'UTF-8 BOM' => { 31 | file => 'utf_8_bom.yml', 32 | perl => [ 33 | { author => 'Ævar Arnfjörð Bjarmason ' } 34 | ], 35 | utf8 => 'author', 36 | }, 37 | ); 38 | 39 | for my $key ( sort keys %passes ) { 40 | subtest $key => sub { 41 | my $case = $passes{$key}; 42 | my $file = test_data_file( $case->{file} ); 43 | ok( -f $file, "Found $case->{file}" ); 44 | 45 | my $got = eval { YAML::Tiny->read( $file ) }; 46 | is( $@, '', "YAML::Tiny reads without exception" ); 47 | SKIP: { 48 | skip( "Shortcutting after failure", 2 ) if $@; 49 | isa_ok( $got, 'YAML::Tiny' ) 50 | or diag "ERROR: " . YAML::Tiny->errstr; 51 | cmp_deeply( $got, $case->{perl}, "YAML::Tiny parses correctly" ); 52 | } 53 | 54 | if ( $case->{utf8} ) { 55 | ok( utf8::is_utf8( $got->[0]->{$case->{utf8}} ), "utf8 decoded" ); 56 | } 57 | 58 | # test that read method on object is also a constructor 59 | ok( my $got2 = eval { $got->read( $file ) }, "read() object method"); 60 | isnt( $got, $got2, "objects are different" ); 61 | cmp_deeply( $got, $got2, "objects have same content" ); 62 | } 63 | } 64 | 65 | #--------------------------------------------------------------------------# 66 | # read() should fail to read these files and provide expected errors 67 | #--------------------------------------------------------------------------# 68 | 69 | my %errors = ( 70 | 'latin1.yml' => qr/latin1\.yml.*does not map to Unicode/, 71 | 'utf_16_le_bom.yml' => qr/utf_16_le_bom\.yml.*does not map to Unicode/, 72 | ); 73 | 74 | for my $key ( sort keys %errors ) { 75 | subtest $key => sub { 76 | my $file = test_data_file( $key ); 77 | ok( -f $file, "Found $key" ); 78 | 79 | my $result = eval { YAML::Tiny->read( $file ) }; 80 | ok( !$result, "returned false" ); 81 | error_like( $errors{$key}, "Got expected error" ); 82 | }; 83 | } 84 | 85 | # Additional errors without a file to read 86 | 87 | subtest "bad read arguments" => sub { 88 | eval { YAML::Tiny->read(); }; 89 | error_like(qr/You did not specify a file name/, 90 | "Got expected error: no filename provided to read()" 91 | ); 92 | 93 | eval { YAML::Tiny->read( test_data_file('nonexistent.yml') ); }; 94 | error_like(qr/File '.*?' does not exist/, 95 | "Got expected error: nonexistent filename provided to read()" 96 | ); 97 | 98 | eval { YAML::Tiny->read( test_data_directory() ); }; 99 | error_like(qr/'.*?' is a directory, not a file/, 100 | "Got expected error: directory provided to read()" 101 | ); 102 | }; 103 | 104 | done_testing; 105 | # COPYRIGHT 106 | # vim: ts=4 sts=4 sw=4 et: 107 | -------------------------------------------------------------------------------- /t/11_read_string.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use lib 't/lib/'; 4 | use Test::More 0.88; 5 | use SubtestCompat; 6 | use TestUtils; 7 | use TestBridge; 8 | 9 | use YAML::Tiny (); 10 | 11 | #--------------------------------------------------------------------------# 12 | # Generally, read_string can be tested with .tml files in t/tml-local/* 13 | # 14 | # This file is for error tests that can't be easily tested via .tml 15 | #--------------------------------------------------------------------------# 16 | 17 | subtest 'read_string without arg' => sub { 18 | eval { YAML::Tiny->read_string(); }; 19 | error_like(qr/Did not provide a string to load/, 20 | "Got expected error: no string provided to read_string()" 21 | ); 22 | }; 23 | 24 | subtest 'YAML without newline' => sub { 25 | my $str = join("\n" => ('---', '- foo', '---', '- bar', '---')); 26 | my $obj = eval { YAML::Tiny->read_string($str); }; 27 | is( $@, '', "YAML without newline is OK"); 28 | }; 29 | 30 | subtest 'read_string as object method' => sub { 31 | ok( my $obj = YAML::Tiny->new( { foo => 'bar' } ), "new YAML object" ); 32 | ok( my $obj2 = $obj->read_string( "---\nfoo: bar\n" ), 33 | "read_string object method" 34 | ); 35 | isnt( $obj, $obj2, "objects are different" ); 36 | cmp_deeply( $obj, $obj2, "objects have same content" ); 37 | }; 38 | 39 | subtest 'invalid UTF-8' => sub { 40 | # get invalid UTF-8 by reading Latin-1 with lax :utf8 layer 41 | my $string = do { 42 | local $SIG{__WARN__} = sub {}; 43 | slurp( test_data_file('latin1.yml'), ":utf8" ); 44 | }; 45 | my $obj = eval { YAML::Tiny->read_string($string); }; 46 | is( $obj, undef, "read_string should return undef" ); 47 | error_like( qr/invalid UTF-8 string/, 48 | "Got expected error about invalid UTF-8 string" 49 | ); 50 | }; 51 | 52 | done_testing; 53 | -------------------------------------------------------------------------------- /t/12_write.t: -------------------------------------------------------------------------------- 1 | use utf8; 2 | use strict; 3 | use warnings; 4 | use lib 't/lib/'; 5 | use Test::More 0.88; 6 | use SubtestCompat; 7 | use TestBridge; 8 | use TestUtils; 9 | 10 | use YAML::Tiny; 11 | use File::Basename qw/basename/; 12 | use File::Spec::Functions 'catfile'; 13 | use File::Temp 0.19; # newdir 14 | 15 | #--------------------------------------------------------------------------# 16 | # Error conditions 17 | #--------------------------------------------------------------------------# 18 | 19 | subtest 'no filename for write()' => sub { 20 | my $obj = YAML::Tiny->new(); 21 | eval { $obj->write(); }; 22 | error_like( qr/You did not specify a file name/, 23 | "No filename provided to write()" 24 | ); 25 | }; 26 | 27 | #--------------------------------------------------------------------------# 28 | # Test that write uses correct encoding and can round-trip 29 | #--------------------------------------------------------------------------# 30 | 31 | my @cases = ( 32 | { label => "ascii", name => "Mengue" }, 33 | { label => "latin1", name => "Mengué" }, 34 | { label => "wide", name => "あ" }, 35 | ); 36 | 37 | my @warnings; 38 | local $SIG{__WARN__} = sub { push @warnings, $_[0] }; 39 | 40 | # YAML::Tiny doesn't preserve order in the file, so we can't actually check 41 | # file equivalence. We have to see if we can round-trip a data structure 42 | # from Perl to YAML and back. 43 | for my $c ( @cases ) { 44 | subtest "write $c->{label} characters" => sub { 45 | my $data; 46 | @warnings = (); 47 | 48 | # get a tempfile name to write to 49 | my $tempdir = File::Temp->newdir("YTXXXXXX", TMPDIR => 1 ); 50 | my $short_tempfile = 'output'; 51 | my $tempfile = catfile($tempdir, $short_tempfile); 52 | 53 | # YAML::Tiny->write 54 | ok( YAML::Tiny->new($c)->write($tempfile), 55 | "case $c->{label}: write $short_tempfile" ) 56 | or diag "ERROR: " . YAML::Tiny->errstr; 57 | 58 | # YAML::Tiny->read 59 | ok( $data = eval { YAML::Tiny->read( $tempfile ) }, 60 | "case $c->{label}: read $short_tempfile" ) 61 | or diag "ERROR: " . YAML::Tiny->errstr; 62 | is( $@, '', "no error caught" ); 63 | SKIP : { 64 | skip "no data read", 1 unless $data; 65 | cmp_deeply( $data, [ $c ], 66 | "case $c->{label}: Perl -> File -> Perl roundtrip" ); 67 | } 68 | 69 | # YAML::Tiny->read_string on UTF-8 decoded data 70 | ok( $data = eval { YAML::Tiny->read_string( slurp($tempfile, ":utf8") ) }, 71 | "case $c->{label}: read_string on UTF-8 decoded $short_tempfile" ); 72 | is( $@, '', "no error caught" ); 73 | SKIP : { 74 | skip "no data read", 1 unless $data; 75 | cmp_deeply( $data, [ $c ], 76 | "case $c->{label}: Perl -> File -> Decoded -> Perl roundtrip" ); 77 | } 78 | 79 | is( scalar @warnings, 0, "case $c->{label}: no warnings caught" ) 80 | or diag @warnings; 81 | } 82 | } 83 | 84 | done_testing; 85 | -------------------------------------------------------------------------------- /t/13_write_string.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use lib 't/lib/'; 4 | use Test::More 0.88; 5 | use SubtestCompat; 6 | use TestUtils; 7 | use TestBridge; 8 | 9 | use YAML::Tiny (); 10 | 11 | #--------------------------------------------------------------------------# 12 | # Generally, write_string can be tested with .tml files in t/tml-local/* 13 | # 14 | # This file is for error tests or conditions that can't be easily tested 15 | # via .tml 16 | #--------------------------------------------------------------------------# 17 | 18 | subtest 'write_string as class method' => sub { 19 | my $got = eval { YAML::Tiny->write_string }; 20 | is( $@, '', "write_string lives" ); 21 | is( $got, '', "returns empty string" ); 22 | }; 23 | 24 | done_testing; 25 | -------------------------------------------------------------------------------- /t/20_subclass.t: -------------------------------------------------------------------------------- 1 | # Testing documents that should fail 2 | use strict; 3 | use warnings; 4 | use lib 't/lib/'; 5 | use Test::More 0.88; 6 | use TestUtils; 7 | 8 | use File::Spec::Functions ':ALL'; 9 | 10 | 11 | 12 | ##################################################################### 13 | # Customized Class 14 | 15 | SCOPE: { 16 | package Foo; 17 | 18 | use YAML::Tiny; 19 | 20 | use vars qw{@ISA}; 21 | BEGIN { 22 | @ISA = 'YAML::Tiny'; 23 | } 24 | 25 | # XXX-INGY subclasses should not use private methods… or if they 26 | # do they should expect method name changes. 27 | # sub _write_scalar { 28 | 29 | sub _dump_scalar { 30 | my $self = shift; 31 | my $string = shift; 32 | my $is_key = shift; 33 | if ( defined $is_key ) { 34 | return scalar reverse $string; 35 | } else { 36 | return $string; 37 | } 38 | } 39 | 40 | 1; 41 | } 42 | 43 | 44 | 45 | 46 | 47 | ##################################################################### 48 | # Generate the value 49 | 50 | my $object = Foo->new( 51 | { foo => 'bar' } 52 | ); 53 | is( $object->write_string, "---\noof: bar\n", 'Subclassing works' ); 54 | 55 | done_testing; 56 | -------------------------------------------------------------------------------- /t/21_yamlpm_compat.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use lib 't/lib/'; 4 | use Test::More 0.88; 5 | use TestBridge; 6 | use File::Spec::Functions 'catfile'; 7 | use File::Temp 0.19; # newdir 8 | 9 | #--------------------------------------------------------------------------# 10 | # This file test that the YAML.pm compatible Dump/Load/DumpFile/LoadFile 11 | # work as documented 12 | #--------------------------------------------------------------------------# 13 | 14 | use YAML::Tiny; 15 | 16 | { 17 | my $scalar = 'this is a string'; 18 | my $arrayref = [ 1 .. 5 ]; 19 | my $hashref = { alpha => 'beta', gamma => 'delta' }; 20 | 21 | my $yamldump = YAML::Tiny::Dump( $scalar, $arrayref, $hashref ); 22 | my @yamldocsloaded = YAML::Tiny::Load($yamldump); 23 | cmp_deeply( 24 | [ @yamldocsloaded ], 25 | [ $scalar, $arrayref, $hashref ], 26 | "Functional interface: Dump to Load roundtrip works as expected" 27 | ); 28 | } 29 | 30 | { 31 | my $scalar = 'this is a string'; 32 | my $arrayref = [ 1 .. 5 ]; 33 | my $hashref = { alpha => 'beta', gamma => 'delta' }; 34 | 35 | my $tempdir = File::Temp->newdir("YTXXXXXX", TMPDIR => 1 ); 36 | my $filename = catfile($tempdir, 'compat'); 37 | 38 | my $rv = YAML::Tiny::DumpFile( 39 | $filename, $scalar, $arrayref, $hashref); 40 | ok($rv, "DumpFile returned true value"); 41 | 42 | my @yamldocsloaded = YAML::Tiny::LoadFile($filename); 43 | cmp_deeply( 44 | [ @yamldocsloaded ], 45 | [ $scalar, $arrayref, $hashref ], 46 | "Functional interface: DumpFile to LoadFile roundtrip works as expected" 47 | ); 48 | } 49 | 50 | { 51 | my $str = "This is not real YAML"; 52 | my @yamldocsloaded; 53 | eval { @yamldocsloaded = YAML::Tiny::Load("$str\n"); }; 54 | error_like( 55 | qr/YAML::Tiny failed to classify line '$str'/, 56 | "Correctly failed to load non-YAML string" 57 | ); 58 | } 59 | 60 | done_testing; 61 | -------------------------------------------------------------------------------- /t/30_yaml_spec_tml.t: -------------------------------------------------------------------------------- 1 | # Run the appropriate tests from https://github.com/ingydotnet/yaml-spec-tml 2 | use strict; 3 | use warnings; 4 | use lib 't/lib'; 5 | use Test::More 0.88; 6 | use SubtestCompat; 7 | use TestBridge; 8 | use TestUtils; 9 | 10 | my $JSON = json_class() 11 | or Test::More::plan skip_all => 'no JSON backends available!?'; 12 | 13 | diag 'using JSON backend: ' . $JSON . ' ' . $JSON->VERSION 14 | if not $ENV{PERL_CORE}; 15 | 16 | # Each spec test will need a different bridge and arguments: 17 | my @spec_tests = ( 18 | ['t/tml-spec/basic-data.tml', 'test_yaml_json', $JSON], 19 | ['t/tml-spec/multiline.tml', 'test_yaml_json', $JSON], 20 | # This test is currently failing massively. We use LAST to only run what is 21 | # covered so far. 22 | ['t/tml-spec/unicode.tml', 'test_code_point'], # uses JSON::PP 23 | ); 24 | 25 | for my $test (@spec_tests) { 26 | my ($file, $bridge, @args) = @$test; 27 | my $code = sub { 28 | my ($file, $blocks) = @_; 29 | subtest "YAML Spec Test; file: $file" => sub { 30 | my $func = \&{$bridge}; 31 | $func->($_) for @$blocks; 32 | }; 33 | }; 34 | run_testml_file($file, $code, @args); 35 | } 36 | 37 | done_testing; 38 | -------------------------------------------------------------------------------- /t/31_local_tml.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use lib 't/lib/'; 4 | use Test::More 0.88; 5 | use TestBridge; 6 | use IO::Dir; 7 | use File::Spec::Functions qw/catdir/; 8 | 9 | my $tml_local = "t/tml-local"; 10 | 11 | for my $dir ( IO::Dir->new($tml_local)->read ) { 12 | next if $dir =~ /^\./; 13 | my $fn = "test_$dir"; 14 | $fn =~ s/-/_/g; 15 | $fn =~ s/\.DIR\z//i if $^O eq 'VMS'; 16 | my $bridge = TestBridge->can($fn); 17 | next unless $bridge; 18 | run_all_testml_files( "TestML", catdir($tml_local, $dir), $bridge ); 19 | } 20 | 21 | done_testing; 22 | -------------------------------------------------------------------------------- /t/32_world_tml.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use lib 't/lib/'; 4 | use Test::More 0.88; 5 | use TestBridge; 6 | 7 | run_all_testml_files( 8 | "Real-world examples", 't/tml-world', \&test_yaml_roundtrip 9 | ); 10 | 11 | done_testing; 12 | -------------------------------------------------------------------------------- /t/86_fail.t: -------------------------------------------------------------------------------- 1 | =pod 2 | 3 | This is an example of a serious design flaw in YAML::Tiny. 4 | 5 | It is generally a bad idea to fake out a parsing process. In this case, 6 | YAML::Tiny strips off all lines that look like comments. 7 | 8 | It should be easy to find dozens of bugs by looking at the assumptions the code 9 | makes and then finding a counter case like this. 10 | 11 | That's why I'm working on Tiny::YAML and YAML::Pegex, which are driven by a 12 | grammar. 13 | 14 | =cut 15 | 16 | use Test::More tests => 1; 17 | use YAML::Tiny; 18 | 19 | TODO: { 20 | local $TODO = "Failing tests for things YAML::Tiny does wrong"; 21 | 22 | my $yaml = <<'...'; 23 | - | 24 | # Perl sub: 25 | sub foo {} 26 | ... 27 | is Load($yaml)->[0], 28 | "# Perl sub:\nsub foo{}\n", 29 | "Comments in literal scalars"; 30 | } 31 | -------------------------------------------------------------------------------- /t/README.md: -------------------------------------------------------------------------------- 1 | # Guide to YAML::Tiny testing 2 | 3 | YAML::Tiny tests use several components: 4 | 5 | * .t files 6 | * Test libraries in t/lib 7 | * YAML data files in t/data 8 | * TestML data files in t/tml-* 9 | 10 | The use of each is described below. 11 | 12 | ## .t files 13 | 14 | The .t files are standard Perl test files. They may use one or more of the 15 | test libraries in t/lib. They may only use modules available in Perl 5.8.1 or 16 | later (and not subsequently deprecated), but they may use newer non-XS versions 17 | of those modules as necessary to avoid known bugs. 18 | 19 | Some .t files have complete inputs/outputs for their tests. Others iterate 20 | over .tml files in the t/tml-* directories. 21 | 22 | A .t file should load Test::More and use `done_testing` at the end 23 | to so that new tests may be added without needing to also update a test plan. 24 | 25 | Currently, the convention is to name .t files matching the pattern 26 | qr/^\d\d_\w+\.t$/ 27 | 28 | ## Test libraries 29 | 30 | There are currently three test libraries in t/lib. A .t file that uses one or 31 | more of them should put `use lib 't/lib';` at the top of the .t file. Test 32 | libraries can assume that if they were loaded, that 't/lib' is already in @INC. 33 | 34 | The test libraries are: 35 | 36 | * SubtestCompat 37 | * TestML::Tiny 38 | * TestBridge 39 | * TestUtils 40 | 41 | The "SubtestCompat" library provides a limited emulation of 42 | Test::More::subtest that is reasonably compatible back to 0.88. If using 43 | subtests, you must not set a plan in the subtest and you must use 44 | done_testing in the *.t file. 45 | 46 | The TestML::Tiny library contains functions for parsing and executing TestML 47 | tests with callbacks. TestML is a data-driven testing language; TestML::Tiny 48 | implements a small subset of its features. See the section on TestML, below, 49 | for an example. Generally, bugs should be patched upstream on CPAN and then 50 | a new Test::Tiny CPAN release can be copied here and pod-stripped. 51 | 52 | The TestBridge library contains testing functions for use in .t files or to 53 | be passed to TestML::Tiny functions as callbacks. Test functions should not 54 | include `done_testing`. They should use `subtest` for any repetitive testing 55 | that loops over test cases. Callback should check for the expected test 56 | points (see below) and skip a TML block if those points are not available. 57 | 58 | The TestUtils library contains utility functions. Testing functions should 59 | not be added here (i.e. nothing that uses Test::More). 60 | 61 | ## YAML data files in t/data 62 | 63 | Files in the t/data directory are intended to test how YAML files are loaded 64 | and decoded and typically need some custom test code to load the file and see 65 | if the result matches expectations (successful or not). 66 | 67 | If a real-world YAML file cannot be loaded due to character set encoding 68 | issues, it should be placed in this directory for testing. If a real-world 69 | YAML file is ASCII or UTF-8 encoded, can be decoded successfully, but has 70 | problems in parsing, it should be reduced to the smallest sample of YAML that 71 | demonstrates the parsing problem and added to a .tml file for testing. See 72 | below for more details. 73 | 74 | ## TestML quick intro 75 | 76 | TestML data files are UTF-8 encoded files with a .tml suffix that contain one 77 | or more test "blocks". Each block has a test label, and one or more 'test 78 | points', usually representing input and expected output, and possibly 79 | additional annotations or flags. 80 | 81 | Here is an example of a .tml file with a single block: 82 | 83 | # This is a TestML block: (this line is a comment) 84 | === This is the test label 85 | Lines until the first point are ignored 86 | 87 | # This is a "block" style point. All non-comment lines until next point 88 | # are the data for the 'yaml' point. The data ends with newline, and 89 | # trailing blank lines are trimmed. 90 | --- yaml 91 | --- 92 | foo: bar 93 | # a comment 94 | \# not a comment 95 | 96 | # This is the second point; "inline" style. The data after the colon goes 97 | # to end of line. Leading/trailing whitespace is trimmed. 98 | --- perl: [ { foo => 'bar' } ] 99 | 100 | # This is a point whose value is the empty string 101 | --- a_flag 102 | 103 | # This is the next block: 104 | === Another test case 105 | 106 | The test label is provided on a line beginning with qr/^===/. Test "points" 107 | are provided in sections beginning with qr/^--- +\w+/. All flush-left comment 108 | lines are stripped. Lines beginning with '\' are escaped. 109 | 110 | Different tests expect different test points in a .tml file, based on the 111 | specific test callback being used. 112 | 113 | Many .tml files have the points 'yaml' and 'perl' as in the example above. The 114 | 'yaml' point is a YAML document and the 'perl' point is a Data::Dumper Perl 115 | data structure. The test checks whether the YAML parses into a data structure 116 | identical to the Perl one. The 'a_flag' point is an annotation that the 117 | testing callback can use to affect the run of a given test. 118 | 119 | The semantics of points (including annotations) is specific to the callback 120 | functions used to process test blocks. 121 | 122 | # TestML data files in t/tml-* 123 | 124 | TestML data files are organized into three directories: 125 | 126 | * t/tml-spec — these test files are provided by the YAML spec maintainers and 127 | should not be modified except to skip testing features that YAML::Tiny does not 128 | support 129 | 130 | * t/tml-local — these test files are YAML::Tiny's own unit tests; generally new 131 | test cases for coverage or correctness should be added here; these are 132 | broken into subdirectories, described later 133 | 134 | * t/tml-world — these test files represent "real world" YAML and their 135 | corresponding expected Perl output 136 | 137 | Generally, if a "real world" problem can be isolated to a particular snippet of 138 | YAML, it's best to add it to a t/tml-local file (or create a new one). If the 139 | problem can only be seen in the context of the entire YAML document, include it 140 | in t/tml-world. If the problem relates to encoding, it should be put into 141 | t/data instead. 142 | 143 | # t/tml-local subdirectories 144 | 145 | The subdirectories in t/tml-local define four types of tests: 146 | 147 | * perl-to-yaml: test that perl data dump to an expected YAML string 148 | 149 | * yaml-roundtrip: test that a YAML string loads to an expected perl data 150 | structure; also tests that the perl data can be dumped and loaded back; 151 | 152 | * dump-error: test that certain perl data trigger expected errors 153 | 154 | * load-error: test that certain YAML strings trigger expected errors 155 | 156 | All .tml files in a t/tml-local directory must have the TestML 157 | test points required by the corresponding test functions defined 158 | in the TestBridge library. 159 | 160 | Generally, files should be grouped by data type or feature so that 161 | related tests are kept together. 162 | -------------------------------------------------------------------------------- /t/data/ascii.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - foo 3 | -------------------------------------------------------------------------------- /t/data/latin1.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Perl-Toolchain-Gang/YAML-Tiny/0b3f6349d5fa2b65dbfd9e46e7ea83460f3eb631/t/data/latin1.yml -------------------------------------------------------------------------------- /t/data/multibyte.yml: -------------------------------------------------------------------------------- 1 | --- 2 | author: "Ævar Arnfjörð Bjarmason " 3 | -------------------------------------------------------------------------------- /t/data/utf_16_le_bom.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Perl-Toolchain-Gang/YAML-Tiny/0b3f6349d5fa2b65dbfd9e46e7ea83460f3eb631/t/data/utf_16_le_bom.yml -------------------------------------------------------------------------------- /t/data/utf_8_bom.yml: -------------------------------------------------------------------------------- 1 | --- 2 | author: "Ævar Arnfjörð Bjarmason " 3 | -------------------------------------------------------------------------------- /t/lib/SubtestCompat.pm: -------------------------------------------------------------------------------- 1 | use 5.008001; 2 | use strict; 3 | use warnings; 4 | 5 | package SubtestCompat; 6 | 7 | # XXX must be used with no_plan or done_testing 8 | use Test::More 0.88; 9 | 10 | use base 'Exporter'; 11 | our @EXPORT; 12 | 13 | our $INDENT = -2; 14 | 15 | # intercept 'skip_all' in subtest and turn into a regular skip 16 | sub _fake_plan { 17 | my ( $self, $cmd, $arg ) = @_; 18 | 19 | return unless $cmd; 20 | 21 | if ( $cmd eq 'skip_all' ) { 22 | die bless { reason => $arg }, "Subtest::SKIP"; 23 | } 24 | else { 25 | goto &Test::Builder::plan; 26 | } 27 | } 28 | 29 | unless ( Test::More->can("subtest") ) { 30 | *subtest = sub { 31 | my ( $label, $code ) = @_; 32 | local $Test::Builder::Level = $Test::Builder::Level + 1; 33 | 34 | local $INDENT = $INDENT + 2; 35 | 36 | $label = "TEST: $label"; 37 | my $sep_len = 60 - length($label); 38 | 39 | note( " " x $INDENT . "$label { " . ( " " x ($sep_len-$INDENT-2) ) ); 40 | eval { 41 | no warnings 'redefine'; 42 | local *Test::Builder::plan = \&_fake_plan; 43 | # only want subtest error reporting to look up to the code ref 44 | # for where test was called, not further up to *our* callers, 45 | # so we *reset* the Level, rather than increment it 46 | local $Test::Builder::Level = 1; 47 | $code->(); 48 | }; 49 | if ( my $err = $@ ) { 50 | if ( ref($err) eq 'Subtest::SKIP' ) { 51 | SKIP: { 52 | skip $err->{reason}, 1; 53 | } 54 | } 55 | else { 56 | fail("SUBTEST: $label"); 57 | diag("Caught exception: $err"); 58 | die "$err\n"; 59 | } 60 | } 61 | note( " " x $INDENT . "}" ); 62 | }; 63 | push @EXPORT, 'subtest'; 64 | } 65 | elsif ( !eval { Test::More->VERSION(0.95_01) } ) { 66 | my $subtest = \&Test::Builder::subtest; 67 | no warnings 'redefine'; 68 | *Test::Builder::subtest = sub { 69 | my ($self, $name, $subtests, @args) = @_; 70 | my $sub = sub { 71 | $subtests->(@_); 72 | $self->done_testing 73 | unless $self->{Have_Plan} || $self->{No_Plan} || $self->{Skip_All}; 74 | }; 75 | return $self->$subtest($name, $sub, @args); 76 | }; 77 | } 78 | 79 | 1; 80 | -------------------------------------------------------------------------------- /t/lib/TestBridge.pm: -------------------------------------------------------------------------------- 1 | package TestBridge; 2 | 3 | use strict; 4 | use warnings; 5 | use lib 't/lib'; 6 | use open ':std', ':encoding(UTF-8)'; # force stdin, stdout, stderr into utf8 7 | use Test::More 0.88; 8 | use SubtestCompat; 9 | use TestUtils; 10 | use TestML::Tiny; 11 | 12 | use YAML::Tiny; 13 | 14 | use Exporter (); 15 | our @ISA = qw{ Exporter }; 16 | our @EXPORT = qw{ 17 | run_all_testml_files 18 | run_testml_file 19 | test_yaml_roundtrip 20 | test_perl_to_yaml 21 | test_dump_error 22 | test_load_error 23 | test_load_warning 24 | test_yaml_json 25 | test_code_point 26 | error_like 27 | cmp_deeply 28 | _testml_has_points 29 | }; 30 | 31 | # regular expressions for checking error messages; incomplete, but more 32 | # can be added as more error messages get test coverage 33 | my %ERROR = ( 34 | E_CIRCULAR => qr{\QYAML::Tiny does not support circular references}, 35 | E_FEATURE => qr{\QYAML::Tiny does not support a feature}, 36 | E_PLAIN => qr{\QYAML::Tiny found illegal characters in plain scalar}, 37 | E_CLASSIFY => qr{\QYAML::Tiny failed to classify the line}, 38 | ); 39 | 40 | my %WARN = ( 41 | E_DUPKEY => qr{\QYAML::Tiny found a duplicate key}, 42 | ); 43 | 44 | # use XXX -with => 'YAML::XS'; 45 | 46 | #--------------------------------------------------------------------------# 47 | # run_all_testml_files 48 | # 49 | # Iterate over all .tml files in a directory using a particular test bridge 50 | # code # reference. Each file is wrapped in a subtest. 51 | #--------------------------------------------------------------------------# 52 | 53 | sub run_all_testml_files { 54 | my ($label, $dir, $bridge, @args) = @_; 55 | 56 | my $code = sub { 57 | my ($file, $blocks) = @_; 58 | subtest "$label: $file" => sub { 59 | $bridge->($_, @args) for @$blocks; 60 | }; 61 | }; 62 | 63 | my @files = find_tml_files($dir); 64 | 65 | run_testml_file($_, $code) for sort @files; 66 | } 67 | 68 | sub run_testml_file { 69 | my ($file, $code) = @_; 70 | 71 | my $blocks = TestML::Tiny->new( 72 | testml => $file, 73 | version => '0.1.0', 74 | )->{function}{data}; 75 | 76 | $code->($file, $blocks); 77 | } 78 | 79 | # retrieves all the keys in @point from the $block hash, returning them in 80 | # order, along with $block->{Label}. 81 | # returns false if any keys cannot be found 82 | sub _testml_has_points { 83 | my ($block, @points) = @_; 84 | my @values; 85 | for my $point (@points) { 86 | defined $block->{$point} or return; 87 | push @values, $block->{$point}; 88 | } 89 | push @values, $block->{Label}; 90 | return @values; 91 | } 92 | 93 | #--------------------------------------------------------------------------# 94 | # test_yaml_roundtrip 95 | # 96 | # two blocks: perl, yaml 97 | # 98 | # Tests that a YAML string loads to the expected perl data. Also, tests 99 | # roundtripping from perl->YAML->perl. 100 | # 101 | # We can't compare the YAML for roundtripping because YAML::Tiny doesn't 102 | # preserve order and comments. Therefore, all we can test is that given input 103 | # YAML we can produce output YAML that produces the same Perl data as the 104 | # input. 105 | # 106 | # The perl must be an array reference of data to serialize: 107 | # 108 | # [ $thing1, $thing2, ... ] 109 | # 110 | # However, if a test point called 'serializes' exists, the output YAML is 111 | # expected to match the input YAML and will be checked for equality. 112 | #--------------------------------------------------------------------------# 113 | 114 | sub test_yaml_roundtrip { 115 | my ($block) = @_; 116 | 117 | my ($yaml, $perl, $label) = 118 | _testml_has_points($block, qw(yaml perl)) or return; 119 | 120 | my %options = (); 121 | for (qw(serializes)) { 122 | if (defined($block->{$_})) { 123 | $options{$_} = 1; 124 | } 125 | } 126 | 127 | my $expected = eval $perl; die $@ if $@; 128 | bless $expected, 'YAML::Tiny'; 129 | 130 | subtest $label, sub { 131 | # Does the string parse to the structure 132 | my $yaml_copy = $yaml; 133 | my $got = eval { YAML::Tiny->read_string( $yaml_copy ); }; 134 | is( $@, '', "YAML::Tiny parses without error" ); 135 | is( $yaml_copy, $yaml, "YAML::Tiny does not modify the input string" ); 136 | SKIP: { 137 | skip( "Shortcutting after failure", 2 ) if $@; 138 | isa_ok( $got, 'YAML::Tiny' ); 139 | cmp_deeply( $got, $expected, "YAML::Tiny parses correctly" ) 140 | or diag "ERROR: $YAML::Tiny::errstr\n\nYAML:$yaml"; 141 | } 142 | 143 | # Does the structure serialize to the string. 144 | # We can't test this by direct comparison, because any 145 | # whitespace or comments would be lost. 146 | # So instead we parse back in. 147 | my $output = eval { $expected->write_string }; 148 | is( $@, '', "YAML::Tiny serializes without error" ); 149 | SKIP: { 150 | skip( "Shortcutting after failure", 5 ) if $@; 151 | ok( 152 | !!(defined $output and ! ref $output), 153 | "YAML::Tiny serializes to scalar", 154 | ); 155 | my $roundtrip = eval { YAML::Tiny->read_string( $output ) }; 156 | is( $@, '', "YAML::Tiny round-trips without error" ); 157 | skip( "Shortcutting after failure", 2 ) if $@; 158 | isa_ok( $roundtrip, 'YAML::Tiny' ); 159 | cmp_deeply( $roundtrip, $expected, "YAML::Tiny round-trips correctly" ); 160 | 161 | # Testing the serialization 162 | skip( "Shortcutting perfect serialization tests", 1 ) unless $options{serializes}; 163 | is( $output, $yaml, 'Serializes ok' ); 164 | } 165 | 166 | }; 167 | } 168 | 169 | #--------------------------------------------------------------------------# 170 | # test_perl_to_yaml 171 | # 172 | # two blocks: perl, yaml 173 | # 174 | # Tests that perl references serialize correctly to a specific YAML output 175 | # 176 | # The perl must be an array reference of data to serialize: 177 | # 178 | # [ $thing1, $thing2, ... ] 179 | #--------------------------------------------------------------------------# 180 | 181 | sub test_perl_to_yaml { 182 | my ($block) = @_; 183 | 184 | my ($perl, $yaml, $label) = 185 | _testml_has_points($block, qw(perl yaml)) or return; 186 | 187 | my $input = eval "no strict; $perl"; die $@ if $@; 188 | 189 | subtest $label, sub { 190 | my $result = eval { YAML::Tiny->new( @$input )->write_string }; 191 | is( $@, '', "write_string lives" ); 192 | is( $result, $yaml, "dumped YAML correct" ); 193 | }; 194 | } 195 | 196 | #--------------------------------------------------------------------------# 197 | # test_dump_error 198 | # 199 | # two blocks: perl, error 200 | # 201 | # Tests that perl references result in an error when dumped 202 | # 203 | # The perl must be an array reference of data to serialize: 204 | # 205 | # [ $thing1, $thing2, ... ] 206 | # 207 | # The error must be a key in the %ERROR hash in this file 208 | #--------------------------------------------------------------------------# 209 | 210 | sub test_dump_error { 211 | my ($block) = @_; 212 | 213 | my ($perl, $error, $label) = 214 | _testml_has_points($block, qw(perl error)) or return; 215 | 216 | my $input = eval "no strict; $perl"; die $@ if $@; 217 | chomp $error; 218 | my $expected = $ERROR{$error}; 219 | 220 | subtest $label, sub { 221 | my $result = eval { YAML::Tiny->new( @$input )->write_string }; 222 | ok( !$result, "returned false" ); 223 | error_like( $expected, "Got expected error" ); 224 | }; 225 | } 226 | 227 | #--------------------------------------------------------------------------# 228 | # test_load_error 229 | # 230 | # two blocks: yaml, error 231 | # 232 | # Tests that a YAML string results in an error when loaded 233 | # 234 | # The error must be a key in the %ERROR hash in this file 235 | #--------------------------------------------------------------------------# 236 | 237 | sub test_load_error { 238 | my ($block) = @_; 239 | 240 | my ($yaml, $error, $label) = 241 | _testml_has_points($block, qw(yaml error)) or return; 242 | 243 | chomp $error; 244 | my $expected = $ERROR{$error}; 245 | 246 | subtest $label, sub { 247 | my $result = eval { YAML::Tiny->read_string( $yaml ) }; 248 | is( $result, undef, 'read_string returns undef' ); 249 | error_like( $expected, "Got expected error" ) 250 | or diag "YAML:\n$yaml"; 251 | }; 252 | } 253 | 254 | #--------------------------------------------------------------------------# 255 | # test_load_warning 256 | # 257 | # two blocks: yaml, warning 258 | # 259 | # Tests that a YAML string results in warning when loaded 260 | # 261 | # The warning must be a key in the %WARN hash in this file 262 | #--------------------------------------------------------------------------# 263 | sub test_load_warning { 264 | my ($block) = @_; 265 | 266 | my ($yaml, $warning, $label) = 267 | _testml_has_points($block, qw(yaml warning)) or return; 268 | 269 | chomp $warning; 270 | my $expected = $WARN{$warning}; 271 | 272 | subtest $label, sub { 273 | # this is not in a sub like warning_like because of the danger of 274 | # matching the regex parameter against something earlier in the stack 275 | my @warnings; 276 | local $SIG{__WARN__} = sub { push @warnings, shift; }; 277 | 278 | my $result = eval { YAML::Tiny->read_string( $yaml ) }; 279 | 280 | is(scalar(@warnings), 1, 'got exactly one warning'); 281 | like( 282 | $warnings[0], 283 | $expected, 284 | 'Got expected warning', 285 | ) or diag "YAML:\n$yaml\n", 'warning: ', explain(\@warnings); 286 | }; 287 | } 288 | 289 | #--------------------------------------------------------------------------# 290 | # test_yaml_json 291 | # 292 | # two blocks: yaml, json 293 | # 294 | # Tests that a YAML string can be loaded to Perl and dumped to JSON and 295 | # match an expected JSON output. The expected JSON is loaded and dumped 296 | # to ensure similar JSON dump options. 297 | #--------------------------------------------------------------------------# 298 | 299 | sub test_yaml_json { 300 | my ($block, $json_lib) = @_; 301 | $json_lib ||= do { require JSON::PP; 'JSON::PP' }; 302 | 303 | my ($yaml, $json, $label) = 304 | _testml_has_points($block, qw(yaml json)) or return; 305 | 306 | subtest "$label", sub { 307 | # test YAML Load 308 | my $object = eval { 309 | YAML::Tiny::Load($yaml); 310 | }; 311 | my $err = $@; 312 | ok !$err, "YAML loads"; 313 | return if $err; 314 | 315 | # test YAML->Perl->JSON 316 | # N.B. round-trip JSON to decode any \uNNNN escapes and get to 317 | # characters 318 | my $want = $json_lib->new->encode( 319 | $json_lib->new->decode($json) 320 | ); 321 | my $got = $json_lib->new->encode($object); 322 | is $got, $want, "Load is accurate"; 323 | }; 324 | } 325 | 326 | #--------------------------------------------------------------------------# 327 | # test_code_point 328 | # 329 | # two blocks: code, yaml 330 | # 331 | # Tests that a Unicode codepoint is correctly dumped to YAML as both 332 | # key and value. 333 | # 334 | # The code test point must be a non-negative integer 335 | # 336 | # The yaml code point is the expected output of { $key => $value } where 337 | # both key and value are the character represented by the codepoint. 338 | #--------------------------------------------------------------------------# 339 | 340 | sub test_code_point { 341 | my ($block) = @_; 342 | 343 | my ($code, $yaml, $label) = 344 | _testml_has_points($block, qw(code yaml)) or return; 345 | 346 | subtest "$label - Unicode map key/value test" => sub { 347 | my $data = { chr($code) => chr($code) }; 348 | my $dump = YAML::Tiny::Dump($data); 349 | $dump =~ s/^---\n//; 350 | is $dump, $yaml, "Dump key and value of code point char $code"; 351 | 352 | my $yny = YAML::Tiny::Dump(YAML::Tiny::Load($yaml)); 353 | $yny =~ s/^---\n//; 354 | is $yny, $yaml, "YAML for code point $code YNY roundtrips"; 355 | 356 | my $nyn = YAML::Tiny::Load(YAML::Tiny::Dump($data)); 357 | cmp_deeply( $nyn, $data, "YAML for code point $code NYN roundtrips" ); 358 | } 359 | } 360 | 361 | #--------------------------------------------------------------------------# 362 | # error_like 363 | # 364 | # Test YAML::Tiny->errstr against a regular expression and clear the 365 | # errstr afterwards 366 | #--------------------------------------------------------------------------# 367 | 368 | sub error_like { 369 | my ($regex, $label) = @_; 370 | $label = "Got expected error" unless defined $label; 371 | local $Test::Builder::Level = $Test::Builder::Level + 1; 372 | my $ok = like( $@, $regex, $label ); 373 | return $ok; 374 | } 375 | 376 | #--------------------------------------------------------------------------# 377 | # cmp_deeply 378 | # 379 | # is_deeply with some better diagnostics 380 | #--------------------------------------------------------------------------# 381 | sub cmp_deeply { 382 | my ($got, $want, $label) = @_; 383 | local $Test::Builder::Level = $Test::Builder::Level + 1; 384 | is_deeply( $got, $want, $label ) 385 | or diag "GOT:\n", explain($got), "\nWANTED:\n", explain($want); 386 | } 387 | 388 | 1; 389 | -------------------------------------------------------------------------------- /t/lib/TestML/Tiny.pm: -------------------------------------------------------------------------------- 1 | use 5.008001; use strict; use warnings; 2 | package TestML::Tiny; 3 | 4 | $TestML::Tiny::VERSION = 0.000001; 5 | 6 | use Carp(); 7 | use Test::More 0.88 (); 8 | 9 | # use XXX; 10 | 11 | sub import { 12 | strict->import; 13 | warnings->import; 14 | } 15 | 16 | sub new { 17 | my $self = bless { @_[1..$#_] }, $_[0]; 18 | my $testml = $self->_get_testml; 19 | my $bridge = $self->_get_bridge; 20 | $self->{runtime} ||= TestML::Tiny::Runtime->new( 21 | bridge => $bridge, 22 | ); 23 | my $compiler = TestML::Tiny::Compiler->new( 24 | $self->{version} ? (version => $self->{version}) : (), 25 | ); 26 | $self->{function} = $compiler->compile($testml); 27 | return $self; 28 | } 29 | 30 | sub run { 31 | my ($self) = @_; 32 | my $runtime = $self->{runtime} || ''; 33 | Carp::croak "Missing or invalid runtime object for TestML::Tiny::run()" 34 | unless defined($runtime) and ref($runtime) eq 'TestML::Tiny::Runtime'; 35 | $runtime->run; 36 | } 37 | 38 | sub _get_testml { 39 | my ($self) = @_; 40 | my $testml = $self->{testml} 41 | or Carp::croak "TestML object requires a testml attribute"; 42 | $testml = $self->_slurp($testml) 43 | if $testml !~ /\n/; 44 | return $testml; 45 | } 46 | 47 | sub _get_bridge { 48 | my ($self) = @_; 49 | my $bridge = $self->{bridge} || 'main'; 50 | return $bridge if ref $bridge; 51 | eval "require $bridge"; 52 | Carp::croak $@ if $@ and $@ !~ /^Can't locate /; 53 | return ( 54 | defined(&{"${bridge}::new"}) 55 | ? $bridge->new 56 | : bless {}, $bridge 57 | ); 58 | } 59 | 60 | sub _slurp { 61 | open my $fh, "<:raw:encoding(UTF-8)", $_[1] 62 | or die "Can't open $_[1] for input"; 63 | local $/; 64 | <$fh>; 65 | } 66 | 67 | #------------------------------------------------------------------------------ 68 | =comment 69 | 70 | =for :stopwords TestML 71 | 72 | ::Runtime -- Run a TestML Function 73 | 74 | The TestML Code and Data get compiled into a Function, and the Function is run 75 | by this Runtime class. Typically data is manipulated by Bridge functions, and 76 | at some point Assertions are made. The assertions are the things that call 77 | Test::More::is and Test::More::ok. 78 | =cut 79 | 80 | package TestML::Tiny::Runtime; 81 | 82 | # use XXX; 83 | 84 | sub new { 85 | my $self = $TestML::Tiny::Runtime::Singleton = 86 | bless { @_[1..$#_] }, $_[0]; 87 | }; 88 | 89 | sub run { 90 | Test::More::fail 'not done yet!'; 91 | Test::More::done_testing; 92 | } 93 | 94 | #------------------------------------------------------------------------------ 95 | =comment 96 | ::Compiler -- Turn a TestML document into a runnable TestML Function. 97 | 98 | A TestML "document" is comprised of 3 main parts: Meta, Code, Data. This 99 | information often is in a single TestML (F<.tml>) file or string, but it doesn't 100 | need to be. The information can come from anywhere and be in any form that is 101 | supported; it just must all be present when it is needed. 102 | 103 | The Meta information must be known first. It dictates where the Code and Data 104 | come from, and in what format they are. Also the Code and Data formats depend 105 | on the TestML API Version that is supplied. Before the Code and Data can be 106 | compiled, a Version must be supplied (no default) and then the compiler must 107 | support that Version. This allows TestML to change over time with no 108 | confusion. 109 | 110 | The compile function returns a Function object, which in turn contains an 111 | array of Statements and an array of Data Blocks. This function is the run by 112 | the Runtime object. 113 | =cut 114 | package TestML::Tiny::Compiler; 115 | 116 | # use XXX; 117 | 118 | my $ID = qr/\w+/; 119 | my $SP = qr/[\ \t]/; 120 | my $LINE = qr/.*$/m; 121 | my $DIRECTIVE = qr/^%($ID)$SP+($LINE)/m; 122 | 123 | sub new { 124 | my $self = bless { @_[1..$#_] }, $_[0]; 125 | } 126 | 127 | sub runtime { 128 | $TestML::Tiny::Runtime::Singleton; 129 | } 130 | 131 | sub compile { 132 | my ($self, $testml) = @_; 133 | my $function = $self->{function} = TestML::Tiny::Function->new; 134 | $self->{testml} = $testml; 135 | $self->preprocess; 136 | my $version = $self->check_version; 137 | my ($code_syntax, $data_syntax) = 138 | @{$self}{qw(code_syntax data_syntax)}; 139 | my $code_method = "compile_code_${code_syntax}_$version"; 140 | Carp::croak "Don't know how to compile TestML '$code_syntax' code" 141 | unless $self->can($code_method); 142 | my $data_method = "compile_data_${data_syntax}_$version"; 143 | Carp::croak "Don't know how to compile TestML '$data_syntax' data" 144 | unless $self->can($data_method); 145 | $function->{statements} = $self->$code_method; 146 | $function->{data} = $self->$data_method; 147 | return $function; 148 | } 149 | 150 | my %directives = ( 151 | code_syntax => 'tiny', 152 | data_syntax => 'testml', 153 | data_marker => '===', 154 | block_marker => '===', 155 | point_marker => '---', 156 | ); 157 | sub preprocess { 158 | my ($self) = @_; 159 | 160 | my $version = $self->{version} || undef; 161 | my $testml = $self->{testml}; 162 | my $directives = [ $testml =~ /$DIRECTIVE/gm ]; 163 | $testml =~ s/($DIRECTIVE)/#$1/g; 164 | while (@$directives) { 165 | my ($key, $value) = splice(@$directives, 0, 2); 166 | if ($key eq "TestML") { 167 | $self->check_not_set_and_set($key, $value, 'version'); 168 | } 169 | elsif ($key eq "BlockMarker") { 170 | $self->check_not_set_and_set( 171 | 'BlockMarker', $value, 'block_marker' 172 | ); 173 | ($self->{block_marker} = $value) =~ 174 | s/([\*\^\$\+\?\(\)\.])/\\$1/g; 175 | } 176 | elsif ($key eq "PointMarker") { 177 | $self->check_not_set_and_set( 178 | 'PointMarker', $value, 'point_marker' 179 | ); 180 | ($self->{point_marker} = $value) =~ 181 | s/([\*\^\$\+\?\(\)\.])/\\$1/g; 182 | } 183 | elsif ($key eq "CodeSyntax") { 184 | die "Untested"; 185 | $self->check_not_set_and_set( 186 | 'CodeSyntax', $value, 'code_syntax' 187 | ); 188 | $self->{code_syntax} = $value; 189 | } 190 | elsif ($key eq "DataSyntax") { 191 | die "Untested"; 192 | $self->check_not_set_and_set( 193 | 'DataSyntax', $value, 'data_syntax' 194 | ); 195 | $self->{data_syntax} = $value; 196 | } 197 | else { 198 | Carp::croak "Unknown TestML directive: '%$key'"; 199 | } 200 | } 201 | $self->{data_marker} = $self->{block_marker} 202 | if not($self->{data_marker}) and $self->{block_marker}; 203 | for my $directive (keys %directives) { 204 | $self->{$directive} ||= $directives{$directive}; 205 | } 206 | 207 | ($self->{code}, $self->{data}) = 208 | ($testml =~ /(.*?)(^$self->{data_marker}.*)/msg); 209 | $self->{code} ||= ''; 210 | $self->{data} ||= ''; 211 | } 212 | 213 | sub check_not_set_and_set { 214 | my ($self, $key, $value, $attr) = @_; 215 | if (defined $self->{$attr} and $self->{$attr} ne $value) { 216 | Carp::croak "Can't set TestML '$key' directive to '$value'. " . 217 | "Already set to '$self->{$attr}'"; 218 | } 219 | $self->{$attr} = $value; 220 | } 221 | 222 | sub check_version { 223 | my ($self) = @_; 224 | my $version = $self->{version} || undef; 225 | Carp::croak "TestML syntax version not defined. Cannot continue" 226 | unless defined $version; 227 | Carp::croak "Invalid value for TestML version '$version'. Must be 0.1.0" 228 | unless $version eq '0.1.0'; 229 | $version =~ s/\./_/g; 230 | return $version; 231 | } 232 | 233 | sub compile_code_tiny_0_1_0 { 234 | my ($self) = @_; 235 | my $num = 1; 236 | [ grep { not /(^#|^\s*$)/ } split /\n/, $self->{code} ]; 237 | } 238 | 239 | sub compile_data_testml_0_1_0 { 240 | my ($self) = @_; 241 | 242 | my $lines = [ grep { ! /^#/ } split /\n/, $self->{data} ]; 243 | 244 | my $blocks = []; 245 | my $parse = []; 246 | push @$lines, undef; # sentinel 247 | while (@$lines) { 248 | push @$parse, shift @$lines; 249 | if (!defined($lines->[0]) or 250 | $lines->[0] =~ /^$self->{block_marker}/ 251 | ) { 252 | my $block = $self->_parse_testml_block($parse); 253 | push @$blocks, $block 254 | unless exists $block->{SKIP}; 255 | last if exists $block->{LAST}; 256 | $parse = []; # clear for next parse 257 | } 258 | last if !defined($lines->[0]); 259 | } 260 | 261 | my $only = [ grep { exists $_->{ONLY} } @$blocks ]; 262 | 263 | return @$only ? $only : $blocks; 264 | } 265 | 266 | sub _parse_testml_block { 267 | my ($self, $lines) = @_; 268 | 269 | my ($label) = $lines->[0] =~ /^$self->{block_marker}(?:\s+(.*))?$/; 270 | shift @$lines until not(@$lines) or 271 | $lines->[0] =~ /^$self->{point_marker} +\w+/; 272 | 273 | my $block = $self->_parse_testml_points($lines); 274 | $block->{Label} = $label || ''; 275 | 276 | return $block; 277 | } 278 | 279 | sub _parse_testml_points { 280 | my ($self, $lines) = @_; 281 | 282 | my $block = {}; 283 | 284 | while (@$lines) { 285 | my $line = shift @$lines; 286 | $line =~ /^$self->{point_marker} +(\w+)/ 287 | or die "Invalid TestML line:\n'$line'"; 288 | my $point_name = $1; 289 | die "$block repeats $point_name" 290 | if exists $block->{$point_name}; 291 | $block->{$point_name} = ''; 292 | if ($line =~ /^$self->{point_marker} +(\w+): +(.*?) *$/) { 293 | ($block->{$1} = $2) =~ s/^ *(.*?) *$/$1/; 294 | shift @$lines while @$lines and 295 | $lines->[0] !~ /^$self->{point_marker} +(\w)/; 296 | } 297 | elsif ($line =~ /^$self->{point_marker} +(\w+)$/) { 298 | $point_name = $1; 299 | while ( @$lines ) { 300 | $line = shift @$lines; 301 | if ($line =~ /^$self->{point_marker} \w+/) { 302 | unshift @$lines, $line; 303 | last; 304 | } 305 | $block->{$point_name} .= "$line\n"; 306 | } 307 | $block->{$point_name} =~ s/\n\s*\z/\n/; 308 | $block->{$point_name} =~ s/^\\//gm; 309 | } 310 | else { 311 | die "Invalid TestML line:\n'$line'"; 312 | } 313 | } 314 | return $block; 315 | } 316 | 317 | #------------------------------------------------------------------------------ 318 | =comment 319 | A Function is just an array of "executable" statements that are proceseded in 320 | order. Some of the statements maybe be function declarations and function 321 | calls. The Compiler produces a top level scope function, with a Data set, and a 322 | Namespace for variables. 323 | 324 | All functions are anonymous, but they can be assigned to variables, and then 325 | you can call that variable name. 326 | =cut 327 | package TestML::Tiny::Function; 328 | 329 | sub new { 330 | my $self = bless { 331 | statements => [], 332 | data => [], 333 | namespace => {}, 334 | }, $_[0]; 335 | } 336 | 337 | #------------------------------------------------------------------------------ 338 | package TestML::Tiny::Bridge; 339 | 340 | sub new { 341 | my $self = bless { @_[1..$#_] }, $_[0]; 342 | } 343 | 344 | #------------------------------------------------------------------------------ 345 | package TestML::Tiny::Library::Standard; 346 | 347 | sub new { 348 | my $self = bless { @_[1..$#_] }, $_[0]; 349 | } 350 | 351 | 1; 352 | -------------------------------------------------------------------------------- /t/lib/TestUtils.pm: -------------------------------------------------------------------------------- 1 | package TestUtils; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Exporter (); 7 | use File::Spec (); 8 | use File::Find (); 9 | 10 | our @ISA = qw{ Exporter }; 11 | our @EXPORT = qw{ 12 | find_tml_files 13 | json_class 14 | slurp 15 | test_data_directory 16 | test_data_file 17 | }; 18 | 19 | sub find_tml_files { 20 | my $dir = shift; 21 | my @files; 22 | File::Find::find( 23 | sub { push @files, $File::Find::name if -f and /\.tml$/ }, 24 | $dir 25 | ); 26 | return @files; 27 | } 28 | 29 | sub json_class { 30 | return eval { require JSON::MaybeXS; JSON::MaybeXS->VERSION('1.001000'); $JSON::MaybeXS::JSON_Class } 31 | || do { require JSON::PP; 'JSON::PP' }; 32 | } 33 | 34 | sub test_data_directory { 35 | return File::Spec->catdir( 't', 'data' ); 36 | } 37 | 38 | sub test_data_file { 39 | return File::Spec->catfile( test_data_directory(), shift ); 40 | } 41 | 42 | sub slurp { 43 | my $file = shift; 44 | local $/ = undef; 45 | open( FILE, " $file" ) or die "open($file) failed: $!"; 46 | binmode( FILE, $_[0] ) if @_ > 0; 47 | # binmode(FILE); # disable perl's BOM interpretation 48 | my $source = ; 49 | close( FILE ) or die "close($file) failed: $!"; 50 | $source; 51 | } 52 | 53 | 1; 54 | -------------------------------------------------------------------------------- /t/tml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use strict; 3 | use warnings; 4 | use lib 'lib', 't/lib/'; 5 | use Test::More 0.88; 6 | use SubtestCompat; 7 | use Getopt::Long qw/:config passthrough/; 8 | use List::Util qw/first/; 9 | use TestBridge; 10 | use TestUtils; 11 | 12 | #--------------------------------------------------------------------------# 13 | # Note: This program is both the proxy to select .tml files for 'prove' and the 14 | # test-runner that 'prove' executes. 15 | #--------------------------------------------------------------------------# 16 | 17 | # match path prefix under t/ 18 | my %BRIDGE_MAP = ( 19 | 'tml-local/dump-error' => \&test_dump_error, 20 | 'tml-local/load-error' => \&test_load_error, 21 | 'tml-local/load-warning' => \&test_load_warning, 22 | 'tml-local/perl-to-yaml' => \&test_perl_to_yaml, 23 | 'tml-local/yaml-roundtrip' => \&test_yaml_roundtrip, 24 | 'tml-spec/basic-data.tml' => \&test_yaml_json, 25 | 'tml-spec/unicode.tml' => \&test_code_point, 26 | 'tml-world' => \&test_yaml_roundtrip, 27 | ); 28 | 29 | sub main { 30 | my ($verbose, $run_tests); 31 | GetOptions( 32 | 'run_test' => \$run_tests, 33 | ); 34 | 35 | if ( $run_tests ) { 36 | my $file = shift @ARGV; 37 | exit 0 unless -f $file; 38 | my ($bridge) = first { $file =~ m{^t/\Q$_} } keys %BRIDGE_MAP; 39 | die "No bridge found for $file" unless $bridge; 40 | 41 | run_testml_file( 42 | $file, 43 | sub { 44 | my ($file, $blocks) = @_; 45 | subtest "TestML dev runner: $file" => sub { 46 | $BRIDGE_MAP{$bridge}->($_) for @$blocks; 47 | }; 48 | done_testing; 49 | }, 50 | ); 51 | } 52 | else { 53 | my (@opts, @files, @patterns); 54 | for (@ARGV) { 55 | if ( /^-/ ) { 56 | push @opts, $_; 57 | } 58 | elsif ( -f ) { 59 | push @files, $_; 60 | } 61 | else { 62 | push @patterns, $_; 63 | } 64 | } 65 | 66 | # if we got no files or patterns, treat that as taking anything 67 | @patterns = "." if !@patterns && !@files; 68 | 69 | if (@patterns) { 70 | FILE: for my $file ( find_tml_files('t') ) { 71 | if ( first { $file =~ /$_/ } @patterns ) { 72 | push @files, $file; 73 | } 74 | } 75 | } 76 | 77 | exec( 'prove', @opts, '--exec', "$0 --run_test", @files ) 78 | if @files; 79 | } 80 | } 81 | 82 | main; 83 | 84 | __END__ 85 | 86 | =head1 NAME 87 | 88 | =for stopwords tml 89 | 90 | t/tml - run .tml files matching a pattern 91 | 92 | =head1 SYNOPSIS 93 | 94 | t/tml [prove options] [patterns] 95 | 96 | =head1 USAGE 97 | 98 | This program runs F against a set of F<.tml> files using their 99 | corresponding test bridge functions. 100 | 101 | Any arguments beginning with C<-> will be passed through to F. All 102 | other arguments will be used as patterns to select F<.tml> files found anywhere 103 | under the F directory. You can use shell globbing syntax, and let the shell 104 | expand the patterns, or you can quote/escape the patterns and let them be 105 | treated as Perl regular expressions. 106 | 107 | For example: 108 | 109 | t/tml unicode # paths matching qr/unicode/ 110 | t/tml basic uni # paths matching qr/basic/ or qr/uni/ 111 | t/tml 'local.*re' # paths matching qr/local.*re/ 112 | t/tml '\d+' # paths matching qr/\d+/ 113 | 114 | Examples of options for prove: 115 | 116 | t/tml -v quoting # verbose run of paths matching qr/quoting/ 117 | t/tml -j9 world # parallel run of paths matching qr/world/ 118 | t/tml -j9 # parallel run of all .tml files 119 | 120 | =cut 121 | -------------------------------------------------------------------------------- /t/tml-local/dump-error/circular.tml: -------------------------------------------------------------------------------- 1 | === Circular Reference Protection 2 | # When we try to serialize, it should NOT infinite loop 3 | --- perl 4 | $VAR1 = [ 5 | { 6 | 'a' => 'b', 7 | 'c' => [ 8 | {}, 9 | 2 10 | ] 11 | }, 12 | [] 13 | ]; 14 | $VAR1->[0]{'c'}[0] = $VAR1->[0]; 15 | $VAR1->[1] = $VAR1->[0]{'c'}; 16 | [ $VAR1 ] 17 | 18 | --- error: E_CIRCULAR 19 | -------------------------------------------------------------------------------- /t/tml-local/load-error/document.tml: -------------------------------------------------------------------------------- 1 | === scalar document followed by mapping 2 | --- yaml 3 | \--- foo 4 | a: 1 5 | --- error: E_CLASSIFY 6 | -------------------------------------------------------------------------------- /t/tml-local/load-error/scalar.tml: -------------------------------------------------------------------------------- 1 | === multiline quote 2 | --- yaml 3 | - 'Multiline 4 | quote' 5 | --- error: E_FEATURE 6 | 7 | === dash dash 2 8 | --- yaml 9 | - - 2 10 | --- error: E_PLAIN 11 | 12 | === dash 13 | --- yaml 14 | foo: - 15 | --- error: E_PLAIN 16 | 17 | === leading ampersand 18 | --- yaml 19 | foo: @INC 20 | --- error: E_PLAIN 21 | 22 | === leading percent 23 | --- yaml 24 | foo: %INC 25 | --- error: E_PLAIN 26 | 27 | === trailing colon 28 | --- yaml 29 | foo: bar: 30 | --- error: E_PLAIN 31 | 32 | === key key value 33 | --- yaml 34 | foo: bar: baz 35 | --- error: E_PLAIN 36 | 37 | === backticks 38 | --- yaml 39 | foo: `perl -V` 40 | --- error: E_PLAIN 41 | 42 | === double-dash 43 | --- yaml 44 | -- 45 | --- error: E_PLAIN 46 | 47 | === multi-line scalar document starting on header 48 | --- yaml 49 | \--- foo 50 | bar 51 | --- error: E_CLASSIFY 52 | -------------------------------------------------------------------------------- /t/tml-local/load-error/tag.tml: -------------------------------------------------------------------------------- 1 | === version object 2 | --- yaml 3 | \--- 4 | version: !!perl/hash:version 5 | original: v2.0.2 6 | qv: 1 7 | version: 8 | - 2 9 | - 0 10 | - 2 11 | --- error: E_FEATURE 12 | -------------------------------------------------------------------------------- /t/tml-local/load-warning/document.tml: -------------------------------------------------------------------------------- 1 | === mapping with double key 2 | --- yaml 3 | foo: 1 4 | foo: 2 5 | --- warning: E_DUPKEY 6 | -------------------------------------------------------------------------------- /t/tml-local/perl-to-yaml/quoting.tml: -------------------------------------------------------------------------------- 1 | === Quote boolean-like string (scalar) 2 | # Strings that could be confused with booleans should be quoted 3 | --- perl 4 | [ 'true' ] 5 | 6 | --- yaml 7 | \--- 'true' 8 | 9 | === Quote boolean-like string (list) 10 | --- perl 11 | [ [ qw{ null true false } ] ] 12 | 13 | --- yaml 14 | \--- 15 | - 'null' 16 | - 'true' 17 | - 'false' 18 | 19 | === Quote scalars ending in colon 20 | --- perl 21 | [ [ 'A:' ] ] 22 | 23 | --- yaml 24 | \--- 25 | - 'A:' 26 | 27 | -------------------------------------------------------------------------------- /t/tml-local/yaml-roundtrip/collection.tml: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------# 2 | # This file is for testing combinations of sequences and mappings 3 | #--------------------------------------------------------------------------# 4 | 5 | ##################################################################### 6 | # Null HASH/ARRAY 7 | 8 | === null hash in array 9 | --- yaml 10 | --- 11 | - foo 12 | - {} 13 | - bar 14 | --- perl 15 | [ [ 'foo', {}, 'bar' ] ] 16 | 17 | 18 | === null array in array 19 | --- yaml 20 | --- 21 | - foo 22 | - [] 23 | - bar 24 | --- perl 25 | [ [ 'foo', [], 'bar' ] ] 26 | 27 | 28 | === null hash in hash 29 | --- yaml 30 | --- 31 | foo: {} 32 | bar: 1 33 | --- perl 34 | [ { foo => {}, bar => 1 } ] 35 | 36 | 37 | === null array in hash 38 | --- yaml 39 | --- 40 | foo: [] 41 | bar: 1 42 | --- perl 43 | [ { foo => [], bar => 1 } ] 44 | 45 | # Simple array inside a hash with an undef 46 | === array_in_hash 47 | --- yaml 48 | --- 49 | foo: 50 | - bar 51 | - ~ 52 | - baz 53 | 54 | --- perl 55 | [ { foo => [ 'bar', undef, 'baz' ] } ] 56 | 57 | 58 | # Simple hash inside a hash with an undef 59 | === hash_in_hash 60 | --- yaml 61 | --- 62 | foo: ~ 63 | bar: 64 | foo: bar 65 | 66 | --- perl 67 | [ { foo => undef, bar => { foo => 'bar' } } ] 68 | 69 | 70 | # Mixed hash and scalars inside an array 71 | === hash_in_array 72 | --- yaml 73 | --- 74 | - 75 | foo: ~ 76 | this: that 77 | - foo 78 | - ~ 79 | - 80 | foo: bar 81 | this: that 82 | 83 | --- perl 84 | [ [ 85 | { foo => undef, this => 'that' }, 86 | 'foo', 87 | undef, 88 | { foo => 'bar', this => 'that' }, 89 | ] ] 90 | 91 | 92 | ###################################################################### 93 | # Non-Indenting Sub-List 94 | 95 | === Non-indenting sub-list 96 | --- yaml 97 | --- 98 | foo: 99 | - list 100 | bar: value 101 | --- perl 102 | [ { foo => [ 'list' ], bar => 'value' } ] 103 | --- noyamlpm 104 | 105 | 106 | 107 | # Inline nested hash 108 | === inline_nested_hash 109 | --- yaml 110 | --- 111 | - ~ 112 | - foo: bar 113 | this: that 114 | - baz 115 | 116 | --- perl 117 | [ [ undef, { foo => 'bar', this => 'that' }, 'baz' ] ] 118 | 119 | 120 | # RT 51491 121 | === space after hypen 122 | --- yaml 123 | \--- 124 | FOO: 125 | - 126 | bar: baz 127 | --- perl 128 | [ { 'FOO' => [ { bar => 'baz' } ] } ] 129 | 130 | # RT 92916 (a Test::Database ticket) 131 | === colon at end of key 132 | --- yaml 133 | \--- 134 | dbi:SQLite:: 135 | foo: bar 136 | --- perl 137 | [ { 'dbi:SQLite:' => { 'foo' => 'bar' } } ] 138 | -------------------------------------------------------------------------------- /t/tml-local/yaml-roundtrip/comment.tml: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # Main Tests 3 | 4 | === Properly ignore comments 5 | --- yaml 6 | --- 7 | a: b#content 8 | c: d #comment 9 | e: 10 | - f #comment 11 | - g# content 12 | h: 'single' # comment 13 | h2: 'single # content' # comment 14 | i: "double" # comment 15 | i2: "double # content" # comment 16 | j: | # comment 17 | literal # content 18 | block # content 19 | k: {} # comment 20 | l: [] # comment 21 | m: # comment 22 | n: o 23 | --- perl 24 | [ 25 | { 26 | a => 'b#content', 27 | c => 'd', 28 | e => [ 29 | 'f', 30 | 'g# content', 31 | ], 32 | h => 'single', 33 | h2 => 'single # content', 34 | i => 'double', 35 | i2 => 'double # content', 36 | j => "literal # content\nblock # content\n", 37 | k => {}, 38 | l => [], 39 | m => { 40 | n => 'o', 41 | }, 42 | }, 43 | ] 44 | --- noyamlpm 45 | 46 | 47 | # Repeat, with otherwise illegal characters in the comments 48 | === Properly ignore comments (with otherwise illegal characters) 49 | --- yaml 50 | --- 51 | a: b#content 52 | c: d #comment '"!&@%` 53 | e: 54 | - f #comment '"!&@%` 55 | - g# content 56 | h: 'single' # comment '"!&@%` 57 | h2: 'single # content' # comment '"!&@%` 58 | i: "double" # comment '"!&@%` 59 | i2: "double # content" # comment '"!&@%` 60 | j: | # comment '"!&@%` 61 | literal # content 62 | block # content 63 | k: {} # comment '"!&@%` 64 | l: [] # comment '"!&@%` 65 | m: # comment '"!&@%` 66 | n: o 67 | --- perl 68 | [ 69 | { 70 | a => 'b#content', 71 | c => 'd', 72 | e => [ 73 | 'f', 74 | 'g# content', 75 | ], 76 | h => 'single', 77 | h2 => 'single # content', 78 | i => 'double', 79 | i2 => 'double # content', 80 | j => "literal # content\nblock # content\n", 81 | k => {}, 82 | l => [], 83 | m => { 84 | n => 'o', 85 | }, 86 | }, 87 | ] 88 | --- noyamlpm 89 | 90 | #################################################################### 91 | # Comment on the Document Line 92 | 93 | === comment header 94 | --- yaml 95 | --- # Comment 96 | foo: bar 97 | --- perl 98 | [ { foo => 'bar' } ] 99 | --- noyamlpm 100 | 101 | 102 | # Empty comments 103 | === empty_comment_in_list 104 | --- yaml 105 | --- 106 | - foo 107 | \# 108 | - bar 109 | 110 | --- perl 111 | [ [ 'foo', 'bar' ] ] 112 | 113 | 114 | === empty_comment_in_hash 115 | --- yaml 116 | --- 117 | foo: bar 118 | \# foo 119 | one: two 120 | 121 | --- perl 122 | [ { foo => 'bar', one => 'two' } ] 123 | 124 | 125 | -------------------------------------------------------------------------------- /t/tml-local/yaml-roundtrip/document.tml: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # Support for YAML version directives 3 | 4 | # Simple inline case (comment variant) 5 | === simple_doctype_comment 6 | --- yaml 7 | --- #YAML:1.0 8 | foo: bar 9 | --- perl 10 | [ { foo => 'bar' } ] 11 | --- nosyck 12 | 13 | 14 | # Simple inline case (percent variant) 15 | === simple_doctype_percent 16 | --- yaml 17 | --- %YAML:1.0 18 | foo: bar 19 | --- perl 20 | [ { foo => 'bar' } ] 21 | --- noyamlpm 22 | --- noxs 23 | 24 | 25 | # Simple header (comment variant) 26 | === predocument_1_0 27 | --- yaml 28 | \%YAML:1.0 29 | --- 30 | foo: bar 31 | --- perl 32 | [ { foo => 'bar' } ] 33 | --- noyamlpm 34 | --- nosyck 35 | --- noxs 36 | 37 | 38 | # Simple inline case (comment variant) 39 | === predocument_1_1 40 | --- yaml 41 | \%YAML 1.1 42 | --- 43 | foo: bar 44 | --- perl 45 | [ { foo => 'bar' } ] 46 | --- noyamlpm 47 | --- nosyck 48 | 49 | 50 | # Multiple inline documents (comment variant) 51 | === multi_doctype_comment 52 | --- yaml 53 | --- #YAML:1.0 54 | foo: bar 55 | --- #YAML:1.0 56 | - 1 57 | --- #YAML:1.0 58 | foo: bar 59 | --- perl 60 | [ { foo => 'bar' }, [ 1 ], { foo => 'bar' } ] 61 | 62 | 63 | # Simple pre-document case (comment variant) 64 | === predocument_percent 65 | --- yaml 66 | \%YAML 1.1 67 | --- 68 | foo: bar 69 | --- perl 70 | [ { foo => 'bar' } ] 71 | --- noyamlpm 72 | --- nosyck 73 | 74 | 75 | # Simple pre-document case (comment variant) 76 | === predocument_comment 77 | --- yaml 78 | \#YAML 1.1 79 | --- 80 | foo: bar 81 | --- perl 82 | [ { foo => 'bar' } ] 83 | 84 | 85 | === two documents 86 | --- yaml 87 | \--- 88 | - foo 89 | \--- 90 | - bar 91 | --- perl 92 | [ [ 'foo' ], [ 'bar' ] ] 93 | 94 | # Document ending (hash) 95 | === document_end_hash 96 | --- yaml 97 | --- 98 | foo: bar 99 | ... 100 | --- perl 101 | [ { foo => "bar" } ] 102 | --- noyamlpm 103 | --- nosyck 104 | 105 | 106 | # Document ending (array) 107 | === document_end_array 108 | --- yaml 109 | --- 110 | - foo 111 | ... 112 | --- perl 113 | [ [ 'foo' ] ] 114 | --- noyamlpm 115 | 116 | 117 | # Multiple documents (simple) 118 | === multi_document_simple 119 | --- yaml 120 | --- 121 | - foo 122 | ... 123 | --- 124 | - foo 125 | ... 126 | --- perl 127 | [ [ 'foo' ], [ 'foo' ] ] 128 | --- noyamlpm 129 | 130 | 131 | # Multiple documents (whitespace-separated) 132 | === multi_document_space 133 | --- yaml 134 | --- 135 | - foo 136 | ... 137 | 138 | --- 139 | - foo 140 | ... 141 | --- perl 142 | [ [ 'foo' ], [ 'foo' ] ] 143 | --- noyamlpm 144 | 145 | ##################################################################### 146 | # Sample Testing 147 | 148 | # Test a completely empty document 149 | === empty 150 | --- yaml 151 | --- perl 152 | [ ] 153 | 154 | 155 | # Just a newline 156 | ### YAML.pm has a bug where it dies on a single newline 157 | === only_newlines 158 | --- yaml 159 | \ 160 | \ 161 | --- perl 162 | [ ] 163 | 164 | 165 | # Just a comment 166 | === only_comment 167 | --- yaml 168 | \# comment 169 | --- perl 170 | [ ] 171 | 172 | 173 | # Empty documents 174 | === only_header 175 | --- yaml 176 | --- 177 | 178 | --- perl 179 | [ undef ] 180 | 181 | 182 | === two_header 183 | --- yaml 184 | --- 185 | --- 186 | 187 | --- perl 188 | [ undef, undef ] 189 | 190 | 191 | === one_undef 192 | --- yaml 193 | --- ~ 194 | 195 | --- perl 196 | [ undef ] 197 | 198 | 199 | === one_undef2 200 | --- yaml 201 | --- ~ 202 | --- perl 203 | [ undef ] 204 | 205 | 206 | === two_undef 207 | --- yaml 208 | --- ~ 209 | --- 210 | 211 | --- perl 212 | [ undef, undef ] 213 | 214 | 215 | -------------------------------------------------------------------------------- /t/tml-local/yaml-roundtrip/mapping.tml: -------------------------------------------------------------------------------- 1 | === Empty mapping 2 | --- yaml 3 | \--- {} 4 | --- perl 5 | [ {} ] 6 | 7 | # Simple hashs 8 | === one_hash1 9 | --- yaml 10 | --- 11 | foo: bar 12 | 13 | --- perl 14 | [ { foo => 'bar' } ] 15 | 16 | 17 | === one_hash2 18 | --- yaml 19 | --- 20 | foo: bar 21 | this: ~ 22 | 23 | --- perl 24 | [ { this => undef, foo => 'bar' } ] 25 | 26 | 27 | === one_hash3 28 | --- yaml 29 | --- 30 | -foo: bar 31 | 32 | --- perl 33 | [ { '-foo' => 'bar' } ] 34 | 35 | 36 | # Implicit document start 37 | === implicit_hash 38 | --- yaml 39 | foo: bar 40 | 41 | --- perl 42 | [ { foo => 'bar' } ] 43 | 44 | 45 | 46 | # Make sure we support x-foo keys 47 | === x-foo key 48 | --- yaml 49 | --- 50 | x-foo: 1 51 | --- perl 52 | [ { 'x-foo' => 1 } ] 53 | 54 | 55 | # Hash key legally containing a colon 56 | === module_hash_key 57 | --- yaml 58 | --- 59 | Foo::Bar: 1 60 | --- perl 61 | [ { 'Foo::Bar' => 1 } ] 62 | 63 | 64 | # Hash indented 65 | === hash_indented 66 | --- yaml 67 | --- 68 | foo: bar 69 | --- perl 70 | [ { foo => "bar" } ] 71 | 72 | ##################################################################### 73 | # Empty Values and Premature EOF 74 | 75 | === empty hash keys 76 | --- yaml 77 | --- 78 | foo: 0 79 | requires: 80 | build_requires: 81 | --- perl 82 | [ { foo => 0, requires => undef, build_requires => undef } ] 83 | --- noyamlpm 84 | 85 | ##################################################################### 86 | # Confirm we can read the synopsis 87 | 88 | === synopsis 89 | --- yaml 90 | --- 91 | rootproperty: blah 92 | section: 93 | one: two 94 | three: four 95 | Foo: Bar 96 | empty: ~ 97 | --- perl 98 | [ { 99 | rootproperty => 'blah', 100 | section => { 101 | one => 'two', 102 | three => 'four', 103 | Foo => 'Bar', 104 | empty => undef, 105 | }, 106 | } ] 107 | 108 | ##################################################################### 109 | # Indentation after empty hash value 110 | 111 | === Indentation after empty hash value 112 | --- yaml 113 | --- 114 | Test: 115 | optmods: 116 | Bad: 0 117 | Foo: 1 118 | Long: 0 119 | version: 5 120 | Test_IncludeA: 121 | optmods: 122 | Test_IncludeB: 123 | optmods: 124 | _meta: 125 | name: 'test profile' 126 | note: 'note this test profile' 127 | --- perl 128 | [ { 129 | Test => { 130 | optmods => { 131 | Bad => 0, 132 | Foo => 1, 133 | Long => 0, 134 | }, 135 | version => 5, 136 | }, 137 | Test_IncludeA => { 138 | optmods => undef, 139 | }, 140 | Test_IncludeB => { 141 | optmods => undef, 142 | }, 143 | _meta => { 144 | name => 'test profile', 145 | note => 'note this test profile', 146 | }, 147 | } ] 148 | 149 | 150 | ##################################################################### 151 | # Spaces in the Key 152 | 153 | === spaces in the key 154 | --- yaml 155 | --- 156 | the key: the value 157 | --- perl 158 | [ { 'the key' => 'the value' } ] 159 | 160 | 161 | # Complex keys 162 | === key_with_whitespace 163 | --- yaml 164 | --- 165 | a b: c d 166 | 167 | --- perl 168 | [ { 'a b' => 'c d' } ] 169 | 170 | === quoted_empty_key 171 | --- yaml 172 | --- 173 | '': foo 174 | 175 | --- perl 176 | [ { '' => 'foo' } ] 177 | 178 | 179 | -------------------------------------------------------------------------------- /t/tml-local/yaml-roundtrip/quoting.tml: -------------------------------------------------------------------------------- 1 | === Empty double-quote 2 | --- yaml 3 | \--- 4 | - "" 5 | --- perl 6 | [ [ "" ] ] 7 | 8 | # Simple single quote 9 | === single_quote1 10 | --- yaml 11 | --- 12 | - 'foo' 13 | 14 | --- perl 15 | [ [ 'foo' ] ] 16 | 17 | 18 | === single_spaces 19 | --- yaml 20 | --- 21 | - ' ' 22 | --- perl 23 | [ [ ' ' ] ] 24 | 25 | 26 | === single_null 27 | --- yaml 28 | --- 29 | - '' 30 | 31 | --- perl 32 | [ [ '' ] ] 33 | 34 | 35 | # Double quotes 36 | === only_spaces 37 | --- noyamlpm 38 | --- yaml 39 | --- " " 40 | 41 | --- perl 42 | [ ' ' ] 43 | 44 | 45 | === leading_trailing_spaces 46 | --- noyamlpm 47 | --- yaml 48 | --- " foo" 49 | --- "bar " 50 | 51 | --- perl 52 | [ " foo", "bar " ] 53 | 54 | === single quotes in double quotes 55 | --- yaml 56 | \--- "'foo'" 57 | --- perl 58 | [ "'foo'" ] 59 | 60 | === double quotes in single quotes 61 | --- yaml 62 | \--- '"foo"' 63 | --- perl 64 | [ '"foo"' ] 65 | 66 | ##################################################################### 67 | # Quote vs Hash 68 | 69 | === hash-like quote 70 | --- yaml 71 | --- 72 | author: 73 | - 'mst: Matt S. Trout ' 74 | --- perl 75 | [ { author => [ 'mst: Matt S. Trout ' ] } ] 76 | 77 | ##################################################################### 78 | # Quote and Escaping Idiosyncracies 79 | 80 | === single quote subtleties 81 | --- yaml 82 | --- 83 | name1: 'O''Reilly' 84 | name2: 'O''Reilly O''Tool' 85 | name3: 'Double '''' Quote' 86 | --- perl 87 | [ { 88 | name1 => "O'Reilly", 89 | name2 => "O'Reilly O'Tool", 90 | name3 => "Double '' Quote", 91 | } ] 92 | 93 | 94 | === single quote subtleties 95 | --- yaml 96 | --- 97 | slash1: '\\' 98 | slash2: '\\foo' 99 | slash3: '\\foo\\\\' 100 | --- perl 101 | [ { 102 | slash1 => "\\\\", 103 | slash2 => "\\\\foo", 104 | slash3 => "\\\\foo\\\\\\\\", 105 | } ] 106 | 107 | ##################################################################### 108 | # Check Multiple-Escaping 109 | 110 | # RT #42119: write of two single quotes 111 | === Multiple escaping of quote ok 112 | --- yaml 113 | --- "A'B'C" 114 | --- perl 115 | [ "A'B'C" ] 116 | 117 | 118 | # Escapes without whitespace 119 | === Multiple escaping of escape ok 120 | --- yaml 121 | \--- A\B\C 122 | --- perl 123 | [ "A\\B\\C" ] 124 | 125 | 126 | # Escapes with whitespace 127 | === Multiple escaping of escape with whitespace ok 128 | --- yaml 129 | --- 'A\B \C' 130 | --- perl 131 | [ "A\\B \\C" ] 132 | 133 | 134 | === Single Dash 135 | --- yaml 136 | --- 137 | foo: '-' 138 | --- perl 139 | [ { foo => '-' } ] 140 | -------------------------------------------------------------------------------- /t/tml-local/yaml-roundtrip/scalar.tml: -------------------------------------------------------------------------------- 1 | %PointMarker +++ 2 | 3 | # Just a scalar 4 | === one_scalar 5 | +++ yaml 6 | --- foo 7 | 8 | +++ perl 9 | [ 'foo' ] 10 | 11 | 12 | === one_scalar2 13 | +++ yaml 14 | --- foo 15 | 16 | +++ perl 17 | [ 'foo' ] 18 | 19 | 20 | === two_scalar 21 | +++ yaml 22 | --- foo 23 | --- bar 24 | 25 | +++ perl 26 | [ 'foo', 'bar' ] 27 | 28 | 29 | ##################################################################### 30 | # Support for literal multi-line scalars 31 | 32 | # Declarative multi-line scalar 33 | === simple_multiline 34 | +++ yaml 35 | --- 36 | foo: > 37 | bar 38 | baz 39 | +++ perl 40 | [ { foo => "bar baz\n" } ] 41 | 42 | 43 | # Piped multi-line scalar 44 | === indented 45 | +++ yaml 46 | --- 47 | - | 48 | foo 49 | bar 50 | - 1 51 | +++ perl 52 | [ [ "foo\nbar\n", 1 ] ] 53 | 54 | 55 | # ... with a pointless hyphen 56 | === indented 57 | +++ yaml 58 | --- 59 | - |- 60 | foo 61 | bar 62 | - 1 63 | +++ perl 64 | [ [ "foo\nbar", 1 ] ] 65 | 66 | 67 | ##################################################################### 68 | # Hitchhiker Scalar 69 | 70 | === hitchhiker scalar 71 | +++ yaml 72 | --- 42 73 | +++ perl 74 | [ 42 ] 75 | +++ serializes 76 | 77 | ##################################################################### 78 | # Newlines and tabs 79 | 80 | === special characters 81 | +++ yaml 82 | foo: "foo\\\n\tbar" 83 | +++ perl 84 | [ { foo => "foo\\\n\tbar" } ] 85 | 86 | ##################################################################### 87 | # Unprintable Characters 88 | 89 | === unprintable 90 | +++ yaml 91 | --- "foo\n\x00" 92 | +++ perl 93 | [ "foo\n\0" ] 94 | 95 | ##################################################################### 96 | # Ticker #32402 97 | 98 | # Tests a particular pathological case 99 | 100 | === Pathological >< case 101 | +++ yaml 102 | --- 103 | - value 104 | - '><' 105 | +++ perl 106 | [ [ 'value', '><' ] ] 107 | 108 | ##################################################################### 109 | # Special Characters 110 | 111 | === Special Characters 112 | +++ SKIP 113 | # Encoding failure 114 | +++ yaml 115 | --- 116 | - "Ingy d\xC3\xB6t Net" 117 | +++ perl 118 | [ [ "Ingy d\xC3\xB6t Net" ] ] 119 | 120 | ###################################################################### 121 | # Check illegal characters that are in legal places 122 | 123 | === Bang in a quote 124 | +++ yaml 125 | --- 'Wow!' 126 | +++ perl 127 | [ "Wow!" ] 128 | 129 | 130 | === Ampersand in a quote 131 | +++ yaml 132 | --- 'This&that' 133 | +++ perl 134 | [ "This&that" ] 135 | 136 | -------------------------------------------------------------------------------- /t/tml-local/yaml-roundtrip/sequence.tml: -------------------------------------------------------------------------------- 1 | === Empty sequence 2 | --- yaml 3 | \--- [] 4 | --- perl 5 | [ [] ] 6 | 7 | # Simple lists 8 | === one_list1 9 | --- yaml 10 | --- 11 | - foo 12 | 13 | --- perl 14 | [ [ 'foo' ] ] 15 | 16 | # Implicit document start 17 | === implicit_array 18 | --- yaml 19 | - foo 20 | 21 | --- perl 22 | [ [ 'foo' ] ] 23 | 24 | 25 | 26 | === one_list2 27 | --- yaml 28 | --- 29 | - foo 30 | - bar 31 | 32 | --- perl 33 | [ [ 'foo', 'bar' ] ] 34 | 35 | 36 | === one_listundef 37 | --- yaml 38 | --- 39 | - ~ 40 | - bar 41 | 42 | --- perl 43 | [ [ undef, 'bar' ] ] 44 | 45 | 46 | === one_listundefs 47 | --- noyamlpm 48 | --- yaml 49 | --- 50 | - ~ 51 | - 52 | - 53 | 54 | --- perl 55 | [ [ undef, undef, undef ] ] 56 | 57 | 58 | ##################################################################### 59 | # Empty Values and Premature EOF 60 | 61 | === empty array keys 62 | --- yaml 63 | --- 64 | - foo 65 | - 66 | - 67 | --- perl 68 | [ [ 'foo', undef, undef ] ] 69 | --- noyamlpm 70 | 71 | ##################################################################### 72 | # Empty Quote Line 73 | 74 | === empty quote line 75 | --- yaml 76 | --- 77 | - foo 78 | \# 79 | - bar 80 | --- perl 81 | [ [ "foo", "bar" ] ] 82 | 83 | ##################################################################### 84 | # Trailing Whitespace 85 | # 86 | === trailing whitespace 87 | --- yaml 88 | --- 89 | abstract: Generate fractal curves 90 | foo: ~ 91 | arr: 92 | # THESE LINES HAVE INTENTIONAL TRAILING WHITESPACE 93 | - foo 94 | - ~ 95 | - 'bar' 96 | --- perl 97 | [ { 98 | abstract => 'Generate fractal curves', 99 | foo => undef, 100 | arr => [ 'foo', undef, 'bar' ], 101 | } ] 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /t/tml-spec/basic-data.tml: -------------------------------------------------------------------------------- 1 | === basic hash 2 | # This is just a simple one key hash. 3 | --- yaml 4 | a: b 5 | --- json 6 | {"a":"b"} 7 | 8 | === double quoted keys 9 | # Hash with quoted key with embedded newline 10 | --- yaml 11 | "a\nb": c 12 | --- json 13 | {"a\nb":"c"} 14 | # --- dump 15 | # "a\nb": c 16 | 17 | === basic array 18 | # This is just a simple one key hash. 19 | --- yaml 20 | - a 21 | -b 22 | --- json 23 | ["a","b"] 24 | 25 | -------------------------------------------------------------------------------- /t/tml-spec/multiline.tml: -------------------------------------------------------------------------------- 1 | === basic multiline 2 | # This is just a simple one key hash. 3 | --- yaml 4 | a: | 5 | ciao 6 | a tutti 7 | --- json 8 | {"a":"ciao\na tutti\n"} 9 | 10 | === multiline with inner indentation 11 | # This is just a simple one key hash. 12 | --- yaml 13 | a: | 14 | ciao 15 | a 16 | tutti 17 | --- json 18 | {"a":"ciao\n a\ntutti\n"} 19 | 20 | === two multilines with variable inner indentation 21 | # This is just a simple one key hash. 22 | --- yaml 23 | - | 24 | ciao 25 | a 26 | tutti 27 | - | 28 | quanti 29 | voi 30 | amici 31 | --- json 32 | ["ciao\n a\n tutti\n","quanti\n voi\namici\n"] 33 | 34 | -------------------------------------------------------------------------------- /t/tml-spec/unicode.tml: -------------------------------------------------------------------------------- 1 | # Test unicode strings in key and value contexts 2 | 3 | %TestML 0.1.0 4 | 5 | ### 6 | # These tests target unicode characters that are handled special or known to be 7 | # problematic. Test YNY (YAML→Native→YAML) and NYN roundtripping. 8 | # 9 | # YAML scalar emission does quoting based on first character, presence of 10 | # escape characters, and special ambiguous cases like ': '. These ones 11 | # character strings go a long way towards making sure an implementation is 12 | # correct. 13 | ### 14 | 15 | 16 | # Make a mapping { "$code" : "$code" } where code is a unicode code point: 17 | 18 | # Dump mapping matches *yaml 19 | *code.dump_code_key_value == *yaml 20 | 21 | # Load *yaml then dump matches *yaml 22 | *yaml.load_yaml.dump_yaml == *yaml 23 | 24 | # Dump mapping the load memory-matches mapping 25 | *code.code_key_value.dump_yaml.load_yaml === *code.code_key_value 26 | 27 | 28 | # 0 → \0 "null" 29 | # 30 | # \z is the other YAML "null" encoding. Most implementations (including 31 | # libyaml), seem to go with \0 when emitting. 32 | === Code point 0 33 | --- code: 0 34 | --- yaml 35 | "\0": "\0" 36 | 37 | 38 | # 1-6,14-27,29-31 → \x## 39 | === Code point 1 40 | --- code: 1 41 | --- yaml 42 | "\x01": "\x01" 43 | 44 | 45 | # 7 → \a "bell" (alarm) 46 | === Code point 7 47 | --- code: 7 48 | --- yaml 49 | "\a": "\a" 50 | 51 | 52 | # 8 → \b "backspace" 53 | === Code point 8 54 | --- code: 8 55 | --- yaml 56 | "\b": "\b" 57 | 58 | 59 | # 9 → \t "horizontal tab" 60 | === Code point 9 61 | --- code: 9 62 | --- yaml 63 | "\t": "\t" 64 | 65 | 66 | # 10 → \n "linefeed" (newline) 67 | === Code point 10 68 | --- code: 10 69 | --- yaml 70 | "\n": "\n" 71 | 72 | 73 | # 11 → \v "vertical tab" 74 | === Code point 11 75 | --- code: 11 76 | --- yaml 77 | "\v": "\v" 78 | 79 | 80 | # 11 → \f "form feed" 81 | === Code point 12 82 | --- code: 12 83 | --- yaml 84 | "\f": "\f" 85 | 86 | 87 | # 11 → \f "carriage return" 88 | === Code point 13 89 | --- code: 13 90 | --- yaml 91 | "\r": "\r" 92 | 93 | # 27 → \e "escape" 94 | === Code point 27 95 | --- code: 27 96 | --- yaml 97 | "\e": "\e" 98 | 99 | 100 | # Space character needs quotes. 101 | === Code point 32 102 | --- code: 32 103 | --- yaml 104 | ' ': ' ' 105 | 106 | 107 | # ! is a tag indicator. Needs quotes. 108 | === Code point 33 109 | --- code: 33 110 | --- yaml 111 | '!': '!' 112 | 113 | 114 | # Quote single quotes with double quotes. 115 | === Code point 34 116 | --- code: 34 117 | --- yaml 118 | '"': '"' 119 | 120 | 121 | # '#' is comment character. Needs quotes. 122 | === Code point 35 123 | --- code: 35 124 | --- yaml 125 | '#': '#' 126 | 127 | 128 | # $ has no special meaning. No quotes. 129 | === Code point 36 130 | --- code: 36 131 | --- yaml 132 | $: $ 133 | 134 | 135 | # % is directive indicator. Needs quotees. 136 | === Code point 37 137 | --- code: 37 138 | --- yaml 139 | '%': '%' 140 | 141 | 142 | # & is anchor indicator. Needs quotes. 143 | === Code point 38 144 | --- code: 38 145 | --- yaml 146 | '&': '&' 147 | 148 | 149 | # Quote double quotes with single quotes. 150 | === Code point 39 151 | --- code: 39 152 | --- yaml 153 | "'": "'" 154 | 155 | 156 | # ( has no special meaning. No quotes. 157 | === Code point 40 158 | --- code: 40 159 | --- yaml 160 | (: ( 161 | 162 | 163 | # ) has no special meaning. No quotes. 164 | === Code point 41 165 | --- code: 41 166 | --- yaml 167 | ): ) 168 | 169 | 170 | # * is an alias indicator. Needs quotes. 171 | === Code point 42 172 | --- code: 42 173 | --- yaml 174 | '*': '*' 175 | 176 | 177 | # + has no special meaning. No quotes. 178 | === Code point 43 179 | --- code: 43 180 | --- yaml 181 | +: + 182 | 183 | 184 | # , is a list separator. Needs quotes. 185 | === Code point 44 186 | --- code: 44 187 | --- yaml 188 | ',': ',' 189 | 190 | 191 | # - is a sequence element marker. In many contexts it is not ambiguous when 192 | # unquoted, but in others it is ambiguous. libyaml always quotes it so going 193 | # with that for now. 194 | === Code point 45 195 | --- code: 45 196 | --- yaml 197 | '-': '-' 198 | 199 | 200 | # . has no special meaning. No quotes. 201 | === Code point 46 202 | --- code: 46 203 | --- yaml 204 | .: . 205 | 206 | 207 | # / has no special meaning. No quotes. 208 | === Code point 47 209 | --- code: 47 210 | --- yaml 211 | /: / 212 | 213 | 214 | # 48-57 → 0-9 "digitss" 215 | # These values are strings, so must quote them. 216 | === Code point 48 217 | --- code: 48 218 | --- yaml 219 | '0': '0' 220 | 221 | 222 | # : is a key/value separator. It is not always ambigous when not quoted, but 223 | # libyaml always quotes it at start of a string. Probably wise. Going with that 224 | # for now. 225 | === Code point 58 226 | --- code: 58 227 | --- yaml 228 | ':': ':' 229 | 230 | 231 | # ; has no special meaning. No quotes. 232 | === Code point 59 233 | --- code: 59 234 | --- yaml 235 | ;: ; 236 | 237 | 238 | # < has no special meaning. No quotes. 239 | === Code point 60 240 | --- code: 60 241 | --- yaml 242 | <: < 243 | 244 | 245 | # = has no special meaning. No quotes. 246 | === Code point 61 247 | --- code: 61 248 | --- yaml 249 | =: = 250 | 251 | 252 | # > is a folded scalar indicator. Needs quotes. 253 | === Code point 62 254 | --- code: 62 255 | --- yaml 256 | '>': '>' 257 | 258 | 259 | # ? is a mapping key indicator. Needs quotes. 260 | === Code point 63 261 | --- code: 63 262 | --- yaml 263 | '?': '?' 264 | 265 | 266 | # @ is a reserved character. Needs quotes. 267 | # TODO Check spec on this. 268 | === Code point 64 269 | --- code: 64 270 | --- yaml 271 | '@': '@' 272 | 273 | 274 | # 65-90 → A-Z "upper case letters". No quotes. 275 | === Code point 65 276 | --- code: 65 277 | --- yaml 278 | A: A 279 | 280 | 281 | # Some implementations think N means false. This should not be the case in a 282 | # default schema. No quotes. 283 | # 284 | # NOTE: 285 | # http://yaml.org/type/bool.html suggests that many simple strings should be 286 | # loaded as boolean, but this is an outdated concept. Currently, only the 287 | # words true/false/null (lower case) should be loaded specially (not as 288 | # strings). This may become even more restrictive in the future. ie Only 289 | # true/false/null in a flow context. 290 | === Code point 78 291 | --- code: 78 292 | --- yaml 293 | N: N 294 | 295 | 296 | # Some implementations think Y means true. This should not be the case in a 297 | # default schema. No quotes. 298 | === Code point 89 299 | --- code: 89 300 | --- yaml 301 | Y: Y 302 | 303 | 304 | # [ is a flow sequence start indicator. Needs quotes. 305 | === Code point 91 306 | --- code: 91 307 | --- yaml 308 | '[': '[' 309 | 310 | 311 | # \ is an escape indicator in double quoted strings. Used on its own it has no 312 | # special meaning. No quotes. 313 | === Code point 92 314 | --- SKIP 315 | --- code: 92 316 | --- yaml 317 | \: \ 318 | 319 | 320 | # ] is a flow sequence end indicator. Needs quotes. 321 | === Code point 93 322 | --- code: 93 323 | --- yaml 324 | ']': ']' 325 | 326 | 327 | # ^ has no special meaning. No quotes. 328 | === Code point 94 329 | --- code: 94 330 | --- yaml 331 | ^: ^ 332 | 333 | 334 | # _ has no special meaning. No quotes. 335 | === Code point 95 336 | --- code: 95 337 | --- yaml 338 | _: _ 339 | 340 | 341 | # ` is a reserved character. Needs quotes. 342 | === Code point 96 343 | --- code: 96 344 | --- yaml 345 | '`': '`' 346 | 347 | 348 | # 65-90 → a-z "lower case letters". No quotes. 349 | === Code point 97 350 | --- code: 97 351 | --- yaml 352 | a: a 353 | 354 | 355 | # Some implementations think n means false. This should not be the case in a 356 | # default schema. No quotes. 357 | === Code point 110 358 | --- code: 110 359 | --- yaml 360 | n: n 361 | 362 | 363 | # Some implementations think y means true. This should not be the case in a 364 | # default schema. No quotes. 365 | === Code point 121 366 | --- code: 121 367 | --- yaml 368 | y: y 369 | 370 | 371 | # { is a flow mapping start indicator. Needs quotes. 372 | === Code point 123 373 | --- code: 123 374 | --- yaml 375 | '{': '{' 376 | 377 | 378 | # | is a literal scalar indicator. Needs quotes. 379 | === Code point 124 380 | --- code: 124 381 | --- yaml 382 | '|': '|' 383 | 384 | 385 | # } is a flow mapping end indicator. Needs quotes. 386 | === Code point 125 387 | --- code: 125 388 | --- yaml 389 | '}': '}' 390 | 391 | 392 | # A single ~ has long been used as a plain scalar representation of null. This 393 | # should be deprecated, but may take a while. 394 | === Code point 126 395 | --- code: 126 396 | --- yaml 397 | '~': '~' 398 | --- unquoted 399 | ~: ~ 400 | 401 | 402 | # 127 → "escape" 403 | # YAML does not have a special character. YAML2 should consider \?. 404 | === Code point 127 405 | --- code: 127 406 | --- yaml 407 | "\x7F": "\x7F" 408 | 409 | 410 | # 80-84,86-159 → \x## 411 | === Code point 128 412 | --- code: 128 413 | --- yaml 414 | "\x80": "\x80" 415 | 416 | 417 | # 133 (\x85) → "next line" (NEL) 418 | === Code point 133 419 | --- code: 133 420 | --- yaml 421 | "\N": "\N" 422 | 423 | 424 | # 160 (\xA0) → "non-breaking space" 425 | # It seems extremely odd that YAML does not escape this. 426 | # Investigate further. 427 | === Code point 160 428 | --- SKIP 429 | --- code: 160 430 | --- yaml 431 |  :   432 | 433 | 434 | # 161-… → From here on up use printable unicode chars. 435 | # XXX Need to look into other special code blocks. Especially those known to 436 | # libyaml. 437 | === Code point 161 438 | --- code: 161 439 | --- yaml 440 | ¡: ¡ 441 | -------------------------------------------------------------------------------- /t/tml-world/Acme-Time-Baby.tml: -------------------------------------------------------------------------------- 1 | === Acme-Time-Baby 2 | --- yaml 3 | \# http://module-build.sourceforge.net/META-spec.html 4 | \#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# 5 | name: Acme-Time-Baby 6 | version: 2.106 7 | version_from: Baby.pm 8 | installdirs: site 9 | requires: 10 | warnings: 11 | 12 | distribution_type: module 13 | generated_by: ExtUtils::MakeMaker version 6.17 14 | 15 | --- perl 16 | [ { 17 | name => 'Acme-Time-Baby', 18 | version => '2.106', 19 | version_from => 'Baby.pm', 20 | installdirs => 'site', 21 | requires => { 22 | warnings => undef, 23 | }, 24 | distribution_type => 'module', 25 | generated_by => 'ExtUtils::MakeMaker version 6.17', 26 | } ] 27 | 28 | -------------------------------------------------------------------------------- /t/tml-world/Data-Swap.tml: -------------------------------------------------------------------------------- 1 | === Data-Swap 2 | # File with a YAML header 3 | --- yaml 4 | \--- #YAML:1.0 5 | name: Data-Swap 6 | version: 0.05 7 | license: perl 8 | distribution_type: module 9 | requires: 10 | perl: 5.6.0 11 | dynamic_config: 0 12 | 13 | --- perl 14 | [ { 15 | name => 'Data-Swap', 16 | version => '0.05', 17 | license => 'perl', 18 | distribution_type => 'module', 19 | requires => { 20 | perl => '5.6.0', 21 | }, 22 | dynamic_config => '0', 23 | } ] 24 | 25 | --- nosyck 26 | -------------------------------------------------------------------------------- /t/tml-world/Games-Nintendo-Wii-Mii.tml: -------------------------------------------------------------------------------- 1 | === Games-Nintendo-Wii-Mii 2 | # Testing various failing META.yml files from CPAN 3 | --- yaml 4 | --- 5 | abstract: Mii in Nintendo Wii data parser and builder 6 | author: Toru Yamaguchi 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: Games-Nintendo-Wii-Mii 14 | no_index: 15 | directory: 16 | - inc 17 | - t 18 | requires: 19 | Carp: 1.03 20 | Class::Accessor::Fast: 0.3 21 | File::Slurp: 9999.12 22 | IO::File: 1.1 23 | Readonly: 0 24 | Tie::IxHash: 1.21 25 | URI: 1.35 26 | XML::LibXML: 1.62 27 | version: 0.02 28 | 29 | --- perl 30 | [ { 31 | abstract => 'Mii in Nintendo Wii data parser and builder', 32 | author => 'Toru Yamaguchi ', 33 | distribution_type => 'module', 34 | generated_by => 'Module::Install version 0.65', 35 | license => 'perl', 36 | 'meta-spec' => { 37 | url => 'http://module-build.sourceforge.net/META-spec-v1.3.html', 38 | version => '1.3', 39 | }, 40 | name => 'Games-Nintendo-Wii-Mii', 41 | no_index => { 42 | directory => [ qw{ inc t } ], 43 | }, 44 | requires => { 45 | 'Carp' => '1.03', 46 | 'Class::Accessor::Fast' => '0.3', 47 | 'File::Slurp' => '9999.12', 48 | 'IO::File' => '1.1', 49 | 'Readonly' => '0', 50 | 'Tie::IxHash' => '1.21', 51 | 'URI' => '1.35', 52 | 'XML::LibXML' => '1.62', 53 | }, 54 | version => '0.02', 55 | } ] 56 | 57 | 58 | -------------------------------------------------------------------------------- /t/tml-world/HTML-WebDAO.tml: -------------------------------------------------------------------------------- 1 | === HTML-WebDAO 2 | --- yaml 3 | \--- #YAML:1.0 4 | name: HTML-WebDAO 5 | version: 0.04 6 | author: 7 | - |- 8 | Zahatski Aliaksandr, Ezagap@users.sourceforge.netE 9 | abstract: Perl extension for create complex web application 10 | license: perl 11 | 12 | --- perl 13 | [ { 14 | abstract => 'Perl extension for create complex web application', 15 | author => [ 16 | 'Zahatski Aliaksandr, Ezagap@users.sourceforge.netE', 17 | ], 18 | license => 'perl', 19 | name => 'HTML-WebDAO', 20 | version => '0.04', 21 | } ] 22 | 23 | --- nosyck 24 | 25 | -------------------------------------------------------------------------------- /t/tml-world/ITS-SIN-FIDS-Content-XML.tml: -------------------------------------------------------------------------------- 1 | === ITS-SIN-FIDS-Content-XML 2 | # Testing a META.yml from a commercial project that crashed 3 | --- yaml 4 | \# http://module-build.sourceforge.net/META-spec.html 5 | \#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# 6 | name: ITS-SIN-FIDS-Content-XML 7 | version: 0.01 8 | version_from: lib/ITS/SIN/FIDS/Content/XML.pm 9 | installdirs: site 10 | requires: 11 | Test::More: 0.45 12 | XML::Simple: 2 13 | 14 | distribution_type: module 15 | generated_by: ExtUtils::MakeMaker version 6.30 16 | 17 | --- perl 18 | [ { 19 | name => 'ITS-SIN-FIDS-Content-XML', 20 | version => "0.01", # this kludge is to prevent floating point comparison errors 21 | version_from => 'lib/ITS/SIN/FIDS/Content/XML.pm', 22 | installdirs => 'site', 23 | requires => { 24 | 'Test::More' => 0.45, 25 | 'XML::Simple' => 2, 26 | }, 27 | distribution_type => 'module', 28 | generated_by => 'ExtUtils::MakeMaker version 6.30', 29 | } ] 30 | 31 | -------------------------------------------------------------------------------- /t/tml-world/Plagger.tml: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # Example Plagger Configuration 1 3 | 4 | === Plagger 5 | --- yaml 6 | plugins: 7 | - module: Subscription::Bloglines 8 | config: 9 | username: you@example.pl 10 | password: foobar 11 | mark_read: 1 12 | 13 | - module: Publish::Gmail 14 | config: 15 | mailto: example@gmail.com 16 | mailfrom: miyagawa@example.com 17 | mailroute: 18 | via: smtp 19 | host: smtp.example.com 20 | --- perl 21 | [ { plugins => [ 22 | { 23 | module => 'Subscription::Bloglines', 24 | config => { 25 | username => 'you@example.pl', 26 | password => 'foobar', 27 | mark_read => 1, 28 | }, 29 | }, 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 | }, 39 | }, 40 | }, 41 | ] } ] 42 | 43 | 44 | ##################################################################### 45 | # Example Plagger Configuration 2 46 | 47 | === plagger2 48 | --- yaml 49 | plugins: 50 | - module: Subscription::Config 51 | config: 52 | feed: 53 | # Trac's feed for changesets 54 | - http://plagger.org/.../rss 55 | 56 | # I don't like to be notified of the same items 57 | # more than once 58 | - module: Filter::Rule 59 | rule: 60 | module: Fresh 61 | mtime: 62 | path: /tmp/rssbot.time 63 | autoupdate: 1 64 | 65 | - module: Notify::IRC 66 | config: 67 | daemon_port: 9999 68 | nickname: plaggerbot 69 | server_host: chat.freenode.net 70 | server_channels: 71 | - '#plagger-ja' 72 | - '#plagger' 73 | 74 | 75 | --- perl 76 | [ { plugins => [ { 77 | module => 'Subscription::Config', 78 | config => { 79 | feed => [ 'http://plagger.org/.../rss' ], 80 | }, 81 | }, { 82 | module => 'Filter::Rule', 83 | rule => { 84 | module => 'Fresh', 85 | mtime => { 86 | path => '/tmp/rssbot.time', 87 | autoupdate => 1, 88 | }, 89 | }, 90 | }, { 91 | module => 'Notify::IRC', 92 | config => { 93 | daemon_port => 9999, 94 | nickname => 'plaggerbot', 95 | server_host => 'chat.freenode.net', 96 | server_channels => [ 97 | '#plagger-ja', 98 | '#plagger', 99 | ], 100 | }, 101 | } ] } ] 102 | -------------------------------------------------------------------------------- /t/tml-world/Spreadsheet-Read.tml: -------------------------------------------------------------------------------- 1 | === Spreadsheet-Read 2 | --- yaml 3 | \--- #YAML:1.1 4 | name: Read 5 | version: VERSION 6 | abstract: Meta-Wrapper for reading spreadsheet data 7 | license: perl 8 | author: 9 | - H.Merijn Brand 10 | generated_by: Author 11 | distribution_type: module 12 | provides: 13 | Spreadsheet::Read: 14 | file: Read.pm 15 | version: VERSION 16 | requires: 17 | perl: 5.006 18 | Exporter: 0 19 | Carp: 0 20 | Data::Dumper: 0 21 | recommends: 22 | perl: 5.008005 23 | File::Temp: 0.14 24 | IO::Scalar: 0 25 | build_requires: 26 | perl: 5.006 27 | Test::Harness: 0 28 | Test::More: 0 29 | optional_features: 30 | - opt_csv: 31 | description: Provides parsing of CSV streams 32 | requires: 33 | Text::CSV_XS: 0.23 34 | recommends: 35 | Text::CSV: 1.10 36 | Text::CSV_PP: 1.10 37 | Text::CSV_XS: 0.58 38 | - opt_excel: 39 | description: Provides parsing of Microsoft Excel files 40 | requires: 41 | Spreadsheet::ParseExcel: 0.26 42 | Spreadsheet::ParseExcel::FmtDefault: 0 43 | recommends: 44 | Spreadsheet::ParseExcel: 0.42 45 | - opt_excelx: 46 | description: Provides parsing of Microsoft Excel 2007 files 47 | requires: 48 | Spreadsheet::XLSX: 0.07 49 | - opt_oo: 50 | description: Provides parsing of OpenOffice spreadsheets 51 | requires: 52 | Spreadsheet::ReadSXC: 0.2 53 | - opt_tools: 54 | description: Spreadsheet tools 55 | recommends: 56 | Tk: 0 57 | Tk::NoteBook: 0 58 | Tk::TableMatrix::Spreadsheet: 0 59 | resources: 60 | license: http://dev.perl.org/licenses/ 61 | meta-spec: 62 | version: 1.4 63 | url: http://module-build.sourceforge.net/META-spec-v1.4.html 64 | 65 | --- perl 66 | [ { 67 | 'resources' => { 68 | 'license' => 'http://dev.perl.org/licenses/' 69 | }, 70 | 'meta-spec' => { 71 | 'version' => '1.4', 72 | 'url' => 'http://module-build.sourceforge.net/META-spec-v1.4.html' 73 | }, 74 | 'distribution_type' => 'module', 75 | 'generated_by' => 'Author', 76 | 'version' => 'VERSION', 77 | 'name' => 'Read', 78 | 'author' => [ 79 | 'H.Merijn Brand ' 80 | ], 81 | 'license' => 'perl', 82 | 'build_requires' => { 83 | 'Test::More' => '0', 84 | 'Test::Harness' => '0', 85 | 'perl' => '5.006' 86 | }, 87 | 'provides' => { 88 | 'Spreadsheet::Read' => { 89 | 'version' => 'VERSION', 90 | 'file' => 'Read.pm' 91 | } 92 | }, 93 | 'optional_features' => [ 94 | { 95 | 'opt_csv' => { 96 | 'requires' => { 97 | 'Text::CSV_XS' => '0.23' 98 | }, 99 | 'recommends' => { 100 | 'Text::CSV_PP' => '1.10', 101 | 'Text::CSV_XS' => '0.58', 102 | 'Text::CSV' => '1.10' 103 | }, 104 | 'description' => 'Provides parsing of CSV streams' 105 | } 106 | }, 107 | { 108 | 'opt_excel' => { 109 | 'requires' => { 110 | 'Spreadsheet::ParseExcel' => '0.26', 111 | 'Spreadsheet::ParseExcel::FmtDefault' => '0' 112 | }, 113 | 'recommends' => { 114 | 'Spreadsheet::ParseExcel' => '0.42' 115 | }, 116 | 'description' => 'Provides parsing of Microsoft Excel files' 117 | } 118 | }, 119 | { 120 | 'opt_excelx' => { 121 | 'requires' => { 122 | 'Spreadsheet::XLSX' => '0.07' 123 | }, 124 | 'description' => 'Provides parsing of Microsoft Excel 2007 files' 125 | } 126 | }, 127 | { 128 | 'opt_oo' => { 129 | 'requires' => { 130 | 'Spreadsheet::ReadSXC' => '0.2' 131 | }, 132 | 'description' => 'Provides parsing of OpenOffice spreadsheets' 133 | } 134 | }, 135 | { 136 | 'opt_tools' => { 137 | 'recommends' => { 138 | 'Tk::TableMatrix::Spreadsheet' => '0', 139 | 'Tk::NoteBook' => '0', 140 | 'Tk' => '0' 141 | }, 142 | 'description' => 'Spreadsheet tools' 143 | } 144 | } 145 | ], 146 | 'requires' => { 147 | 'perl' => '5.006', 148 | 'Data::Dumper' => '0', 149 | 'Exporter' => '0', 150 | 'Carp' => '0' 151 | }, 152 | 'recommends' => { 153 | 'perl' => '5.008005', 154 | 'IO::Scalar' => '0', 155 | 'File::Temp' => '0.14' 156 | }, 157 | 'abstract' => 'Meta-Wrapper for reading spreadsheet data' 158 | } ] 159 | 160 | --- noyamlpm 161 | 162 | -------------------------------------------------------------------------------- /t/tml-world/Template-Provider-Unicode-Japanese.tml: -------------------------------------------------------------------------------- 1 | === Template-Provider-Unicode-Japanese 2 | --- yaml 3 | --- 4 | abstract: Decode all templates by Unicode::Japanese 5 | author: Hironori Yoshida C<< >> 6 | distribution_type: module 7 | generated_by: Module::Install version 0.65 8 | license: perl 9 | meta-spec: 10 | url: http://module-build.sourceforge.net/META-spec-v1.3.html 11 | version: 1.3 12 | name: Template-Provider-Unicode-Japanese 13 | no_index: 14 | directory: 15 | - inc 16 | - t 17 | requires: 18 | Template::Config: 0 19 | Unicode::Japanese: 0 20 | perl: 5.6.0 21 | version: 0 22 | version: 1.2.1 23 | 24 | --- perl 25 | [ { 26 | abstract => 'Decode all templates by Unicode::Japanese', 27 | author => 'Hironori Yoshida C<< >>', 28 | distribution_type => 'module', 29 | generated_by => 'Module::Install version 0.65', 30 | license => 'perl', 31 | 'meta-spec' => { 32 | url => 'http://module-build.sourceforge.net/META-spec-v1.3.html', 33 | version => '1.3', 34 | }, 35 | name => 'Template-Provider-Unicode-Japanese', 36 | no_index => { 37 | directory => [ qw{ inc t } ], 38 | }, 39 | requires => { 40 | 'Template::Config' => 0, 41 | 'Unicode::Japanese' => 0, 42 | perl => '5.6.0', 43 | version => '0', 44 | }, 45 | version => '1.2.1', 46 | } ] 47 | 48 | -------------------------------------------------------------------------------- /t/tml-world/Vanilla-Perl.tml: -------------------------------------------------------------------------------- 1 | === vanilla_perl 2 | # VanillaPerl YAML config file 3 | --- yaml 4 | # package info 5 | package_name: VanillaPerl 6 | package_version: 5 7 | 8 | # directories 9 | download_dir: c:\temp\vp_sources 10 | build_dir: c:\temp\vp_build 11 | image_dir: c:\vanilla-perl 12 | 13 | # Binary components 14 | binary: 15 | - name: dmake 16 | url: http://search.cpan.org/CPAN/authors/id/S/SH/SHAY/dmake-4.5-20060619-SHAY.zip 17 | license: 18 | dmake/COPYING : dmake/COPYING 19 | dmake/readme/license.txt: dmake/license.txt 20 | install_to: 21 | dmake/dmake.exe: dmake/bin/dmake.exe 22 | dmake/startup: dmake/bin/startup 23 | 24 | - name: gcc-core 25 | url: http://umn.dl.sourceforge.net/mingw/gcc-core-3.4.5-20060117-1.tar.gz 26 | license: 27 | COPYING: gcc/COPYING 28 | COPYING.lib: gcc/COPYING.lib 29 | install_to: mingw 30 | 31 | - name: gcc-g++ 32 | url: http://umn.dl.sourceforge.net/mingw/gcc-g++-3.4.5-20060117-1.tar.gz 33 | license: 34 | install_to: mingw 35 | 36 | - name: binutils 37 | url: http://umn.dl.sourceforge.net/mingw/binutils-2.16.91-20060119-1.tar.gz 38 | license: 39 | Copying: binutils/Copying 40 | Copying.lib: binutils/Copying.lib 41 | install_to: mingw 42 | 43 | - name: mingw-runtime 44 | url: http://umn.dl.sourceforge.net/mingw/mingw-runtime-3.10.tar.gz 45 | license: 46 | doc/mingw-runtime/Contributors: mingw/Contributors 47 | doc/mingw-runtime/Disclaimer: mingw/Disclaimer 48 | install_to: mingw 49 | 50 | - name: w32api 51 | url: http://umn.dl.sourceforge.net/mingw/w32api-3.6.tar.gz 52 | license: 53 | install_to: mingw 54 | extra: 55 | extra\README.w32api: licenses\win32api\README.w32api 56 | 57 | # Source components 58 | source: 59 | - name: perl 60 | url: http://mirrors.kernel.org/CPAN/src/perl-5.8.8.tar.gz 61 | license: 62 | perl-5.8.8/Readme: perl/Readme 63 | perl-5.8.8/Artistic: perl/Artistic 64 | perl-5.8.8/Copying: perl/Copying 65 | unpack_to: perl 66 | install_to: perl 67 | after: 68 | extra\Config.pm: lib\CPAN\Config.pm 69 | 70 | # Additional modules to bundle in site\lib 71 | modules: 72 | # i.e. not used, but gets us the libwin32 dist 73 | - name: Win32::Job 74 | unpack_to: 75 | APIFile: Win32API-File 76 | - name: IO 77 | force: 1 78 | - name: Compress::Zlib 79 | - name: IO::Zlib 80 | - name: Archive::Tar 81 | - name: Net::FTP 82 | extra: 83 | extra\libnet.cfg: libnet.cfg 84 | 85 | # Extra files to be placed 86 | # Signature.pm: perl\site\lib\Module\Signature.pm 87 | extra: 88 | README: README.txt 89 | LICENSE.txt: LICENSE.txt 90 | Changes: Release-Notes.txt 91 | extra\Config.pm: perl\lib\CPAN\Config.pm 92 | # reset this again 93 | 94 | extra\links\Perl-Documentation.url: links\Perl Documentation.url 95 | extra\links\Perl-Homepage.url: links\Perl Homepage.url 96 | extra\links\Perl-Mailing-Lists.url: links\Perl Mailing Lists.url 97 | extra\links\Perlmonks-Community-Forum.url: links\Perlmonks Community Forum.url 98 | extra\links\Search-CPAN-Modules.url: links\Search CPAN Modules.url 99 | extra\links\Vanilla-Perl-Homepage.url: links\Vanilla Perl Homepage.url 100 | 101 | --- perl 102 | [ { 103 | package_name => 'VanillaPerl', 104 | package_version => 5, 105 | download_dir => 'c:\temp\vp_sources', 106 | build_dir => 'c:\temp\vp_build', 107 | image_dir => 'c:\vanilla-perl', 108 | binary => [ 109 | { 110 | name => 'dmake', 111 | url => 'http://search.cpan.org/CPAN/authors/id/S/SH/SHAY/dmake-4.5-20060619-SHAY.zip', 112 | license => { 113 | 'dmake/COPYING' => 'dmake/COPYING', 114 | 'dmake/readme/license.txt' => 'dmake/license.txt', 115 | }, 116 | install_to => { 117 | 'dmake/dmake.exe' => 'dmake/bin/dmake.exe', 118 | 'dmake/startup' => 'dmake/bin/startup', 119 | }, 120 | }, 121 | { 122 | name => 'gcc-core', 123 | url => 'http://umn.dl.sourceforge.net/mingw/gcc-core-3.4.5-20060117-1.tar.gz', 124 | license => { 125 | 'COPYING' => 'gcc/COPYING', 126 | 'COPYING.lib' => 'gcc/COPYING.lib', 127 | }, 128 | install_to => 'mingw', 129 | }, 130 | { 131 | name => 'gcc-g++', 132 | url => 'http://umn.dl.sourceforge.net/mingw/gcc-g++-3.4.5-20060117-1.tar.gz', 133 | license => undef, 134 | install_to => 'mingw', 135 | }, 136 | { 137 | name => 'binutils', 138 | url => 'http://umn.dl.sourceforge.net/mingw/binutils-2.16.91-20060119-1.tar.gz', 139 | license => { 140 | 'Copying' => 'binutils/Copying', 141 | 'Copying.lib' => 'binutils/Copying.lib', 142 | }, 143 | install_to => 'mingw', 144 | }, 145 | { 146 | name => 'mingw-runtime', 147 | url => 'http://umn.dl.sourceforge.net/mingw/mingw-runtime-3.10.tar.gz', 148 | license => { 149 | 'doc/mingw-runtime/Contributors' => 'mingw/Contributors', 150 | 'doc/mingw-runtime/Disclaimer' => 'mingw/Disclaimer', 151 | }, 152 | install_to => 'mingw', 153 | }, 154 | { 155 | name => 'w32api', 156 | url => 'http://umn.dl.sourceforge.net/mingw/w32api-3.6.tar.gz', 157 | license => undef, 158 | install_to => 'mingw', 159 | extra => { 160 | 'extra\README.w32api' => 'licenses\win32api\README.w32api', 161 | }, 162 | } 163 | ], 164 | source => [ 165 | { 166 | name => 'perl', 167 | url => 'http://mirrors.kernel.org/CPAN/src/perl-5.8.8.tar.gz', 168 | license => { 169 | 'perl-5.8.8/Readme' => 'perl/Readme', 170 | 'perl-5.8.8/Artistic' => 'perl/Artistic', 171 | 'perl-5.8.8/Copying' => 'perl/Copying', 172 | }, 173 | unpack_to => 'perl', 174 | install_to => 'perl', 175 | after => { 176 | 'extra\Config.pm' => 'lib\CPAN\Config.pm', 177 | }, 178 | } 179 | ], 180 | modules => [ 181 | { 182 | name => 'Win32::Job', 183 | unpack_to => { 184 | APIFile => 'Win32API-File', 185 | }, 186 | }, 187 | { 188 | name => 'IO', 189 | force => 1, 190 | }, 191 | { 192 | name => 'Compress::Zlib', 193 | }, 194 | { 195 | name => 'IO::Zlib', 196 | }, 197 | { 198 | name => 'Archive::Tar', 199 | }, 200 | { 201 | name => 'Net::FTP', 202 | extra => { 203 | 'extra\libnet.cfg' => 'libnet.cfg', 204 | }, 205 | }, 206 | ], 207 | extra => { 208 | 'README' => 'README.txt', 209 | 'LICENSE.txt' => 'LICENSE.txt', 210 | 'Changes' => 'Release-Notes.txt', 211 | 'extra\Config.pm' => 'perl\lib\CPAN\Config.pm', 212 | 'extra\links\Perl-Documentation.url' => 'links\Perl Documentation.url', 213 | 'extra\links\Perl-Homepage.url' => 'links\Perl Homepage.url', 214 | 'extra\links\Perl-Mailing-Lists.url' => 'links\Perl Mailing Lists.url', 215 | 'extra\links\Perlmonks-Community-Forum.url' => 'links\Perlmonks Community Forum.url', 216 | 'extra\links\Search-CPAN-Modules.url' => 'links\Search CPAN Modules.url', 217 | 'extra\links\Vanilla-Perl-Homepage.url' => 'links\Vanilla Perl Homepage.url', 218 | }, 219 | } ] 220 | 221 | --- nosyck 222 | -------------------------------------------------------------------------------- /t/tml-world/YAML-Tiny-META.tml: -------------------------------------------------------------------------------- 1 | === YAML::Tiny 2 | # Testing YAML::Tiny's own META.yml file -- at least as of some time ago 3 | --- yaml 4 | abstract: Read/Write YAML files with as little code as possible 5 | author: 'Adam Kennedy ' 6 | build_requires: 7 | File::Spec: 0.80 8 | Test::More: 0.47 9 | distribution_type: module 10 | generated_by: Module::Install version 0.63 11 | license: perl 12 | name: YAML-Tiny 13 | no_index: 14 | directory: 15 | - inc 16 | - t 17 | requires: 18 | perl: 5.005 19 | version: 0.03 20 | 21 | --- perl 22 | [ { 23 | abstract => 'Read/Write YAML files with as little code as possible', 24 | author => 'Adam Kennedy ', 25 | build_requires => { 26 | 'File::Spec' => '0.80', 27 | 'Test::More' => '0.47', 28 | }, 29 | distribution_type => 'module', 30 | generated_by => 'Module::Install version 0.63', 31 | license => 'perl', 32 | name => 'YAML-Tiny', 33 | no_index => { 34 | directory => [ qw{inc t} ], 35 | }, 36 | requires => { 37 | perl => '5.005', 38 | }, 39 | version => '0.03', 40 | } ] 41 | 42 | -------------------------------------------------------------------------------- /t/tml-world/toolbar.tml: -------------------------------------------------------------------------------- 1 | === toolbar 2 | # Testing of a known-bad file from an editor 3 | --- yaml 4 | main_toolbar: 5 | - item file-new 6 | - item file-open 7 | - item file-print# 8 | - item file-close# 9 | - item file-save-all 10 | - item file-save 11 | - 12 | - item edit-changes-undo 13 | - item edit-changes-redo 14 | - 15 | - item edit-cut 16 | - item edit-copy 17 | - item edit-paste 18 | - item edit-replace 19 | - item edit-delete 20 | 21 | --- perl 22 | [ { 23 | main_toolbar => [ 24 | 'item file-new', 25 | 'item file-open', 26 | 'item file-print#', 27 | 'item file-close#', 28 | 'item file-save-all', 29 | 'item file-save', 30 | undef, 31 | 'item edit-changes-undo', 32 | 'item edit-changes-redo', 33 | undef, 34 | 'item edit-cut', 35 | 'item edit-copy', 36 | 'item edit-paste', 37 | 'item edit-replace', 38 | 'item edit-delete', 39 | ] 40 | } ] 41 | 42 | -------------------------------------------------------------------------------- /t/tml-world/yaml_org.tml: -------------------------------------------------------------------------------- 1 | === yaml_org_example 2 | # Testing sample data structure from yaml.org 3 | --- yaml 4 | --- 5 | invoice: 34843 6 | date : 2001-01-23 7 | bill-to: 8 | given : Chris 9 | family : Dumars 10 | address: 11 | lines: | 12 | 458 Walkman Dr. 13 | Suite #292 14 | city : Royal Oak 15 | state : MI 16 | postal : 48046 17 | product: 18 | - sku : BL394D 19 | quantity : 4 20 | description : Basketball 21 | price : 450.00 22 | - sku : BL4438H 23 | quantity : 1 24 | description : Super Hoop 25 | price : 2392.00 26 | tax : 251.42 27 | total: 4443.52 28 | comments: > 29 | Late afternoon is best. 30 | Backup contact is Nancy 31 | Billsmer @ 338-4338. 32 | 33 | --- perl 34 | [ { 35 | invoice => 34843, 36 | date => '2001-01-23', 37 | 'bill-to' => { 38 | given => 'Chris', 39 | family => 'Dumars', 40 | address => { 41 | lines => "458 Walkman Dr.\nSuite #292\n", 42 | city => 'Royal Oak', 43 | state => 'MI', 44 | postal => 48046, 45 | }, 46 | }, 47 | product => [ 48 | { 49 | sku => 'BL394D', 50 | quantity => '4', 51 | description => 'Basketball', 52 | price => '450.00', 53 | }, 54 | { 55 | sku => 'BL4438H', 56 | quantity => '1', 57 | description => 'Super Hoop', 58 | price => '2392.00', 59 | }, 60 | ], 61 | tax => '251.42', 62 | total => '4443.52', 63 | comments => <<'END_TEXT', 64 | Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338. 65 | END_TEXT 66 | } ] 67 | 68 | --- nosyck 69 | 70 | -------------------------------------------------------------------------------- /xt/compare/roundtrip.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use Test::More 0.88; 4 | use lib 't/lib'; 5 | use TestBridge; 6 | use lib 'xt/lib'; 7 | use ExtraTest; 8 | 9 | use YAML::Tiny; 10 | 11 | my $local_dir = "t/tml-local/yaml-roundtrip"; 12 | my $world_dir = "t/tml-world"; 13 | 14 | my @parsers = ( 15 | (have_yamlpm() ? "YAML" : () ), 16 | (have_yamlxs() ? "YAML::XS" : () ), 17 | (have_yamlsyck() ? "YAML::Syck" : () ), 18 | ); 19 | 20 | plan skip_all => "No other YAML parsers installed for comparison" 21 | unless @parsers; 22 | 23 | my %skip_map = ( 24 | 'YAML' => 'noyamlpm', 25 | 'YAML::XS' => 'noxs', 26 | 'YAML::Syck' => 'nosyck', 27 | ); 28 | 29 | my %loader_for = do { 30 | no strict 'refs'; 31 | map {; $_ => *{$_ . "::Load"}{CODE} } "YAML::Tiny", @parsers; 32 | }; 33 | 34 | my %dumper_for = do { 35 | no strict 'refs'; 36 | map {; $_ => *{$_ . "::Dump"}{CODE} } "YAML::Tiny", @parsers; 37 | }; 38 | 39 | for my $dir ( $local_dir, $world_dir ) { 40 | run_all_testml_files( "TestML", $dir, \&compare_roundtrip ); 41 | } 42 | 43 | #--------------------------------------------------------------------------# 44 | # compare_roundtrip 45 | # 46 | # two blocks: perl, yaml 47 | # 48 | # We compare behaviors for multiple parsers 49 | # 50 | # Tests that a YAML string loads to the expected perl data. Also, tests 51 | # roundtripping from perl->YAML->perl. 52 | # 53 | # We can't compare the YAML for roundtripping because YAML::Tiny doesn't 54 | # preserve order and comments. Therefore, all we can test is that given input 55 | # YAML we can produce output YAML that produces the same Perl data as the 56 | # input. 57 | # 58 | # The perl must be an array reference of data to serialize: 59 | # 60 | # [ $thing1, $thing2, ... ] 61 | # 62 | # However, if a test point called 'serializes' exists, the output YAML is 63 | # expected to match the input YAML and will be checked for equality. 64 | #--------------------------------------------------------------------------# 65 | 66 | sub compare_roundtrip { 67 | my ($block) = @_; 68 | 69 | my ($yaml, $perl, $label) = 70 | _testml_has_points($block, qw(yaml perl)) or return; 71 | 72 | my %options = (); 73 | for (qw(serializes noxs nosyck noyamlpm)) { 74 | if (defined($block->{$_})) { 75 | $options{$_} = 1; 76 | } 77 | } 78 | 79 | my $expected = eval $perl; die $@ if $@; 80 | 81 | subtest $label, sub { 82 | 83 | my %perl_from; 84 | 85 | subtest "YAML to Perl" => sub { 86 | for my $p ( 'YAML::Tiny', @parsers ) { 87 | subtest $p => sub { 88 | plan skip_all => "Not supported by $p" 89 | if $p ne 'YAML::Tiny' && $options{$skip_map{$p}}; 90 | 91 | my $yaml_copy = $yaml; 92 | 93 | ok( 94 | $perl_from{$p} = [ eval { $loader_for{$p}->($yaml_copy) } ], 95 | "Load with $p" 96 | ) or diag "ERROR: " . _error_for($p); 97 | 98 | return if $p eq 'YAML::Tiny'; # don't compare vs self 99 | 100 | cmp_deeply( 101 | $perl_from{"YAML::Tiny"}, 102 | $perl_from{$p}, 103 | "YAML::Tiny should match $p" 104 | ) or diag "\nYAML:\n$yaml"; 105 | } 106 | } 107 | 108 | }; 109 | }; 110 | } 111 | 112 | #--------------------------------------------------------------------------# 113 | # _error_for -- normalize error handling 114 | #--------------------------------------------------------------------------# 115 | 116 | sub _error_for { 117 | my $p = shift; 118 | return $p eq 'YAML::Tiny' ? YAML::Tiny->errstr : $@; 119 | } 120 | 121 | done_testing; 122 | -------------------------------------------------------------------------------- /xt/lib/ExtraTest.pm: -------------------------------------------------------------------------------- 1 | package ExtraTest; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Exporter (); 7 | 8 | our @ISA = qw{ Exporter }; 9 | our @EXPORT = qw{ 10 | have_yamlpm 11 | have_yamlsyck 12 | have_yamlxs 13 | }; 14 | 15 | # Do we have the authorative YAML to test against 16 | my $HAVE_YAMLPM = !! eval { 17 | require YAML; 18 | 19 | # This doesn't currently work, but is documented to. 20 | # So if it ever turns up, use it. 21 | $YAML::UseVersion = 1; 22 | YAML->VERSION('0.66'); 23 | }; 24 | sub have_yamlpm { $HAVE_YAMLPM } 25 | 26 | # Do we have YAML::Syck to test against? 27 | my $HAVE_SYCK = !! eval { 28 | require YAML::Syck; 29 | YAML::Syck->VERSION('1.05') 30 | }; 31 | sub have_yamlsyck { $HAVE_SYCK } 32 | 33 | # Do we have YAML::XS to test against? 34 | my $HAVE_XS = !! eval { 35 | require YAML::XS; 36 | YAML::XS->VERSION('0.29') 37 | }; 38 | sub have_yamlxs{ $HAVE_XS } 39 | 40 | 1; 41 | --------------------------------------------------------------------------------