Re: [Catalyst] Testing View
* On Sat, Apr 19 2008, Yao Wang wrote: > Hi, > > Thanks Matt. Now i know i have used wrong way to call a method in the > controller. > > However ,the reason i use $c->prepare is for unit testing. I have seen > Catalyst::Test and Test::WWW::Mechanize::Catalyst, i think they are > the testing tools for application, not for unit testing. When i do the > unit testing, i need to pass $c and some other params to the methods. > So can anybody tell me how to create this kind of $c for testing only > ? If you want to do what you described in your previous message, you need to take a different approach. I recommend something like this: use Catalyst::Test 'MyApp'; my $template; my $old_process = \&YourApp::View::Whatever::process; *YourApp::View::Whatever::process = sub { my ($self, $c, @args) = @_; $template = $c->stash->{template}; $self->$old_process($c, @args); } request('foo'); is $template, 'the_template_for_foo.tt'; You really want to keep this kind of testing to a minimum. The Catalyst part of your application should be simple enough to not require intensive testing. Test::WWW::Mechanize::Catalyst (and friends) is mostly good for a quick sanity check. The important parts of your application should reside in easily-testable classes, and Catalyst should just be a few lines of code to make the those classes available to web users. Regards, Jonathan Rockway -- print just => another => perl => hacker => if $,=$" ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Unit Testing
On Sat, 19 Apr 2008, John Romkey wrote: I suspect that most Catalyst users build their applications so that the controllers do too much work. I certainly did, and I'm gradually rewriting mine to move most of the work into the model. Where before my controllers A good way to approach a webapp is to think of the Controller as a thin shim between the the web/HTTP environment and your model. The controller code should handle web/HTTP-specific things like URIs, form submissions, etc. and translate that into API calls on model classes. It also might handle something like authentication, since the way you authenticate a user via the web is different than how you'd do it via the command line. Besides the testability benefits, another benefit is that it makes it easy to reuse this business logic in things like cron jobs, daemons, and command line driven code. Invariably, any app of a certain size will need this flexibility. Of course, the ultimate benefit is that it's the only sane way to write an application ;) -dave /*== VegGuide.Org Your guide to all that's veg ==*/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Unit Testing
On Apr 19, 2008, at 10:51 PM, Yao Wang wrote: Hi Everybody, Recently, i am looking for some modules for unit testing. I have seen Catalyst::Test, Test::WWW::Mechanize::Catalyst etc, i think they are the testing tools for application, not for unit testing. When i do the unit testing, i need to pass $c and some other params to the methods right ? But how can i create $c for testing ? So can anybody tell me how to create this kind of $c ? Yao, Here's what I'd suggest: Structure your application so that all the real work is done in a set of modules which Catalyst then calls to do the work. Use Catalyst as a wrapper to interface your application to the web. Catalyst documents refer to this as the "business logic" of your application. The application itself will have no dependencies on Catalyst and can be tested independently of it. The application wrapped in Catalyst can be tested using the testing tools you mentioned above. I suspect that most Catalyst users build their applications so that the controllers do too much work. I certainly did, and I'm gradually rewriting mine to move most of the work into the model. Where before my controllers would interact directly with the database, now they ask the model to do it for them. The model is now the heart of the application; it does all the work and Catalyst only glues it to the web. You could discard Catalyst and build a command-line interface using the same model, or build some other kind of interface and not have to change the model at all. Suppose you need to be able to create a user account for your web site. You probably want to do a variety of tests on the account information... does an account already exist with that email address? Is the password strong or weak? Does the account name use any prohibited words in it? And if the account is acceptable you need to write at least one record, possibly more, into a database. The way I originally wrote my controller, the controller itself did all that itself. The way I've rewritten it, my business logic model does it for me. The controller has an action in it which handles the account creation request. That action gathers the necessary information from the request, performs any web-related validation on it (at least making sure all the needed parameters are there) and then calls the model to create the account. If there's an error, it reports the error back to the user. Now if you want a command-line utility to create an account, you just write a Perl script which gets its arguments from the command-line and calls the same business logic. Then you can write unit tests that completely bypass Catalyst and call the business logic to confirm that it properly creates an account, or properly rejects an account with a bad password or unacceptable word in its name. And you can write Catalyst tests to confirm that Catalyst correctly maps web actions into the business logic. This is all a bit more work than might seem necessary at first, but if your application evolves at all you'll probably find that modularizing it in this manner really helps make it more understandable and maintainable in the long term, as well as making it more testable. - john romkey http://www.romkey.com/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Unit Testing
HI Yao, I solved this by reverse-engineering the context with a debug session ($DB::single=1). In short, $c is an instance of MyApp. You may have to manually instantiate some of the internal hashes, etc for the needs of the test target. I'll assume that if you're truly unit-testing, you'll be mocking the other externals of your controller. Hope that helps. -- Peter Fitzgibbons -- iPhone -- "IT"-ness. href= http://www.macdailynews.com/index.php/weblog/comments/apples_iphone_could_become_iconic_it_object -- ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Unit Testing
Hi Everybody, Recently, i am looking for some modules for unit testing. I have seen Catalyst::Test, Test::WWW::Mechanize::Catalyst etc, i think they are the testing tools for application, not for unit testing. When i do the unit testing, i need to pass $c and some other params to the methods right ? But how can i create $c for testing ? So can anybody tell me how to create this kind of $c ? Thanks, Yao ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Catalyst::Log::Log4perl autoflush
It seems that 'autoflush' doesn't mean what it usually does in Catalyst::Log::Log4perl. It usually means that a write should happen immediately, and not be buffered. That isn't the behaviour in Catalyst::Log::Log4perl, either when set using the log4perl conf, or when using the option to new(). The option to new() disables 'abort', which I think is a misunderstanding. The logging functions always simply push to the log4perlstack, which is only flushed after the request has been mostly handled. In order to get autoflush working as expected, I have had to create a derived class and override _log(): sub _log { my $self = shift; $self->SUPER::_log(@_); $self->_flush if scalar(caller(1)) =~ /^MyApp(::|$)/; } perl -v: v5.8.8 built for i486-linux-gnu-thread-multi uname -a: Linux PC-5023452 2.6.22-14-generic #1 SMP Fri Feb 1 04:59:50 UTC 2008 i686 GNU/Linux Catalyst::Log::Log4perl version: 1.0 I've raised a bug in RT for this: http://rt.cpan.org/Public/Bug/Display.html?id=35221 David, Could you throw a test case in with this (either on the RT bug or in this mail) and I'll get a patch put in place? Hello Jay, Which of the autoflushes should I test against: the parameter to new(), or the option in a log4perl configuration file? Do you (or others) agree that the autoflush option to new() is a misnomer? If not, wouldn't my test simply prove that the code doesn't do what it doesn't say it does? David ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Catalyst::Controller::SOAP + Pod::WSDL?
On Fri, Apr 11, 2008 at 11:22 AM, Ian Sillitoe <[EMAIL PROTECTED]> wrote: > I'm just getting started on implementing SOAP services in my Catalyst > app so I figured I would try and make sure I'm using the best tools > before I start coding. > > Catalyst::Controller::SOAP looks perfect as I'm not doing anything too > complicated yet, really just exposing data via SOAP. C::C::SOAP++. That combined with pre-built schemas allowed me to get into the difficult (and mostly fun) bits of actually implementing the SOAP calls very quickly. Also Ruoso++ for his awesome work in the recent releases to automate working WSDL. > However, I was > also looking to automate the process of generating (and more > importantly, maintaining) the WSDL file describing those services. It > looks like Pod::WSDL does a good job of this, so I was wondering > whether anyone was already working on getting Pod::WSDL to generate > the WSDL file directly from the docs in the Controller at startup? I briefly looked at Pod::WSDL, but ended up not needing to because of my prebuilt schemas. Once you have schemas, the WSDL becomes pretty straightforward. That said, I'd be very interested to hear from anyone who had to generate their own WSDL/schemas too. Drew -- Drew Taylor * Web development & consulting Email: [EMAIL PROTECTED] * Site implementation & hosting Web : www.drewtaylor.com * perl/mod_perl/DBI/mysql/postgres ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Catalyst::Log::Log4perl autoflush
On Sat, Apr 19, 2008 at 8:01 AM, David Wright <[EMAIL PROTECTED]> wrote: > Hi, > > It seems that 'autoflush' doesn't mean what it usually does in > Catalyst::Log::Log4perl. It usually means that a write should happen > immediately, and not be buffered. > > That isn't the behaviour in Catalyst::Log::Log4perl, either when set using > the log4perl conf, or when using the option to new(). The option to new() > disables 'abort', which I think is a misunderstanding. The logging functions > always simply push to the log4perlstack, which is only flushed after the > request has been mostly handled. > > In order to get autoflush working as expected, I have had to create a > derived class and override _log(): > > sub _log { > my $self = shift; > $self->SUPER::_log(@_); > $self->_flush if scalar(caller(1)) =~ /^MyApp(::|$)/; > } > > perl -v: v5.8.8 built for i486-linux-gnu-thread-multi > uname -a: Linux PC-5023452 2.6.22-14-generic #1 SMP Fri Feb 1 04:59:50 > UTC 2008 i686 GNU/Linux > Catalyst::Log::Log4perl version: 1.0 > > I've raised a bug in RT for this: > http://rt.cpan.org/Public/Bug/Display.html?id=35221 > > Thanks, > David Wright > David, Could you throw a test case in with this (either on the RT bug or in this mail) and I'll get a patch put in place? Thanks, -Jay ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Sending email safely with Catalyst
On Fri, Apr 18, 2008 at 01:31:37PM -0700, Tatsuhiko Miyagawa wrote: > On Fri, Apr 18, 2008 at 10:54 AM, Matt S Trout <[EMAIL PROTECTED]> wrote: > > But you're writing a new catalyst app, so you're deploying it under > > fastcgi, > > right? > > > > Really, mod_perl is a legacy deployment option. Don't. > ... > > http://chainsawblues.vox.com/ > > Your blog is powered by Catalyst running under mod_perl 1.x. Seriously... Thus proving that people who've spent many years wrangling mod_perl 1 can make it run very impressively. I've spent a couple years with MP1 and while I doubt I'm as good as you guys are with it I can make it behave quite well enough for any purpose I've ever needed to. And yet I still deploy everything on FastCGI now, because it's an order of magnitude less fucking about. Draw your own conclusions. -- Matt S Trout Need help with your Catalyst or DBIx::Class project? Technical Directorhttp://www.shadowcat.co.uk/catalyst/ Shadowcat Systems Ltd. Want a managed development or deployment platform? http://chainsawblues.vox.com/http://www.shadowcat.co.uk/servers/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Why does $c->stats require -Debug flag?
On Sat, Apr 19, 2008 at 9:48 AM, Jon Schutz <[EMAIL PROTECTED]<[EMAIL PROTECTED]>> wrote: > > I apologise to anyone who was inconvenienced by this change. I've > written a guide to upgrading for anyone who was using the Tree::Simple > object directly: > > > http://notes.jschutz.net/17/perl/adding-action-timings-to-your-catalyst-output > I've updated my post to point to yours, so that people see the correct way to do things. > Nevertheless I stand by my comment that anyone who digs through the > source code to find an internal object or function and then chooses to > use that in external code does so at their own risk. Furthermore I > suggest that anyone who is savvy enough to get into the code, understand > it, and chooses to use an internal object/function, is aware of the risk > and is more than capable of adapting their own code should an internal > object/function change. > I'll assume you are talking about me, since I was the one who posted the use of the method. I don't recall the circumstances, but I don't remember there being any particular red flags in the vicinity. It was merely a method that returned a Tree::Simple object. It's entirely possible I ignored any warnings. :) > How would one define backwards compatibility in this case? That $c- > >stats must return a Tree::Simple object with all of the same user- > defined fields as before? The logical extension of this argument says > that on any minor release, the internal representation of *any* stored > data or the signature of *any* internal function or method may not > change, which surely is too restrictive on developers. > When we added the Statistics code to DBIx::Class we went to great pain to make the implementation behave exactly as it did before if the user didn't change anything. It was a severe pain in the ass. :) That being said, the internal code could've been changed beyond all recognition, so long as calling $c->stats() returned the same object as before. This has nothing to do with the internal representation of the stats, only the way you choose to return it. 5.7012 has been out since December 2007. It seems to me a case of > closing the gate after the horse has bolted. I don't hear an angry mob > out there complaining. Perhaps as a result of this being raised the > angry mob will come knocking; that being the case, I'll be happy to > revisit the code. As it stands I'm unconvinced of the need for backward > compatibility in this case, both of the principle (of preserving > unpublished undocumented undefined interfaces) and the level of popular > demand. It broke my code also. I just fixed it and went back to work. :) I agree with your assertion that the horse has already bolted, but I think you are missing the point of Matt's comments. Maintaining compatibility in these situations is a PITA, but it's what separates the good projects from the bad ones. -- Cory 'G' Watson http://www.onemogin.com ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: Re: [Catalyst] Testing View
Hi, Thanks Matt. Now i know i have used wrong way to call a method in the controller. However ,the reason i use $c->prepare is for unit testing. I have seen Catalyst::Test and Test::WWW::Mechanize::Catalyst, i think they are the testing tools for application, not for unit testing. When i do the unit testing, i need to pass $c and some other params to the methods. So can anybody tell me how to create this kind of $c for testing only ? Thanks, Yao -Original Message- From: Matt S Trout <[EMAIL PROTECTED]> To: The elegant MVC web framework Date: Fri, 18 Apr 2008 20:11:22 +0100 Subject: Re: [Catalyst] Testing View On Thu, Apr 17, 2008 at 02:56:49PM +1000, Yao Wang wrote: > Dear Friends, > > I have just started working on a project using Catalyst. I am trying my hand > at testing and got the following issue :( > > I have created the following test file: > > my $c = MyApp -> prepare(); > > MyApp::Controller::MyController::MyAction(undef, $c); > > ok($c->stash->{template} eq $expected_template_name, "comparing template > returned"); > > Now, all seemed to work fine till i realized that its better to explicitly > forward $c to MyApp::View::TT rather than doing in the end method. But after > adding this line to my controller action i got this error: > > "Modification of non-creatable array value attempted, subscript -1 at > /usr/lib/perl5/vendor_perl/5.8.8/Catalyst/Dispatcher.pm line 186." > > I guess this is happening because $c->stash->template does not exist anymore? > > Any way to get around this problem. use Catalyst::Test 'MyApp'; use Test::WWW::Mechanize::Catalyst 'MyApp'; You can't just call ->prepare with no engine, bypass the entire dispatch setup and then expect the dispatcher to work. Also, a controller is an object. Calling methods as subroutines is -just- -wrong-. -- Matt S Trout Need help with your Catalyst or DBIx::Class project? Technical Directorhttp://www.shadowcat.co.uk/catalyst/ Shadowcat Systems Ltd. Want a managed development or deployment platform? http://chainsawblues.vox.com/http://www.shadowcat.co.uk/servers/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] Catalyst::Log::Log4perl autoflush
Hi, It seems that 'autoflush' doesn't mean what it usually does in Catalyst::Log::Log4perl. It usually means that a write should happen immediately, and not be buffered. That isn't the behaviour in Catalyst::Log::Log4perl, either when set using the log4perl conf, or when using the option to new(). The option to new() disables 'abort', which I think is a misunderstanding. The logging functions always simply push to the log4perlstack, which is only flushed after the request has been mostly handled. In order to get autoflush working as expected, I have had to create a derived class and override _log(): sub _log { my $self = shift; $self->SUPER::_log(@_); $self->_flush if scalar(caller(1)) =~ /^MyApp(::|$)/; } perl -v: v5.8.8 built for i486-linux-gnu-thread-multi uname -a: Linux PC-5023452 2.6.22-14-generic #1 SMP Fri Feb 1 04:59:50 UTC 2008 i686 GNU/Linux Catalyst::Log::Log4perl version: 1.0 I've raised a bug in RT for this: http://rt.cpan.org/Public/Bug/Display.html?id=35221 Thanks, David Wright ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Why does $c->stats require -Debug flag?
On Fri, 2008-04-18 at 19:54 +0100, Matt S Trout wrote: > On Sat, Apr 12, 2008 at 08:37:49PM +0930, Jon Schutz wrote: > > Prior to 5.7012, $c->stats was an internal object (in so far as it was > > not documented as part of the API) so anyone manipulating it directly > > does so at their own risk. > > This one user who was kind enough to report it to the list will by far not > be the only one with this problem. > > Catalyst::Plugin::SubRequest was also hit by this. > > Never, ever assume that 'undocumented' means 'I can break compat any time > I like'. This works in theory, and in theory, theory is the same as practice, > but ... I apologise to anyone who was inconvenienced by this change. I've written a guide to upgrading for anyone who was using the Tree::Simple object directly: http://notes.jschutz.net/17/perl/adding-action-timings-to-your-catalyst-output Nevertheless I stand by my comment that anyone who digs through the source code to find an internal object or function and then chooses to use that in external code does so at their own risk. Furthermore I suggest that anyone who is savvy enough to get into the code, understand it, and chooses to use an internal object/function, is aware of the risk and is more than capable of adapting their own code should an internal object/function change. > > > Catalyst::Stats was introduced to define an > > interface for the stats object so that one could safely override the > > default implementation if they wished; the default implementation also > > introduced profiling methods that were not there before. > > You need to consider your failure to maintain backwards compatibility a bug > and fix it. I said this at the time but apparently you didn't get round to > fixing the Catalyst::Stats patch. Please do so as soon as you get time; > Catalyst::Stats' API is a great leap forward but not at the cost of > previously running code (although I think perhaps the compat code -should- > warn that you're using an API you shouldn't have been and that it'll go > away in the future). How would one define backwards compatibility in this case? That $c- >stats must return a Tree::Simple object with all of the same user- defined fields as before? The logical extension of this argument says that on any minor release, the internal representation of *any* stored data or the signature of *any* internal function or method may not change, which surely is too restrictive on developers. 5.7012 has been out since December 2007. It seems to me a case of closing the gate after the horse has bolted. I don't hear an angry mob out there complaining. Perhaps as a result of this being raised the angry mob will come knocking; that being the case, I'll be happy to revisit the code. As it stands I'm unconvinced of the need for backward compatibility in this case, both of the principle (of preserving unpublished undocumented undefined interfaces) and the level of popular demand. -- Jon SchutzMy tech notes http://notes.jschutz.net Chief Technology Officerhttp://www.youramigo.com YourAmigo ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Sending email safely with Catalyst
Hi Tatsuhiko! > I'm assuming what he says is Don't use mod_perl because it's old, and > use FastCGI instead. mod_perl isn't really old, as it still enjoys active development (version 2.04 was released just a couple of days ago). So, I presume there are other arguments against it, even though I don't know much about it: I use FastCGI myself. Michele. -- Michele Beltrame http://www.cattlegrid.info/ ICQ 76660101 - MSN [EMAIL PROTECTED] ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/