Params-ValidationCompiler-0.30/0000775000175000017500000000000013330066233016303 5ustar autarchautarchParams-ValidationCompiler-0.30/lib/0000775000175000017500000000000013330066233017051 5ustar autarchautarchParams-ValidationCompiler-0.30/lib/Params/0000775000175000017500000000000013330066233020274 5ustar autarchautarchParams-ValidationCompiler-0.30/lib/Params/ValidationCompiler/0000775000175000017500000000000013330066233024061 5ustar autarchautarchParams-ValidationCompiler-0.30/lib/Params/ValidationCompiler/Exceptions.pm0000644000175000017500000000550313330066233026541 0ustar autarchautarchpackage Params::ValidationCompiler::Exceptions; use strict; use warnings; our $VERSION = '0.30'; use Exception::Class ( 'Params::ValidationCompiler::Exception::BadArguments', 'Params::ValidationCompiler::Exception::Named::Extra' => { fields => ['parameters'], }, 'Params::ValidationCompiler::Exception::Named::Required' => { fields => ['parameter'], }, 'Params::ValidationCompiler::Exception::Positional::Extra' => { fields => [ 'got', 'maximum' ], }, 'Params::ValidationCompiler::Exception::Positional::Required' => { fields => [ 'got', 'minimum' ], }, 'Params::ValidationCompiler::Exception::ValidationFailedForMooseTypeConstraint' => { fields => [qw( parameter value type )], }, ); 1; # ABSTRACT: Defines exceptions thrown by Params::ValidationCompiler __END__ =pod =encoding UTF-8 =head1 NAME Params::ValidationCompiler::Exceptions - Defines exceptions thrown by Params::ValidationCompiler =head1 VERSION version 0.30 =head1 DESCRIPTION This module defines the following exceptions: =head2 Params::ValidationCompiler::Exception::BadArguments Exception thrown when @_ does not contain a hash or hashref. =head2 Params::ValidationCompiler::Exception::Named::Extra Exception thrown when @_ contains unexpected extra named arguments. =head2 Params::ValidationCompiler::Exception::Named::Required Exception thrown when a required named parameter is not passed. =head2 Params::ValidationCompiler::Exception::Positional::Extra Exception thrown when @_ contains unexpected extra arguments. =head2 Params::ValidationCompiler::Exception::Positional::Required Exception thrown when a required positional parameter is not passed. =head2 Params::ValidationCompiler::Exception::ValidationFailedForMooseTypeConstraint Exception thrown when a Moose type constraint check fails. This class provides the following methods: =head3 $e->parameter This returns a string describing the parameter, something like C or C. =head3 $e->value This is the value that failed the type constraint check. =head3 $e->type This is the type constraint object that did not accept the value. =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Params-ValidationCompiler can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2016 - 2018 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Params-ValidationCompiler-0.30/lib/Params/ValidationCompiler/Compiler.pm0000644000175000017500000006623613330066233026204 0ustar autarchautarchpackage Params::ValidationCompiler::Compiler; use strict; use warnings; our $VERSION = '0.30'; use Carp qw( croak ); use Eval::Closure qw( eval_closure ); use List::Util 1.29 qw( pairkeys pairvalues ); use Params::ValidationCompiler::Exceptions; use Scalar::Util qw( blessed looks_like_number reftype ); use overload (); use B qw( perlstring ); our @CARP_NOT = ( 'Params::ValidationCompiler', __PACKAGE__ ); BEGIN { ## no critic (Variables::RequireInitializationForLocalVars) local $@; my $has_sub_util = eval { require Sub::Util; Sub::Util->VERSION(1.40); Sub::Util->import('set_subname'); 1; }; sub HAS_SUB_UTIL () {$has_sub_util} unless ($has_sub_util) { *set_subname = sub { croak 'Cannot name a generated validation subroutine. Please install Sub::Util.'; }; } my $has_cxsa = eval { require Class::XSAccessor; 1; }; sub HAS_CXSA {$has_cxsa} } my %known = map { $_ => 1 } qw( debug name name_is_optional named_to_list params return_object slurpy ); # I'd rather use Moo here but I want to make things relatively high on the # CPAN river like DateTime use this distro, so reducing deps is important. sub new { my $class = shift; my %p = @_; unless ( exists $p{params} ) { croak q{You must provide a "params" parameter when creating a parameter validator}; } if ( ref $p{params} eq 'HASH' ) { croak q{The "params" hashref must contain at least one key-value pair} unless %{ $p{params} }; croak q{"named_to_list" must be used with arrayref params containing key-value pairs} if $p{named_to_list}; $class->_validate_param_spec($_) for values %{ $p{params} }; } elsif ( ref $p{params} eq 'ARRAY' ) { croak q{The "params" arrayref must contain at least one element} unless @{ $p{params} }; croak q{You can only use "return_object" with named params} if $p{return_object}; my @specs = $p{named_to_list} ? pairvalues @{ $p{params} } : @{ $p{params} }; $class->_validate_param_spec($_) for @specs; } else { my $type = _describe( $p{params} ); croak qq{The "params" parameter when creating a parameter validator must be a hashref or arrayref, you passed $type}; } if ( $p{named_to_list} && $p{slurpy} ) { croak q{You cannot use "named_to_list" and "slurpy" together}; } if ( exists $p{name} && ( !defined $p{name} || ref $p{name} ) ) { my $type = _describe( $p{name} ); croak qq{The "name" parameter when creating a parameter validator must be a scalar, you passed $type}; } if ( $p{return_object} && $p{slurpy} ) { croak q{You cannot use "return_object" and "slurpy" together}; } my @unknown = sort grep { !$known{$_} } keys %p; if (@unknown) { croak "You passed unknown parameters when creating a parameter validator: [@unknown]"; } my $self = bless \%p, $class; $self->{_source} = []; $self->{_env} = {}; return $self; } sub _describe { my $thing = shift; if ( !defined $thing ) { return 'an undef'; } elsif ( my $class = blessed $thing ) { my $article = $class =~ /^[aeiou]/i ? 'an' : 'a'; return "$article $class object"; } elsif ( ref $thing ) { my $ref = lc ref $thing; my $article = $ref =~ /^[aeiou]/i ? 'an' : 'a'; return "$article $ref" . 'ref'; } return 'a scalar'; } { my %known_keys = ( default => 1, getter => 1, optional => 1, predicate => 1, type => 1, ); sub _validate_param_spec { shift; my $spec = shift; my $ref = ref $spec; return unless $ref; croak "Specifications must be a scalar or hashref, but received a $ref" unless $ref eq 'HASH'; my @unknown = sort grep { !$known_keys{$_} } keys %{$spec}; if (@unknown) { croak "Specification contains unknown keys: [@unknown]"; } } } sub name { $_[0]->{name} } sub _has_name { exists $_[0]->{name} } sub _name_is_optional { $_[0]->{name_is_optional} } # I have no idea why critic thinks _caller isn't used. ## no critic (Subroutines::ProhibitUnusedPrivateSubroutines) sub _caller { $_[0]->{caller} } ## use critic sub _has_caller { exists $_[0]->{caller} } sub params { $_[0]->{params} } sub slurpy { $_[0]->{slurpy} } sub _source { $_[0]->{_source} } sub _env { $_[0]->{_env} } sub named_to_list { $_[0]->{named_to_list} } sub return_object { $_[0]->{return_object} } sub _inlineable_name { return defined $_[0]->{name} ? $_[0]->{name} : 'an un-named validation subroutine'; } sub _any_type_has_coercion { my $self = shift; return $self->{_has_coercion} if exists $self->{_has_coercion}; for my $type ( $self->_types ) { # Specio if ( $type->can('has_coercions') && $type->has_coercions ) { return $self->{_has_coercion} = 1; } # Moose and Type::Tiny elsif ( $type->can('has_coercion') && $type->has_coercion ) { return $self->{_has_coercion} = 1; } } return $self->{_has_coercion} = 0; } sub _types { my $self = shift; my @types; if ( ref $self->params eq 'HASH' ) { @types = map { $_->{type} || () } grep { ref $_ } values %{ $self->params }; } elsif ( ref $self->params eq 'ARRAY' ) { if ( $self->named_to_list ) { my %p = @{ $self->params }; @types = map { $_->{type} || () } grep { ref $_ } values %p; } else { @types = map { $_->{type} || () } grep { ref $_ } @{ $self->params }; } } push @types, $self->slurpy if $self->slurpy && ref $self->slurpy; return @types; } sub subref { my $self = shift; $self->_compile; local $ENV{EVAL_CLOSURE_PRINT_SOURCE} = 1 if $self->{debug}; my $sub = eval_closure( source => 'sub { ' . ( join "\n", @{ $self->_source } ) . ' };', environment => $self->_env, ); if ( $self->_has_name ) { my $caller = $self->_has_caller ? $self->_caller : caller(1); my $name = join '::', $caller, $self->name; return $sub if $self->_name_is_optional && !HAS_SUB_UTIL; set_subname( $name, $sub ); } return $sub; } sub source { my $self = shift; $self->_compile; return ( ( join "\n", @{ $self->_source } ), $self->_env, ); } sub _compile { my $self = shift; if ( ref $self->params eq 'HASH' ) { $self->_compile_named_args_check; } elsif ( ref $self->params eq 'ARRAY' ) { if ( $self->named_to_list ) { $self->_compile_named_args_list_check; } else { $self->_compile_positional_args_check; } } } sub _compile_named_args_check { my $self = shift; $self->_compile_named_args_check_body( $self->params ); if ( $self->return_object ) { push @{ $self->_source }, $self->_add_return_named_args_object; } else { push @{ $self->_source }, 'return %args;'; } return; } { my $class_id = 0; sub _add_return_named_args_object { my $self = shift; my $params = $self->params; my %getters; my %predicates; for my $p ( keys %{$params} ) { $getters{ ref $params->{$p} && exists $params->{$p}{getter} ? $params->{$p}{getter} : $p } = $p; $predicates{ $params->{$p}{predicate} } = $p if ref $params->{$p} && exists $params->{$p}{predicate}; } my $use_cxsa = HAS_CXSA && !$ENV{TEST_NAMED_ARGS_OBJECT_WITHOUT_CXSA}; my $class = sprintf( '%s::OO::Args%d::%s', __PACKAGE__, $class_id++, $use_cxsa ? 'XS' : 'PP', ); if ($use_cxsa) { $self->_create_cxsa_return_class( $class, \%getters, \%predicates, ); } else { $self->_create_pp_return_class( $class, \%getters, \%predicates ); } return sprintf( 'bless \%%args, %s', perlstring($class) ); } } sub _create_cxsa_return_class { my $self = shift; my $class = shift; my $getters = shift; my $predicates = shift; Class::XSAccessor->import( redefine => 1, class => $class, getters => $getters, exists_predicates => $predicates, ); return; } sub _create_pp_return_class { my $self = shift; my $class = shift; my $getters = shift; my $predicates = shift; my @source = sprintf( 'package %s;', $class ); for my $sub ( keys %{$getters} ) { push @source, sprintf( 'sub %s { return $_[0]->{%s} }', $sub, perlstring( $getters->{$sub} ) ); } for my $sub ( keys %{$predicates} ) { push @source, sprintf( 'sub %s { return exists $_[0]->{%s} }', $sub, perlstring( $predicates->{$sub} ) ); } push @source, q{1;}; ## no critic (BuiltinFunctions::ProhibitStringyEval, ErrorHandling::RequireCheckingReturnValueOfEval) eval join q{}, @source or die $@; return; } sub _compile_named_args_list_check { my $self = shift; $self->_compile_named_args_check_body( { @{ $self->params } } ); my @keys = map { perlstring($_) } pairkeys @{ $self->params }; # If we don't handle the one-key case specially we end up getting a # warning like "Scalar value @args{"bar"} better written as $args{"bar"} # at ..." if ( @keys == 1 ) { push @{ $self->_source }, "return \$args{$keys[0]};"; } else { my $keys_str = join q{, }, @keys; push @{ $self->_source }, "return \@args{$keys_str};"; } return; } sub _compile_named_args_check_body { my $self = shift; my $params = shift; push @{ $self->_source }, $self->_set_named_args_hash; for my $name ( sort keys %{$params} ) { my $spec = $params->{$name}; $spec = { optional => !$spec } unless ref $spec; my $qname = perlstring($name); my $access = "\$args{$qname}"; # We check exists $spec->{optional} so as not to blow up on a # restricted hash. $self->_add_check_for_required_named_param( $access, $name ) unless ( exists $spec->{optional} && $spec->{optional} ) || exists $spec->{default}; $self->_add_named_default_assignment( $access, $name, $spec->{default} ) if exists $spec->{default}; # Same issue with restricted hashes here. $self->_add_type_check( $access, $name, $spec ) if exists $spec->{type} && $spec->{type}; } if ( $self->slurpy ) { $self->_add_check_for_extra_hash_param_types( $self->slurpy, $params ) if ref $self->slurpy; } else { $self->_add_check_for_extra_hash_params($params); } return; } sub _set_named_args_hash { my $self = shift; push @{ $self->_source }, sprintf( <<'EOF', ( $self->_inlineable_name ) x 4 ); my %%args; if ( @_ %% 2 == 0 ) { %%args = @_; } elsif ( @_ == 1 ) { if ( ref $_[0] ) { if ( Scalar::Util::blessed( $_[0] ) ) { if ( overload::Overloaded( $_[0] ) && defined overload::Method( $_[0], '%%{}' ) ) { %%args = %%{ $_[0] }; } else { Params::ValidationCompiler::Exception::BadArguments->throw( message => 'Expected a hash or hash reference but a single object argument was passed to %s', show_trace => 1, ); } } elsif ( ref $_[0] eq 'HASH' ) { %%args = %%{ $_[0] }; } else { Params::ValidationCompiler::Exception::BadArguments->throw( message => 'Expected a hash or hash reference but a single ' . ( ref $_[0] ) . ' reference argument was passed to %s', show_trace => 1, ); } } else { Params::ValidationCompiler::Exception::BadArguments->throw( message => 'Expected a hash or hash reference but a single non-reference argument was passed to %s', show_trace => 1, ); } } else { Params::ValidationCompiler::Exception::BadArguments->throw( message => 'Expected a hash or hash reference but an odd number of arguments was passed to %s', show_trace => 1, ); } EOF return; } sub _add_check_for_required_named_param { my $self = shift; my $access = shift; my $name = shift; my $qname = perlstring($name); push @{ $self->_source }, sprintf( <<'EOF', $access, $qname, $self->_inlineable_name, $qname ); exists %s or Params::ValidationCompiler::Exception::Named::Required->throw( message => %s . ' is a required parameter for %s', parameter => %s, show_trace => 1, ); EOF return; } sub _add_check_for_extra_hash_param_types { my $self = shift; my $type = shift; my $params = shift; $self->_env->{'%known'} = { map { $_ => 1 } keys %{$params} }; # We need to set the name argument to something that won't conflict with # names someone would actually use for a parameter. my $check = join q{}, $self->_type_check( '$args{$key}', '__PCC extra parameters__', $type, ); push @{ $self->_source }, sprintf( <<'EOF', $check ); for my $key ( grep { !$known{$_} } keys %%args ) { %s; } EOF return; } sub _add_check_for_extra_hash_params { my $self = shift; my $params = shift; $self->_env->{'%known'} = { map { $_ => 1 } keys %{$params} }; push @{ $self->_source }, sprintf( <<'EOF', $self->_inlineable_name ); my @extra = grep { !$known{$_} } keys %%args; if (@extra) { my $u = join ', ', sort @extra; Params::ValidationCompiler::Exception::Named::Extra->throw( message => "Found extra parameters passed to %s: [$u]", parameters => \@extra, show_trace => 1, ); } EOF return; } sub _compile_positional_args_check { my $self = shift; my @specs = $self->_munge_and_check_positional_params; my $first_optional_idx = -1; for my $i ( 0 .. $#specs ) { next unless $specs[$i]{optional} || exists $specs[$i]{default}; $first_optional_idx = $i; last; } # If optional params start anywhere after the first parameter spec then we # must require at least one param. If there are no optional params then # they're all required. $self->_add_check_for_required_positional_params( $first_optional_idx == -1 ? ( scalar @specs ) : $first_optional_idx ) if $first_optional_idx != 0; $self->_add_check_for_extra_positional_params( scalar @specs ) unless $self->slurpy; my $access_var = '$_'; my $return_var = '@_'; if ( $self->_any_type_has_coercion ) { push @{ $self->_source }, 'my @copy = @_;'; $access_var = '$copy'; $return_var = '@copy'; } for my $i ( 0 .. $#specs ) { my $spec = $specs[$i]; my $name = "Parameter $i"; my $access = sprintf( '%s[%i]', $access_var, $i ); $self->_add_positional_default_assignment( $i, $access, $name, $spec->{default} ) if exists $spec->{default}; $self->_add_type_check( $access, $name, $spec ) if $spec->{type}; } if ( ref $self->slurpy ) { $self->_add_check_for_extra_positional_param_types( scalar @specs, $self->slurpy, $access_var, ); } push @{ $self->_source }, sprintf( 'return %s;', $return_var ); return; } sub _munge_and_check_positional_params { my $self = shift; my @specs; my $in_optional = 0; for my $spec ( @{ $self->params } ) { $spec = ref $spec ? $spec : { optional => !$spec }; if ( $spec->{optional} || exists $spec->{default} ) { $in_optional = 1; } elsif ($in_optional) { croak 'Parameter list contains an optional parameter followed by a required parameter.'; } push @specs, $spec; } return @specs; } sub _add_check_for_required_positional_params { my $self = shift; my $min = shift; push @{ $self->_source }, sprintf( <<'EOF', ($min) x 2, $self->_inlineable_name, $min ); if ( @_ < %d ) { my $got = scalar @_; my $got_n = @_ == 1 ? 'parameter' : 'parameters'; Params::ValidationCompiler::Exception::Positional::Required->throw( message => "Got $got $got_n but expected at least %d for %s", minimum => %d, got => scalar @_, show_trace => 1, ); } EOF return; } sub _add_check_for_extra_positional_param_types { my $self = shift; my $max = shift; my $type = shift; my $access_var = shift; # We need to set the name argument to something that won't conflict with # names someone would actually use for a parameter. my $check = join q{}, $self->_type_check( sprintf( '%s[$i]', $access_var ), '__PCC extra parameters__', $type, ); push @{ $self->_source }, sprintf( <<'EOF', $max, $max, $check ); if ( @_ > %d ) { for my $i ( %d .. $#_ ) { %s; } } EOF return; } sub _add_check_for_extra_positional_params { my $self = shift; my $max = shift; push @{ $self->_source }, sprintf( <<'EOF', ($max) x 2, $self->_inlineable_name, $max ); if ( @_ > %d ) { my $extra = @_ - %d; my $extra_n = $extra == 1 ? 'parameter' : 'parameters'; Params::ValidationCompiler::Exception::Positional::Extra->throw( message => "Got $extra extra $extra_n for %s", maximum => %d, got => scalar @_, show_trace => 1, ); } EOF return; } sub _add_positional_default_assignment { my $self = shift; my $position = shift; my $access = shift; my $name = shift; my $default = shift; push @{ $self->_source }, "if ( \$#_ < $position ) {"; $self->_add_shared_default_assignment( $access, $name, $default ); push @{ $self->_source }, '}'; return; } sub _add_named_default_assignment { my $self = shift; my $access = shift; my $name = shift; my $default = shift; my $qname = perlstring($name); push @{ $self->_source }, "unless ( exists \$args{$qname} ) {"; $self->_add_shared_default_assignment( $access, $name, $default ); push @{ $self->_source }, '}'; return; } sub _add_shared_default_assignment { my $self = shift; my $access = shift; my $name = shift; my $default = shift; my $qname = perlstring($name); croak 'Default must be either a plain scalar or a subroutine reference' if ref $default && reftype($default) ne 'CODE'; if ( ref $default ) { push @{ $self->_source }, "$access = \$defaults{$qname}->();"; $self->_env->{'%defaults'}{$name} = $default; } else { if ( defined $default ) { if ( looks_like_number($default) ) { push @{ $self->_source }, "$access = $default;"; } else { push @{ $self->_source }, "$access = " . perlstring($default) . ';'; } } else { push @{ $self->_source }, "$access = undef;"; } } return; } sub _add_type_check { my $self = shift; my $access = shift; my $name = shift; my $spec = shift; my $type = $spec->{type}; croak "Passed a type that is not an object for $name: $type" unless blessed $type; push @{ $self->_source }, sprintf( 'if ( exists %s ) {', $access ) if $spec->{optional}; push @{ $self->_source }, $self->_type_check( $access, $name, $spec->{type} ); push @{ $self->_source }, '}' if $spec->{optional}; return; } sub _type_check { my $self = shift; my $access = shift; my $name = shift; my $type = shift; # Specio return $type->can('can_inline_coercion_and_check') ? $self->_add_specio_check( $access, $name, $type ) # Type::Tiny : $type->can('inline_assert') ? $self->_add_type_tiny_check( $access, $name, $type ) # Moose : $type->can('can_be_inlined') ? $self->_add_moose_check( $access, $name, $type ) : croak 'Unknown type object ' . ref $type; } # From reading through the Type::Tiny source, I can't see any cases where a # Type::Tiny type or coercion needs to provide any environment variables to # compile with. sub _add_type_tiny_check { my $self = shift; my $access = shift; my $name = shift; my $type = shift; my $qname = perlstring($name); my @source; if ( $type->has_coercion ) { my $coercion = $type->coercion; if ( $coercion->can_be_inlined ) { push @source, "$access = " . $coercion->inline_coercion($access) . ';'; } else { $self->_env->{'%tt_coercions'}{$name} = $coercion->compiled_coercion; push @source, sprintf( '%s = $tt_coercions{%s}->( %s );', $access, $qname, $access, ); } } if ( $type->can_be_inlined ) { push @source, $type->inline_assert($access); } else { push @source, sprintf( '$types{%s}->assert_valid( %s );', $qname, $access, ); $self->_env->{'%types'}{$name} = $type; } return @source; } sub _add_specio_check { my $self = shift; my $access = shift; my $name = shift; my $type = shift; my $qname = perlstring($name); my @source; if ( $type->can_inline_coercion_and_check ) { if ( $type->has_coercions ) { my ( $source, $env ) = $type->inline_coercion_and_check($access); push @source, sprintf( '%s = %s;', $access, $source ); $self->_add_to_environment( sprintf( 'The inline_coercion_and_check for %s ', $type->_description ), $env, ); } else { my ( $source, $env ) = $type->inline_assert($access); push @source, $source . ';'; $self->_add_to_environment( sprintf( 'The inline_assert for %s ', $type->_description ), $env, ); } } else { my @coercions = $type->coercions; $self->_env->{'%specio_coercions'}{$name} = \@coercions; for my $i ( 0 .. $#coercions ) { my $c = $coercions[$i]; if ( $c->can_be_inlined ) { push @source, sprintf( '%s = %s if %s;', $access, $c->inline_coercion($access), $c->from->inline_check($access) ); $self->_add_to_environment( sprintf( 'The inline_coercion for %s ', $c->_description ), # This should really be public in Specio $c->_inline_environment, ); } else { push @source, sprintf( '%s = $specio_coercions{%s}[%s]->coerce(%s) if $specio_coercions{%s}[%s]->from->value_is_valid(%s);', $access, $qname, $i, $access, $qname, $i, $access ); } } push @source, sprintf( '$types{%s}->validate_or_die(%s);', $qname, $access, ); $self->_env->{'%types'}{$name} = $type; } return @source; } sub _add_moose_check { my $self = shift; my $access = shift; my $name = shift; my $type = shift; my $qname = perlstring($name); my @source; if ( $type->has_coercion ) { $self->_env->{'%moose_coercions'}{$name} = $type->coercion; push @source, sprintf( '%s = $moose_coercions{%s}->coerce( %s );', $access, $qname, $access, ); } $self->_env->{'%types'}{$name} = $type; my $code = <<'EOF'; if ( !%s ) { my $type = $types{%s}; my $param = %s; my $value = %s; my $msg = $param . q{ failed with: } . $type->get_message($value); die Params::ValidationCompiler::Exception::ValidationFailedForMooseTypeConstraint ->new( message => $msg, parameter => $param, value => $value, type => $type, ); } EOF my $check = $type->can_be_inlined ? $type->_inline_check($access) : sprintf( '$types{%s}->check( %s )', $qname, $access ); push @source, sprintf( $code, $check, $qname, $qname, $access, ); if ( $type->can_be_inlined ) { $self->_add_to_environment( sprintf( 'The %s type', $type->name ), $type->inline_environment, ); } return @source; } sub _add_to_environment { my $self = shift; my $what = shift; my $new_env = shift; my $env = $self->_env; for my $key ( keys %{$new_env} ) { if ( exists $env->{$key} ) { croak sprintf( '%s has an inline environment variable named %s' . ' that conflicts with a variable already in the environment', $what, $key ); } $self->_env->{$key} = $new_env->{$key}; } } 1; # ABSTRACT: Object that implements the check subroutine compilation __END__ =pod =encoding UTF-8 =head1 NAME Params::ValidationCompiler::Compiler - Object that implements the check subroutine compilation =head1 VERSION version 0.30 =for Pod::Coverage .* =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Params-ValidationCompiler can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2016 - 2018 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Params-ValidationCompiler-0.30/lib/Params/ValidationCompiler.pm0000644000175000017500000002320213330066233024414 0ustar autarchautarchpackage Params::ValidationCompiler; use strict; use warnings; our $VERSION = '0.30'; use Params::ValidationCompiler::Compiler; use Exporter qw( import ); our @EXPORT_OK = qw( compile source_for validation_for ); sub validation_for { return Params::ValidationCompiler::Compiler->new(@_)->subref; } ## no critic (TestingAndDebugging::ProhibitNoWarnings) no warnings 'once'; *compile = \&validation_for; ## use critic sub source_for { return Params::ValidationCompiler::Compiler->new(@_)->source; } 1; # ABSTRACT: Build an optimized subroutine parameter validator once, use it forever __END__ =pod =encoding UTF-8 =head1 NAME Params::ValidationCompiler - Build an optimized subroutine parameter validator once, use it forever =head1 VERSION version 0.30 =head1 SYNOPSIS use Types::Standard qw( Int Str ); use Params::ValidationCompiler qw( validation_for ); { my $validator = validation_for( params => { foo => { type => Int }, bar => { type => Str, optional => 1, }, baz => { type => Int, default => 42, }, }, ); sub foo { my %args = $validator->(@_); } } { my $validator = validation_for( params => [ { type => Int }, { type => Str, optional => 1, }, ], ); sub bar { my ( $int, $str ) = $validator->(@_); } } { my $validator = validation_for( params => [ foo => { type => Int }, bar => { type => Str, optional => 1, }, ], named_to_list => 1, ); sub baz { my ( $foo, $bar ) = $validator->(@_); } } =head1 DESCRIPTION This module creates a customized, highly efficient parameter checking subroutine. It can handle named or positional parameters, and can return the parameters as key/value pairs or a list of values. In addition to type checks, it also supports parameter defaults, optional parameters, and extra "slurpy" parameters. =for Pod::Coverage compile =head1 PARAMETERS This module has two options exports, C and C. Both of these subs accept the same options: =head2 params An arrayref or hashref containing a parameter specification. If you pass a hashref then the generated validator sub will expect named parameters. The C value should be a hashref where the parameter names are keys and the specs are the values. If you pass an arrayref and C is false, the validator will expect positional params. Each element of the C arrayref should be a parameter spec. If you pass an arrayref and C is true, the validator will expect named params, but will return a list of values. In this case the arrayref should contain a I of key/value pairs, where parameter names are the keys and the specs are the values. Each spec can contain either a boolean or hashref. If the spec is a boolean, this indicates required (true) or optional (false). The spec hashref accepts the following keys: =over 4 =item * type A type object. This can be a L type (from L or L), a L type, or a L type. If the type has coercions, those will always be used. =item * default This can either be a simple (non-reference) scalar or a subroutine reference. The sub ref will be called without any arguments (for now). =item * optional A boolean indicating whether or not the parameter is optional. By default, parameters are required unless you provide a default. =back =head2 slurpy If this is a simple true value, then the generated subroutine accepts additional arguments not specified in C. By default, extra arguments cause an exception. You can also pass a type constraint here, in which case all extra arguments must be values of the specified type. =head2 named_to_list If this is true, the generated subroutine will expect a list of key-value pairs or a hashref and it will return a list containing only values. The C you pass must be a arrayref of key-value pairs. The order of these pairs determines the order in which values are returned. You cannot combine C with C as there is no way to know how to order the extra return values. =head2 return_object If this is true, the generated subroutine will return an object instead of a hashref. You cannot set this option to true if you set either or C or C. The object's methods correspond to the parameter names passed to the subroutine. While calling methods on an object is slower than accessing a hashref, the advantage is that if you typo a parameter name you'll get a helpful error. If you have L installed then this will be used to create the class's methods, which makes it fairly fast. The returned object is in a generated class. Do not rely on this class name being anything in specific, and don't check this object using C, C, or anything similar. When C is true, the parameter spec hashref also accepts to the following additional keys: =over 4 =item * getter Use this to set an explicit getter method name for the parameter. By default the method name will be the same as the parameter name. Note that if the parameter name is not a valid sub name, then you will get an error compiling the validation sub unless you specify a getter for the parameter. =item * predicate Use this to ask for a predicate method to be created for this parameter. The predicate method returns true if the parameter was passed and false if it wasn't. Note that this is only useful for optional parameters, but you can ask for a predicate for any parameter. =back =head1 EXPORTS The exported subs are: =head2 validation_for(...) This returns a subroutine that implements the specific parameter checking. This subroutine expects to be given the parameters to validate in C<@_>. If all the parameters are valid, it will return the validated parameters (with defaults as appropriate), either as a list of key-value pairs or as a list of just values. If any of the parameters are invalid it will throw an exception. For validators expected named params, the generated subroutine accepts either a list of key-value pairs or a single hashref. Otherwise the validator expects a list of values. For now, you must shift off the invocant yourself. This subroutine accepts the following additional parameters: =over 4 =item * name If this is given, then the generated subroutine will be named using L. This is strongly recommended as it makes it possible to distinguish different check subroutines when profiling or in stack traces. This name will also be used in some exception messages, even if L is not available. Note that you must install L yourself separately, as it is not required by this distribution, in order to avoid requiring a compiler. =item * name_is_optional If this is true, then the name is ignored when C is not installed. If this is false, then passing a name when L cannot be loaded causes an exception. This is useful for CPAN modules where you want to set a name if you can, but you do not want to add a prerequisite on L. =item * debug Sets the C environment variable to true before calling C. This causes the source of the subroutine to be printed before it's C'd. =back =head2 source_for(...) This returns a two element list. The first is a string containing the source code for the generated sub. The second is a hashref of "environment" variables to be used when generating the subroutine. These are the arguments that are passed to L. =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Params-ValidationCompiler can be found at L. =head1 DONATIONS If you'd like to thank me for the work I've done on this module, please consider making a "donation" to me via PayPal. I spend a lot of free time creating free software, and would appreciate any support you'd care to offer. Please note that B in order for me to continue working on this particular software. I will continue to do so, inasmuch as I have in the past, for as long as it interests me. Similarly, a donation made in this way will probably not make me work on this software much more, unless I get so many donations that I can consider working on free software full time (let's all have a chuckle at that together). To donate, log into PayPal and send money to autarch@urth.org, or use the button at L. =head1 AUTHOR Dave Rolsky =head1 CONTRIBUTORS =for stopwords Gregory Oschwald Tomasz Konojacki =over 4 =item * Gregory Oschwald =item * Gregory Oschwald =item * Tomasz Konojacki =back =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2016 - 2018 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Params-ValidationCompiler-0.30/cpanfile0000644000175000017500000000457713330066233020022 0ustar autarchautarchrequires "B" => "0"; requires "Carp" => "0"; requires "Eval::Closure" => "0"; requires "Exception::Class" => "0"; requires "Exporter" => "0"; requires "List::Util" => "1.29"; requires "Scalar::Util" => "0"; requires "overload" => "0"; requires "strict" => "0"; requires "warnings" => "0"; recommends "Class::XSAccessor" => "0"; recommends "Sub::Util" => "1.40"; on 'test' => sub { requires "ExtUtils::MakeMaker" => "0"; requires "File::Spec" => "0"; requires "Hash::Util" => "0"; requires "Specio" => "0.14"; requires "Test2::Plugin::NoWarnings" => "0"; requires "Test2::Require::Module" => "0"; requires "Test2::V0" => "0"; requires "Test::More" => "1.302015"; requires "Test::Without::Module" => "0"; }; on 'test' => sub { recommends "CPAN::Meta" => "2.120900"; }; on 'configure' => sub { requires "ExtUtils::MakeMaker" => "0"; }; on 'develop' => sub { requires "Class::XSAccessor" => "0"; requires "Code::TidyAll" => "0.56"; requires "Code::TidyAll::Plugin::SortLines::Naturally" => "0.000003"; requires "Code::TidyAll::Plugin::Test::Vars" => "0.02"; requires "Const::Fast" => "0.014"; requires "File::Spec" => "0"; requires "Hash::Merge" => "0"; requires "Hash::Util" => "0"; requires "IO::Handle" => "0"; requires "IPC::Open3" => "0"; requires "List::AllUtils" => "0"; requires "Moose" => "2.0000"; requires "Parallel::ForkManager" => "1.19"; requires "Perl::Critic" => "1.126"; requires "Perl::Tidy" => "20160302"; requires "Pod::Coverage::TrustPod" => "0"; requires "Pod::Wordlist" => "0"; requires "Set::Scalar" => "0"; requires "Specio" => "0.14"; requires "Sub::Util" => "1.40"; requires "Test2::Bundle::Extended" => "0"; requires "Test2::Plugin::NoWarnings" => "0"; requires "Test2::Require::Perl" => "0"; requires "Test::CPAN::Changes" => "0.19"; requires "Test::CPAN::Meta::JSON" => "0.16"; requires "Test::Code::TidyAll" => "0.50"; requires "Test::EOL" => "0"; requires "Test::Mojibake" => "0"; requires "Test::More" => "0.96"; requires "Test::NoTabs" => "0"; requires "Test::Pod" => "1.41"; requires "Test::Pod::Coverage" => "1.08"; requires "Test::Portability::Files" => "0"; requires "Test::Spelling" => "0.12"; requires "Test::Synopsis" => "0"; requires "Test::Vars" => "0.009"; requires "Test::Version" => "2.05"; requires "Type::Tiny" => "0"; requires "Type::Utils" => "0"; requires "perl" => "5.006"; }; Params-ValidationCompiler-0.30/perlcriticrc0000644000175000017500000000347113330066233020716 0ustar autarchautarchseverity = 3 verbose = 11 theme = core + pbp + bugs + maintenance + cosmetic + complexity + security + tests + moose program-extensions = pl psgi t exclude = Subroutines::ProhibitCallsToUndeclaredSubs [BuiltinFunctions::ProhibitStringySplit] severity = 3 [CodeLayout::RequireTrailingCommas] severity = 3 [ControlStructures::ProhibitCStyleForLoops] severity = 3 [InputOutput::RequireCheckedSyscalls] functions = :builtins exclude_functions = sleep severity = 3 [RegularExpressions::ProhibitComplexRegexes] max_characters = 200 [RegularExpressions::ProhibitUnusualDelimiters] severity = 3 [Subroutines::ProhibitUnusedPrivateSubroutines] private_name_regex = _(?!build)\w+ [TestingAndDebugging::ProhibitNoWarnings] allow = redefine [ValuesAndExpressions::ProhibitEmptyQuotes] severity = 3 [ValuesAndExpressions::ProhibitInterpolationOfLiterals] severity = 3 [ValuesAndExpressions::RequireUpperCaseHeredocTerminator] severity = 3 [Variables::ProhibitPackageVars] add_packages = Carp Test::Builder [-Subroutines::RequireFinalReturn] # This incorrectly thinks signatures are prototypes. [-Subroutines::ProhibitSubroutinePrototypes] [-ErrorHandling::RequireCarping] # No need for /xsm everywhere [-RegularExpressions::RequireDotMatchAnything] [-RegularExpressions::RequireExtendedFormatting] [-RegularExpressions::RequireLineBoundaryMatching] # http://stackoverflow.com/questions/2275317/why-does-perlcritic-dislike-using-shift-to-populate-subroutine-variables [-Subroutines::RequireArgUnpacking] # "use v5.14" is more readable than "use 5.014" [-ValuesAndExpressions::ProhibitVersionStrings] # Explicitly returning undef is a _good_ thing in many cases, since it # prevents very common errors when using a sub in list context to construct a # hash and ending up with a missing value or key. [-Subroutines::ProhibitExplicitReturnUndef] Params-ValidationCompiler-0.30/eg/0000775000175000017500000000000013330066233016676 5ustar autarchautarchParams-ValidationCompiler-0.30/eg/bench-pos.pl0000644000175000017500000001322713330066233021114 0ustar autarchautarch## no critic (Moose::RequireCleanNamespace, ErrorHandling::RequireCheckingReturnValueOfEval) use strict; use warnings; use Benchmark qw( cmpthese ); use DateTime; use Moose::Util::TypeConstraints qw( class_type find_type_constraint ); use MooseX::Params::Validate; use Params::Validate qw( validate_pos SCALAR ARRAYREF ); use Params::ValidationCompiler (); use Specio::Declare; use Specio::Library::Builtins; use Test2::V0; use Test2::Plugin::DieOnFail; use Type::Params (); use Types::Standard qw( ArrayRef Dict InstanceOf Int Optional slurpy ); my $dt = DateTime->new( year => 2016 ); { my $pvc_moose = Params::ValidationCompiler::validation_for( params => [ { type => find_type_constraint('Int') }, { type => find_type_constraint('ArrayRef') }, { type => class_type('DateTime'), optional => 1 }, ], ); sub pvc_moose { return $pvc_moose->(@_); } } { is( dies { pvc_moose( 42, [ 1, 2, 3 ], $dt ); }, undef, ); is( dies { pvc_moose( 42, [ 1, 2, 3 ] ); }, undef, ); ok( dies { pvc_moose( 42, [ 1, 2, 3 ], { year => 2016 } ); } ); } sub call_pvc_moose_lives { pvc_moose( 42, [ 1, 2, 3 ], $dt ); pvc_moose( 42, [ 1, 2, 3 ] ); } sub call_pvc_moose_dies { eval { pvc_moose( 42, [ 1, 2, 3 ], { year => 2016 } ); }; } { my $pvc_tt = Params::ValidationCompiler::validation_for( params => [ { type => Int }, { type => ArrayRef }, { type => InstanceOf ['DateTime'], optional => 1 }, ], ); sub pvc_tt { return $pvc_tt->(@_); } } { is( dies { pvc_tt( 42, [ 1, 2, 3 ], $dt ); }, undef, ); is( dies { pvc_tt( 42, [ 1, 2, 3 ] ); }, undef, ); ok( dies { pvc_tt( 42, [ 1, 2, 3 ], { year => 2016 } ); } ); } sub call_pvc_tt_lives { pvc_tt( 42, [ 1, 2, 3 ], $dt ); pvc_tt( 42, [ 1, 2, 3 ] ); } sub call_pvc_tt_dies { eval { pvc_tt( 42, [ 1, 2, 3 ], { year => 2016 } ) }; } { my $pvc_specio = Params::ValidationCompiler::validation_for( params => [ { type => t('Int') }, { type => t('ArrayRef') }, { type => object_isa_type('DateTime'), optional => 1 }, ], ); sub pvc_specio { return $pvc_specio->(@_); } } { is( dies { pvc_specio( 42, [ 1, 2, 3 ], $dt ); }, undef, ); is( dies { pvc_specio( 42, [ 1, 2, 3 ] ); }, undef, ); ok( dies { pvc_specio( 42, [ 1, 2, 3 ], { year => 2016 } ); } ); } sub call_pvc_specio_lives { pvc_specio( 42, [ 1, 2, 3 ], $dt ); pvc_specio( 42, [ 1, 2, 3 ] ); } sub call_pvc_specio_dies { eval { pvc_specio( 42, [ 1, 2, 3 ], { year => 2016 } ); }; } { my @spec = ( { isa => find_type_constraint('Int') }, { isa => find_type_constraint('ArrayRef') }, { isa => class_type('DateTime'), optional => 1 }, ); sub mxpv { return pos_validated_list( \@_, @spec ); } } { is( dies { mxpv( 42, [ 1, 2, 3 ], $dt ); }, undef, ); is( dies { mxpv( 42, [ 1, 2, 3 ] ); }, undef, ); ok( dies { mxpv( 42, [ 1, 2, 3 ], { year => 2016 } ); } ); } sub call_mxpv_lives { mxpv( 42, [ 1, 2, 3 ], $dt ); mxpv( 42, [ 1, 2, 3 ] ); } sub call_mxpv_dies { eval { mxpv( 42, [ 1, 2, 3 ], { year => 2016 } ) }; } { my $tp = Type::Params::compile( Int, ArrayRef, Optional [ InstanceOf ['DateTime'] ], ); sub tp { return $tp->(@_); } } { is( dies { tp( 42, [ 1, 2, 3 ], $dt ); }, undef, ); is( dies { tp( 42, [ 1, 2, 3 ] ); }, undef, ); ok( dies { tp( 42, [ 1, 2, 3 ], { year => 2016 } ); } ); } sub call_tp_lives { tp( 42, [ 1, 2, 3 ], $dt ); tp( 42, [ 1, 2, 3 ] ); } sub call_tp_dies { eval { tp( 42, [ 1, 2, 3 ], { year => 2016 } ) }; } sub pv { return validate_pos( @_, { type => SCALAR, regex => qr/^\d+$/a, }, { type => ARRAYREF }, { isa => 'DateTime', optional => 1 }, ); } { is( dies { pv( 42, [ 1, 2, 3 ], $dt ); }, undef, ); is( dies { pv( 42, [ 1, 2, 3 ] ); }, undef, ); ok( dies { pv( 42, [ 1, 2, 3 ], { year => 2016 } ); } ); } sub call_pv_lives { pv( 42, [ 1, 2, 3 ], $dt ); pv( 42, [ 1, 2, 3 ] ); } sub call_pv_dies { eval { pv( 42, [ 1, 2, 3 ], { year => 2016 } ) }; } done_testing(); cmpthese( 500000, { pvc_moose_lives => \&call_pvc_moose_lives, pvc_tt_lives => \&call_pvc_tt_lives, pvc_specio_lives => \&call_pvc_specio_lives, mxpv_lives => \&call_mxpv_lives, tp_lives => \&call_tp_lives, pv_lives => \&call_pv_lives, } ); print "\n" or die $!; cmpthese( 50000, { pvc_moose_dies => \&call_pvc_moose_dies, pvc_tt_dies => \&call_pvc_tt_dies, pvc_specio_dies => \&call_pvc_specio_dies, mxpv_dies => \&call_mxpv_dies, tp_dies => \&call_tp_dies, pv_dies => \&call_pv_dies, }, ); Params-ValidationCompiler-0.30/eg/bench-named.pl0000644000175000017500000001501313330066233021372 0ustar autarchautarch## no critic (Moose::RequireCleanNamespace, ErrorHandling::RequireCheckingReturnValueOfEval) use strict; use warnings; use Benchmark qw( cmpthese ); use DateTime; use Moose::Util::TypeConstraints qw( class_type find_type_constraint ); use MooseX::Params::Validate; use Params::Validate qw( validate SCALAR ARRAYREF ); use Params::ValidationCompiler (); use Specio::Declare; use Specio::Library::Builtins; use Test2::V0; use Test2::Plugin::DieOnFail; use Type::Params (); use Types::Standard qw( ArrayRef Dict InstanceOf Int Optional slurpy ); my $dt = DateTime->new( year => 2016 ); { my $pvc_moose = Params::ValidationCompiler::validation_for( params => { foo => { type => find_type_constraint('Int') }, bar => { type => find_type_constraint('ArrayRef') }, baz => { type => class_type('DateTime'), optional => 1 }, } ); sub pvc_moose { return $pvc_moose->(@_); } } { is( dies { pvc_moose( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); }, undef, ); is( dies { pvc_moose( foo => 42, bar => [ 1, 2, 3 ] ); }, undef, ); ok( dies { pvc_moose( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ); } ); } sub call_pvc_moose_lives { pvc_moose( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); pvc_moose( foo => 42, bar => [ 1, 2, 3 ] ); } sub call_pvc_moose_dies { eval { pvc_moose( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ); }; } { my $pvc_tt = Params::ValidationCompiler::validation_for( params => { foo => { type => Int }, bar => { type => ArrayRef }, baz => { type => InstanceOf ['DateTime'], optional => 1 }, } ); sub pvc_tt { return $pvc_tt->(@_); } } { is( dies { pvc_tt( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); }, undef, ); is( dies { pvc_tt( foo => 42, bar => [ 1, 2, 3 ] ); }, undef, ); ok( dies { pvc_tt( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ); } ); } sub call_pvc_tt_lives { pvc_tt( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); pvc_tt( foo => 42, bar => [ 1, 2, 3 ] ); } sub call_pvc_tt_dies { eval { pvc_tt( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ) }; } { my $pvc_specio = Params::ValidationCompiler::validation_for( params => { foo => { type => t('Int') }, bar => { type => t('ArrayRef') }, baz => { type => object_isa_type('DateTime'), optional => 1 }, } ); sub pvc_specio { return $pvc_specio->(@_); } } { is( dies { pvc_specio( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); }, undef, ); is( dies { pvc_specio( foo => 42, bar => [ 1, 2, 3 ] ); }, undef, ); ok( dies { pvc_specio( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ); } ); } sub call_pvc_specio_lives { pvc_specio( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); pvc_specio( foo => 42, bar => [ 1, 2, 3 ] ); } sub call_pvc_specio_dies { eval { pvc_specio( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ); }; } { my %spec = ( foo => { isa => find_type_constraint('Int') }, bar => { isa => find_type_constraint('ArrayRef') }, baz => { isa => class_type('DateTime'), optional => 1 }, ); sub mxpv { return validated_hash( \@_, %spec ); } } { is( dies { mxpv( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); }, undef, ); is( dies { mxpv( foo => 42, bar => [ 1, 2, 3 ] ); }, undef, ); ok( dies { mxpv( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ); } ); } sub call_mxpv_lives { mxpv( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); mxpv( foo => 42, bar => [ 1, 2, 3 ] ); } sub call_mxpv_dies { eval { mxpv( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ) }; } { my $tp = Type::Params::compile_named( foo => Int, bar => ArrayRef, baz => Optional [ InstanceOf ['DateTime'] ], ); sub tp { return $tp->(@_); } } { is( dies { tp( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); }, undef, ); is( dies { tp( foo => 42, bar => [ 1, 2, 3 ] ); }, undef, ); ok( dies { tp( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ); } ); } sub call_tp_lives { tp( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); tp( foo => 42, bar => [ 1, 2, 3 ] ); } sub call_tp_dies { eval { tp( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ) }; } sub pv { validate( @_, { foo => { type => SCALAR, regex => qr/^\d+$/a, }, bar => { type => ARRAYREF }, baz => { isa => 'DateTime', optional => 1, }, }, ); } { is( dies { pv( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); }, undef, ); is( dies { pv( foo => 42, bar => [ 1, 2, 3 ] ); }, undef, ); ok( dies { pv( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ); } ); } sub call_pv_lives { pv( foo => 42, bar => [ 1, 2, 3 ], baz => $dt ); pv( foo => 42, bar => [ 1, 2, 3 ] ); } sub call_pv_dies { eval { pv( foo => 42, bar => [ 1, 2, 3 ], baz => { year => 2016 } ) }; } done_testing(); cmpthese( 100000, { pvc_moose_lives => \&call_pvc_moose_lives, pvc_tt_lives => \&call_pvc_tt_lives, pvc_specio_lives => \&call_pvc_specio_lives, mxpv_lives => \&call_mxpv_lives, tp_lives => \&call_tp_lives, pv_lives => \&call_pv_lives, } ); print "\n" or die $!; cmpthese( 50000, { pvc_moose_dies => \&call_pvc_moose_dies, pvc_tt_dies => \&call_pvc_tt_dies, pvc_specio_dies => \&call_pvc_specio_dies, mxpv_dies => \&call_mxpv_dies, tp_dies => \&call_tp_dies, pv_dies => \&call_pv_dies, }, ); Params-ValidationCompiler-0.30/INSTALL0000644000175000017500000000363613330066233017342 0ustar autarchautarchThis is the Perl distribution Params-ValidationCompiler. Installing Params-ValidationCompiler is straightforward. ## Installation with cpanm If you have cpanm, you only need one line: % cpanm Params::ValidationCompiler If it does not have permission to install modules to the current perl, cpanm will automatically set up and install to a local::lib in your home directory. See the local::lib documentation (https://metacpan.org/pod/local::lib) for details on enabling it in your environment. ## Installing with the CPAN shell Alternatively, if your CPAN shell is set up, you should just be able to do: % cpan Params::ValidationCompiler ## Manual installation As a last resort, you can manually install it. Download the tarball, untar it, install configure prerequisites (see below), then build it: % perl Makefile.PL % make && make test Then install it: % make install On Windows platforms, you should use `dmake` or `nmake`, instead of `make`. If your perl is system-managed, you can create a local::lib in your home directory to install modules to. For details, see the local::lib documentation: https://metacpan.org/pod/local::lib The prerequisites of this distribution will also have to be installed manually. The prerequisites are listed in one of the files: `MYMETA.yml` or `MYMETA.json` generated by running the manual build process described above. ## Configure Prerequisites This distribution requires other modules to be installed before this distribution's installer can be run. They can be found under the "configure_requires" key of META.yml or the "{prereqs}{configure}{requires}" key of META.json. ## Documentation Params-ValidationCompiler documentation is available as POD. You can run `perldoc` from a shell to read the documentation: % perldoc Params::ValidationCompiler For more information on installing Perl modules via CPAN, please see: https://www.cpan.org/modules/INSTALL.html Params-ValidationCompiler-0.30/appveyor.yml0000644000175000017500000000056313330066233020675 0ustar autarchautarch--- skip_tags: true cache: - C:\strawberry install: - if not exist "C:\strawberry" cinst strawberryperl -y - set PATH=C:\strawberry\perl\bin;C:\strawberry\perl\site\bin;C:\strawberry\c\bin;%PATH% - cd %APPVEYOR_BUILD_FOLDER% - cpanm --installdeps . -n build_script: - perl -e 1 test_script: - prove -lrv t/ ### __app_cisetup__ # --- {} ### __app_cisetup__ Params-ValidationCompiler-0.30/LICENSE0000644000175000017500000002152713330066233017315 0ustar autarchautarchThis software is Copyright (c) 2016 - 2018 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The Artistic License 2.0 Copyright (c) 2000-2006, The Perl Foundation. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software. You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement. Definitions "Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package. "Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures. "You" and "your" means any person who would like to copy, distribute, or modify the Package. "Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version. "Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization. "Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees. "Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder. "Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder. "Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future. "Source" form means the source code, documentation source, and configuration files for the Package. "Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form. Permission for Use and Modification Without Distribution (1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version. Permissions for Redistribution of the Standard Version (2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package. (3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License. Distribution of Modified Versions of the Package as Source (4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following: (a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version. (b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version. (c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under (i) the Original License or (ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed. Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source (5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license. (6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version. Aggregating or Linking the Package (7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation. (8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package. Items That are Not Considered Part of a Modified Version (9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license. General Provisions (10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license. (11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license. (12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder. (13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed. (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Params-ValidationCompiler-0.30/tidyall.ini0000644000175000017500000000105213330066233020442 0ustar autarchautarchignore = .build/**/* ignore = Params-ValidationCompiler-*/**/* ignore = blib/**/* ignore = t/00-* ignore = t/author-* ignore = t/release-* ignore = t/zzz-* ignore = xt/**/* [PerlCritic] select = **/*.{pl,pm,t,psgi} argv = --profile=$ROOT/perlcriticrc [PerlCritic non-auto-generated xt] select = xt/author/matrix.t argv = --profile=$ROOT/perlcriticrc [PerlTidy] select = **/*.{pl,pm,t,psgi} argv = --profile=$ROOT/perltidyrc [PerlTidy non-auto-generated xt] select = xt/author/matrix.t argv = --profile=$ROOT/perltidyrc [Test::Vars] select = **/*.pm Params-ValidationCompiler-0.30/CONTRIBUTING.md0000644000175000017500000000773713330066233020550 0ustar autarchautarch# CONTRIBUTING Thank you for considering contributing to this distribution. This file contains instructions that will help you work with the source code. Please note that if you have any questions or difficulties, you can reach the maintainer(s) through the bug queue described later in this document (preferred), or by emailing the releaser directly. You are not required to follow any of the steps in this document to submit a patch or bug report; these are just recommendations, intended to help you (and help us help you faster). The distribution is managed with [Dist::Zilla](https://metacpan.org/release/Dist-Zilla). However, you can still compile and test the code with the `MakeFile.PL` in the repository: perl Makefile.PL make make test You may need to satisfy some dependencies. The easiest way to satisfy dependencies is to install the last release. This is available at https://metacpan.org/release/Params-ValidationCompiler You can use [`cpanminus`](https://metacpan.org/pod/App::cpanminus) to do this without downloading the tarball first: $ cpanm --reinstall --installdeps --with-recommends Params::ValidationCompiler [`Dist::Zilla`](https://metacpan.org/pod/Dist::Zilla) is a very powerful authoring tool, but requires a number of author-specific plugins. If you would like to use it for contributing, install it from CPAN, then the following command to install the needed distros: $ dzil authordeps --missing | cpanm There may also be additional requirements not needed by the dzil build which are needed for tests or other development: $ dzil listdeps --author --missing | cpanm Or, you can use the 'dzil stale' command to install all requirements at once: $ cpanm Dist::Zilla::App::Command::stale $ dzil stale --all | cpanm You can also do this via cpanm directly: $ cpanm --reinstall --installdeps --with-develop --with-recommends Params::ValidationCompiler Once installed, here are some dzil commands you might try: $ dzil build $ dzil test $ dzil test --release $ dzil xtest $ dzil listdeps --json $ dzil build --notgz You can learn more about Dist::Zilla at http://dzil.org/. The code for this distribution is [hosted on GitHub](https://github.com/houseabsolute/Params-ValidationCompiler). You can submit code changes by forking the repository, pushing your code changes to your clone, and then submitting a pull request. See the GitHub documentation for [detailed instructions on pull requests](https://help.github.com/articles/creating-a-pull-request) If you have found a bug, but do not have an accompanying patch to fix it, you can submit an issue report [via the web](https://github.com/houseabsolute/Params-ValidationCompiler/issues). ## Continuous Integration All pull requests for this distribution will be automatically tested by [Travis](https://travis-ci.org/) and the build status will be reported on the pull request page. If your build fails, please take a look at the output. All CI results will be visible in the pull request on GitHub. Follow the appropriate links for details when tests fail. ## TidyAll This distribution uses [Code::TidyAll](https://metacpan.org/release/Code-TidyAll) to enforce a uniform coding style. This is tested as part of the author testing suite. You can install and run tidyall by running the following commands: $ cpanm Code::TidyAll $ tidyall -a Please run this before committing your changes and address any issues it brings up. ## Contributor Names If you send a patch or pull request, your name and email address will be included in the documentation as a contributor (using the attribution on the commit or patch), unless you specifically request for it not to be. If you wish to be listed under a different name or address, you should submit a pull request to the `.mailmap` file to contain the correct mapping. ## Generated By This file was generated via Dist::Zilla::Plugin::GenerateFile::FromShareDir 0.014 from a template file originating in Dist-Zilla-PluginBundle-DROLSKY-1.00. Params-ValidationCompiler-0.30/Changes0000644000175000017500000001507513330066233017604 0ustar autarchautarch0.30 2018-07-31 - Tweaked the POD formatting so that the table of contents generated by MetaCPAN is more useful. 0.29 2018-07-31 - Make Class::XSAccessor a recommended dep, not a required one. 0.28 2018-07-31 - Added a new option for named params, "return_object". This causes the validation sub to return an object with methods for each param rather than a hashref. This is a great way to avoid typos in hash keys. This idea (and some of the implementation) was shamelessly stolen from Toby Inkster's Type::Params module. 0.27 2018-02-11 - Fixed a bug with inlining Moose types. If a type's parent needed environment variables those would not get closed over. Reported by Mark Fowler. GH #22. - Added a debug option to dump the source of the subroutine before it is eval'd. 0.26 2017-11-28 - The exceptions.t test would fail if Sub::Util was not installed. Reported by Paul Howarth. GH #19. - Fix test failures on Windows. GH #20. 0.25 2017-11-23 - All exceptions now include a stack trace by default when treated as a string. This makes finding where validation failed a lot easier. Fixes GH #18. - The name for a subroutine is now used in some exception messages, even if Sub::Util cannot be installed. 0.24 2017-04-08 - The source_for() exported by Params::ValidationCompiler did not work at all. Reported by Diab Jerius. GH #16. 0.23 2017-01-23 - Trying to create a validator for positional parameters where a required param came after one with a default did not throw an exception. - A positional params validator with a slurpy type which had coercions did not return the coerced values. It returned the original values instead. 0.22 2016-12-31 - Explicitly load the B module. Previously the code relied on this already being loaded by something else. Fixed by Tomasz Konojacki. PR #11. - Removed the alpha warning from the docs. 0.21 2016-12-06 - Switched to using GitHub issues. 0.20 2016-12-05 - The keys for parameter specifications are now validated. If an unknown key is seen then an exception will be thrown. This will help you catch typos in your parameter specification. Implemented by Greg Oschwald. PR #8. 0.19 2016-11-21 - Non-inlinable Specio types caused a syntax error when used with positional params. - Positional params with coercions and defaults did not work properly. The coerced value and the default would simply not be returned in any case. 0.18 2016-11-13 - Using coercions with positional parameters could cause a "Modification of a read-only value attempted" exception when the generated code tried to assign to elements of @_. This is now fixed by making a copy if any of the types have a coercion. - Using Moose types with coercions in a positional params check would cause invalid code to be generated. This could also happen with Type::Tiny if either the type or a coercion could not be inlined. 0.17 2016-11-04 - When using positional parameters, parameters with a default are now optional. For named parameters, this was already the case. 0.16 2016-11-03 - Moose and Specio types (and coercions) which provide variables to close over when being inlined did not always compile properly. Most notable, this was not being handled at all for Moose types, and not completely handled for Specio coercions. 0.15 2016-11-03 - Previously, using a default with a positional parameter would result in an error when compiling the validator subroutine. Defaults now work with positional parameters. Implemented by Greg Oschwald. Based on PR #5. 0.14 2016-11-02 - Added a "named_to_list" option to support returning only the parameter values from a named parameter validator rather than the key-value pairs. Implemented by Greg Oschwald. Based on PR #4. - Errors from calls to validation_for() now use croak so as to show up at the call site, rather than in the internals 0.13 2016-09-16 - Small fixes to make sure that you can pass both readonly and locked hashes to both validation_for and the subroutine it creates for you. Locked hashes work and readonly hashes sort of work on some Perls. - Added a new parameter, "name_is_optional". When this is true, the "name" parameter is simply ignored when Sub::Util is not available, rather than causing an exception. - Removed List::SomeUtils as a prereq. 0.12 2016-08-16 - Require Specio for tests instead of Type::Tiny. Type::Tiny does not work with blead and the maintainer has not responded to bug reports for a while. 0.11 2016-08-14 - Use Sub::Util instead of Sub::Name as our optional sub-naming module, since Sub::Util is part of core as of 5.22. 0.10 2016-08-10 - The parameters you pass when creating a validator are now validated. - The $e->message returned when a Moose type fails now includes the parameter name or position. Adding these for other type systems will come in a future release. 0.09 2016-07-04 - Really make Sub::Name optional. 0.08 2016-07-03 - Renamed from Params-CheckCompiler to Params-ValidationCompiler. - Made Sub::Name optional. If you try to set the name of a generation validation sub without Sub::Name installed, you will get a fatal error. 0.07 2016-06-18 - Make the compiled sub for checking named params die if given a single object as an argument, even if the object is implemented using a hashref. However, if the object overloads hash dereferencing then the overloading is used. Reported by Mark Fowler. GitHub #3. - Renamed compile() to validation_for(). The latter is not a very specific name. Requested by Mark Fowler. GitHub #1. 0.06 2016-06-18 - Require Type::Tiny for tests. Reported by Slave Rezic. RT #115413. - Fix tests when Moose is installed but Devel::PartialDump is not. Reported by Slave Rezic. RT #115413. 0.05 2016-06-18 - Removed all remaining uses of Moo. 0.04 2016-06-17 - Removed more modules from test prereqs that are only used in optional tests. - Replace Throwable with Exception::Class. 0.03 2016-06-17 - Remove Moose from test prereqs. This is only used for an optional test. - When generating the source for named params checking, sort the parameters so that the order in which keys are checked is consistent. - You can now pass a name parameter when creating a check subroutine. This will be used to name the generated subroutine using Sub::Name. 0.02 2016-05-28 - Add support for positional parameters. - Add support for type checking extra parameters. - Renamed allow_extra to slurpy. 0.01 2016-05-24 - First release upon an unsuspecting world. Params-ValidationCompiler-0.30/META.json0000644000175000017500000011235013330066233017724 0ustar autarchautarch{ "abstract" : "Build an optimized subroutine parameter validator once, use it forever", "author" : [ "Dave Rolsky " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 6.012, CPAN::Meta::Converter version 2.150010", "license" : [ "artistic_2" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Params-ValidationCompiler", "prereqs" : { "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "develop" : { "requires" : { "Class::XSAccessor" : "0", "Code::TidyAll" : "0.56", "Code::TidyAll::Plugin::SortLines::Naturally" : "0.000003", "Code::TidyAll::Plugin::Test::Vars" : "0.02", "Const::Fast" : "0.014", "File::Spec" : "0", "Hash::Merge" : "0", "Hash::Util" : "0", "IO::Handle" : "0", "IPC::Open3" : "0", "List::AllUtils" : "0", "Moose" : "2.0000", "Parallel::ForkManager" : "1.19", "Perl::Critic" : "1.126", "Perl::Tidy" : "20160302", "Pod::Coverage::TrustPod" : "0", "Pod::Wordlist" : "0", "Set::Scalar" : "0", "Specio" : "0.14", "Sub::Util" : "1.40", "Test2::Bundle::Extended" : "0", "Test2::Plugin::NoWarnings" : "0", "Test2::Require::Perl" : "0", "Test::CPAN::Changes" : "0.19", "Test::CPAN::Meta::JSON" : "0.16", "Test::Code::TidyAll" : "0.50", "Test::EOL" : "0", "Test::Mojibake" : "0", "Test::More" : "0.96", "Test::NoTabs" : "0", "Test::Pod" : "1.41", "Test::Pod::Coverage" : "1.08", "Test::Portability::Files" : "0", "Test::Spelling" : "0.12", "Test::Synopsis" : "0", "Test::Vars" : "0.009", "Test::Version" : "2.05", "Type::Tiny" : "0", "Type::Utils" : "0", "perl" : "5.006" } }, "runtime" : { "recommends" : { "Class::XSAccessor" : "0", "Sub::Util" : "1.40" }, "requires" : { "B" : "0", "Carp" : "0", "Eval::Closure" : "0", "Exception::Class" : "0", "Exporter" : "0", "List::Util" : "1.29", "Scalar::Util" : "0", "overload" : "0", "strict" : "0", "warnings" : "0" } }, "test" : { "recommends" : { "CPAN::Meta" : "2.120900" }, "requires" : { "ExtUtils::MakeMaker" : "0", "File::Spec" : "0", "Hash::Util" : "0", "Specio" : "0.14", "Test2::Plugin::NoWarnings" : "0", "Test2::Require::Module" : "0", "Test2::V0" : "0", "Test::More" : "1.302015", "Test::Without::Module" : "0" } } }, "provides" : { "Params::ValidationCompiler" : { "file" : "lib/Params/ValidationCompiler.pm", "version" : "0.30" }, "Params::ValidationCompiler::Compiler" : { "file" : "lib/Params/ValidationCompiler/Compiler.pm", "version" : "0.30" }, "Params::ValidationCompiler::Exceptions" : { "file" : "lib/Params/ValidationCompiler/Exceptions.pm", "version" : "0.30" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/houseabsolute/Params-ValidationCompiler/issues" }, "homepage" : "http://metacpan.org/release/Params-ValidationCompiler", "repository" : { "type" : "git", "url" : "git://github.com/houseabsolute/Params-ValidationCompiler.git", "web" : "https://github.com/houseabsolute/Params-ValidationCompiler" } }, "version" : "0.30", "x_Dist_Zilla" : { "perl" : { "version" : "5.026002" }, "plugins" : [ { "class" : "Dist::Zilla::Plugin::Git::GatherDir", "config" : { "Dist::Zilla::Plugin::GatherDir" : { "exclude_filename" : [ "CODE_OF_CONDUCT.md", "CONTRIBUTING.md", "LICENSE", "Makefile.PL", "README.md", "cpanfile" ], "exclude_match" : [], "follow_symlinks" : 0, "include_dotfiles" : 0, "prefix" : "", "prune_directory" : [], "root" : "." }, "Dist::Zilla::Plugin::Git::GatherDir" : { "include_untracked" : 0 } }, "name" : "@DROLSKY/Git::GatherDir", "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::ManifestSkip", "name" : "@DROLSKY/ManifestSkip", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::License", "name" : "@DROLSKY/License", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::ExecDir", "name" : "@DROLSKY/ExecDir", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::ShareDir", "name" : "@DROLSKY/ShareDir", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::Manifest", "name" : "@DROLSKY/Manifest", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::CheckVersionIncrement", "name" : "@DROLSKY/CheckVersionIncrement", "version" : "0.121750" }, { "class" : "Dist::Zilla::Plugin::TestRelease", "name" : "@DROLSKY/TestRelease", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::ConfirmRelease", "name" : "@DROLSKY/ConfirmRelease", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::UploadToCPAN", "name" : "@DROLSKY/UploadToCPAN", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::VersionFromMainModule", "config" : { "Dist::Zilla::Role::ModuleMetadata" : { "Module::Metadata" : "1.000033", "version" : "0.006" } }, "name" : "@DROLSKY/VersionFromMainModule", "version" : "0.04" }, { "class" : "Dist::Zilla::Plugin::Authority", "name" : "@DROLSKY/Authority", "version" : "1.009" }, { "class" : "Dist::Zilla::Plugin::AutoPrereqs", "name" : "@DROLSKY/AutoPrereqs", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::CopyFilesFromBuild", "name" : "@DROLSKY/CopyFilesFromBuild", "version" : "0.170880" }, { "class" : "Dist::Zilla::Plugin::GitHub::Meta", "name" : "@DROLSKY/GitHub::Meta", "version" : "0.45" }, { "class" : "Dist::Zilla::Plugin::GitHub::Update", "config" : { "Dist::Zilla::Plugin::GitHub::Update" : { "metacpan" : 1 } }, "name" : "@DROLSKY/GitHub::Update", "version" : "0.45" }, { "class" : "Dist::Zilla::Plugin::MetaResources", "name" : "@DROLSKY/MetaResources", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::MetaProvides::Package", "config" : { "Dist::Zilla::Plugin::MetaProvides::Package" : { "finder_objects" : [ { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM", "version" : "6.012" } ], "include_underscores" : 0 }, "Dist::Zilla::Role::MetaProvider::Provider" : { "$Dist::Zilla::Role::MetaProvider::Provider::VERSION" : "2.002004", "inherit_missing" : 1, "inherit_version" : 1, "meta_noindex" : 1 }, "Dist::Zilla::Role::ModuleMetadata" : { "Module::Metadata" : "1.000033", "version" : "0.006" } }, "name" : "@DROLSKY/MetaProvides::Package", "version" : "2.004003" }, { "class" : "Dist::Zilla::Plugin::Meta::Contributors", "name" : "@DROLSKY/Meta::Contributors", "version" : "0.003" }, { "class" : "Dist::Zilla::Plugin::MetaConfig", "name" : "@DROLSKY/MetaConfig", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::MetaJSON", "name" : "@DROLSKY/MetaJSON", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::MetaYAML", "name" : "@DROLSKY/MetaYAML", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::NextRelease", "name" : "@DROLSKY/NextRelease", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "test", "type" : "requires" } }, "name" : "@DROLSKY/Test::More with Test2", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "develop", "type" : "requires" } }, "name" : "@DROLSKY/Modules for use with tidyall", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "develop", "type" : "requires" } }, "name" : "@DROLSKY/Test::Version which fixes https://github.com/plicease/Test-Version/issues/7", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::PromptIfStale", "config" : { "Dist::Zilla::Plugin::PromptIfStale" : { "check_all_plugins" : 0, "check_all_prereqs" : 0, "modules" : [ "Dist::Zilla::PluginBundle::DROLSKY" ], "phase" : "build", "run_under_travis" : 0, "skip" : [] } }, "name" : "@DROLSKY/Dist::Zilla::PluginBundle::DROLSKY", "version" : "0.055" }, { "class" : "Dist::Zilla::Plugin::PromptIfStale", "config" : { "Dist::Zilla::Plugin::PromptIfStale" : { "check_all_plugins" : 1, "check_all_prereqs" : 1, "modules" : [], "phase" : "release", "run_under_travis" : 0, "skip" : [ "Dist::Zilla::Plugin::DROLSKY::Contributors", "Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch", "Dist::Zilla::Plugin::DROLSKY::License", "Dist::Zilla::Plugin::DROLSKY::TidyAll", "Dist::Zilla::Plugin::DROLSKY::WeaverConfig", "Pod::Weaver::PluginBundle::DROLSKY" ] } }, "name" : "@DROLSKY/PromptIfStale", "version" : "0.055" }, { "class" : "Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable", "name" : "@DROLSKY/Test::Pod::Coverage::Configurable", "version" : "0.07" }, { "class" : "Dist::Zilla::Plugin::Test::PodSpelling", "config" : { "Dist::Zilla::Plugin::Test::PodSpelling" : { "directories" : [ "bin", "lib" ], "spell_cmd" : "", "stopwords" : [ "DROLSKY", "DROLSKY's", "PayPal", "Rolsky", "Rolsky's", "drolsky", "getter", "params", "slurpy", "uncompromised", "validator", "validators" ], "wordlist" : "Pod::Wordlist" } }, "name" : "@DROLSKY/Test::PodSpelling", "version" : "2.007005" }, { "class" : "Dist::Zilla::Plugin::PodSyntaxTests", "name" : "@DROLSKY/PodSyntaxTests", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::RunExtraTests", "config" : { "Dist::Zilla::Role::TestRunner" : { "default_jobs" : 8 } }, "name" : "@DROLSKY/DROLSKY::RunExtraTests", "version" : "1.00" }, { "class" : "Dist::Zilla::Plugin::MojibakeTests", "name" : "@DROLSKY/MojibakeTests", "version" : "0.8" }, { "class" : "Dist::Zilla::Plugin::Test::CPAN::Changes", "config" : { "Dist::Zilla::Plugin::Test::CPAN::Changes" : { "changelog" : "Changes" } }, "name" : "@DROLSKY/Test::CPAN::Changes", "version" : "0.012" }, { "class" : "Dist::Zilla::Plugin::Test::CPAN::Meta::JSON", "name" : "@DROLSKY/Test::CPAN::Meta::JSON", "version" : "0.004" }, { "class" : "Dist::Zilla::Plugin::Test::EOL", "config" : { "Dist::Zilla::Plugin::Test::EOL" : { "filename" : "xt/author/eol.t", "finder" : [ ":ExecFiles", ":InstallModules", ":TestFiles" ], "trailing_whitespace" : 1 } }, "name" : "@DROLSKY/Test::EOL", "version" : "0.19" }, { "class" : "Dist::Zilla::Plugin::Test::NoTabs", "config" : { "Dist::Zilla::Plugin::Test::NoTabs" : { "filename" : "xt/author/no-tabs.t", "finder" : [ ":InstallModules", ":ExecFiles", ":TestFiles" ] } }, "name" : "@DROLSKY/Test::NoTabs", "version" : "0.15" }, { "class" : "Dist::Zilla::Plugin::Test::Portability", "config" : { "Dist::Zilla::Plugin::Test::Portability" : { "options" : "" } }, "name" : "@DROLSKY/Test::Portability", "version" : "2.001000" }, { "class" : "Dist::Zilla::Plugin::Test::Synopsis", "name" : "@DROLSKY/Test::Synopsis", "version" : "2.000007" }, { "class" : "Dist::Zilla::Plugin::Test::TidyAll", "name" : "@DROLSKY/Test::TidyAll", "version" : "0.04" }, { "class" : "Dist::Zilla::Plugin::Test::Compile", "config" : { "Dist::Zilla::Plugin::Test::Compile" : { "bail_out_on_fail" : 0, "fail_on_warning" : "author", "fake_home" : 0, "filename" : "xt/author/00-compile.t", "module_finder" : [ ":InstallModules" ], "needs_display" : 0, "phase" : "develop", "script_finder" : [ ":PerlExecFiles" ], "skips" : [], "switch" : [] } }, "name" : "@DROLSKY/Test::Compile", "version" : "2.058" }, { "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs", "name" : "@DROLSKY/Test::ReportPrereqs", "version" : "0.027" }, { "class" : "Dist::Zilla::Plugin::Test::Version", "name" : "@DROLSKY/Test::Version", "version" : "1.09" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::Contributors", "name" : "@DROLSKY/DROLSKY::Contributors", "version" : "1.00" }, { "class" : "Dist::Zilla::Plugin::Git::Contributors", "config" : { "Dist::Zilla::Plugin::Git::Contributors" : { "git_version" : "2.7.4", "include_authors" : 0, "include_releaser" : 1, "order_by" : "name", "paths" : [] } }, "name" : "@DROLSKY/Git::Contributors", "version" : "0.034" }, { "class" : "Dist::Zilla::Plugin::SurgicalPodWeaver", "config" : { "Dist::Zilla::Plugin::PodWeaver" : { "config_plugins" : [ "@DROLSKY" ], "finder" : [ ":InstallModules", ":ExecFiles" ], "plugins" : [ { "class" : "Pod::Weaver::Plugin::EnsurePod5", "name" : "@CorePrep/EnsurePod5", "version" : "4.015" }, { "class" : "Pod::Weaver::Plugin::H1Nester", "name" : "@CorePrep/H1Nester", "version" : "4.015" }, { "class" : "Pod::Weaver::Plugin::SingleEncoding", "name" : "@DROLSKY/SingleEncoding", "version" : "4.015" }, { "class" : "Pod::Weaver::Plugin::Transformer", "name" : "@DROLSKY/List", "version" : "4.015" }, { "class" : "Pod::Weaver::Plugin::Transformer", "name" : "@DROLSKY/Verbatim", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@DROLSKY/header", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Name", "name" : "@DROLSKY/Name", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Version", "name" : "@DROLSKY/Version", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@DROLSKY/prelude", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "SYNOPSIS", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "DESCRIPTION", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "OVERVIEW", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "ATTRIBUTES", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "METHODS", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "FUNCTIONS", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "TYPES", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Leftovers", "name" : "@DROLSKY/Leftovers", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@DROLSKY/postlude", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::GenerateSection", "name" : "@DROLSKY/generate SUPPORT", "version" : "1.06" }, { "class" : "Pod::Weaver::Section::AllowOverride", "name" : "@DROLSKY/allow override SUPPORT", "version" : "0.05" }, { "class" : "Pod::Weaver::Section::GenerateSection", "name" : "@DROLSKY/generate SOURCE", "version" : "1.06" }, { "class" : "Pod::Weaver::Section::GenerateSection", "name" : "@DROLSKY/generate DONATIONS", "version" : "1.06" }, { "class" : "Pod::Weaver::Section::Authors", "name" : "@DROLSKY/Authors", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Contributors", "name" : "@DROLSKY/Contributors", "version" : "0.009" }, { "class" : "Pod::Weaver::Section::Legal", "name" : "@DROLSKY/Legal", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@DROLSKY/footer", "version" : "4.015" } ] } }, "name" : "@DROLSKY/SurgicalPodWeaver", "version" : "0.0023" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::WeaverConfig", "name" : "@DROLSKY/DROLSKY::WeaverConfig", "version" : "1.00" }, { "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", "config" : { "Dist::Zilla::Role::FileWatcher" : { "version" : "0.006" } }, "name" : "@DROLSKY/README.md in build", "version" : "0.163250" }, { "class" : "Dist::Zilla::Plugin::GenerateFile::FromShareDir", "config" : { "Dist::Zilla::Plugin::GenerateFile::FromShareDir" : { "destination_filename" : "CONTRIBUTING.md", "dist" : "Dist-Zilla-PluginBundle-DROLSKY", "encoding" : "UTF-8", "has_xs" : 0, "location" : "build", "source_filename" : "CONTRIBUTING.md" }, "Dist::Zilla::Role::RepoFileInjector" : { "allow_overwrite" : 1, "repo_root" : ".", "version" : "0.009" } }, "name" : "@DROLSKY/Generate CONTRIBUTING.md", "version" : "0.014" }, { "class" : "Dist::Zilla::Plugin::GenerateFile::FromShareDir", "config" : { "Dist::Zilla::Plugin::GenerateFile::FromShareDir" : { "destination_filename" : "CODE_OF_CONDUCT.md", "dist" : "Dist-Zilla-PluginBundle-DROLSKY", "encoding" : "UTF-8", "has_xs" : 0, "location" : "build", "source_filename" : "CODE_OF_CONDUCT.md" }, "Dist::Zilla::Role::RepoFileInjector" : { "allow_overwrite" : 1, "repo_root" : ".", "version" : "0.009" } }, "name" : "@DROLSKY/Generate CODE_OF_CONDUCT.md", "version" : "0.014" }, { "class" : "Dist::Zilla::Plugin::InstallGuide", "name" : "@DROLSKY/InstallGuide", "version" : "1.200011" }, { "class" : "Dist::Zilla::Plugin::CPANFile", "name" : "@DROLSKY/CPANFile", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::License", "name" : "@DROLSKY/DROLSKY::License", "version" : "1.00" }, { "class" : "Dist::Zilla::Plugin::CheckStrictVersion", "name" : "@DROLSKY/CheckStrictVersion", "version" : "0.001" }, { "class" : "Dist::Zilla::Plugin::CheckSelfDependency", "config" : { "Dist::Zilla::Plugin::CheckSelfDependency" : { "finder" : [ ":InstallModules" ] }, "Dist::Zilla::Role::ModuleMetadata" : { "Module::Metadata" : "1.000033", "version" : "0.006" } }, "name" : "@DROLSKY/CheckSelfDependency", "version" : "0.011" }, { "class" : "Dist::Zilla::Plugin::CheckPrereqsIndexed", "name" : "@DROLSKY/CheckPrereqsIndexed", "version" : "0.020" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch", "config" : { "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.7.4", "repo_root" : "." } }, "name" : "@DROLSKY/DROLSKY::Git::CheckFor::CorrectBranch", "version" : "1.00" }, { "class" : "Dist::Zilla::Plugin::EnsureChangesHasContent", "name" : "@DROLSKY/EnsureChangesHasContent", "version" : "0.02" }, { "class" : "Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts", "config" : { "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.7.4", "repo_root" : "." } }, "name" : "@DROLSKY/Git::CheckFor::MergeConflicts", "version" : "0.014" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::TidyAll", "name" : "@DROLSKY/DROLSKY::TidyAll", "version" : "1.00" }, { "class" : "Dist::Zilla::Plugin::Git::Check", "config" : { "Dist::Zilla::Plugin::Git::Check" : { "untracked_files" : "die" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "CODE_OF_CONDUCT.md", "CONTRIBUTING.md", "Changes", "LICENSE", "Makefile.PL", "README.md", "cpanfile", "tidyall.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.7.4", "repo_root" : "." } }, "name" : "@DROLSKY/Git::Check", "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::Git::Commit", "config" : { "Dist::Zilla::Plugin::Git::Commit" : { "add_files_in" : [], "commit_msg" : "v%v%n%n%c" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "CODE_OF_CONDUCT.md", "CONTRIBUTING.md", "Changes", "LICENSE", "Makefile.PL", "README.md", "cpanfile", "tidyall.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.7.4", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "@DROLSKY/Commit generated files", "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::Git::Tag", "config" : { "Dist::Zilla::Plugin::Git::Tag" : { "branch" : null, "changelog" : "Changes", "signed" : 0, "tag" : "v0.30", "tag_format" : "v%v", "tag_message" : "v%v" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.7.4", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "@DROLSKY/Git::Tag", "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::Git::Push", "config" : { "Dist::Zilla::Plugin::Git::Push" : { "push_to" : [ "origin" ], "remotes_must_exist" : 1 }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.7.4", "repo_root" : "." } }, "name" : "@DROLSKY/Git::Push", "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::BumpVersionAfterRelease", "config" : { "Dist::Zilla::Plugin::BumpVersionAfterRelease" : { "finders" : [ ":ExecFiles", ":InstallModules" ], "global" : 0, "munge_makefile_pl" : 1 } }, "name" : "@DROLSKY/BumpVersionAfterRelease", "version" : "0.018" }, { "class" : "Dist::Zilla::Plugin::Git::Commit", "config" : { "Dist::Zilla::Plugin::Git::Commit" : { "add_files_in" : [], "commit_msg" : "Bump version after release" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "Changes", "dist.ini" ], "allow_dirty_match" : [ "(?^:.+)" ], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.7.4", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "@DROLSKY/Commit version bump", "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::Git::Push", "config" : { "Dist::Zilla::Plugin::Git::Push" : { "push_to" : [ "origin" ], "remotes_must_exist" : 1 }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.7.4", "repo_root" : "." } }, "name" : "@DROLSKY/Push version bump", "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::MakeMaker", "config" : { "Dist::Zilla::Plugin::MakeMaker" : { "make_path" : "make", "version" : "6.012" }, "Dist::Zilla::Plugin::MakeMaker::Awesome" : { "version" : "0.47" }, "Dist::Zilla::Role::TestRunner" : { "default_jobs" : 8, "version" : "6.012" } }, "name" : "@DROLSKY/DROLSKY::MakeMaker", "version" : "1.00" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "develop", "type" : "requires" } }, "name" : "DevelopRequires", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "runtime", "type" : "recommends" } }, "name" : "Recommends", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "test", "type" : "requires" } }, "name" : "TestRequires", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":InstallModules", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":IncModules", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":TestFiles", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExtraTestFiles", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExecFiles", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":PerlExecFiles", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ShareFiles", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":MainModule", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":AllFiles", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":NoFiles", "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM", "version" : "6.012" } ], "zilla" : { "class" : "Dist::Zilla::Dist::Builder", "config" : { "is_trial" : 0 }, "version" : "6.012" } }, "x_authority" : "cpan:DROLSKY", "x_contributors" : [ "Gregory Oschwald ", "Gregory Oschwald ", "Tomasz Konojacki " ], "x_generated_by_perl" : "v5.26.2", "x_serialization_backend" : "Cpanel::JSON::XS version 4.03" } Params-ValidationCompiler-0.30/CODE_OF_CONDUCT.md0000644000175000017500000000625413330066233021107 0ustar autarchautarch# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at autarch@urth.org. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org Params-ValidationCompiler-0.30/dist.ini0000644000175000017500000000155113330066233017747 0ustar autarchautarchname = Params-ValidationCompiler author = Dave Rolsky license = Artistic_2_0 copyright_holder = Dave Rolsky copyright_year = 2016 [@DROLSKY] dist = Params-ValidationCompiler prereqs_skip = Class::XSAccessor prereqs_skip = Const::Fast prereqs_skip = Moose::Util::TypeConstraints prereqs_skip = Specio prereqs_skip = Sub::Util prereqs_skip = Types::Standard stopwords = getter stopwords = params stopwords = slurpy stopwords = uncompromised stopwords = validator stopwords = validators use_github_issues = 1 -remove = Test::CleanNamespaces [Prereqs / DevelopRequires] Class::XSAccessor = 0 Const::Fast = 0.014 Hash::Util = 0 Moose = 2.0000 Specio = 0.14 Sub::Util = 1.40 Type::Tiny = 0 [Prereqs / Recommends] Class::XSAccessor = 0 Sub::Util = 1.40 [Prereqs / TestRequires] Specio = 0.14 Params-ValidationCompiler-0.30/perltidyrc0000644000175000017500000000045513330066233020411 0ustar autarchautarch-l=78 -i=4 -ci=4 -se -b -bar -boc -vt=0 -vtc=0 -cti=0 -pt=1 -bt=1 -sbt=1 -bbt=1 -nolq -npro -nsfs --blank-lines-before-packages=0 --opening-hash-brace-right --no-outdent-long-comments --iterations=2 -wbb="% + - * / x != == >= <= =~ !~ < > | & >= < = **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x=" Params-ValidationCompiler-0.30/MANIFEST0000644000175000017500000000213013330066233017426 0ustar autarchautarch# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.012. CODE_OF_CONDUCT.md CONTRIBUTING.md Changes INSTALL LICENSE MANIFEST META.json META.yml Makefile.PL README.md appveyor.yml cpanfile dist.ini eg/bench-named.pl eg/bench-pos.pl lib/Params/ValidationCompiler.pm lib/Params/ValidationCompiler/Compiler.pm lib/Params/ValidationCompiler/Exceptions.pm perlcriticrc perltidyrc t/00-report-prereqs.dd t/00-report-prereqs.t t/default.t t/exceptions.t t/moose.t t/name-fails.t t/name.t t/named/args-check.t t/named/const-hash.t t/named/locked-hash.t t/named/required.t t/named/return-object.t t/named/slurpy.t t/pairs-to-value-list.t t/positional/default.t t/positional/required.t t/positional/slurpy.t t/self-check.t t/source_for.t t/specio.t t/type-tiny.t test-matrix.als tidyall.ini xt/author/00-compile.t xt/author/eol.t xt/author/matrix.t xt/author/mojibake.t xt/author/no-tabs.t xt/author/pod-coverage.t xt/author/pod-spell.t xt/author/pod-syntax.t xt/author/portability.t xt/author/synopsis.t xt/author/test-version.t xt/author/tidyall.t xt/release/cpan-changes.t xt/release/meta-json.t Params-ValidationCompiler-0.30/test-matrix.als0000644000175000017500000000101613330066233021261 0ustar autarchautarchone sig Validator { style: Style, specs: set Spec, slurpy: Slurpy, } abstract sig Slurpy { } enum Style { named, positional, named_to_list } sig Spec { is_required: Bool, type: Type, default: Default, } enum Bool { false, true } enum Default { absent, simple, coderef } sig Type extends Slurpy { system: TypeSystem, inlinable: Inlinable, coercions: set Coercion, } enum TypeSystem { moose, specio, type_tiny} enum Inlinable { cannot, yes, with_env } sig Coercion { inlinable: Inlinable, } run {} for 5 Params-ValidationCompiler-0.30/META.yml0000644000175000017500000005657313330066233017572 0ustar autarchautarch--- abstract: 'Build an optimized subroutine parameter validator once, use it forever' author: - 'Dave Rolsky ' build_requires: ExtUtils::MakeMaker: '0' File::Spec: '0' Hash::Util: '0' Specio: '0.14' Test2::Plugin::NoWarnings: '0' Test2::Require::Module: '0' Test2::V0: '0' Test::More: '1.302015' Test::Without::Module: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 generated_by: 'Dist::Zilla version 6.012, CPAN::Meta::Converter version 2.150010' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Params-ValidationCompiler provides: Params::ValidationCompiler: file: lib/Params/ValidationCompiler.pm version: '0.30' Params::ValidationCompiler::Compiler: file: lib/Params/ValidationCompiler/Compiler.pm version: '0.30' Params::ValidationCompiler::Exceptions: file: lib/Params/ValidationCompiler/Exceptions.pm version: '0.30' recommends: Class::XSAccessor: '0' Sub::Util: '1.40' requires: B: '0' Carp: '0' Eval::Closure: '0' Exception::Class: '0' Exporter: '0' List::Util: '1.29' Scalar::Util: '0' overload: '0' strict: '0' warnings: '0' resources: bugtracker: https://github.com/houseabsolute/Params-ValidationCompiler/issues homepage: http://metacpan.org/release/Params-ValidationCompiler repository: git://github.com/houseabsolute/Params-ValidationCompiler.git version: '0.30' x_Dist_Zilla: perl: version: '5.026002' plugins: - class: Dist::Zilla::Plugin::Git::GatherDir config: Dist::Zilla::Plugin::GatherDir: exclude_filename: - CODE_OF_CONDUCT.md - CONTRIBUTING.md - LICENSE - Makefile.PL - README.md - cpanfile exclude_match: [] follow_symlinks: 0 include_dotfiles: 0 prefix: '' prune_directory: [] root: . Dist::Zilla::Plugin::Git::GatherDir: include_untracked: 0 name: '@DROLSKY/Git::GatherDir' version: '2.045' - class: Dist::Zilla::Plugin::ManifestSkip name: '@DROLSKY/ManifestSkip' version: '6.012' - class: Dist::Zilla::Plugin::License name: '@DROLSKY/License' version: '6.012' - class: Dist::Zilla::Plugin::ExecDir name: '@DROLSKY/ExecDir' version: '6.012' - class: Dist::Zilla::Plugin::ShareDir name: '@DROLSKY/ShareDir' version: '6.012' - class: Dist::Zilla::Plugin::Manifest name: '@DROLSKY/Manifest' version: '6.012' - class: Dist::Zilla::Plugin::CheckVersionIncrement name: '@DROLSKY/CheckVersionIncrement' version: '0.121750' - class: Dist::Zilla::Plugin::TestRelease name: '@DROLSKY/TestRelease' version: '6.012' - class: Dist::Zilla::Plugin::ConfirmRelease name: '@DROLSKY/ConfirmRelease' version: '6.012' - class: Dist::Zilla::Plugin::UploadToCPAN name: '@DROLSKY/UploadToCPAN' version: '6.012' - class: Dist::Zilla::Plugin::VersionFromMainModule config: Dist::Zilla::Role::ModuleMetadata: Module::Metadata: '1.000033' version: '0.006' name: '@DROLSKY/VersionFromMainModule' version: '0.04' - class: Dist::Zilla::Plugin::Authority name: '@DROLSKY/Authority' version: '1.009' - class: Dist::Zilla::Plugin::AutoPrereqs name: '@DROLSKY/AutoPrereqs' version: '6.012' - class: Dist::Zilla::Plugin::CopyFilesFromBuild name: '@DROLSKY/CopyFilesFromBuild' version: '0.170880' - class: Dist::Zilla::Plugin::GitHub::Meta name: '@DROLSKY/GitHub::Meta' version: '0.45' - class: Dist::Zilla::Plugin::GitHub::Update config: Dist::Zilla::Plugin::GitHub::Update: metacpan: 1 name: '@DROLSKY/GitHub::Update' version: '0.45' - class: Dist::Zilla::Plugin::MetaResources name: '@DROLSKY/MetaResources' version: '6.012' - class: Dist::Zilla::Plugin::MetaProvides::Package config: Dist::Zilla::Plugin::MetaProvides::Package: finder_objects: - class: Dist::Zilla::Plugin::FinderCode name: '@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM' version: '6.012' include_underscores: 0 Dist::Zilla::Role::MetaProvider::Provider: $Dist::Zilla::Role::MetaProvider::Provider::VERSION: '2.002004' inherit_missing: '1' inherit_version: '1' meta_noindex: '1' Dist::Zilla::Role::ModuleMetadata: Module::Metadata: '1.000033' version: '0.006' name: '@DROLSKY/MetaProvides::Package' version: '2.004003' - class: Dist::Zilla::Plugin::Meta::Contributors name: '@DROLSKY/Meta::Contributors' version: '0.003' - class: Dist::Zilla::Plugin::MetaConfig name: '@DROLSKY/MetaConfig' version: '6.012' - class: Dist::Zilla::Plugin::MetaJSON name: '@DROLSKY/MetaJSON' version: '6.012' - class: Dist::Zilla::Plugin::MetaYAML name: '@DROLSKY/MetaYAML' version: '6.012' - class: Dist::Zilla::Plugin::NextRelease name: '@DROLSKY/NextRelease' version: '6.012' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: test type: requires name: '@DROLSKY/Test::More with Test2' version: '6.012' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: develop type: requires name: '@DROLSKY/Modules for use with tidyall' version: '6.012' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: develop type: requires name: '@DROLSKY/Test::Version which fixes https://github.com/plicease/Test-Version/issues/7' version: '6.012' - class: Dist::Zilla::Plugin::PromptIfStale config: Dist::Zilla::Plugin::PromptIfStale: check_all_plugins: 0 check_all_prereqs: 0 modules: - Dist::Zilla::PluginBundle::DROLSKY phase: build run_under_travis: 0 skip: [] name: '@DROLSKY/Dist::Zilla::PluginBundle::DROLSKY' version: '0.055' - class: Dist::Zilla::Plugin::PromptIfStale config: Dist::Zilla::Plugin::PromptIfStale: check_all_plugins: 1 check_all_prereqs: 1 modules: [] phase: release run_under_travis: 0 skip: - Dist::Zilla::Plugin::DROLSKY::Contributors - Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch - Dist::Zilla::Plugin::DROLSKY::License - Dist::Zilla::Plugin::DROLSKY::TidyAll - Dist::Zilla::Plugin::DROLSKY::WeaverConfig - Pod::Weaver::PluginBundle::DROLSKY name: '@DROLSKY/PromptIfStale' version: '0.055' - class: Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable name: '@DROLSKY/Test::Pod::Coverage::Configurable' version: '0.07' - class: Dist::Zilla::Plugin::Test::PodSpelling config: Dist::Zilla::Plugin::Test::PodSpelling: directories: - bin - lib spell_cmd: '' stopwords: - DROLSKY - "DROLSKY's" - PayPal - Rolsky - "Rolsky's" - drolsky - getter - params - slurpy - uncompromised - validator - validators wordlist: Pod::Wordlist name: '@DROLSKY/Test::PodSpelling' version: '2.007005' - class: Dist::Zilla::Plugin::PodSyntaxTests name: '@DROLSKY/PodSyntaxTests' version: '6.012' - class: Dist::Zilla::Plugin::DROLSKY::RunExtraTests config: Dist::Zilla::Role::TestRunner: default_jobs: 8 name: '@DROLSKY/DROLSKY::RunExtraTests' version: '1.00' - class: Dist::Zilla::Plugin::MojibakeTests name: '@DROLSKY/MojibakeTests' version: '0.8' - class: Dist::Zilla::Plugin::Test::CPAN::Changes config: Dist::Zilla::Plugin::Test::CPAN::Changes: changelog: Changes name: '@DROLSKY/Test::CPAN::Changes' version: '0.012' - class: Dist::Zilla::Plugin::Test::CPAN::Meta::JSON name: '@DROLSKY/Test::CPAN::Meta::JSON' version: '0.004' - class: Dist::Zilla::Plugin::Test::EOL config: Dist::Zilla::Plugin::Test::EOL: filename: xt/author/eol.t finder: - ':ExecFiles' - ':InstallModules' - ':TestFiles' trailing_whitespace: 1 name: '@DROLSKY/Test::EOL' version: '0.19' - class: Dist::Zilla::Plugin::Test::NoTabs config: Dist::Zilla::Plugin::Test::NoTabs: filename: xt/author/no-tabs.t finder: - ':InstallModules' - ':ExecFiles' - ':TestFiles' name: '@DROLSKY/Test::NoTabs' version: '0.15' - class: Dist::Zilla::Plugin::Test::Portability config: Dist::Zilla::Plugin::Test::Portability: options: '' name: '@DROLSKY/Test::Portability' version: '2.001000' - class: Dist::Zilla::Plugin::Test::Synopsis name: '@DROLSKY/Test::Synopsis' version: '2.000007' - class: Dist::Zilla::Plugin::Test::TidyAll name: '@DROLSKY/Test::TidyAll' version: '0.04' - class: Dist::Zilla::Plugin::Test::Compile config: Dist::Zilla::Plugin::Test::Compile: bail_out_on_fail: '0' fail_on_warning: author fake_home: 0 filename: xt/author/00-compile.t module_finder: - ':InstallModules' needs_display: 0 phase: develop script_finder: - ':PerlExecFiles' skips: [] switch: [] name: '@DROLSKY/Test::Compile' version: '2.058' - class: Dist::Zilla::Plugin::Test::ReportPrereqs name: '@DROLSKY/Test::ReportPrereqs' version: '0.027' - class: Dist::Zilla::Plugin::Test::Version name: '@DROLSKY/Test::Version' version: '1.09' - class: Dist::Zilla::Plugin::DROLSKY::Contributors name: '@DROLSKY/DROLSKY::Contributors' version: '1.00' - class: Dist::Zilla::Plugin::Git::Contributors config: Dist::Zilla::Plugin::Git::Contributors: git_version: 2.7.4 include_authors: 0 include_releaser: 1 order_by: name paths: [] name: '@DROLSKY/Git::Contributors' version: '0.034' - class: Dist::Zilla::Plugin::SurgicalPodWeaver config: Dist::Zilla::Plugin::PodWeaver: config_plugins: - '@DROLSKY' finder: - ':InstallModules' - ':ExecFiles' plugins: - class: Pod::Weaver::Plugin::EnsurePod5 name: '@CorePrep/EnsurePod5' version: '4.015' - class: Pod::Weaver::Plugin::H1Nester name: '@CorePrep/H1Nester' version: '4.015' - class: Pod::Weaver::Plugin::SingleEncoding name: '@DROLSKY/SingleEncoding' version: '4.015' - class: Pod::Weaver::Plugin::Transformer name: '@DROLSKY/List' version: '4.015' - class: Pod::Weaver::Plugin::Transformer name: '@DROLSKY/Verbatim' version: '4.015' - class: Pod::Weaver::Section::Region name: '@DROLSKY/header' version: '4.015' - class: Pod::Weaver::Section::Name name: '@DROLSKY/Name' version: '4.015' - class: Pod::Weaver::Section::Version name: '@DROLSKY/Version' version: '4.015' - class: Pod::Weaver::Section::Region name: '@DROLSKY/prelude' version: '4.015' - class: Pod::Weaver::Section::Generic name: SYNOPSIS version: '4.015' - class: Pod::Weaver::Section::Generic name: DESCRIPTION version: '4.015' - class: Pod::Weaver::Section::Generic name: OVERVIEW version: '4.015' - class: Pod::Weaver::Section::Collect name: ATTRIBUTES version: '4.015' - class: Pod::Weaver::Section::Collect name: METHODS version: '4.015' - class: Pod::Weaver::Section::Collect name: FUNCTIONS version: '4.015' - class: Pod::Weaver::Section::Collect name: TYPES version: '4.015' - class: Pod::Weaver::Section::Leftovers name: '@DROLSKY/Leftovers' version: '4.015' - class: Pod::Weaver::Section::Region name: '@DROLSKY/postlude' version: '4.015' - class: Pod::Weaver::Section::GenerateSection name: '@DROLSKY/generate SUPPORT' version: '1.06' - class: Pod::Weaver::Section::AllowOverride name: '@DROLSKY/allow override SUPPORT' version: '0.05' - class: Pod::Weaver::Section::GenerateSection name: '@DROLSKY/generate SOURCE' version: '1.06' - class: Pod::Weaver::Section::GenerateSection name: '@DROLSKY/generate DONATIONS' version: '1.06' - class: Pod::Weaver::Section::Authors name: '@DROLSKY/Authors' version: '4.015' - class: Pod::Weaver::Section::Contributors name: '@DROLSKY/Contributors' version: '0.009' - class: Pod::Weaver::Section::Legal name: '@DROLSKY/Legal' version: '4.015' - class: Pod::Weaver::Section::Region name: '@DROLSKY/footer' version: '4.015' name: '@DROLSKY/SurgicalPodWeaver' version: '0.0023' - class: Dist::Zilla::Plugin::DROLSKY::WeaverConfig name: '@DROLSKY/DROLSKY::WeaverConfig' version: '1.00' - class: Dist::Zilla::Plugin::ReadmeAnyFromPod config: Dist::Zilla::Role::FileWatcher: version: '0.006' name: '@DROLSKY/README.md in build' version: '0.163250' - class: Dist::Zilla::Plugin::GenerateFile::FromShareDir config: Dist::Zilla::Plugin::GenerateFile::FromShareDir: destination_filename: CONTRIBUTING.md dist: Dist-Zilla-PluginBundle-DROLSKY encoding: UTF-8 has_xs: '0' location: build source_filename: CONTRIBUTING.md Dist::Zilla::Role::RepoFileInjector: allow_overwrite: 1 repo_root: . version: '0.009' name: '@DROLSKY/Generate CONTRIBUTING.md' version: '0.014' - class: Dist::Zilla::Plugin::GenerateFile::FromShareDir config: Dist::Zilla::Plugin::GenerateFile::FromShareDir: destination_filename: CODE_OF_CONDUCT.md dist: Dist-Zilla-PluginBundle-DROLSKY encoding: UTF-8 has_xs: '0' location: build source_filename: CODE_OF_CONDUCT.md Dist::Zilla::Role::RepoFileInjector: allow_overwrite: 1 repo_root: . version: '0.009' name: '@DROLSKY/Generate CODE_OF_CONDUCT.md' version: '0.014' - class: Dist::Zilla::Plugin::InstallGuide name: '@DROLSKY/InstallGuide' version: '1.200011' - class: Dist::Zilla::Plugin::CPANFile name: '@DROLSKY/CPANFile' version: '6.012' - class: Dist::Zilla::Plugin::DROLSKY::License name: '@DROLSKY/DROLSKY::License' version: '1.00' - class: Dist::Zilla::Plugin::CheckStrictVersion name: '@DROLSKY/CheckStrictVersion' version: '0.001' - class: Dist::Zilla::Plugin::CheckSelfDependency config: Dist::Zilla::Plugin::CheckSelfDependency: finder: - ':InstallModules' Dist::Zilla::Role::ModuleMetadata: Module::Metadata: '1.000033' version: '0.006' name: '@DROLSKY/CheckSelfDependency' version: '0.011' - class: Dist::Zilla::Plugin::CheckPrereqsIndexed name: '@DROLSKY/CheckPrereqsIndexed' version: '0.020' - class: Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch config: Dist::Zilla::Role::Git::Repo: git_version: 2.7.4 repo_root: . name: '@DROLSKY/DROLSKY::Git::CheckFor::CorrectBranch' version: '1.00' - class: Dist::Zilla::Plugin::EnsureChangesHasContent name: '@DROLSKY/EnsureChangesHasContent' version: '0.02' - class: Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts config: Dist::Zilla::Role::Git::Repo: git_version: 2.7.4 repo_root: . name: '@DROLSKY/Git::CheckFor::MergeConflicts' version: '0.014' - class: Dist::Zilla::Plugin::DROLSKY::TidyAll name: '@DROLSKY/DROLSKY::TidyAll' version: '1.00' - class: Dist::Zilla::Plugin::Git::Check config: Dist::Zilla::Plugin::Git::Check: untracked_files: die Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - CODE_OF_CONDUCT.md - CONTRIBUTING.md - Changes - LICENSE - Makefile.PL - README.md - cpanfile - tidyall.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: git_version: 2.7.4 repo_root: . name: '@DROLSKY/Git::Check' version: '2.045' - class: Dist::Zilla::Plugin::Git::Commit config: Dist::Zilla::Plugin::Git::Commit: add_files_in: [] commit_msg: v%v%n%n%c Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - CODE_OF_CONDUCT.md - CONTRIBUTING.md - Changes - LICENSE - Makefile.PL - README.md - cpanfile - tidyall.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: git_version: 2.7.4 repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: '@DROLSKY/Commit generated files' version: '2.045' - class: Dist::Zilla::Plugin::Git::Tag config: Dist::Zilla::Plugin::Git::Tag: branch: ~ changelog: Changes signed: 0 tag: v0.30 tag_format: v%v tag_message: v%v Dist::Zilla::Role::Git::Repo: git_version: 2.7.4 repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: '@DROLSKY/Git::Tag' version: '2.045' - class: Dist::Zilla::Plugin::Git::Push config: Dist::Zilla::Plugin::Git::Push: push_to: - origin remotes_must_exist: 1 Dist::Zilla::Role::Git::Repo: git_version: 2.7.4 repo_root: . name: '@DROLSKY/Git::Push' version: '2.045' - class: Dist::Zilla::Plugin::BumpVersionAfterRelease config: Dist::Zilla::Plugin::BumpVersionAfterRelease: finders: - ':ExecFiles' - ':InstallModules' global: 0 munge_makefile_pl: 1 name: '@DROLSKY/BumpVersionAfterRelease' version: '0.018' - class: Dist::Zilla::Plugin::Git::Commit config: Dist::Zilla::Plugin::Git::Commit: add_files_in: [] commit_msg: 'Bump version after release' Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - Changes - dist.ini allow_dirty_match: - (?^:.+) changelog: Changes Dist::Zilla::Role::Git::Repo: git_version: 2.7.4 repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: '@DROLSKY/Commit version bump' version: '2.045' - class: Dist::Zilla::Plugin::Git::Push config: Dist::Zilla::Plugin::Git::Push: push_to: - origin remotes_must_exist: 1 Dist::Zilla::Role::Git::Repo: git_version: 2.7.4 repo_root: . name: '@DROLSKY/Push version bump' version: '2.045' - class: Dist::Zilla::Plugin::DROLSKY::MakeMaker config: Dist::Zilla::Plugin::MakeMaker: make_path: make version: '6.012' Dist::Zilla::Plugin::MakeMaker::Awesome: version: '0.47' Dist::Zilla::Role::TestRunner: default_jobs: 8 version: '6.012' name: '@DROLSKY/DROLSKY::MakeMaker' version: '1.00' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: develop type: requires name: DevelopRequires version: '6.012' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: runtime type: recommends name: Recommends version: '6.012' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: test type: requires name: TestRequires version: '6.012' - class: Dist::Zilla::Plugin::FinderCode name: ':InstallModules' version: '6.012' - class: Dist::Zilla::Plugin::FinderCode name: ':IncModules' version: '6.012' - class: Dist::Zilla::Plugin::FinderCode name: ':TestFiles' version: '6.012' - class: Dist::Zilla::Plugin::FinderCode name: ':ExtraTestFiles' version: '6.012' - class: Dist::Zilla::Plugin::FinderCode name: ':ExecFiles' version: '6.012' - class: Dist::Zilla::Plugin::FinderCode name: ':PerlExecFiles' version: '6.012' - class: Dist::Zilla::Plugin::FinderCode name: ':ShareFiles' version: '6.012' - class: Dist::Zilla::Plugin::FinderCode name: ':MainModule' version: '6.012' - class: Dist::Zilla::Plugin::FinderCode name: ':AllFiles' version: '6.012' - class: Dist::Zilla::Plugin::FinderCode name: ':NoFiles' version: '6.012' - class: Dist::Zilla::Plugin::FinderCode name: '@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM' version: '6.012' zilla: class: Dist::Zilla::Dist::Builder config: is_trial: '0' version: '6.012' x_authority: cpan:DROLSKY x_contributors: - 'Gregory Oschwald ' - 'Gregory Oschwald ' - 'Tomasz Konojacki ' x_generated_by_perl: v5.26.2 x_serialization_backend: 'YAML::Tiny version 1.73' Params-ValidationCompiler-0.30/t/0000775000175000017500000000000013330066233016546 5ustar autarchautarchParams-ValidationCompiler-0.30/t/default.t0000644000175000017500000000153713330066233020363 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( validation_for ); { my $sub = validation_for( params => { foo => { default => 42 }, bar => { default => undef }, baz => { default => 'string' }, buz => { default => sub { [] } }, }, ); is( { $sub->() }, { foo => 42, bar => undef, baz => 'string', buz => [], }, 'all defaults are used when no values are passed' ); is( { $sub->( foo => 99 ) }, { foo => 99, bar => undef, baz => 'string', buz => [], }, 'defaults are not used when when a value is passed' ); } done_testing(); Params-ValidationCompiler-0.30/t/name.t0000644000175000017500000000070113330066233017647 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Test2::Require::Module 'Sub::Util'; use Params::ValidationCompiler qw( validation_for ); { my $sub = validation_for( name => 'Check for X', params => { foo => 1 }, ); my $e = dies { $sub->() }; like( $e->trace->as_string, qr/main::Check for X/, 'got expected sub name in stack trace', ); } done_testing(); Params-ValidationCompiler-0.30/t/named/0000775000175000017500000000000013330066233017632 5ustar autarchautarchParams-ValidationCompiler-0.30/t/named/slurpy.t0000644000175000017500000000431513330066233021356 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( validation_for ); use Specio::Library::Builtins; { my $sub = validation_for( params => { foo => 1, bar => { optional => 1 }, }, ); like( dies { $sub->( foo => 42, extra => [] ) }, qr/Found extra parameters passed to an un-named validation subroutine: \[extra\]/, 'dies when given one extra parameter' ); like( dies { $sub->( foo => 42, extra => [], more => 0 ) }, qr/Found extra parameters passed to an un-named validation subroutine: \[extra, more\]/, 'dies when given two extra parameters' ); } { my $sub = validation_for( params => { foo => 1, }, slurpy => 1, ); like( dies { $sub->() }, qr/foo is a required parameter/, 'foo is still required when slurpy is true' ); is( { $sub->( foo => 42, bar => 'whatever', ) }, { foo => 42, bar => 'whatever', }, 'extra parameters are returned', ); } { my $sub = validation_for( params => { foo => 1, }, slurpy => t('Int'), ); like( dies { $sub->() }, qr/foo is a required parameter/, 'foo is still required when slurpy is a type constraint' ); is( { $sub->( foo => 42, bar => 43, ) }, { foo => 42, bar => 43, }, 'extra parameters are returned when they pass the type constraint', ); like( dies { $sub->( foo => 42, bar => 'string' ); }, qr/Validation failed for type named Int.+with value "string"/, 'extra parameters are type checked with one extra', ); like( dies { $sub->( foo => 42, baz => 1, bar => 'string' ); }, qr/Validation failed for type named Int.+with value "string"/, 'all extra parameters are type checked with multiple extras', ); } done_testing(); Params-ValidationCompiler-0.30/t/named/args-check.t0000644000175000017500000000300613330066233022023 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( validation_for ); { my $sub = validation_for( params => { foo => 1, }, ); like( dies { $sub->(42) }, qr/\QExpected a hash or hash reference but a single non-reference argument was passed/, 'dies when given a single non-ref argument' ); like( dies { $sub->( [] ) }, qr/\QExpected a hash or hash reference but a single ARRAY reference argument was passed/, 'dies when given a single arrayref argument' ); like( dies { $sub->( foo => 42, 'bar' ) }, qr/\QExpected a hash or hash reference but an odd number of arguments was passed/, 'dies when given three arguments' ); is( dies { $sub->( foo => 42 ) }, undef, 'lives when given two arguments' ); is( dies { $sub->( { foo => 42 } ) }, undef, 'lives when given a single hashref argument' ); like( dies { $sub->( bless { foo => 42 }, 'anything' ) }, qr/Expected a hash or hash reference but a single object argument was passed/, 'dies when passed a blessed object', ); { package OverloadsHash; use overload '%{}' => sub { return { foo => 42 } }; } is( dies { $sub->( bless [], 'OverloadsHash' ) }, undef, 'lives when given a single object that overloads hash dereferencing' ); } done_testing(); Params-ValidationCompiler-0.30/t/named/locked-hash.t0000644000175000017500000000250213330066233022176 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Test2::Require::Module 'Hash::Util'; use Hash::Util qw( lock_hash ); use Params::ValidationCompiler qw( validation_for ); use Specio::Library::Builtins; { my %spec = ( foo => 1, bar => { type => t('Int'), optional => 1, }, ); lock_hash(%spec); my $sub = validation_for( params => \%spec ); my %params1 = ( foo => 42 ); lock_hash(%params1); is( dies { $sub->(%params1) }, undef, 'lives when given foo param but no bar' ); my %params2 = ( foo => 42, bar => 42 ); lock_hash(%params2); is( dies { $sub->(%params2) }, undef, 'lives when given foo and bar params' ); } { my %spec = ( foo => 1, bar => { optional => 1, }, ); lock_hash(%spec); is( dies { validation_for( params => \%spec ) }, undef, 'can pass locked hashref as spec to validation_for' ); } { my %spec = ( foo => {}, bar => { optional => 1, }, ); lock_hash(%spec); is( dies { validation_for( params => \%spec ) }, undef, 'can pass locked hash as spec to validation_for' ); } done_testing(); Params-ValidationCompiler-0.30/t/named/const-hash.t0000644000175000017500000000425113330066233022066 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Test2::Require::Module 'Const::Fast'; use Const::Fast; use Params::ValidationCompiler qw( validation_for ); use Specio::Library::Builtins; skip_all( q{Const::Fast doesn't work on dev/blead perl. Also the tests fail on Perl 5.18 but not others for no reason I can understand} ); { # Trying to use const my %spec gives a "Can't store CODE items at # /home/autarch/.perlbrew/libs/perl-5.24.0@dev/lib/perl5/Const/Fast.pm # line 29." Presumably this is because the Specio type ultimately contains # a code ref deep inside. Is Const::Fast iterating through the object and # trying to make it readonly as well?! todo( 'cannot pass a hash with a CODE ref nested in it', sub { is( dies { const my %spec => ( foo => 1, bar => { type => t('Int'), optional => 1, }, ); }, undef, ); } ); # But somehow this works. const my $spec => { foo => 1, bar => { type => t('Int'), optional => 1, }, }; my $sub = validation_for( params => $spec ); const my %params1 => ( foo => 42 ); is( dies { $sub->(%params1) }, undef, 'lives when given foo param but no bar' ); const my %params2 => ( foo => 42, bar => 42 ); is( dies { $sub->(%params2) }, undef, 'lives when given foo and bar params' ); } { const my $spec => { foo => 1, bar => { optional => 1, }, }; is( dies { validation_for( params => $spec ) }, undef, 'can pass constant hashref as spec to validation_for' ); } { const my %spec => ( foo => {}, bar => { optional => 1, }, ); is( dies { validation_for( params => \%spec ) }, undef, 'can pass constant hash as spec to validation_for' ); } done_testing(); Params-ValidationCompiler-0.30/t/named/required.t0000644000175000017500000000136313330066233021640 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( validation_for ); use Specio::Library::Builtins; { my $sub = validation_for( params => { foo => 1, bar => { type => t('Int'), optional => 1, }, }, ); is( dies { $sub->( foo => 42 ) }, undef, 'lives when given foo param but no bar' ); is( dies { $sub->( foo => 42, bar => 42 ) }, undef, 'lives when given foo and bar params' ); like( dies { $sub->( bar => 42 ) }, qr/foo is a required parameter/, 'dies when not given foo param' ); } done_testing(); Params-ValidationCompiler-0.30/t/named/return-object.t0000644000175000017500000000420513330066233022601 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( validation_for ); use Scalar::Util qw( blessed ); use Specio::Library::Builtins; for my $want_cxsa ( 0, 1 ) { next if $want_cxsa && !Params::ValidationCompiler::Compiler->HAS_CXSA; subtest( ( $want_cxsa ? 'with' : 'without' ) . ' Class::XSAccessor', sub { test_return_object($want_cxsa) }, ); } sub test_return_object { my $want_cxsa = shift; local $ENV{TEST_NAMED_ARGS_OBJECT_WITHOUT_CXSA} = !$want_cxsa; { my $sub = validation_for( params => { foo => 1, bar => { type => t('Int'), optional => 1, }, }, return_object => 1, ); my $ret = $sub->( foo => 42 ); ok( blessed $ret, 'returned value is a blessed object' ); if ($want_cxsa) { like( blessed $ret, qr/XS/, 'returned object class uses Class::XSAccessor' ); } else { like( blessed $ret, qr/PP/, 'returned object class uses pure Perl' ); } is( $ret->foo, 42, 'returned object contains foo param' ); is( $ret->bar, undef, 'returned object has undef for bar param' ); } { my $sub = validation_for( params => { foo => { getter => 'get_foo' }, bar => { type => t('Int'), optional => 1, predicate => 'has_bar', }, }, return_object => 1, ); my $ret = $sub->( foo => 42 ); is( $ret->get_foo, 42, 'getter name is used instead of param name' ); ok( !$ret->has_bar, 'predicated is created when requested' ); } } done_testing(); Params-ValidationCompiler-0.30/t/specio.t0000644000175000017500000000547613330066233020227 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( validation_for ); use Specio::Declare; use Specio::Library::Builtins; subtest( 'type can be inlined', sub { _test_int_type( t('Int') ); } ); declare( 'MyInt', where => sub { $_[0] =~ /\A-?[0-9]+\z/ }, ); declare( 'MyInt2', where => sub { $_[0] =~ /\A-?[0-9]+\z/ }, ); declare( 'ArrayRefOfInt', parent => t( 'ArrayRef', of => t('Int') ), ); declare( 'ArrayRefOfInt2', parent => t( 'ArrayRef', of => t('Int') ), ); subtest( 'type cannot be inlined', sub { _test_int_type( t('MyInt') ); } ); subtest( 'type and coercion can be inlined', sub { coerce( t('ArrayRefOfInt'), from => t('Int'), inline => sub { return "[ $_[1] ]" }, ); _test_arrayref_to_int_coercion( t('ArrayRefOfInt') ); } ); subtest( 'type can be inlined but coercion cannot', sub { coerce( t('ArrayRefOfInt2'), from => t('Int'), using => sub { return [ $_[0] ] }, ); _test_arrayref_to_int_coercion( t('ArrayRefOfInt2') ); } ); subtest( 'type cannot be inlined but coercion can', sub { coerce( t('MyInt'), from => t('ArrayRef'), inline => sub { return "scalar \@{ $_[1] }" }, ); _test_arrayref_to_int_coercion( t('MyInt') ); } ); subtest( 'neither type not coercion can be inlined', sub { coerce( t('MyInt2'), from => t('ArrayRef'), using => sub { return scalar @{ $_[0] } }, ); _test_arrayref_to_int_coercion( t('MyInt2') ); } ); done_testing(); sub _test_int_type { my $type = shift; my $sub = validation_for( params => { foo => { type => $type }, }, ); is( dies { $sub->( foo => 42 ) }, undef, 'lives when foo is an integer' ); my $name = $type->name; like( dies { $sub->( foo => [] ) }, qr/Validation failed for type named $name declared in .+ with value \Q[ ]/, 'dies when foo is an arrayref' ); } sub _test_arrayref_to_int_coercion { my $type = shift; my $sub = validation_for( params => { foo => { type => $type }, }, ); is( dies { $sub->( foo => 42 ) }, undef, 'lives when foo is an integer' ); is( dies { $sub->( foo => [ 42, 1 ] ) }, undef, 'lives when foo is an arrayref of integers' ); my $name = $type->name; like( dies { $sub->( foo => {} ) }, qr/Validation failed for type named $name declared in .+ with value \Q{ }/, 'dies when foo is a hashref' ); } Params-ValidationCompiler-0.30/t/00-report-prereqs.t0000644000175000017500000001342613330066233022146 0ustar autarchautarch#!perl use strict; use warnings; # This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.027 use Test::More tests => 1; use ExtUtils::MakeMaker; use File::Spec; # from $version::LAX my $lax_version_re = qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )? | (?:\.[0-9]+) (?:_[0-9]+)? ) | (?: v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )? | (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)? ) )/x; # hide optional CPAN::Meta modules from prereq scanner # and check if they are available my $cpan_meta = "CPAN::Meta"; my $cpan_meta_pre = "CPAN::Meta::Prereqs"; my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic # Verify requirements? my $DO_VERIFY_PREREQS = 1; sub _max { my $max = shift; $max = ( $_ > $max ) ? $_ : $max for @_; return $max; } sub _merge_prereqs { my ($collector, $prereqs) = @_; # CPAN::Meta::Prereqs object if (ref $collector eq $cpan_meta_pre) { return $collector->with_merged_prereqs( CPAN::Meta::Prereqs->new( $prereqs ) ); } # Raw hashrefs for my $phase ( keys %$prereqs ) { for my $type ( keys %{ $prereqs->{$phase} } ) { for my $module ( keys %{ $prereqs->{$phase}{$type} } ) { $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module}; } } } return $collector; } my @include = qw( ); my @exclude = qw( ); # Add static prereqs to the included modules list my $static_prereqs = do './t/00-report-prereqs.dd'; # Merge all prereqs (either with ::Prereqs or a hashref) my $full_prereqs = _merge_prereqs( ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ), $static_prereqs ); # Add dynamic prereqs to the included modules list (if we can) my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; my $cpan_meta_error; if ( $source && $HAS_CPAN_META && (my $meta = eval { CPAN::Meta->load_file($source) } ) ) { $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs); } else { $cpan_meta_error = $@; # capture error from CPAN::Meta->load_file($source) $source = 'static metadata'; } my @full_reports; my @dep_errors; my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs; # Add static includes into a fake section for my $mod (@include) { $req_hash->{other}{modules}{$mod} = 0; } for my $phase ( qw(configure build test runtime develop other) ) { next unless $req_hash->{$phase}; next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING}); for my $type ( qw(requires recommends suggests conflicts modules) ) { next unless $req_hash->{$phase}{$type}; my $title = ucfirst($phase).' '.ucfirst($type); my @reports = [qw/Module Want Have/]; for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) { next if $mod eq 'perl'; next if grep { $_ eq $mod } @exclude; my $file = $mod; $file =~ s{::}{/}g; $file .= ".pm"; my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC; my $want = $req_hash->{$phase}{$type}{$mod}; $want = "undef" unless defined $want; $want = "any" if !$want && $want == 0; my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required"; if ($prefix) { my $have = MM->parse_version( File::Spec->catfile($prefix, $file) ); $have = "undef" unless defined $have; push @reports, [$mod, $want, $have]; if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) { if ( $have !~ /\A$lax_version_re\z/ ) { push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)"; } elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) { push @dep_errors, "$mod version '$have' is not in required range '$want'"; } } } else { push @reports, [$mod, $want, "missing"]; if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) { push @dep_errors, "$mod is not installed ($req_string)"; } } } if ( @reports ) { push @full_reports, "=== $title ===\n\n"; my $ml = _max( map { length $_->[0] } @reports ); my $wl = _max( map { length $_->[1] } @reports ); my $hl = _max( map { length $_->[2] } @reports ); if ($type eq 'modules') { splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports; } else { splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports; } push @full_reports, "\n"; } } } if ( @full_reports ) { diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports; } if ( $cpan_meta_error || @dep_errors ) { diag "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n"; } if ( $cpan_meta_error ) { my ($orig_source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; diag "\nCPAN::Meta->load_file('$orig_source') failed with: $cpan_meta_error\n"; } if ( @dep_errors ) { diag join("\n", "\nThe following REQUIRED prerequisites were not satisfied:\n", @dep_errors, "\n" ); } pass; # vim: ts=4 sts=4 sw=4 et: Params-ValidationCompiler-0.30/t/self-check.t0000644000175000017500000001220113330066233020731 0ustar autarchautarch## no critic (Moose::RequireCleanNamespace) use strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( validation_for ); use Specio::Library::Builtins; like( dies { validation_for() }, qr/\QYou must provide a "params" parameter when creating a parameter validator\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called without parameters' ); like( dies { validation_for( params => 42 ) }, qr/\QThe "params" parameter when creating a parameter validator must be a hashref or arrayref, you passed a scalar\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called with params as a scalar' ); like( dies { validation_for( params => undef ) }, qr/\QThe "params" parameter when creating a parameter validator must be a hashref or arrayref, you passed an undef\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called params as an undef' ); like( dies { validation_for( params => \42 ) }, qr/\QThe "params" parameter when creating a parameter validator must be a hashref or arrayref, you passed a scalarref\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called params as a scalarref' ); like( dies { validation_for( params => bless {}, 'Foo' ) }, qr/\QThe "params" parameter when creating a parameter validator must be a hashref or arrayref, you passed a Foo object\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called params as anobject' ); like( dies { validation_for( params => { a => {} }, foo => 1, bar => 2 ) }, qr/\QYou passed unknown parameters when creating a parameter validator: [bar foo]\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called with extra unknown parameters' ); like( dies { validation_for( params => { a => {} }, name => undef, ) }, qr/\QThe "name" parameter when creating a parameter validator must be a scalar, you passed an undef\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called with name as an undef' ); like( dies { validation_for( params => { a => {} }, name => [], ) }, qr/\QThe "name" parameter when creating a parameter validator must be a scalar, you passed an arrayref\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called with name as an arrayref' ); like( dies { validation_for( params => { a => {} }, name => bless {}, 'Foo' ) }, qr/\QThe "name" parameter when creating a parameter validator must be a scalar, you passed a Foo object\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called with name as an object' ); like( dies { validation_for( params => [ a => 1 ], named_to_list => 1, slurpy => 1, ); }, qr/\QYou cannot use "named_to_list" and "slurpy" together\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called with named_to_list and slurpy' ); like( dies { validation_for( params => [ a => { isa => 1, typo => 2 } ], named_to_list => 1, ); }, qr/\QSpecification contains unknown keys: [isa typo]\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called with named_to_list and an invalid spec keys' ); like( dies { validation_for( params => [ { isa => 1, } ], ); }, qr/\QSpecification contains unknown keys: [isa]\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called with an arrayref params and an invalid spec keys' ); like( dies { validation_for( params => { a => { isa => 1, typo => 2 } }, ); }, qr/\QSpecification contains unknown keys: [isa typo]\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called with an hashref params and an invalid spec keys' ); like( dies { validation_for( params => { foo => t('Int') }, ); }, qr/\QSpecifications must be a scalar or hashref, but received a Specio::Constraint::Simple/, 'got expected error message when validation_for is called with a spec that is a type instead of a hashref' ); like( dies { validation_for( params => [ { type => t('Str') } ], return_object => 1, ); }, qr/\QYou can only use "return_object" with named params\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called with arrayref params and return_object is true' ); like( dies { validation_for( params => { foo => { type => t('Str') } }, return_object => 1, slurpy => 1, ); }, qr/\QYou cannot use "return_object" and "slurpy" together\E.+at t.self-check\.t line \d+/, 'got expected error message when validation_for is called with return_object and slurpy both set' ); done_testing(); Params-ValidationCompiler-0.30/t/positional/0000775000175000017500000000000013330066233020727 5ustar autarchautarchParams-ValidationCompiler-0.30/t/positional/default.t0000644000175000017500000000364413330066233022545 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( validation_for ); use Specio::Declare; use Specio::Library::Builtins; { my $validator = validation_for( params => [ { type => t('Int') }, { default => 10, }, ], ); is( [ $validator->(3) ], [ 3, 10 ], 'able to set defaults on positional validator' ); is( [ $validator->( 3, undef ) ], [ 3, undef ], 'default is only set when element does not exist' ); } { my $validator = validation_for( params => [ 1, { default => 0 }, ], ); is( [ $validator->(0) ], [ 0, 0 ], 'positional params with default are optional' ); } { my $x = 1; my $validator = validation_for( params => [ 1, { default => sub { $x++ } }, ], ); is( [ $validator->(0) ], [ 0, 1 ], 'default sub for positional params is called' ); is( [ $validator->(0) ], [ 0, 2 ], 'default sub for positional params is called again' ); } { declare( 'UCStr', parent => t('Str'), where => sub { $_[0] =~ /^[A-Z]+$/ }, ); coerce( t('UCStr'), from => t('Str'), using => sub { uc $_[0] }, ); my $validator = validation_for( params => [ 1, { type => t('UCStr'), default => sub {'ABC'} }, ], ); is( [ $validator->( 0, 'xyz' ) ], [ 0, 'XYZ' ], 'coercion for positional param is called' ); is( [ $validator->(0) ], [ 0, 'ABC' ], 'default for position param with coercion is called' ); } done_testing(); Params-ValidationCompiler-0.30/t/positional/slurpy.t0000644000175000017500000000300513330066233022446 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( validation_for ); use Specio::Library::Builtins; { my $sub = validation_for( params => [ 1, { optional => 1 }, ], ); like( dies { $sub->( 42, 43, 44 ) }, qr/Got 1 extra parameter/, 'dies when given one extra parameter' ); like( dies { $sub->( 42, 43, 44, 'whuh' ) }, qr/Got 2 extra parameters/, 'dies when given two extra parameters' ); } { my $sub = validation_for( params => [ 1, ], slurpy => 1, ); like( dies { $sub->() }, qr/Got 0 parameters but expected at least 1/, 'foo is still required when slurpy is true' ); is( [ $sub->( 42, 'whatever' ) ], [ 42, 'whatever' ], 'extra parameters are returned', ); } { my $sub = validation_for( params => [ 1, ], slurpy => t('Int'), ); like( dies { $sub->() }, qr/Got 0 parameters but expected at least 1/, 'foo is still required when slurpy is a type constraint' ); is( [ $sub->( 42, 43 ) ], [ 42, 43 ], 'one extra parameter is returned when they pass the type constraint', ); is( [ $sub->( 42, 43, 44 ) ], [ 42, 43, 44 ], 'two extra parameters are returned when they pass the type constraint', ); } done_testing(); Params-ValidationCompiler-0.30/t/positional/required.t0000644000175000017500000000301313330066233022727 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( validation_for ); use Specio::Library::Builtins; { my $sub = validation_for( params => [ 1, { type => t('Int'), optional => 1, }, ], ); is( dies { $sub->(42) }, undef, 'lives when given 1st param but no 2nd' ); is( dies { $sub->( 42, 42 ) }, undef, 'lives when given 1st and 2nd params' ); like( dies { $sub->() }, qr/Got 0 parameters but expected at least 1/, 'dies when not given any params' ); } { like( dies { validation_for( params => [ { optional => 1 }, { type => t('Int') }, ], ); }, qr/\QParameter list contains an optional parameter followed by a required parameter/, 'cannot have positional parameters where an optional param comes before a required one' ); like( dies { validation_for( params => [ { default => 42 }, { type => t('Int') }, ], ); }, qr/\QParameter list contains an optional parameter followed by a required parameter/, 'cannot have positional parameters where a param with a default comes before a required one' ); } done_testing(); Params-ValidationCompiler-0.30/t/source_for.t0000644000175000017500000000054713330066233021105 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( source_for ); my ( $source, $env ) = source_for( params => { foo => 1 } ); like( $source, qr/exists \$args/, 'source_for returns expected source' ); is( $env, { '%known' => { foo => 1 } }, 'got expected environment' ); done_testing(); Params-ValidationCompiler-0.30/t/00-report-prereqs.dd0000644000175000017500000001112013330066233022257 0ustar autarchautarchdo { my $x = { 'configure' => { 'requires' => { 'ExtUtils::MakeMaker' => '0' } }, 'develop' => { 'requires' => { 'Class::XSAccessor' => '0', 'Code::TidyAll' => '0.56', 'Code::TidyAll::Plugin::SortLines::Naturally' => '0.000003', 'Code::TidyAll::Plugin::Test::Vars' => '0.02', 'Const::Fast' => '0.014', 'File::Spec' => '0', 'Hash::Merge' => '0', 'Hash::Util' => '0', 'IO::Handle' => '0', 'IPC::Open3' => '0', 'List::AllUtils' => '0', 'Moose' => '2.0000', 'Parallel::ForkManager' => '1.19', 'Perl::Critic' => '1.126', 'Perl::Tidy' => '20160302', 'Pod::Coverage::TrustPod' => '0', 'Pod::Wordlist' => '0', 'Set::Scalar' => '0', 'Specio' => '0.14', 'Sub::Util' => '1.40', 'Test2::Bundle::Extended' => '0', 'Test2::Plugin::NoWarnings' => '0', 'Test2::Require::Perl' => '0', 'Test::CPAN::Changes' => '0.19', 'Test::CPAN::Meta::JSON' => '0.16', 'Test::Code::TidyAll' => '0.50', 'Test::EOL' => '0', 'Test::Mojibake' => '0', 'Test::More' => '0.96', 'Test::NoTabs' => '0', 'Test::Pod' => '1.41', 'Test::Pod::Coverage' => '1.08', 'Test::Portability::Files' => '0', 'Test::Spelling' => '0.12', 'Test::Synopsis' => '0', 'Test::Vars' => '0.009', 'Test::Version' => '2.05', 'Type::Tiny' => '0', 'Type::Utils' => '0', 'perl' => '5.006' } }, 'runtime' => { 'recommends' => { 'Class::XSAccessor' => '0', 'Sub::Util' => '1.40' }, 'requires' => { 'B' => '0', 'Carp' => '0', 'Eval::Closure' => '0', 'Exception::Class' => '0', 'Exporter' => '0', 'List::Util' => '1.29', 'Scalar::Util' => '0', 'overload' => '0', 'strict' => '0', 'warnings' => '0' } }, 'test' => { 'recommends' => { 'CPAN::Meta' => '2.120900' }, 'requires' => { 'ExtUtils::MakeMaker' => '0', 'File::Spec' => '0', 'Hash::Util' => '0', 'Specio' => '0.14', 'Test2::Plugin::NoWarnings' => '0', 'Test2::Require::Module' => '0', 'Test2::V0' => '0', 'Test::More' => '1.302015', 'Test::Without::Module' => '0' } } }; $x; }Params-ValidationCompiler-0.30/t/type-tiny.t0000644000175000017500000000502413330066233020674 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Test2::Require::Module 'Type::Tiny' => '0.024'; use Params::ValidationCompiler qw( validation_for ); use Types::Standard qw( ArrayRef Int ); subtest( 'type can be inlined', sub { _test_int_type(Int); } ); my $myint = Type::Tiny->new( name => 'MyInt', constraint => sub {/\A-?[0-9]+\z/}, ); subtest( 'type cannot be inlined', sub { _test_int_type($myint); } ); subtest( 'type and coercion can be inlined', sub { my $type = ( ArrayRef [Int] )->plus_coercions( Int, '[$_]', ); _test_int_to_arrayref_coercion($type); } ); subtest( 'type can be inlined but coercion cannot', sub { my $type = ( ArrayRef [Int] )->plus_coercions( Int, sub { [$_] }, ); _test_int_to_arrayref_coercion($type); } ); # XXX - if the type cannot be inlined then the coercion reports itself as # uninlinable as well, but that could change in the future. subtest( 'type cannot be inlined but coercion can', sub { my $type = ( ArrayRef [$myint] )->plus_coercions( $myint, '[$_]', ); _test_int_to_arrayref_coercion($type); } ); subtest( 'neither type not coercion can be inlined', sub { my $type = ( ArrayRef [$myint] )->plus_coercions( $myint, sub { [$_] }, ); _test_int_to_arrayref_coercion($type); } ); done_testing(); sub _test_int_type { my $type = shift; my $sub = validation_for( params => { foo => { type => $type }, }, ); is( dies { $sub->( foo => 42 ) }, undef, 'lives when foo is an integer' ); my $name = $type->display_name; like( dies { $sub->( foo => [] ) }, qr/\QReference [] did not pass type constraint "$name"/, 'dies when foo is an arrayref' ); } sub _test_int_to_arrayref_coercion { my $type = shift; my $sub = validation_for( params => { foo => { type => $type }, }, ); is( dies { $sub->( foo => 42 ) }, undef, 'lives when foo is an integer' ); is( dies { $sub->( foo => [ 42, 1 ] ) }, undef, 'lives when foo is an arrayref of integers' ); my $name = $type->display_name; like( dies { $sub->( foo => {} ) }, qr/\QReference {} did not pass type constraint "$name"/, 'dies when foo is a hashref' ); } Params-ValidationCompiler-0.30/t/name-fails.t0000644000175000017500000000152613330066233020751 0ustar autarchautarch# HARNESS-NO-PRELOAD use strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Test::Without::Module qw( Sub::Util ); use Params::ValidationCompiler qw( validation_for ); { my $e = dies { validation_for( name => 'Check for X', params => { foo => 1 }, ); }; like( $e, qr/\QCannot name a generated validation subroutine. Please install Sub::Util./, 'passing name when Sub::Util is not installed fails', ); } { is( dies { validation_for( name => 'Check for X', name_is_optional => 1, params => { foo => 1 }, ); }, undef, 'passing name and name_is_optional when Sub::Util is not installed lives' ); } done_testing(); Params-ValidationCompiler-0.30/t/pairs-to-value-list.t0000644000175000017500000000135613330066233022557 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Params::ValidationCompiler qw( validation_for ); { my $sub = validation_for( params => [ bar => 0, foo => 1, ], named_to_list => 1, ); is( [ $sub->( foo => 'test' ) ], [ undef, 'test' ], 'passing required param returns optional values as undef' ); is( [ $sub->( foo => 'test', bar => 'b' ) ], [ 'b', 'test' ], 'optional params are returned as expected' ); } { # We have to handle a single named argument specially to avoid warnings. validation_for( params => [ bar => 0, ], named_to_list => 1, ); } done_testing(); Params-ValidationCompiler-0.30/t/exceptions.t0000644000175000017500000000113013330066233021105 0ustar autarchautarchuse strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Test2::Require::Module 'Specio::Library::Builtins'; use Params::ValidationCompiler qw( validation_for ); use Specio::Library::Builtins; { my $sub = validation_for( params => [ { type => t('Str') } ], name => 'test validator', name_is_optional => 1, ); like( dies { $sub->( 'foo', 'bar' ) }, qr{Got 1 extra parameter for test validator.+called at t[\\/]exceptions\.t line \d+}s, 'exception includes stack trace', ); } done_testing(); Params-ValidationCompiler-0.30/t/moose.t0000644000175000017500000000631013330066233020053 0ustar autarchautarch## no critic (Moose::RequireCleanNamespace) use strict; use warnings; use Test2::V0; use Test2::Plugin::NoWarnings; use Test2::Require::Module 'Moose::Util::TypeConstraints'; use Params::ValidationCompiler qw( validation_for ); use Moose::Util::TypeConstraints; my $moose_int = find_type_constraint('Int'); subtest( 'type can be inlined', sub { _test_int_type($moose_int); } ); my $myint = subtype 'MyInt' => as 'Num' => where {/\A-?[0-9]+\z/}; subtest( 'type cannot be inlined', sub { _test_int_type($myint); } ); subtest( 'type can be inlined but coercion cannot', sub { my $type = subtype 'ArrayRefInt', as 'ArrayRef[Int]'; coerce $type => from 'Int' => via { [$_] }; _test_int_to_arrayref_coercion($type); } ); subtest( 'neither type not coercion can be inlined', sub { my $type = subtype as 'ArrayRef[MyInt]'; coerce $type => from 'Int' => via { [$_] }; _test_int_to_arrayref_coercion($type); } ); # This tests that a type which provides an inline_environment actually has # that env available. subtest( 'enum type', sub { my $sub = validation_for( params => { foo => { type => enum [qw( red green blue )] }, }, ); is( { $sub->( foo => 'red' ) }, { foo => 'red' }, 'enum type is validated properly' ); } ); # This tests that a type which provides an inline_environment actually has # that env available. subtest( 'empty enum subtype', sub { my $enum = enum [qw( red green blue )]; my $subtype = subtype( as $enum ); my $sub = validation_for( params => { foo => { type => $subtype }, }, ); is( { $sub->( foo => 'red' ) }, { foo => 'red' }, 'enum type is validated properly' ); } ); done_testing(); sub _test_int_type { my $type = shift; my $sub = validation_for( params => { foo => { type => $type }, }, ); is( dies { $sub->( foo => 42 ) }, undef, 'lives when foo is an integer' ); my $name = $type->name; like( dies { $sub->( foo => [] ) }, qr/\Qfoo failed with: Validation failed for '$name' with value \E(?:ARRAY|\[ +\])/, 'dies when foo is an arrayref' ); } sub _test_int_to_arrayref_coercion { my $type = shift; my $sub = validation_for( params => { foo => { type => $type }, }, ); is( dies { $sub->( foo => 42 ) }, undef, 'lives when foo is an integer' ); is( dies { $sub->( foo => [ 42, 1 ] ) }, undef, 'lives when foo is an arrayref of integers' ); my $name = $type->name; like( dies { $sub->( foo => {} ) }, qr/\QValidation failed for '$name' with value \E(?:HASH|\{ +\})/, 'dies when foo is a hashref' ); my $pos = validation_for( params => [ { type => $type } ], ); is( dies { $pos->(42) }, undef, 'lives when coercing a moose type with positional parameters' ); } Params-ValidationCompiler-0.30/README.md0000644000175000017500000002263213330066233017565 0ustar autarchautarch# NAME Params::ValidationCompiler - Build an optimized subroutine parameter validator once, use it forever # VERSION version 0.30 # SYNOPSIS use Types::Standard qw( Int Str ); use Params::ValidationCompiler qw( validation_for ); { my $validator = validation_for( params => { foo => { type => Int }, bar => { type => Str, optional => 1, }, baz => { type => Int, default => 42, }, }, ); sub foo { my %args = $validator->(@_); } } { my $validator = validation_for( params => [ { type => Int }, { type => Str, optional => 1, }, ], ); sub bar { my ( $int, $str ) = $validator->(@_); } } { my $validator = validation_for( params => [ foo => { type => Int }, bar => { type => Str, optional => 1, }, ], named_to_list => 1, ); sub baz { my ( $foo, $bar ) = $validator->(@_); } } # DESCRIPTION This module creates a customized, highly efficient parameter checking subroutine. It can handle named or positional parameters, and can return the parameters as key/value pairs or a list of values. In addition to type checks, it also supports parameter defaults, optional parameters, and extra "slurpy" parameters. # PARAMETERS This module has two options exports, `validation_for` and `source_for`. Both of these subs accept the same options: ## params An arrayref or hashref containing a parameter specification. If you pass a hashref then the generated validator sub will expect named parameters. The `params` value should be a hashref where the parameter names are keys and the specs are the values. If you pass an arrayref and `named_to_list` is false, the validator will expect positional params. Each element of the `params` arrayref should be a parameter spec. If you pass an arrayref and `named_to_list` is true, the validator will expect named params, but will return a list of values. In this case the arrayref should contain a _list_ of key/value pairs, where parameter names are the keys and the specs are the values. Each spec can contain either a boolean or hashref. If the spec is a boolean, this indicates required (true) or optional (false). The spec hashref accepts the following keys: - type A type object. This can be a [Moose](https://metacpan.org/pod/Moose) type (from [Moose](https://metacpan.org/pod/Moose) or [MooseX::Types](https://metacpan.org/pod/MooseX::Types)), a [Type::Tiny](https://metacpan.org/pod/Type::Tiny) type, or a [Specio](https://metacpan.org/pod/Specio) type. If the type has coercions, those will always be used. - default This can either be a simple (non-reference) scalar or a subroutine reference. The sub ref will be called without any arguments (for now). - optional A boolean indicating whether or not the parameter is optional. By default, parameters are required unless you provide a default. ## slurpy If this is a simple true value, then the generated subroutine accepts additional arguments not specified in `params`. By default, extra arguments cause an exception. You can also pass a type constraint here, in which case all extra arguments must be values of the specified type. ## named\_to\_list If this is true, the generated subroutine will expect a list of key-value pairs or a hashref and it will return a list containing only values. The `params` you pass must be a arrayref of key-value pairs. The order of these pairs determines the order in which values are returned. You cannot combine `slurpy` with `named_to_list` as there is no way to know how to order the extra return values. ## return\_object If this is true, the generated subroutine will return an object instead of a hashref. You cannot set this option to true if you set either or `slurpy` or `named_to_list`. The object's methods correspond to the parameter names passed to the subroutine. While calling methods on an object is slower than accessing a hashref, the advantage is that if you typo a parameter name you'll get a helpful error. If you have [Class::XSAccessor](https://metacpan.org/pod/Class::XSAccessor) installed then this will be used to create the class's methods, which makes it fairly fast. The returned object is in a generated class. Do not rely on this class name being anything in specific, and don't check this object using `isa`, `DOES`, or anything similar. When `return_object` is true, the parameter spec hashref also accepts to the following additional keys: - getter Use this to set an explicit getter method name for the parameter. By default the method name will be the same as the parameter name. Note that if the parameter name is not a valid sub name, then you will get an error compiling the validation sub unless you specify a getter for the parameter. - predicate Use this to ask for a predicate method to be created for this parameter. The predicate method returns true if the parameter was passed and false if it wasn't. Note that this is only useful for optional parameters, but you can ask for a predicate for any parameter. # EXPORTS The exported subs are: ## validation\_for(...) This returns a subroutine that implements the specific parameter checking. This subroutine expects to be given the parameters to validate in `@_`. If all the parameters are valid, it will return the validated parameters (with defaults as appropriate), either as a list of key-value pairs or as a list of just values. If any of the parameters are invalid it will throw an exception. For validators expected named params, the generated subroutine accepts either a list of key-value pairs or a single hashref. Otherwise the validator expects a list of values. For now, you must shift off the invocant yourself. This subroutine accepts the following additional parameters: - name If this is given, then the generated subroutine will be named using [Sub::Util](https://metacpan.org/pod/Sub::Util). This is strongly recommended as it makes it possible to distinguish different check subroutines when profiling or in stack traces. This name will also be used in some exception messages, even if [Sub::Util](https://metacpan.org/pod/Sub::Util) is not available. Note that you must install [Sub::Util](https://metacpan.org/pod/Sub::Util) yourself separately, as it is not required by this distribution, in order to avoid requiring a compiler. - name\_is\_optional If this is true, then the name is ignored when `Sub::Util` is not installed. If this is false, then passing a name when [Sub::Util](https://metacpan.org/pod/Sub::Util) cannot be loaded causes an exception. This is useful for CPAN modules where you want to set a name if you can, but you do not want to add a prerequisite on [Sub::Util](https://metacpan.org/pod/Sub::Util). - debug Sets the `EVAL_CLOSURE_PRINT_SOURCE` environment variable to true before calling `Eval::Closure::eval_closure()`. This causes the source of the subroutine to be printed before it's `eval`'d. ## source\_for(...) This returns a two element list. The first is a string containing the source code for the generated sub. The second is a hashref of "environment" variables to be used when generating the subroutine. These are the arguments that are passed to [Eval::Closure](https://metacpan.org/pod/Eval::Closure). # SUPPORT Bugs may be submitted at [https://github.com/houseabsolute/Params-ValidationCompiler/issues](https://github.com/houseabsolute/Params-ValidationCompiler/issues). I am also usually active on IRC as 'autarch' on `irc://irc.perl.org`. # SOURCE The source code repository for Params-ValidationCompiler can be found at [https://github.com/houseabsolute/Params-ValidationCompiler](https://github.com/houseabsolute/Params-ValidationCompiler). # DONATIONS If you'd like to thank me for the work I've done on this module, please consider making a "donation" to me via PayPal. I spend a lot of free time creating free software, and would appreciate any support you'd care to offer. Please note that **I am not suggesting that you must do this** in order for me to continue working on this particular software. I will continue to do so, inasmuch as I have in the past, for as long as it interests me. Similarly, a donation made in this way will probably not make me work on this software much more, unless I get so many donations that I can consider working on free software full time (let's all have a chuckle at that together). To donate, log into PayPal and send money to autarch@urth.org, or use the button at [http://www.urth.org/~autarch/fs-donation.html](http://www.urth.org/~autarch/fs-donation.html). # AUTHOR Dave Rolsky # CONTRIBUTORS - Gregory Oschwald - Gregory Oschwald - Tomasz Konojacki # COPYRIGHT AND LICENSE This software is Copyright (c) 2016 - 2018 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the `LICENSE` file included with this distribution. Params-ValidationCompiler-0.30/Makefile.PL0000644000175000017500000000403613330066233020256 0ustar autarchautarch# This Makefile.PL for Params-ValidationCompiler was generated by # Dist::Zilla::Plugin::DROLSKY::MakeMaker 1.00 # and Dist::Zilla::Plugin::MakeMaker::Awesome 0.47. # Don't edit it but the dist.ini and plugins used to construct it. use strict; use warnings; use ExtUtils::MakeMaker; my %WriteMakefileArgs = ( "ABSTRACT" => "Build an optimized subroutine parameter validator once, use it forever", "AUTHOR" => "Dave Rolsky ", "CONFIGURE_REQUIRES" => { "ExtUtils::MakeMaker" => 0 }, "DISTNAME" => "Params-ValidationCompiler", "LICENSE" => "artistic_2", "NAME" => "Params::ValidationCompiler", "PREREQ_PM" => { "B" => 0, "Carp" => 0, "Eval::Closure" => 0, "Exception::Class" => 0, "Exporter" => 0, "List::Util" => "1.29", "Scalar::Util" => 0, "overload" => 0, "strict" => 0, "warnings" => 0 }, "TEST_REQUIRES" => { "ExtUtils::MakeMaker" => 0, "File::Spec" => 0, "Hash::Util" => 0, "Specio" => "0.14", "Test2::Plugin::NoWarnings" => 0, "Test2::Require::Module" => 0, "Test2::V0" => 0, "Test::More" => "1.302015", "Test::Without::Module" => 0 }, "VERSION" => "0.30", "test" => { "TESTS" => "t/*.t t/named/*.t t/positional/*.t" } ); my %FallbackPrereqs = ( "B" => 0, "Carp" => 0, "Eval::Closure" => 0, "Exception::Class" => 0, "Exporter" => 0, "ExtUtils::MakeMaker" => 0, "File::Spec" => 0, "Hash::Util" => 0, "List::Util" => "1.29", "Scalar::Util" => 0, "Specio" => "0.14", "Test2::Plugin::NoWarnings" => 0, "Test2::Require::Module" => 0, "Test2::V0" => 0, "Test::More" => "1.302015", "Test::Without::Module" => 0, "overload" => 0, "strict" => 0, "warnings" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION('6.63_03') } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); Params-ValidationCompiler-0.30/xt/0000775000175000017500000000000013330066233016736 5ustar autarchautarchParams-ValidationCompiler-0.30/xt/author/0000775000175000017500000000000013330066233020240 5ustar autarchautarchParams-ValidationCompiler-0.30/xt/author/pod-coverage.t0000644000175000017500000000172013330066233022776 0ustar autarchautarch#!perl # This file was automatically generated by Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable 0.07. use Test::Pod::Coverage 1.08; use Test::More 0.88; BEGIN { if ( $] <= 5.008008 ) { plan skip_all => 'These tests require Pod::Coverage::TrustPod, which only works with Perl 5.8.9+'; } } use Pod::Coverage::TrustPod; my %skip = map { $_ => 1 } qw( ); my @modules; for my $module ( all_modules() ) { next if $skip{$module}; push @modules, $module; } plan skip_all => 'All the modules we found were excluded from POD coverage test.' unless @modules; plan tests => scalar @modules; my %trustme = (); my @also_private; for my $module ( sort @modules ) { pod_coverage_ok( $module, { coverage_class => 'Pod::Coverage::TrustPod', also_private => \@also_private, trustme => $trustme{$module} || [], }, "pod coverage for $module" ); } done_testing(); Params-ValidationCompiler-0.30/xt/author/no-tabs.t0000644000175000017500000000154013330066233021766 0ustar autarchautarchuse strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.15 use Test::More 0.88; use Test::NoTabs; my @files = ( 'lib/Params/ValidationCompiler.pm', 'lib/Params/ValidationCompiler/Compiler.pm', 'lib/Params/ValidationCompiler/Exceptions.pm', 't/00-report-prereqs.dd', 't/00-report-prereqs.t', 't/default.t', 't/exceptions.t', 't/moose.t', 't/name-fails.t', 't/name.t', 't/named/args-check.t', 't/named/const-hash.t', 't/named/locked-hash.t', 't/named/required.t', 't/named/return-object.t', 't/named/slurpy.t', 't/pairs-to-value-list.t', 't/positional/default.t', 't/positional/required.t', 't/positional/slurpy.t', 't/self-check.t', 't/source_for.t', 't/specio.t', 't/type-tiny.t' ); notabs_ok($_) foreach @files; done_testing; Params-ValidationCompiler-0.30/xt/author/synopsis.t0000644000175000017500000000006013330066233022306 0ustar autarchautarch#!perl use Test::Synopsis; all_synopsis_ok(); Params-ValidationCompiler-0.30/xt/author/pod-spell.t0000644000175000017500000000070413330066233022323 0ustar autarchautarchuse strict; use warnings; use Test::More; # generated by Dist::Zilla::Plugin::Test::PodSpelling 2.007005 use Test::Spelling 0.12; use Pod::Wordlist; add_stopwords(); all_pod_files_spelling_ok( qw( bin lib ) ); __DATA__ Compiler DROLSKY DROLSKY's Dave Exceptions Gregory Konojacki Oschwald Params PayPal Rolsky Rolsky's Tomasz ValidationCompiler autarch drolsky getter goschwald lib me oschwald params slurpy uncompromised validator validators Params-ValidationCompiler-0.30/xt/author/matrix.t0000644000175000017500000004432113330066233021733 0ustar autarchautarch## no critic (Moose::RequireCleanNamespace) use strict; use warnings; use Test2::Bundle::Extended; use Test2::Plugin::NoWarnings; use Test2::Require::Perl '5.012'; use Hash::Merge qw( merge ); use List::AllUtils qw( first_index reduce ); use Params::ValidationCompiler qw( validation_for ); use Set::Scalar; # It'd be nice to add a third parameter and test with three but that ends up # running a ridiculous number of tests. my %foo = _one_param_permutations('foo'); my %bar = _one_param_permutations('bar'); my %slurpy = _slurpy_param_permutations('slurpy'); OUTER: for my $foo_desc ( sort keys %foo ) { subtest 'one parameter' => sub { my $p = $foo{$foo_desc}; subtest $foo_desc => sub { subtest 'named params' => sub { _named_params_tests($p); }; subtest 'positional params' => sub { _positional_params_tests($p); }; subtest 'named_to_list params' => sub { _named_to_list_params_tests($p); }; for my $slurpy_desc ( sort keys %slurpy ) { subtest 'slurpy named params' => sub { _named_slurpy_tests( $p, $slurpy{$slurpy_desc} ); }; subtest 'slurpy positional params' => sub { _positional_slurpy_tests( $p, $slurpy{$slurpy_desc} ); }; } }; } or last OUTER; for my $bar_desc ( sort keys %bar ) { subtest 'two parameters' => sub { my @p = ( $foo{$foo_desc}, $bar{$bar_desc} ); subtest "$foo_desc + $bar_desc" => sub { subtest 'named params' => sub { _named_params_tests(@p); }; subtest 'positional params' => sub { _positional_params_tests(@p); }; subtest 'named_to_list params' => sub { _named_to_list_params_tests(@p); }; }; } or last OUTER; } } done_testing(); sub _named_params_tests { my @p = @_; my $named_v; is( dies { $named_v = validation_for( params => { map { $_->{key} => $_->{spec} } @p } ); }, undef, 'no exception compiling named params validator' ) or return; _run_param_tests( \@p, 'named', sub { my $input = shift; my $output = shift; is( { $named_v->( %{$input} ) }, $output, 'input as k/v pairs' ); is( { $named_v->($input) }, $output, 'input as hashref' ); }, ); } sub _positional_params_tests { my @p = @_; # If this permutation has an optional param before a required param then # we cannot run these tests, as this is not allowed. my $first_o = first_index { $_->{spec}{optional} || exists $_->{spec}{default} } @p; my $first_r = first_index { !( $_->{spec}{optional} || exists $_->{spec}{default} ) } @p; if ( $first_o >= 0 && $first_o < $first_r ) { SKIP: { skip( 'test would end up with optional params before required', 1 ); } return; } my $pos_v; is( dies { $pos_v = validation_for( params => [ map { $_->{spec} } @p ] ) }, undef, 'no exception compiling positional params validator' ) or return; _run_param_tests( \@p, 'pos', sub { my $input = shift; my $output = shift; is( [ $pos_v->( @{$input} ) ], $output, 'input as list' ); }, ); } sub _named_to_list_params_tests { my @p = @_; my @sorted_p = sort { $a->{key} cmp $b->{key} } @p; my $ntl_v; is( dies { $ntl_v = validation_for( params => [ map { $_->{key} => $_->{spec} } @sorted_p ], named_to_list => 1, ); }, undef, 'no exception compiling positional params validator with named_to_list' ) or return; _run_param_tests( \@p, 'named', sub { my $input = shift; my $output = shift; is( [ $ntl_v->($input) ], [ map { $output->{$_} } map { $_->{key} } @sorted_p ], ); }, ); } sub _named_slurpy_tests { my $p = shift; my $slurpy = shift; my $slurpy_v; is( dies { $slurpy_v = validation_for( params => { $p->{key} => $p->{spec} }, slurpy => ( $slurpy->{spec}{type} || 1 ), ); }, undef, 'no exception compiling named params + slurpy validator' ) or return; _run_param_tests( [ $p, $slurpy ], 'named', sub { my $input = shift; my $output = shift; is( { $slurpy_v->( %{$input} ) }, $output, 'input as k/v pairs' ); }, ); } sub _positional_slurpy_tests { my $p = shift; my $slurpy = shift; my $slurpy_v; is( dies { $slurpy_v = validation_for( params => [ $p->{spec} ], slurpy => ( $slurpy->{spec}{type} || 1 ), ); }, undef, 'no exception compiling positional params + slurpy validator' ) or return; _run_param_tests( [ $p, $slurpy ], 'pos', sub { my $input = shift; my $output = shift; is( [ $slurpy_v->( @{$input} ) ], $output, 'input as list' ); }, ); } sub _run_param_tests { my $p = shift; my $type = shift; my $test_code = shift; my @sets = map { Set::Scalar->new( keys %{ $_->{tests} } ) } @{$p}; my $iter = Set::Scalar->cartesian_product_iterator(@sets); while ( my @test_keys = $iter->() ) { my $subtest = join q{ + }, @test_keys; # If we're testing positional params with more than 1 parameter, and # any parameter but the last has an empty input list, then we cannot # run that particular test set. We'd end up with an array built from # [], [42], [{ foo => 1 }] as the list of inputs, which gets turned # into a 2 element array when 3 need to be passed in. if ( $type eq 'pos' && @{$p} > 1 ) { for my $i ( 0 .. $#test_keys - 1 ) { if ( @{ $p->[$i]->{tests}{ $test_keys[$i] }{$type}{input} } == 0 ) { subtest $subtest => sub { SKIP: { skip 'Cannot run a test set where any non-last parameter has an empty input list', 1; } }; return; } } } my $in_out = reduce { merge( $a, $b ) } map { $p->[$_]->{tests}{ $test_keys[$_] }{$type} } 0 .. $#test_keys; subtest $subtest => sub { $test_code->( $in_out->{input}, $in_out->{output} ); }; } } sub _one_param_permutations { my $key = shift; my %types = ( 'no type' => undef, _one_type_permutations(), ); my %optional = ( required => 0, optional => 1, ); my %default = ( none => undef, 'simple scalar' => 42, 'subroutine' => sub {42}, ); my %perms; for my $t ( sort keys %types ) { for my $o ( sort keys %optional ) { for my $d ( sort keys %default ) { my $desc = "type = $t"; my %spec; my %tests = ( ( $t eq 'no type' ? 'any value is accepted' : 'value passes type check' ) => { named => { input => { $key => 700 }, output => { $key => 700 }, }, pos => { input => [700], output => [700], }, }, ); if ( $t =~ /coercion/ ) { $tests{'value is coerced'} = { named => { input => { $key => [ 1 .. 4 ] }, output => { $key => 4 }, }, pos => { input => [ [ 1 .. 4 ] ], output => [4], }, }; } if ( $optional{$o} ) { $spec{optional} = 1; $desc .= "; $o"; $tests{'no value given for optional param'} = { named => { input => {}, output => {}, }, pos => { input => [], output => [], } }; } else { $spec{default} = $default{$d} if $default{$d}; if ( $d eq 'none' ) { $desc .= "; $o; default = $d"; } else { $tests{'no value given for param with default'} = { named => { input => {}, output => { $key => 42 }, }, pos => { input => [], output => [42], } }; $desc .= "; default = $d"; } } $spec{type} = $types{$t} if $types{$t}; $perms{$desc} = { key => $key, spec => \%spec, tests => \%tests, }; } } } return %perms; } sub _slurpy_param_permutations { my $key = shift; my %types = ( 'no type' => undef, _one_type_permutations(), ); my %perms; for my $t ( sort keys %types ) { my $desc = "type = $t"; my %spec; my %tests = ( ( $t eq 'no type' ? 'any value is accepted' : 'value passes type check' ) => { named => { input => { $key => 700 }, output => { $key => 700 }, }, pos => { input => [700], output => [700], }, }, ); if ( $t =~ /coercion/ ) { $tests{'value is coerced'} = { named => { input => { $key => [ 1 .. 4 ] }, output => { $key => 4 }, }, pos => { input => [ [ 1 .. 4 ] ], output => [4], }, }; } $spec{type} = $types{$t} if $types{$t}; $spec{$desc} = { key => $key, spec => \%spec, tests => \%tests, }; } return %perms; } sub _one_type_permutations { my %subs = ( 'inlinable type' => 'inl_type', 'inlinable type, inlinable coercion' => 'inl_type_with_inl_coercion', 'inlinable type, non-inlinable coercion' => 'inl_type_with_no_inl_coercion', 'non-inlinable type' => 'no_inl_type', 'non-inlinable type, inlinable coercion' => 'no_inl_type_with_inl_coercion', 'non-inlinable type, non-inlinable coercion' => 'no_inl_type_with_no_inl_coercion', 'inlinable type with closed-over variables' => 'closure_inl_env_type', ); my %perms; for my $flavor (qw( Moose TT Specio )) { my $pkg = '_Types::' . $flavor; for my $k ( sort keys %subs ) { my $s = $subs{$k}; next unless $pkg->can($s); $perms{"$flavor - $k"} = $pkg->$s(); } } return %perms; } ## no critic (Modules::ProhibitMultiplePackages) { package _Types::Moose; use Moose::Util::TypeConstraints; ## no critic (Subroutines::ProtectPrivateSubs) sub inl_type { my $type = subtype( as 'Int', where { $_ > 0 }, inline_as { $_[0]->parent->_inline_check( $_[1] ) . " && $_[1] > 0" }, ); return $type; } sub inl_type_with_no_inl_coercion { my $type = subtype( as 'Int', where { $_ > 0 }, inline_as { $_[0]->parent->_inline_check( $_[1] ) . " && $_[1] > 0" }, ); coerce( $type, from 'ArrayRef', via { scalar @{$_} }, ); return $type; } sub no_inl_type { my $type = subtype( as 'Int', where { $_ > 0 }, ); return $type; } sub no_inl_type_with_no_inl_coercion { my $type = subtype( as 'Int', where { $_ > 0 }, ); coerce( $type, from 'ArrayRef', via { scalar @{$_} }, ); return $type; } sub closure_inl_env_type { return enum( [ 42, 43, 44, 700 ] ); } } { package _Types::TT; use Types::Standard qw( Int ArrayRef ); use Type::Utils -all; sub inl_type { my $type = subtype( as Int, where { $_ > 0 }, inline_as { $_[0]->parent->inline_check( $_[1] ) . " && $_[1] > 0" }, ); return $type; } sub inl_type_with_inl_coercion { my $type = subtype( as Int, where { $_ > 0 }, inline_as { $_[0]->parent->inline_check( $_[1] ) . " && $_[1] > 0" }, ); return $type->plus_coercions( ArrayRef, 'scalar @{ $_ }' ); } sub inl_type_with_no_inl_coercion { my $type = subtype( as Int, where { $_ > 0 }, inline_as { $_[0]->parent->inline_check( $_[1] ) . " && $_[1] > 0" }, ); return $type->plus_coercions( ArrayRef, sub { scalar @{$_} } ); } sub no_inl_type { my $type = subtype( as Int, where { $_ > 0 } ); return $type; } sub no_inl_type_with_inl_coercion { my $type = subtype( as Int, where { $_ > 0 } ); return $type->plus_coercions( ArrayRef, 'scalar @{ $_ }' ); } sub no_inl_type_with_no_inl_coercion { my $type = subtype( as Int, where { $_ > 0 } ); return $type->plus_coercions( ArrayRef, sub { scalar @{$_} } ); } } { package _Types::Specio; use Specio::Declare; use Specio::Library::Builtins; sub inl_type { my $type = anon( parent => t('Int'), inline => sub { $_[0]->parent->inline_check( $_[1] ) . " && $_[1] > 0"; }, ); return $type; } sub inl_type_with_inl_coercion { my $type = anon( parent => t('Int'), inline => sub { $_[0]->parent->inline_check( $_[1] ) . " && $_[1] > 0"; }, ); coerce( $type, from => t('ArrayRef'), inline => sub {"scalar \@{ $_[1] }"}, ); return $type; } sub inl_type_with_no_inl_coercion { my $type = anon( parent => t('Int'), inline => sub { $_[0]->parent->inline_check( $_[1] ) . " && $_[1] > 0"; }, ); coerce( $type, from => t('ArrayRef'), using => sub { scalar @{ $_[0] } }, ); return $type; } sub no_inl_type { my $type = anon( parent => t('Int'), inline => sub { $_[0]->parent->inline_check( $_[1] ) . " && $_[1] > 0"; }, ); return $type; } sub no_inl_type_with_inl_coercion { my $type = anon( parent => t('Int'), inline => sub { $_[0]->parent->inline_check( $_[1] ) . " && $_[1] > 0"; }, ); coerce( $type, from => t('ArrayRef'), inline => sub {"scalar \@{ $_[1] }"}, ); return $type; } sub no_inl_type_with_no_inl_coercion { my $type = anon( parent => t('Int'), inline => sub { $_[0]->parent->inline_check( $_[1] ) . " && $_[1] > 0"; }, ); coerce( $type, from => t('ArrayRef'), using => sub { scalar @{ $_[0] } }, ); return $type; } sub closure_inl_env_type { return enum( values => [ 42, 43, 44, 700 ] ); } } __END__ ## Parameter specs ### Type * No type, just required * Has a type -> [Types](#types) ### Required or not * Required * Optional ### Defaults * No default * Has a non-sub default * Has a subroutine default ## Slurpy * Any type * A specific type -> [Types](#types) ## Parameter passing style * Named * As k/v pairs * As hashref * Named to list * Positional ## Types ### Type System * Moose * Specio * Type::Tiny ### Inlining * Type can be inlined * Type inlining requires "env" vars * Coercion inlining requires "env" vars * Type cannot be inlined ### Coercions * No coercion * With coercion(s) * that can all be inlined * none of which can be inlined * some of which can be inlined Params-ValidationCompiler-0.30/xt/author/mojibake.t0000644000175000017500000000015113330066233022201 0ustar autarchautarch#!perl use strict; use warnings qw(all); use Test::More; use Test::Mojibake; all_files_encoding_ok(); Params-ValidationCompiler-0.30/xt/author/tidyall.t0000644000175000017500000000067413330066233022074 0ustar autarchautarch# This file was automatically generated by Dist::Zilla::Plugin::Test::TidyAll v$VERSION use Test::More 0.88; BEGIN { if ( $] < 5.010 ) { plan skip_all => 'This test requires Perl version 5.010'; } } use Test::Code::TidyAll 0.24; tidyall_ok( verbose => ( exists $ENV{TEST_TIDYALL_VERBOSE} ? $ENV{TEST_TIDYALL_VERBOSE} : 1 ), jobs => ( exists $ENV{TEST_TIDYALL_JOBS} ? $ENV{TEST_TIDYALL_JOBS} : 4 ), ); done_testing; Params-ValidationCompiler-0.30/xt/author/eol.t0000644000175000017500000000157213330066233021207 0ustar autarchautarchuse strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::EOL 0.19 use Test::More 0.88; use Test::EOL; my @files = ( 'lib/Params/ValidationCompiler.pm', 'lib/Params/ValidationCompiler/Compiler.pm', 'lib/Params/ValidationCompiler/Exceptions.pm', 't/00-report-prereqs.dd', 't/00-report-prereqs.t', 't/default.t', 't/exceptions.t', 't/moose.t', 't/name-fails.t', 't/name.t', 't/named/args-check.t', 't/named/const-hash.t', 't/named/locked-hash.t', 't/named/required.t', 't/named/return-object.t', 't/named/slurpy.t', 't/pairs-to-value-list.t', 't/positional/default.t', 't/positional/required.t', 't/positional/slurpy.t', 't/self-check.t', 't/source_for.t', 't/specio.t', 't/type-tiny.t' ); eol_unix_ok($_, { trailing_whitespace => 1 }) foreach @files; done_testing; Params-ValidationCompiler-0.30/xt/author/test-version.t0000644000175000017500000000063713330066233023073 0ustar autarchautarchuse strict; use warnings; use Test::More; # generated by Dist::Zilla::Plugin::Test::Version 1.09 use Test::Version; my @imports = qw( version_all_ok ); my $params = { is_strict => 1, has_version => 1, multiple => 0, }; push @imports, $params if version->parse( $Test::Version::VERSION ) >= version->parse('1.002'); Test::Version->import(@imports); version_all_ok; done_testing; Params-ValidationCompiler-0.30/xt/author/00-compile.t0000644000175000017500000000271513330066233022275 0ustar autarchautarchuse 5.006; use strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::Compile 2.058 use Test::More; plan tests => 4; my @module_files = ( 'Params/ValidationCompiler.pm', 'Params/ValidationCompiler/Compiler.pm', 'Params/ValidationCompiler/Exceptions.pm' ); # no fake home requested my @switches = ( -d 'blib' ? '-Mblib' : '-Ilib', ); use File::Spec; use IPC::Open3; use IO::Handle; open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!"; my @warnings; for my $lib (@module_files) { # see L my $stderr = IO::Handle->new; diag('Running: ', join(', ', map { my $str = $_; $str =~ s/'/\\'/g; q{'} . $str . q{'} } $^X, @switches, '-e', "require q[$lib]")) if $ENV{PERL_COMPILE_TEST_DEBUG}; my $pid = open3($stdin, '>&STDERR', $stderr, $^X, @switches, '-e', "require q[$lib]"); binmode $stderr, ':crlf' if $^O eq 'MSWin32'; my @_warnings = <$stderr>; waitpid($pid, 0); is($?, 0, "$lib loaded ok"); shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/ and not eval { +require blib; blib->VERSION('1.01') }; if (@_warnings) { warn @_warnings; push @warnings, @_warnings; } } is(scalar(@warnings), 0, 'no warnings found') or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ); Params-ValidationCompiler-0.30/xt/author/portability.t0000644000175000017500000000026713330066233022772 0ustar autarchautarchuse strict; use warnings; use Test::More; eval 'use Test::Portability::Files'; plan skip_all => 'Test::Portability::Files required for testing portability' if $@; run_tests(); Params-ValidationCompiler-0.30/xt/author/pod-syntax.t0000644000175000017500000000025213330066233022530 0ustar autarchautarch#!perl # This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. use strict; use warnings; use Test::More; use Test::Pod 1.41; all_pod_files_ok(); Params-ValidationCompiler-0.30/xt/release/0000775000175000017500000000000013330066233020356 5ustar autarchautarchParams-ValidationCompiler-0.30/xt/release/cpan-changes.t0000644000175000017500000000034413330066233023071 0ustar autarchautarchuse strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::CPAN::Changes 0.012 use Test::More 0.96 tests => 1; use Test::CPAN::Changes; subtest 'changes_ok' => sub { changes_file_ok('Changes'); }; Params-ValidationCompiler-0.30/xt/release/meta-json.t0000644000175000017500000000006413330066233022436 0ustar autarchautarch#!perl use Test::CPAN::Meta::JSON; meta_json_ok();