diff --git a/t/101_issues/Int.t b/t/101_issues/Int.t new file mode 100644 index 00000000..2ef53cea --- /dev/null +++ b/t/101_issues/Int.t @@ -0,0 +1,44 @@ +#!/usr/bin/perl +use strict; +use warnings; +use Test::More; +use Mouse::Util::TypeConstraints; + +my $Int = find_type_constraint 'Int'; + +subtest "Non-Int from numerical literal: my \$num = 3.14", sub { + my $num = 3.14; + ok !$Int->check($num), "\$num is not Int"; + { no warnings; int($num) }; + ok !$Int->check($num), "\$num is still not Int"; +}; + +subtest "Non-Int from string literal: my \$num = \"3.14\"", sub { + my $num = "3.14"; + ok !$Int->check($num), "\$num is not Int"; + { no warnings; int($num) }; + ok !$Int->check($num), "\$num is still not Int"; +}; + +subtest "Int from string literal: my \$num = \"3\"", sub { + my $num = "3"; + ok $Int->check($num), "\$num is Int"; + { no warnings; int($num) }; + ok $Int->check($num), "\$num is still Int"; +}; + +subtest "Int from integer literal: my \$num = 3", sub { + my $num = 3; + ok $Int->check($num), "\$num is Int"; + { no warnings; int($num) }; + ok $Int->check($num), "\$num is still Int"; +}; + +subtest "MAXUINT", sub { + my $maxuint = ~0; + ok $Int->check( $maxuint ), 'yes MAXUINT'; + my $as_string = sprintf '%f', $maxuint; + ok $Int->check( $maxuint ), 'yes MAXUINT after use as float'; +}; + +done_testing; diff --git a/xs-src/MouseTypeConstraints.xs b/xs-src/MouseTypeConstraints.xs index fd581875..4ef92c39 100644 --- a/xs-src/MouseTypeConstraints.xs +++ b/xs-src/MouseTypeConstraints.xs @@ -168,16 +168,21 @@ S_nv_is_integer(pTHX_ NV const nv) { int mouse_tc_Int(pTHX_ SV* const data PERL_UNUSED_DECL, SV* const sv) { assert(sv); - if(SvPOKp(sv)){ + + if(SvPOK(sv)){ int const num_type = grok_number(SvPVX(sv), SvCUR(sv), NULL); return num_type && !(num_type & IS_NUMBER_NOT_INT); } - else if(SvIOKp(sv)){ + else if(SvIOK(sv)){ return TRUE; } - else if(SvNOKp(sv)) { + else if(SvNOK(sv)) { return S_nv_is_integer(aTHX_ SvNVX(sv)); } + else if (SvOK(sv) && (SvMAGIC(sv) || SvTYPE(sv) == SVt_PVMG) && SvIOKp(sv)) { + return TRUE; + } + return FALSE; }