Negated is_deeply() function in Test::More - unit-testing

Test::More has is_deeply() and mentions in the documentation that it should be used instead of eq_array() or eq_hash() because it has better diagnostics, and it states ...They may be deprecated in future versions
Now I'm replacing the use of eq_...() functions for is_deeply() but I run into a problem, there is no is_not_deeply() or such function, and I have a test like this:
ok (!eq_hash(\%h1, \%h2));
Is there an idiomatic alternative I can use to test deep inequality, preferably using Test::More?
Unlike eq_hash(), which just returns true or false and needs to be wrapped in ok(), is_deeply() itself is a test. So if you wrap it in "ok()" like below:
ok(!is_deeply(\%h1, \%h2));
There are now TWO tests, is_deeply() which is failing and ok(), which would pass!

It seems like this feature is not readily available with Test::More. Then I would recommend using Test2 instead:
use strict;
use warnings;
use Test2::V0;
my %h1 = (a => [1,2,3], b=>"x");
my %h2 = (a => [1,2,3], b=>"x");
isnt (\%h1, \%h2, "Hashes are not equal" );
done_testing;

Related

NUnit Console command line regex case insensitive?

I'm running NUnit tests on Jenkins/Mono and this is what my command looks like:
mono /opt/NUnit-3.8.0/nunit3-console.exe $WORKSPACE/ProjectName/bin/$CONFIG/ProjectName.dll --where="test~=$TEST_NAME" --config=$CONFIG
The idea is to be able to select tests using a regular expression. Now, I want to select tests with Regex but ignoring case. I tried something like this:
TEST_NAME = ^.*(?i)something(?-i).*$
And also tried:
TEST_NAME = ^.*something.*$/i
But I got the "unexpected token '('" and "unexpected token '/'" errors. Is there any way to use a case-insensitive modifier?
The NUnit console runner --where=EXPRESSION uses a specific test selection language (TSL) where
an expression indicating which tests to run. It may specify test
names, classes, methods, categories or properties comparing them to
actual values with the operators ==, !=, =~ and !~.
For matching regular expressions, NUnit users .NET's Regex.IsMatch
method... as described here.
Try it like this and check out the samples in the linked TSL doc above.
--where "test =~ /(?i).*mytest/"
However, if you are using NUnit V2 you are probably out of luck:
The driver for NUnit V2 supports a subset of TSL. Because the V2 NUnit
framework only allowed filtering on test names and categories, you may
only use the cat and test keywords in comparisons. In addition, the
regular expression operators =~ and !~ are not supported.

Regexp::Debugger Perl module doesn't seem to work within another Perl Module

I am writing a Perl module that involves some very complicated regular expressions that are nearly impossible to debug without a tool to help me. I figured the Regexp::Debugger module would be the perfect tool for the job, but it only seems to work in .pl scripts and doesn't seem to work within a .pm module.
For example, this works:
test.pl
use strict;
use warnings;
use Regexp::Debugger;
my $text = "text";
if ($text =~ /tex/) {
print "Match!";
}
And I get the expected debugging functionality.
But the second I introduce a Perl Module to the mix it no longer works:
test.pl
use strict;
use warnings;
use TestModule;
TestModule::func();
TestModule.pm
package TestModule;
use strict;
use warnings;
use Regexp::Debugger;
sub func {
my $text = "text";
if ($text =~ /tex/) {
print "Match!";
}
}
1;
Attempting to run this code gives the following error:
Can't use an undefined value as a HASH reference at Regexp/Debugger.pm line 160
Simply including Regexp::Debugger in the "test.pl" file instead doesn't work either because it doesn't try to debug regexes within included modules.
How can I get this to work so I can debug the regexes within a module that I'm working on?
UPDATE:
A bug report has been filed, and a new version (v0.002001) is now available on CPAN that works as expected. :)
This seems to be a bug in the way Regexp::Debugger checks lexical hints in calling scopes, but I'm not sure how to fix it. For reference, https://metacpan.org/source/DCONWAY/Regexp-Debugger-0.002000/lib/Regexp/Debugger.pm#L160 is:
my $lexical_scope = (caller 1)[10]{'Regexp::Debugger::lexical_scope'};
Maybe it should do ((caller 1)[10] || {})->{'Regexp::Debugger::lexical_scope'} instead?
Anyway, I was able to reproduce your problem and I found a workaround. In test.pl, do:
use strict;
use warnings;
no Regexp::Debugger;
use TestModule;
I.e. load Regexp::Debugger before you use TestModule, but with no instead of use to avoid activating it for the main program.
With this change, I get:
TestModule.pm did not return a true value at test.pl line 4.
BEGIN failed--compilation aborted at test.pl line 4.
... which is still an error, but it's a good error. It means there were no problems with Regexp::Debugger.
If I then add a line of 1 at the end of TestModule.pm, everything works.
Update: OP reported the problem and it was fixed in version 0.002001 of Regexp::Debugger.

Grails Filter regexs

I am new to grails and so far i have only been able to use simple filters. I want to use filter in an efficient manner.
(I am using grails 2.4.3, with jdk_1.6)
I want to create a filter to allow accessing AppName/ and AppName/user/login and i could not get it right! I wanted to use regex but i am not getting it right!
i tried this
loggedInOnly(uri:'/**',uriExclude :"*.css|*.js|*image*|/|/user/login"){
before = {
println "### ###### #### #"
}
}
and i also tried to revers the regex parameter, but i am getting no luck! I searched all of google but i could not find a single thread to tell me how filter regex work!
i know i could create xxxx(controller:'*', action:'*') filter then use the controllerName and actionName parameters to check! But there gotta be a better way!
My question in a nutshell: How does regex work in filters?
First, take a closer look at the documentation. Notice that uri and uriExclude are ant paths and not regular expressions. Keeping that in mind if you look how ant paths function you will see they aren't capable of logical ors.
So, with all of that in mind it's back to using enabling regex and using the find attribute instead.
loggedInOnly(regex: true, find: '(.​*.css|.*.js|.*image.*|\\/|\\/user\\/login)​', invert: true){
before = {
...
}
}
Notice I hae used invert to have this filter apply to anything that doesn't match any of the patterns inside the find. Also, I wrote this off the top of my head so you may have to spot check the regular expression in your application (I did check it using groovy web console to make sure I didn't really mess up the syntax).
Hope this helps.

When and why did the output of qr() change?

The output of perl's qr has changed, apparently sometime between versions 5.10.1 and 5.14.2, and the change is not documented--at least not fully.
To demonstrate the change, execute the following one-liner on each version:
perl -e 'print qr(foo)is."\n"'
Output from perl 5.10.1-17squeeze6 (Debian squeeze):
(?-xism:foo)
Output from perl 5.14.2-21+deb7u1 (Debian wheezy):
(?^:foo)
The perl documentation (perldoc perlop) says:
$rex = qr/my.STRING/is;
print $rex; # prints (?si-xm:my.STRING)
s/$rex/foo/;
which appears to no longer be true:
$ perl -e 'print qr/my.STRING/is."\n"'
(?^si:my.STRING)
I would like to know when this change occurred (which version of Perl, or supporting library or whatever).
Some background, in case it's relevant:
This change has caused a bunch of unit tests to fail. I need to decide if I should simply update the unit tests to reflect the new format, or make the tests dynamic enough to support both formats, etc. To make an informed decision, I would like to understand why the change took place. Knowing when and where it took place seems like the best place to start in that investigation.
It's documented in perl5140delta:
Regular Expressions
(?^...) construct signifies default modifiers
[...] Stringification of regular expressions now uses this notation. [...]
This change is likely to break code that compares stringified regular expressions with fixed strings containing ?-xism.
The function regexp_pattern can be used to parse the modifiers for normalisation purposes.
Part of the reason this was added, was that regular expressions were getting quite a few new modifiers.
Your example would actually produce something like this if that change didn't happen:
(?d-xismpaul:foo)
That also doesn't really express the modifiers in place.
d/u/l can only be added to a regex, not subtracted like i.
They are also mutually exclusive.
a/aa There are actually two levels for this modifier.
While work went underway adding these modifiers it was determined that this will break quite a few tests on CPAN modules.
Seeing as the tests were going to break anyway, it was agreed upon that there should be a way of specifying just use the defaults ((?^:…)).
That way, the tests wouldn't have to updated every time a new modifier was added.
To receive the stringified form of a regexp you can use Regexp::Parser and its qr method. Using this module you can not only test the representation of a regexp, but also walk a tree.

How do I check if a scalar has a compiled regex in it with Perl?

Let's say I have a subroutine/method that a user can call to test some data that (as an example) might look like this:
sub test_output {
my ($self, $test) = #_;
my $output = $self->long_process_to_get_data();
if ($output =~ /\Q$test/) {
$self->assert_something();
}
else {
$self->do_something_else();
}
}
Normally, $test is a string, which we're looking for anywhere in the output. This was an interface put together to make calling it very easy. However, we've found that sometimes, a straight string is problematic - for example, a large, possibly varying number of spaces...a pattern, if you will. Thus, I'd like to let them pass in a regex as an option. I could just do:
$output =~ $test
if I could assume that it's always a regex, but ah, but the backwards compatibility! If they pass in a string, it still needs to test it like a raw string.
So in that case, I'll need to test to see if $test is a regex. Is there any good facility for detecting whether or not a scalar has a compiled regex in it?
As hobbs points out, if you're sure that you'll be on 5.10 or later, you can use the built-in check:
use 5.010;
use re qw(is_regexp);
if (is_regexp($pattern)) {
say "It's a regex";
} else {
say "Not a regex";
}
However, I don't always have that option. In general, I do this by checking against a prototype value with ref:
if( ref $scalar eq ref qr// ) { ... }
One of the reasons I started doing it this way was that I could never remember the type name for a regex reference. I can't even remember it now. It's not uppercase like the rest of them, either, because it's really one of the packages implemented in the perl source code (in regcomp.c if you care to see it).
If you have to do that a lot, you can make that prototype value a constant using your favorite constant creator:
use constant REGEX_TYPE => ref qr//;
I talk about this at length in Effective Perl Programming as "Item 59: Compare values to prototypes".
If you want to try it both ways, you can use a version check on perl:
if( $] < 5.010 ) { warn "upgrade now!\n"; ... do it my way ... }
else { ... use is_regex ... }
As of perl 5.10.0 there's a direct, non-tricky way to do this:
use 5.010;
use re qw(is_regexp);
if (is_regexp($pattern)) {
say "It's a regex";
} else {
say "Not a regex";
}
is_regexp uses the same internal test that perl uses, which means that unlike ref, it won't be fooled if, for some strange reason, you decide to bless a regex object into a class other than Regexp (yes, that's possible).
In the future (or right now, if you can ship code with a 5.10.0 requirement) this should be considered the standard answer to the problem. Not only because it avoids a tricky edge-case, but also because it has the advantage of saying exactly what it means. Expressive code is a good thing.
See the ref built-in.