#!/usr/bin/perl
# Testing of common META.yml examples
use strict;
BEGIN {
$| = 1;
$^W = 1;
}
use File::Spec::Functions ':ALL';
use t::lib::Test;
use Test::More tests(37, 0, 12);
use CPAN::Meta::YAML qw{
Load Dump
LoadFile DumpFile
freeze thaw
};
#####################################################################
# Check Exports
ok( defined(&Load), 'Found exported Load function' );
ok( defined(&Dump), 'Found exported Dump function' );
ok( defined(&LoadFile), 'Found exported LoadFile function' );
ok( defined(&DumpFile), 'Found exported DumpFile function' );
ok( defined(&freeze), 'Found exported freeze function' );
ok( defined(&thaw), 'Found exported thaw functiona' );
#####################################################################
# In META.yml files, some hash keys contain module names
# Hash key legally containing a colon
yaml_ok(
"---\nFoo::Bar: 1\n",
[ { 'Foo::Bar' => 1 } ],
'module_hash_key',
);
# Hash indented
yaml_ok(
"---\n"
. " foo: bar\n",
[ { foo => "bar" } ],
'hash_indented',
);
#####################################################################
# Support for literal multi-line scalars
# Declarative multi-line scalar
yaml_ok(
"---\n"
. " foo: >\n"
. " bar\n"
. " baz\n",
[ { foo => "bar baz\n" } ],
'simple_multiline',
);
# Piped multi-line scalar
yaml_ok(
<<'END_YAML',
---
- |
foo
bar
- 1
END_YAML
[ [ "foo\nbar\n", 1 ] ],
'indented',
);
# ... with a pointless hyphen
yaml_ok( <<'END_YAML',
---
- |-
foo
bar
- 1
END_YAML
[ [ "foo\nbar", 1 ] ],
'indented',
);
#####################################################################
# Support for YAML version directives
# Simple inline case (comment variant)
yaml_ok(
<<'END_YAML',
--- #YAML:1.0
foo: bar
END_YAML
[ { foo => 'bar' } ],
'simple_doctype_comment',
nosyck => 1,
);
# Simple inline case (percent variant)
yaml_ok(
<<'END_YAML',
--- %YAML:1.0
foo: bar
END_YAML
[ { foo => 'bar' } ],
'simple_doctype_percent',
noyamlpm => 1,
noxs => 1,
noyamlperl => 1,
);
# Simple header (comment variant)
yaml_ok(
<<'END_YAML',
%YAML:1.0
---
foo: bar
END_YAML
[ { foo => 'bar' } ],
'predocument_1_0',
noyamlpm => 1,
nosyck => 1,
noxs => 1,
noyamlperl => 1,
);
# Simple inline case (comment variant)
yaml_ok(
<<'END_YAML',
%YAML 1.1
---
foo: bar
END_YAML
[ { foo => 'bar' } ],
'predocument_1_1',
noyamlpm => 1,
nosyck => 1,
noyamlperl => 1,
);
# Multiple inline documents (comment variant)
yaml_ok(
<<'END_YAML',
--- #YAML:1.0
foo: bar
--- #YAML:1.0
- 1
--- #YAML:1.0
foo: bar
END_YAML
[ { foo => 'bar' }, [ 1 ], { foo => 'bar' } ],
'multi_doctype_comment',
);
# Simple pre-document case (comment variant)
yaml_ok(
<<'END_YAML',
%YAML 1.1
---
foo: bar
END_YAML
[ { foo => 'bar' } ],
'predocument_percent',
noyamlpm => 1,
nosyck => 1,
noyamlperl => 1,
);
# Simple pre-document case (comment variant)
yaml_ok(
<<'END_YAML',
#YAML 1.1
---
foo: bar
END_YAML
[ { foo => 'bar' } ],
'predocument_comment',
);
#####################################################################
# Hitchhiker Scalar
yaml_ok(
<<'END_YAML',
--- 42
END_YAML
[ 42 ],
'hitchhiker scalar',
serializes => 1,
);
#####################################################################
# Null HASH/ARRAY
yaml_ok(
<<'END_YAML',
---
- foo
- {}
- bar
END_YAML
[ [ 'foo', {}, 'bar' ] ],
'null hash in array',
);
yaml_ok(
<<'END_YAML',
---
- foo
- []
- bar
END_YAML
[ [ 'foo', [], 'bar' ] ],
'null array in array',
);
yaml_ok(
<<'END_YAML',
---
foo: {}
bar: 1
END_YAML
[ { foo => {}, bar => 1 } ],
'null hash in hash',
);
yaml_ok(
<<'END_YAML',
---
foo: []
bar: 1
END_YAML
[ { foo => [], bar => 1 } ],
'null array in hash',
);
#####################################################################
# Trailing Whitespace
yaml_ok(
<<'END_YAML',
---
abstract: Generate fractal curves
foo: ~
arr:
- foo
- ~
- 'bar'
END_YAML
[ {
abstract => 'Generate fractal curves',
foo => undef,
arr => [ 'foo', undef, 'bar' ],
} ],
'trailing whitespace',
noyamlperl => 1,
);
#####################################################################
# Quote vs Hash
yaml_ok(
<<'END_YAML',
---
author:
- 'mst: Matt S. Trout <mst@shadowcatsystems.co.uk>'
END_YAML
[ { author => [ 'mst: Matt S. Trout <mst@shadowcatsystems.co.uk>' ] } ],
'hash-like quote',
);
#####################################################################
# Quote and Escaping Idiosyncracies
yaml_ok(
<<'END_YAML',
---
name1: 'O''Reilly'
name2: 'O''Reilly O''Tool'
name3: 'Double '''' Quote'
END_YAML
[ {
name1 => "O'Reilly",
name2 => "O'Reilly O'Tool",
name3 => "Double '' Quote",
} ],
'single quote subtleties',
);
yaml_ok(
<<'END_YAML',
---
slash1: '\\'
slash2: '\\foo'
slash3: '\\foo\\\\'
END_YAML
[ {
slash1 => "\\\\",
slash2 => "\\\\foo",
slash3 => "\\\\foo\\\\\\\\",
} ],
'single quote subtleties',
);
#####################################################################
# Empty Values and Premature EOF
yaml_ok(
<<'END_YAML',
---
foo: 0
requires:
build_requires:
END_YAML
[ { foo => 0, requires => undef, build_requires => undef } ],
'empty hash keys',
noyamlpm => 1,
noyamlperl => 1,
);
yaml_ok(
<<'END_YAML',
---
- foo
-
-
END_YAML
[ [ 'foo', undef, undef ] ],
'empty array keys',
noyamlpm => 1,
noyamlperl => 1,
);
#####################################################################
# Comment on the Document Line
yaml_ok(
<<'END_YAML',
--- # Comment
foo: bar
END_YAML
[ { foo => 'bar' } ],
'comment header',
noyamlpm => 1,
noyamlperl => 1,
);
#####################################################################
# Newlines and tabs
yaml_ok(
<<'END_YAML',
foo: "foo\\\n\tbar"
END_YAML
[ { foo => "foo\\\n\tbar" } ],
'special characters',
);
#####################################################################
# Circular Reference Protection
SCOPE: {
my $foo = { a => 'b' };
my $bar = [ $foo, 2 ];
$foo->{c} = $bar;
my $circ = CPAN::Meta::YAML->new( [ $foo, $bar ] );
isa_ok( $circ, 'CPAN::Meta::YAML' );
# When we try to serialize, it should NOT infinite loop
my $string = undef;
$string = eval { $circ->write_string; };
is( $string, undef, '->write_string does not return a value' );
ok( $@, 'Error string is defined' );
ok(
$@ =~ /does not support circular references/,
'Got the expected error message',
);
}
#####################################################################
# Confirm we can read the synopsis
yaml_ok(
<<'END_YAML',
---
rootproperty: blah
section:
one: two
three: four
Foo: Bar
empty: ~
END_YAML
[ {
rootproperty => 'blah',
section => {
one => 'two',
three => 'four',
Foo => 'Bar',
empty => undef,
},
} ],
'synopsis',
noyamlperl => 1,
);
#####################################################################
# Unprintable Characters
yaml_ok(
"--- \"foo\\n\\x00\"\n",
[ "foo\n\0" ],
'unprintable',
);
#####################################################################
# Empty Quote Line
yaml_ok(
<<'END_YAML',
---
- foo
#
- bar
END_YAML
[ [ "foo", "bar" ] ],
);
#####################################################################
# Indentation after empty hash value
yaml_ok(
<<'END_YAML',
---
Test:
optmods:
Bad: 0
Foo: 1
Long: 0
version: 5
Test_IncludeA:
optmods:
Test_IncludeB:
optmods:
_meta:
name: 'test profile'
note: 'note this test profile'
END_YAML
[ {
Test => {
optmods => {
Bad => 0,
Foo => 1,
Long => 0,
},
version => 5,
},
Test_IncludeA => {
optmods => undef,
},
Test_IncludeB => {
optmods => undef,
},
_meta => {
name => 'test profile',
note => 'note this test profile',
},
} ],
'Indentation after empty hash value',
noyamlperl => 1,
);
#####################################################################
# Spaces in the Key
yaml_ok(
<<'END_YAML',
---
the key: the value
END_YAML
[ { 'the key' => 'the value' } ],
);
#####################################################################
# Ticker #32402
# Tests a particular pathological case
yaml_ok(
<<'END_YAML',
---
- value
- '><'
END_YAML
[ [ 'value', '><' ] ],
'Pathological >< case',
);
#####################################################################
# Special Characters
#yaml_ok(
# <<'END_YAML',
#---
#- "Ingy d\xC3\xB6t Net"
#END_YAML
# [ [ "Ingy d\xC3\xB6t Net" ] ],
#);
######################################################################
# Non-Indenting Sub-List
yaml_ok(
<<'END_YAML',
---
foo:
- list
bar: value
END_YAML
[ { foo => [ 'list' ], bar => 'value' } ],
'Non-indenting sub-list',
noyamlpm => 1,
noyamlperl => 1,
);
#####################################################################
# Check Multiple-Escaping
# RT #42119: write of two single quotes
yaml_ok(
"--- \"A'B'C\"\n",
[ "A'B'C" ],
'Multiple escaping of quote ok',
);
# Escapes without whitespace
yaml_ok(
"--- A\\B\\C\n",
[ "A\\B\\C" ],
'Multiple escaping of escape ok',
);
# Escapes with whitespace
yaml_ok(
"--- 'A\\B \\C'\n",
[ "A\\B \\C" ],
'Multiple escaping of escape with whitespace ok',
);
######################################################################
# Check illegal characters that are in legal places
yaml_ok(
"--- 'Wow!'\n",
[ "Wow!" ],
'Bang in a quote',
);
yaml_ok(
"--- 'This&that'\n",
[ "This&that" ],
'Ampersand in a quote',
);
######################################################################
# Check for unescaped boolean keywords
is_deeply(
CPAN::Meta::YAML->new( 'True' )->write_string,
"--- 'True'\n",
'Idiomatic trivial boolean string is escaped',
);
is_deeply( CPAN::Meta::YAML->new( [ qw{
null Null NULL
y Y yes Yes YES n N no No NO
true True TRUE false False FALSE
on On ON off Off OFF
} ] )->write_string, <<'END_YAML' );
---
- 'null'
- 'Null'
- 'NULL'
- 'y'
- 'Y'
- 'yes'
- 'Yes'
- 'YES'
- 'n'
- 'N'
- 'no'
- 'No'
- 'NO'
- 'true'
- 'True'
- 'TRUE'
- 'false'
- 'False'
- 'FALSE'
- 'on'
- 'On'
- 'ON'
- 'off'
- 'Off'
- 'OFF'
END_YAML