[Rubygems-developers] Suggestions regarding new CLI

Chad Fowler chad at chadfowler.com
Thu Jun 24 05:17:06 EDT 2004


On 24/6/2004, at 6:00 AM, Jim Weirich wrote:

> 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
>         code_that_uses_say_or_alert_or_terminate
>         assert_match /interesting message/, ui.output
>         assert_match /interesting error/, ui.error
>         assert ui.terminated?, "Should have terminated"
>         assert ui.banged?,     "... with a bang!"
>       end
>       # Now the ui object is back to whatever it was before.
>     end
>   end
>
> I'm tired.  Time for bed.  Maybe I'll attack the monolithic 
> CommandManager again tomorrow.
>
> BTW, the Unit Tests still show one failure.
>
>

This stuff looks nice.

I believe the failing test is a result of unimplemented features, 
right?  Rich left it that way when he went on vacation as a flag, I 
think.  if you look through the file with the failing test, it's 
obviously still scaffolding.  It may be that with your recent 
refactoring work, the test is easier to get passing.  I've had very 
little time on this vacation to look at any of this I'm afraid.

Good to see things evolving!

Chad



More information about the Rubygems-developers mailing list