Aion

 view release on metacpan or  search on metacpan

t/aion/types.t  view on Meta::CPAN

use common::sense; use open qw/:std :utf8/;  use Carp qw//; use Cwd qw//; use File::Basename qw//; use File::Find qw//; use File::Slurper qw//; use File::Spec qw//; use File::Path qw//; use Scalar::Util qw//;  use Test::More 0.98;  use String::Diff q...
# # NAME
# 
# Aion::Types - библиотека стандартных валидаторов и служит для создания новых валидаторов
# 
# # SYNOPSIS
# 
subtest 'SYNOPSIS' => sub { 
use Aion::Types;

BEGIN {
	subtype SpeakOfKitty => as StrMatch[qr/\bkitty\b/i],
		message { "Speak is'nt included kitty!" };
}

local ($::_g0 = do {"Kitty!" ~~ SpeakOfKitty}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"Kitty!" ~~ SpeakOfKitty # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {"abc"    ~~ SpeakOfKitty}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"abc"    ~~ SpeakOfKitty # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

eval {SpeakOfKitty->validate("abc", "This")}; local ($::_g0 = $@, $::_e0 = 'Speak is\'nt included kitty!'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'SpeakOfKitty->validate("abc", "This") # @-> Speak is\'nt included kitty!' or ::diag ...


BEGIN {
	subtype IntOrArrayRef => as (Int | ArrayRef);
}

local ($::_g0 = do {[] ~~ IntOrArrayRef}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '[] ~~ IntOrArrayRef  # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {35 ~~ IntOrArrayRef}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '35 ~~ IntOrArrayRef  # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {"" ~~ IntOrArrayRef}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"" ~~ IntOrArrayRef  # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;


coerce IntOrArrayRef, from Num, via { int($_ + .5) };

local ($::_g0 = do {IntOrArrayRef->coerce(5.5)}, $::_e0 = "6"); ::ok $::_g0 eq $::_e0, 'IntOrArrayRef->coerce(5.5) # => 6' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# # DESCRIPTION
# 
# Этот модуль экспортирует подпрограммы:
# 
# * `subtype`, `as`, `init_where`, `where`, `awhere`, `message` — для создания валидаторов.
# * `SELF`, `ARGS`, `A`, `B`, `C`, `D`, `M`, `N` — для использования в валидаторах типа и его аргументов.
# * `coerce`, `from`, `via` — для создания конвертора значений из одного класса в другой.
# 
# Иерархия валидаторов:
# 

# Any
# 	Control
# 		Union[A, B...]
# 		Intersection[A, B...]
# 		Exclude[A...]
# 		Option[A]
# 		Wantarray[A, B]
# 	Item
# 		External[type]
# 		Bool
# 		BoolLike
# 		Enum[e...]
# 		Maybe[A]
# 		Undef
# 		Defined
# 			Value
# 				Version
# 				Str
# 					Uni
# 					Bin
# 					NonEmptyStr
# 					StartsWith[start]
# 					EndsWith[end]
# 					Email
# 					Tel
# 					Url
# 					Path
# 					Html
# 					StrDate
# 					StrDateTime
# 					StrMatch[regexp]
# 					ClassName
# 					RoleName
# 					Join[separator]
# 					Split[separator]
# 					StrRat
# 					Num
# 						PositiveNum
# 						Int
# 							PositiveInt
# 							Nat
# 			Ref
# 				Tied`[class]
# 				LValueRef
# 				FormatRef
# 				CodeRef
# 					NamedCode[subname]
# 					ProtoCode[prototype]
# 					ForwardRef
# 					ImplementRef
# 					Isa[A...]
# 				RegexpRef
# 				ValueRef`[A]
# 					ScalarRef`[A]
# 					RefRef`[A]
# 				GlobRef
# 					FileHandle
# 				ArrayRef`[A]
# 				HashRef`[A]
# 				Object`[class]
# 					Me
# 					Rat
# 				Map[A => B]
# 				Tuple[A...]

t/aion/types.t  view on Meta::CPAN

local ($::_g0 = do {Int->coerce(2.5)}, $::_e0 = do {3}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Int->coerce(2.5)  # -> 3' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Int->coerce(-2.5)}, $::_e0 = do {-3}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Int->coerce(-2.5) # -> -3' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# Bool from Any — 1 or ""
local ($::_g0 = do {Bool->coerce([])}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Bool->coerce([]) # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Bool->coerce(0)}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Bool->coerce(0)  # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## from ($type)
# 
# Синтаксический сахар для `coerce`.
# 
# ## via ($code)
# 
# Синтаксический сахар для `coerce`.
# 
# # ATTRIBUTES
# 
# ## :Isa (@signature)
# 
# Проверяет сигнатуру подпрограммы: аргументы и результаты.
# 
::done_testing; }; subtest ':Isa (@signature)' => sub { 
sub minint($$) : Isa(Int => Int => Int) {
	my ($x, $y) = @_;
	$x < $y? $x : $y
}

local ($::_g0 = do {minint 6, 5;}, $::_e0 = do {5}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'minint 6, 5; # -> 5' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
::like scalar do {eval {minint 5.5, 2}; $@}, qr{Arguments of method `minint` must have the type Tuple\[Int, Int\]\.}, 'eval {minint 5.5, 2}; $@ # ~> Arguments of method `minint` must have the type Tuple\[Int, Int\]\.'; undef $::_g0; undef $::_e0;

sub half($) : Isa(Int => Int) {
	my ($x) = @_;
	$x / 2
}

local ($::_g0 = do {half 4;}, $::_e0 = do {2}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'half 4; # -> 2' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
::like scalar do {eval {half 5}; $@}, qr{Return of method `half` must have the type Int. The it is 2.5}, 'eval {half 5}; $@ # ~> Return of method `half` must have the type Int. The it is 2.5'; undef $::_g0; undef $::_e0;

# 
# # TYPES
# 
# ## Any
# 
# Тип верхнего уровня в иерархии. Сопоставляет всё.
# 
# ## Control
# 
# Тип верхнего уровня в конструкторах иерархии создает новые типы из любых типов.
# 
# ## Union[A, B...]
# 
# Союз нескольких типов. Аналогичен оператору `$type1 | $type2`.
# 
::done_testing; }; subtest 'Union[A, B...]' => sub { 
local ($::_g0 = do {33  ~~ Union[Int, Ref]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '33  ~~ Union[Int, Ref] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {[]  ~~ Union[Int, Ref]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '[]  ~~ Union[Int, Ref]	# -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {"a" ~~ Union[Int, Ref]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"a" ~~ Union[Int, Ref]	# -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## Intersection[A, B...]
# 
# Пересечение нескольких типов. Аналогичен оператору `$type1 & $type2`.
# 
::done_testing; }; subtest 'Intersection[A, B...]' => sub { 
local ($::_g0 = do {15 ~~ Intersection[Int, StrMatch[/5/]]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '15 ~~ Intersection[Int, StrMatch[/5/]] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef ...

# 
# ## Exclude[A, B...]
# 
# Исключение нескольких типов. Аналогичен оператору `~ $type`.
# 
::done_testing; }; subtest 'Exclude[A, B...]' => sub { 
local ($::_g0 = do {-5  ~~ Exclude[PositiveInt]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '-5  ~~ Exclude[PositiveInt] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {"a" ~~ Exclude[PositiveInt]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"a" ~~ Exclude[PositiveInt] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {5   ~~ Exclude[PositiveInt]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '5   ~~ Exclude[PositiveInt] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {5.5 ~~ Exclude[PositiveInt]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '5.5 ~~ Exclude[PositiveInt] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# Если `Exclude` имеет много аргументов, то это аналог `~ ($type1 | $type2 ...)`.
# 

local ($::_g0 = do {-5  ~~ Exclude[PositiveInt, Enum[-2]]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '-5  ~~ Exclude[PositiveInt, Enum[-2]] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $:...
local ($::_g0 = do {-2  ~~ Exclude[PositiveInt, Enum[-2]]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '-2  ~~ Exclude[PositiveInt, Enum[-2]] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef ...
local ($::_g0 = do {0   ~~ Exclude[PositiveInt, Enum[-2]]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '0   ~~ Exclude[PositiveInt, Enum[-2]] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef ...

# 
# ## Option[A]
# 
# Дополнительные ключи в `Dict`.
# 
::done_testing; }; subtest 'Option[A]' => sub { 
local ($::_g0 = do {{a=>55} ~~ Dict[a=>Int, b => Option[Int]]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{a=>55} ~~ Dict[a=>Int, b => Option[Int]]          # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef...
local ($::_g0 = do {{a=>55, b=>31} ~~ Dict[a=>Int, b => Option[Int]]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{a=>55, b=>31} ~~ Dict[a=>Int, b => Option[Int]]   # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0)...
local ($::_g0 = do {{a=>55, b=>31.5} ~~ Dict[a=>Int, b => Option[Int]]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{a=>55, b=>31.5} ~~ Dict[a=>Int, b => Option[Int]] # -> ""' or ::diag ::_struct_diff($::_g0, $::...

# 
# ## Wantarray[A, S]
# 
# Если подпрограмма возвращает разные значения в контексте массива и скаляра, то используется тип `Wantarray` с типом `A` для контекста массива...
# 
::done_testing; }; subtest 'Wantarray[A, S]' => sub { 
sub arr : Isa(PositiveInt => Wantarray[ArrayRef[PositiveInt], PositiveInt]) {
	my ($n) = @_;
	wantarray? 1 .. $n: $n
}

my @a = arr(3);
my $s = arr(3);

local ($::_g0 = do {\@a}, $::_e0 = do {[1,2,3]}); ::is_deeply $::_g0, $::_e0, '\@a # --> [1,2,3]' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$s}, $::_e0 = do {3}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$s  # -> 3' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## Item
# 
# Тип верхнего уровня в иерархии скалярных типов.
# 
# ## External[type]
# 
# Правращает `type` в `Aion::Type`.
# 
# * Если `type` - `Aion::Type`, то возвращает его без изменений.
# * Если `type` строка, то оборачивает его в `Object`.
# * Если `type` можно вызвать, то оборачивает его в `Aion::Type->new(test => $type, ...)`. А если он имеет метод `coerce`, то будет его использовать для преобразова...
# 



( run in 1.913 second using v1.01-cache-2.11-cpan-f56aa216473 )