Skip Menu |

This queue is for tickets about the Test-Most CPAN distribution.

Report information
The Basics
Id: 73299
Status: open
Priority: 0/
Queue: Test-Most

People
Owner: Nobody in particular
Requestors: RWSTAUNER [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.25
Fixed in: (no value)



Subject: Mangling Test::More's @EXPORT causes confusion when combined with Test::Aggregate
I was in a small test script using only Test::More but was receiving weird errors trying to use `diag explain $obj` for debugging. The errors varied from indirect-object syntax on an unblessed reference to undefined sub, etc (depending on what I changed to try to figure out the problem). I traced it down the the fact that my test script was being run under Test::Aggregate which was launched from a test script that uses Test::Most. I found in the source code that Test::Most splices 'explain' out of @Test::More::EXPORT (which is why it wasn't being imported here). So after some confusion and some digging I guess I'm just wondering if this is necessary. I tried to look at the source history but that code was there from the first 'lost the history' commit i found on github. Was that necessary just to avoid importing `explain` into your own namespace? Or was there also a problem of it getting exported to the main package? In the end it may not even be worth dealing with, but it was darn confusing there for a while :-) Just something you need to know when combining all these pieces together, I guess. I guess if you're using Test::Most somewhere in the beginning you might as well be using it later down the line, at which point you'd already know that 'explain' was different in Test::Most. Does this maybe warrant a mention in the documentation?
Subject: Re: [rt.cpan.org #73299] Mangling Test::More's @EXPORT causes confusion when combined with Test::Aggregate
Date: Fri, 16 Dec 2011 01:06:36 -0800 (PST)
To: "bug-Test-Most [...] rt.cpan.org" <bug-Test-Most [...] rt.cpan.org>
From: Ovid <curtis_ovid_poe [...] yahoo.com>
Hi Randy, The reason Test::Most removes explain() from Test::More's @EXPORT is because I added explain() long before Test::More added it. Unfortunately, I optimized for the common case where you want to explain() your data and Schwern felt it was more important to give flexibility. We never agreed on that, so he decided to implement a different explain() than Test::Most's. Thus, I had to pull his from the @EXPORT list for backwards-compatibility.   You're right that it could probably use a mention in the docs, but other ideas are welcome. Maybe I could localize @EXPORT in Test::Most? I never tried that before. Cheers, Ovid -- Live and work overseas - http://overseas-exile.blogspot.com/ Buy the book - http://www.oreilly.com/catalog/perlhks/ Tech blog - http://blogs.perl.org/users/ovid/ Twitter - http://twitter.com/OvidPerl/
On Fri, 16 Dec 2011 04:06:45 -0500, curtis_ovid_poe@yahoo.com wrote: Show quoted text
> Hi Randy, > > The reason Test::Most removes explain() from Test::More's @EXPORT is > because I added explain() long before Test::More added it. > Unfortunately, I optimized for the common case where you want to > explain() your data and Schwern felt it was more important to give > flexibility. We never agreed on that, so he decided to implement a > different explain() than Test::Most's. Thus, I had to pull his from > the @EXPORT list for backwards-compatibility.
The end result is really confusing. This class: package MyTests::Foo; use base 'MyTests::Base'; use Test::More; sub explain_some_stuff :Test(1) { diag(explain("some stuff")); pass; } 1; coupled with: package MyTests::Base; use base 'Test::Class'; INIT { Test::Class->runtests }; 1; is IMHO a pretty normal/standard situation. Foo.pm on its own runs fine. package MyTests::Bar; use base 'MyBaseTestClass'; use Test::Most; sub explain_more_stuff :Test(1) { explain("more stuff"); pass; } 1; Bar.pm also runs fine on its own. Now we do yet another normal thing: #!perl use lib 't/lib'; use MyTests::Bar; use MyTests::Foo; # or Test::Class::Load them and Foo.pm no longer works, because no one exports explain() into it anymore! (But if you use MyTests::Bar before Foo, both work, even more confusingly.) This combination of normal use cases should not produce a failure. My opinion is that no module should modify another module's export list, that's typical spooky action at a distance. Show quoted text
> You're right that it could probably use a mention in the docs, but > other ideas are welcome. Maybe I could localize @EXPORT in Test::Most? > I never tried that before.
Localizing @Test::More::EXPORT just before you import it in Test::Most seems to work just fine. It allows you to import all but explain() in the Test::Most namespace, and then your own import() exports Test::Most::explain as usual.
Typo: "MyTests::Bar before Foo" should be "MyTests::Foo before Bar", obviously.
The localizing the change to @Test::More::EXPORT seems to work, and doesn't break any other module that imports explain from Test::More afer Test::Most has been loaded. Pull request: https://github.com/Ovid/test--most/pull/11 (This bug bit me hard when I was using Test::Class::Moose and I wrote a helper role that imported from Test::More and I couldn't work out why "explain" simply wasn't being imported...)
I vote for localizing the clobber of @Test::More::EXPORT as done in the github PR. I ran into this today, using Test::Most along with Test::Mojo::WithRoles. Localizing the change fixes it. -- Regards, Michael Schout