[Rubygems-developers] Suggestions regarding new CLI

Jim Weirich jim at weirichhouse.org
Thu Jun 24 00:00:29 EDT 2004

Ok, I still didn't get done what I planned, but I did make some changes, 
some small and some not so small.

Small things first.  I added some unit tests around the check command. 
Check is small enough that I thought I would start there.  My goal is to 
pull the option building and command handling out of the monolithic 
CommandManager class and give it a class identity of its own.  I almost 
did, but I backed out the changes at the last moment.  There was still 
to much interaction with the monolithic class.  But I think I know where 
I'm going.

Big change.  I swapped out the "when_invoked" style UI and made an 
object based approach.  Now using a mock object for UI is straight 
forward and easy.  I was getting too many flaky answers on using the 
capture/when_invoked technique that were cleaned up immediately when 
going to the object based system.

Here's how things work.  The UI object is a instance variable of the 
DefaultUserInteraction module.  Including DefaultUserInteraction into a 
class will grant that class three methods:

   ui           -- Return the default UI.
   ui=(new_ui)  -- Set the default UI.
   use_ui(new_ui) do ... end
                -- Set the default UI for the duration of the block.

The UserInteraction module (same name as what Rich used) also defines 
the methods say, question, alert, etc.  This methods are forwarded to 
the default UI object for actual handling.  So including UserInteraction 
into your class will grant your class all the say/alert methods that 
Rich's technique used. (You also get the ui/ui=/use_ui methods too). 
This means the new objects are used without changes to the production code.

However, the capture method and when_invoked are gone.  The tests have 
alread been changed to reflect that.  If you wish to test against the 
outputs, you can use a ockGemUi object.  Here's an example...

   class TestSomething < Test::Unit::TestCase
     include DefaultUserInteraction

     def test_something
       use_ui(MockGemUi.new) do
         assert_match /interesting message/, ui.output
         assert_match /interesting error/, ui.error
         assert ui.terminated?, "Should have terminated"
         assert ui.banged?,     "... with a bang!"
       # Now the ui object is back to whatever it was before.

I'm tired.  Time for bed.  Maybe I'll attack the monolithic 
CommandManager again tomorrow.

BTW, the Unit Tests still show one failure.

-- Jim Weirich    jim at weirichhouse.org     http://onestepback.org
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

More information about the Rubygems-developers mailing list