Re: is(), undef, '' and 0 (was Re: [PATCH lib/DB.pm MANIFEST lib

2001-11-24 Thread Tels

-BEGIN PGP SIGNED MESSAGE-

Moin,

On 23-Nov-01 Nicholas Clark tried to scribble about:
> On Fri, Nov 23, 2001 at 05:59:56PM -0500, Michael G Schwern wrote:
>> Crap, this doesn't quite work in the general case.
>> 
>> is( undef, undef ); # ok
>> is( 0, undef ); # not ok
>> is('', undef ); # ok
>> 
>> is() uses eq and undef stringifies to ''.  is( $foo, undef ) is a nice
>> idiom, though.
>> 
>> Should is() distinguish between undef, 0 and ''?  Seeing as how it
>> already does between undef and 0 (accidentally), I guess it wouldn't
>> hurt.
> 
> I really think it should distinguish between undef and ''.
> Test::ok makes the distinction, and I find that useful.
> (and a reason to use Test; rather than use Test::More
> [if that's not a red rag to a Schwern, what is? :-) ])
> 
> In the general case I want to test that $foo is an empty defined string,
> where undef will be an error (probably an error not forseen when I was
> writing the test case).

Or the reverse: If I want totest whether $foo is undef, '' should be a
failed test.

use Math::String;
use test::More;

$x = Math::String->new('ABC');  # NaN => undef on stringify
is ($x, undef); # ok
$x = Math::String->new(''); # '' => '' on stringify
is ($x, undef); # doesn't fail as it should

> If I mean '' and undef to be equivalently correct, I usually want to
> express that explicitly.

Like:

is ($x || '', '');

Cheers,

Tels

- -- 
 perl -MDev::Bollocks -e'print Dev::Bollocks->rand(),"\n"'
 quickly enable 24/365 communities

 http://bloodgate.com/perl   My current Perl projects
 PGP key available on http://bloodgate.com/tels.asc or via email 

-BEGIN PGP SIGNATURE-
Version: 2.6.3i
Charset: latin1

iQEVAwUBO/7yUXcLPEOTuEwVAQFaKgf+P5Jsllg+3Lm8ltvoiBEtVcmIRMRlqf9j
7I6kLSWJj2GCAgge6/o9/pCfumrVNeRmkRiG8prjxVelKGd55AeYgwTcfQv2vDcm
SBVcQc9VfCuIj5T/2mQtxzeGwoxScLIW/pH5G2D3/+MuWBiyuRWQ1rxsnaoRQJrz
Zi6nchW45c2HxMMGqhSaBFMRAsp3gLmlfotG6EKih9BRxzZVLXenaC+b2NeNKIBJ
3a15h7t9HVcYGKFMQwsyA+HlsAzXEezzMQB1GYWa+D0DoMKCCaVwGehFjxHdqjpX
CbdySPtuex7Xn3kTAF4LjNpX5f3GSWbl8GpMHUNWFXaCdiwwyIk/BA==
=qtXV
-END PGP SIGNATURE-



[PATCH lib/DB.pm MANIFEST lib/DB.t] Add Tests for DB.pm

2001-11-24 Thread chromatic

Here's a bunch of tests for DB.pm.  Some bits aren't easily testable, and
there's room for someone more knowledgeable or clever to come along to improve
them even more.

In the process of writing these tests, I patched one little thing in DB.pm, per
the comment.

With the patch, all pass.

-- c

--- lib/~DB.pm  Fri Nov 23 14:04:53 2001
+++ lib/DB.pm   Fri Nov 23 14:48:12 2001
@@ -406,8 +406,7 @@
   $name = "main" . $name if substr($name,0,2) eq "::";
   my($fname, $from, $to) = ($DB::sub{$name} =~ /^(.*):(\d+)-(\d+)$/);
   if ($from) {
-# XXX this needs local()-ization of some sort
-*DB::dbline = "::_<$fname";
+local *DB::dbline = "::_<$fname";
 ++$from while $DB::dbline[$from] == 0 && $from < $to;
 return $from;
   }

--- ~MANIFEST   Fri Nov 23 14:51:04 2001
+++ MANIFESTFri Nov 23 14:51:27 2001
@@ -888,6 +888,7 @@
 lib/ctime.pl   A ctime workalike
 lib/Cwd.pm Various cwd routines (getcwd, fastcwd, chdir)
 lib/DB.pm  Debugger API (draft)
+lib/DB.t   See if DB works
 lib/Devel/SelfStubber.pm   Generate stubs for SelfLoader.pm
 lib/Devel/SelfStubber.tSee if Devel::SelfStubber works
 lib/diagnostics.pm Print verbose diagnostics
--- /dev/null   Thu Aug 30 03:54:37 2001
+++ lib/DB.tFri Nov 23 15:22:17 2001
@@ -0,0 +1,486 @@
+#!./perl
+
+BEGIN {
+   chdir 't' if -d 't';
+   @INC = '../lib';
+}
+
+use Test::More tests => 106;
+
+# must happen at compile time for DB:: package variable localizations to work
+BEGIN {
+   use_ok( 'DB' );
+}
+
+# test DB::sub()
+{
+   my $callflag = 0;
+   local $DB::sub = sub {
+   $callflag += shift || 1;
+   my @vals = (1, 4, 9);
+   return @vals;
+   };
+   my $ret = DB::sub;
+   is( $ret, 3, 'DB::sub() should handle scalar context' );
+   is( $callflag, 1, '... should call $DB::sub contents' );
+   $ret = join(' ', DB::sub(2));
+   is( $ret, '1 4 9', '... should handle scalar context' );
+   is( $callflag, 3, '... should pass along arguments to the sub' );
+   ok( defined($DB::ret),'$DB::ret should be defined after successful return');
+   DB::sub;
+   ok( !defined($DB::ret), '... should respect void context' );
+   $DB::sub = '::DESTROY';
+   ok( !defined($DB::ret), '... should return undef for DESTROY()' );
+}
+
+# test DB::DB()
+{ 
+   is( DB::DB(), undef, 'DB::DB() should return undef if $DB::ready is false');
+   is( DB::catch(), 1, 'DB::catch() should work' );
+   is( DB->skippkg('foo'), 1, 'DB->skippkg() should push args' );
+
+   # change packages to mess with caller()
+   package foo;
+   ::is( DB::DB(), undef, 'DB::DB() should skip skippable packages' );
+
+   package main;
+   is( $DB::filename, $0, '... should set $DB::filename' );
+   is( $DB::lineno, __LINE__ - 4, '... should set $DB::lineno' );
+
+   DB::DB();
+   # stops at line 94
+}
+
+# test DB::save()
+{
+   # assigning a number to $! seems to produce an error message, when read
+   local ($@, $,, $/, $\, $^W, $!) = (1 .. 5);
+   DB::save();
+   is( "$@$!$,$/$\$^W", "1\n0", 'DB::save() should reset punctuation vars' );
+}
+
+# test DB::catch()
+{
+   local $DB::signal;
+   DB::catch();
+   ok( $DB::signal, 'DB::catch() should set $DB::signal' );
+   # add clients and test to see if they are awakened
+}
+
+# test DB::_clientname()
+is( DB::_clientname('foo=A(1)'), 'foo','DB::_clientname should return refname');
+is( DB::_clientname('bar'), '','DB::_clientname should not return non refname');
+
+# test DB::next() and DB::step()
+{
+   local $DB::single;
+   DB->next();
+   is( $DB::single, 2, 'DB->next() should set $DB::single to 2' );
+   DB->step();
+   is( $DB::single, 1, 'DB->step() should set $DB::single to 1' );
+}
+
+# test DB::cont()
+{
+   # cannot test @stack
+
+   local $DB::single = 1;
+   my $fdb = FakeDB->new();
+   DB::cont($fdb, 2);
+   is( $fdb->{tbreak}, 2, 'DB::cont() should set tbreak in object' );
+   is( $DB::single, 0, '... should set $DB::single to 0' );
+}
+
+# test DB::ret()
+{
+   # cannot test @stack
+
+   local $DB::single = 1;
+   DB::ret();
+   is( $DB::single, 0, 'DB::ret() should set $DB::single to 0' );
+}
+
+# test DB::backtrace()
+{
+   local (@DB::args, $DB::signal);
+
+   my $line = __LINE__ + 1;
+   my @ret = eval { DB->backtrace() };
+   like( $ret[0], qr/file.+$0/, 'DB::backtrace() should report current file');
+   like( $ret[0], qr/line $line/, '... should report calling line number' );
+   like( $ret[0], qr/eval {...}/, '... should catch eval BLOCK' );
+
+   @ret = eval "one(2)";
+   is( scalar @ret, 1, '... should report from provided stack frame number' );
+   like( $ret[0], qr/\@ = &eval \'one.+?2\)\'/, #'
+   '... should find eval STRING construct')

Re: is(), undef, '' and 0 (was Re: [PATCH lib/DB.pm MANIFEST lib/DB.t] Add Tests for DB.pm)

2001-11-24 Thread chromatic

On Friday 23 November 2001 15:59, you wrote:

> On Fri, Nov 23, 2001 at 03:32:41PM -0700, chromatic wrote:
> > +   is( DB::DB(), undef, 'DB::DB() should return undef if $DB::ready is
> > false');
>
> Crap, this doesn't quite work in the general case.
>
> is( undef, undef ); # ok
> is( 0, undef ); # not ok
> is('', undef ); # ok
>
> is() uses eq and undef stringifies to ''.  is( $foo, undef ) is a nice
> idiom, though.

I got it from *somewhere*.  I'd almost swear it was in the first version of 
Test::Builder, having been untimely ripped from the womb of pre-wrapper 
Test::More.

> Should is() distinguish between undef, 0 and ''?  Seeing as how it
> already does between undef and 0 (accidentally), I guess it wouldn't
> hurt.

Perl does, why shouldn't the tests?  Something like this only has one problem:

$test = 'undef' unless defined $test;

Most people likely to write tests are smart enough to avoid nasty literal 
phrases like '0 but true' and 'undef'.  I hope.  I left room at lunch to eat 
those words, though.

-- c



is(), undef, '' and 0 (was Re: [PATCH lib/DB.pm MANIFEST lib/DB.t] Add Tests for DB.pm)

2001-11-24 Thread Michael G Schwern

On Fri, Nov 23, 2001 at 03:32:41PM -0700, chromatic wrote:
> + is( DB::DB(), undef, 'DB::DB() should return undef if $DB::ready is false');

Crap, this doesn't quite work in the general case.

is( undef, undef ); # ok
is( 0, undef ); # not ok
is('', undef ); # ok

is() uses eq and undef stringifies to ''.  is( $foo, undef ) is a nice
idiom, though.

Should is() distinguish between undef, 0 and ''?  Seeing as how it
already does between undef and 0 (accidentally), I guess it wouldn't
hurt.

-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl Quality Assurance  <[EMAIL PROTECTED]> Kwalitee Is Job One
The truth is you suck!