Hi all Long time since I''ve posted here, hope you''re all well :-) I have a question about ignoring exceptions when they''re not interesting. For example, I have a few cases in my code along these lines? it "prints an error" do expect { run_command(%w[ missing_wallet.dat ]) }.to raise_error stream_bundle.captured_error.should eq "Couldn''t find wallet file: missing_wallet.dat\n" end it "raises a CLI::CommandError" do expect { run_command(%w[ missing_wallet.dat ]) }.to raise_error(CLI::CommandError) end But in the first example, I''m only bothered about the output, not the error. So I was thinking of writing something along the lines of: it "prints an error" do ignoring_errors { run_command(%w[ missing_wallet.dat ]) } stream_bundle.captured_error.should eq "Couldn''t find wallet file: missing_wallet.dat\n" end Now obviously that wouldn''t be hard to add as a helper method. But it got me thinking? * Do any of you do this? * Does RSpec already let you somehow? * Is it a useful convention? * Is it hiding anything else? (I don''t use exceptions much, so I may be abusing them.) Cheers Ash -- http://www.patchspace.co.uk/ http://www.linkedin.com/in/ashmoran
Hi all Long time since I''ve posted to rspec-users. Glad to see the place is still here and hope you''re all well :-) I have a question about ignoring exceptions when they''re not interesting. For example, I have a few cases in my code along these lines? it "prints an error" do expect { run_command(%w[ missing_wallet.dat ]) }.to raise_error stream_bundle.captured_error.should eq "Couldn''t find wallet file: missing_wallet.dat\n" end it "raises a CLI::CommandError" do expect { run_command(%w[ missing_wallet.dat ]) }.to raise_error(CLI::CommandError) end But in the first example, I''m only bothered about the output, not the error. So I was thinking of writing something along the lines of: it "prints an error" do ignoring_errors { run_command(%w[ missing_wallet.dat ]) } stream_bundle.captured_error.should eq "Couldn''t find wallet file: missing_wallet.dat\n" end Now obviously that wouldn''t be hard to add as a helper method. But it got me thinking? * Do any of you do this? * Does RSpec already let you somehow? * Is it a useful convention? * Is it hiding anything else? (I don''t use exceptions much, so I may be abusing them.) Cheers Ash -- http://www.patchspace.co.uk/ http://www.linkedin.com/in/ashmoran
Hey there, Ash. Why not put your call to #run_command inside a begin-rescue statement? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110829/b5a215ad/attachment.html>
On 29 Aug 2011, at 20:09, Nick wrote:> Hey there, Ash. Why not put your call to #run_command inside a begin-rescue statement?Hi Nick Yes I''m missing the obvious as usual* :-) Well I guess I could, but the syntax then is even more intrusive. I guess I just want the lightest way possible to say "Yes, I know this code fails, but I still want to know what''s going on inside it!" That''s why I wondered maybe I should give more thought to how I''m using exceptions. (I''m raising a CLI::CommandError anywhere in a Command class where I know I don''t want the CLI to proceed any further.) Cheers Ash * I''m sorry, I wrote the code on my own, my pair was actually taking his bank holiday off :) -- http://www.patchspace.co.uk/ http://www.linkedin.com/in/ashmoran
Alex Chaffee
2011-Aug-29 23:09 UTC
[rspec-users] Selectively ignoring exceptions in examples
On Mon, Aug 29, 2011 at 9:24 AM, Ash Moran <ash.moran at patchspace.co.uk> wrote:> ? it "prints an error" do > ? ? ignoring_errors { > ? ? ? run_command(%w[ missing_wallet.dat ]) > ? ? } > ? ? stream_bundle.captured_error.should eq "Couldn''t find wallet file: missing_wallet.dat\n" > ? end > > Now obviously that wouldn''t be hard to add as a helper method. But it got me thinking? > > * Do any of you do this?I do. So often that I wrote a helper and put it in Wrong. I don''t quite get what "stream_bundle.captured_error" is in your example, but I think the above example would become rescuing { run_command(%w[ missing_wallet.dat ]) }.message.should == "Couldn''t find whatever" We''ve also got "capturing" for grabbing console output, e.g. capturing { puts "hi" }.should == "hi" or out, err = capturing(:stdout, :stderr) { ... } See https://github.com/sconover/wrong -- Alex Chaffee - alex at stinky.com http://alexch.github.com http://twitter.com/alexch
Ash Moran
2011-Aug-30 10:20 UTC
[rspec-users] Testing console IO / Re: Selectively ignoring exceptions in examples
On 30 Aug 2011, at 00:09, Alex Chaffee wrote:> I do. So often that I wrote a helper and put it in Wrong.Cool, and also? I really should try Wrong! I''ve just put it on my project TODO list as something to investigate> I don''t quite get what "stream_bundle.captured_error" is in your > example, but I think the above example would become > > rescuing { > run_command(%w[ missing_wallet.dat ]) > }.message.should == "Couldn''t find whatever" > > We''ve also got "capturing" for grabbing console output, e.g. > > capturing { puts "hi" }.should == "hi"Sorry, I didn''t realise how opaque that is if you don''t know what one is. Basically, I wanted to decouple the app from STDIN/STDOUT/STDERR so I started injecting StringIO objects around for testing. After a while I had a data clump of @input/@output/@error in classes everywhere, so I made a StreamBundle[1] to encapsulate them. (Apologies for lack of syntax highlighting on patch-tag.com) But then I realised my tests were making a `StreamBundle.new(StringIO.new, StringIO.new, StringIO.new)` everywhere, so I factored out the duplication into a CapturingStreamBundle[2] decorator that records all output to secondary StringIO objects. Now I just call `CapturingStreamBundle.test_bundle` to get one. I''ve found this pattern useful as now that only files in my bin/ folder ever access ARGV, STDOUT etc, the code is more loosely coupled, but also I can see exactly where I''m talking to the outside world. Every time I want to send some output, I think- "Should I really be giving this object a StreamBundle? Is it really appropriate for it to be talking to the user directly?" That''s the backstory anyway! Ash [1] https://patch-tag.com/r/ashmoran/rbcoin/snapshot/current/content/pretty/lib/bitcoin/console/stream_bundle.rb [2] https://patch-tag.com/r/ashmoran/rbcoin/snapshot/current/content/pretty/lib/bitcoin/console/capturing_stream_bundle.rb -- http://www.patchspace.co.uk/ http://www.linkedin.com/in/ashmoran
Alex Chaffee
2011-Aug-30 18:24 UTC
[rspec-users] Testing console IO / Re: Selectively ignoring exceptions in examples
> I''ve found this pattern useful as now that only files in my bin/ folder ever access ARGV, STDOUT etc, the code is more loosely coupled, but also I can see exactly where I''m talking to the outside world. Every time I want to send some output, I think- "Should I really be giving this object a StreamBundle? Is it really appropriate for it to be talking to the user directly?"I hear you. When I first started coding in Ruby I was injecting all over the place. But nowadays I''m much more comfortable with the flexibility of things like reopening classes during tests, or mocking methods, or resetting globals... ...or grabbing and reassigning $stdout and $stderr, which is what "capturing" does. The basic idea is that Ruby is *already* decoupled from stdin/out/err via its dynamic nature and $globals. I get that by naming the inputs explicitly you''re ensuring 100% compliance but you should consider whether it''s worth it. Passing around DI clumps (aka "value objects" or "parameter objects" in some circles) can make your code a lot less concise, and concision is one of the great joys of Ruby. btw apologies if you already know this, but inside a normal Ruby program you should always use $stderr/$stdout/$stdin, not STDERR/STDOUT/STDIN since the former are settable and the latter are hardcoded to the "real" streams and, as true CONSTANTS, not easy to change. For whatever reason I see the caps versions used a lot more than the dollar versions, which is a shame. -- Alex Chaffee - alex at stinky.com http://alexch.github.com http://twitter.com/alexch
Ash Moran
2011-Aug-30 20:59 UTC
[rspec-users] Testing console IO / Re: Selectively ignoring exceptions in examples
On 30 Aug 2011, at 19:24, Alex Chaffee wrote:> ...or grabbing and reassigning $stdout and $stderr, which is what > "capturing" does. > > The basic idea is that Ruby is *already* decoupled from stdin/out/err > via its dynamic nature and $globals. I get that by naming the inputs > explicitly you''re ensuring 100% compliance but you should consider > whether it''s worth it. Passing around DI clumps (aka "value objects" > or "parameter objects" in some circles) can make your code a lot less > concise, and concision is one of the great joys of Ruby.Yes, I''ve done constant reassigning in the past, with before/after blocks to control the environment. I wasn''t specifically avoiding that here, it''s just what fell out my my initial design to pass the standard streams in as variables from the bin/ command. I''m going to see how it pans out, as I''ve never been so strict about IO before.> btw apologies if you already know this, but inside a normal Ruby > program you should always use $stderr/$stdout/$stdin, not > STDERR/STDOUT/STDIN since the former are settable and the latter are > hardcoded to the "real" streams and, as true CONSTANTS, not easy to > change. For whatever reason I see the caps versions used a lot more > than the dollar versions, which is a shame.Actually I didn''t know that, so thanks for pointing it out :-) Although I have often been puzzled by the presence of both forms? Cheers Ash -- http://www.patchspace.co.uk/ http://www.linkedin.com/in/ashmoran