Create your test PrimeFactorsGui Test Suite

   1 # prime_factors_gui_test.rb
   2 require 'test/unit'
   3 
   4 class PrimeFactorsGuiTest < Test::Unit::TestCase
   5 end

Test 1: When the form is created, the generate button is disabled

   1 # prime_factors_gui_test.rb
   2 require 'prime_factors_mediator'
   3 
   4 require 'test/unit'
   5 require 'flexmock/test_unit'
   6 
   7 class PrimeFactorsGuiTest < Test::Unit::TestCase
   8   def test_button_disabled_when_created
   9     mock_form = flexmock('PrimeFactorsGui')
  10     mock_form.should_receive(:disable_button).once
  11 
  12     PrimeFactorsMediator.new(mock_form)
  13   end
  14 end

Make it pass

   1 # prime_factors_mediator.rb
   2 
   3 class PrimeFactorsMediator
   4   def initialize(form)
   5     form.disable_button
   6   end
   7 end

Test 2: Generate button is enabled when an integer is input

   1 ...
   2   def test_button_enabled_on_valid_integer
   3     mock_form = flexmock('form')
   4     mock_form.should_receive(:disable_button).once
   5     mediator = PrimeFactorsMediator.new(mock_form)
   6 
   7     mock_form.should_receive(:enable_button).once
   8     mediator.value_changed('123')
   9   end
  10 ...

Make it pass

   1 # prime_factors_mediator.rb
   2 
   3 class PrimeFactorsMediator
   4   def initialize(form)
   5     @form = form
   6     @form.disable_button
   7   end
   8 
   9   def value_changed(new_value)
  10     case new_value
  11     when /^\d+$/
  12       @form.enable_button
  13     end
  14   end
  15 end

Test 3: Generate button is disabled when input is blank

   1 ...
   2   def test_button_disabled_when_blank
   3     mock_form = flexmock('form')
   4     mock_form.should_receive(:disable_button).once
   5     mediator = PrimeFactorsMediator.new(mock_form)
   6 
   7     mock_form.should_receive(:disable_button).once
   8     mediator.value_changed('')
   9   end
  10 ...

Make it pass

   1 ...
   2 def value_changed(new_value)
   3     case new_value
   4     when /^\d+$/
   5       @form.enable_button
   6     when /^$/
   7       @form.disable_button
   8     end
   9   end
  10 ...

Refactor: Shorten tests by moving mock to setup.

   1 ...
   2   def setup
   3     @mock_dialog = flexmock('dialog')
   4   end
   5 
   6   def test_button_disabled_when_created
   7     @mock_form.should_receive(:disable_button).once
   8 
   9     PrimeFactorsMediator.new(mock_form)
  10   end
  11 
  12   def test_button_enabled_on_valid_integer
  13     @mock_form.should_receive(:disable_button).once
  14     mediator = PrimeFactorsMediator.new(@mock_form)
  15 
  16     @mock_form.should_receive(:enable_button).once
  17     mediator.value_changed('123')
  18   end
  19 
  20   def test_button_disabled_when_blank
  21     @mock_form.should_receive(:disable_button).once
  22     mediator = PrimeFactorsMediator.new(@mock_form)
  23 
  24     @mock_form.should_receive(:disable_button).once
  25     mediator.value_changed('')
  26   end

Refactor: Target tests by extracting mediator creation.

Refactor: Remove duplication in tests

   1 ...
   2   def test_disable_button_with_empty_value
   3     @mock_form.should_receive(:disable_button).once
   4     enabled_mediator.value_changed('')
   5   end
   6 
   7   def test_disable_button_with_negative_integer
   8     @mock_form.should_receive(:disable_button).once
   9     enabled_mediator.value_changed('-123')
  10   end
  11 ...
  12 private
  13 ...
  14   def enabled_mediator
  15     @mock_form.should_receive(:enable_button).once
  16     mediator = disabled_mediator
  17     mediator.value_changed('123')
  18     mediator
  19   end
  20 ...

Hooked up using Fox

   1 #!/usr/bin/env ruby
   2 
   3 require 'fox16'
   4 
   5 include Fox
   6 
   7 class PrimeFactorsMediator
   8   def initialize(dialog)
   9     @dialog = dialog
  10     dialog.disable_button
  11   end
  12 
  13   def value_changed(new_value)
  14     case new_value
  15     when /^[0-9]+$/
  16       @dialog.enable_button
  17     else
  18       @dialog.disable_button
  19     end
  20   end
  21 end
  22 
  23 class PrimeFactorsWindow < FXMainWindow
  24   def initialize(app)
  25     super(app, "Prime Factors", :opts => DECOR_ALL, :x => 20, :y => 20, :width => 220, :height => 110)
  26 
  27     input_layout = FXHorizontalFrame.new(self, LAYOUT_FILL_X)
  28     button_layout = FXHorizontalFrame.new(self, LAYOUT_FILL_X)
  29     output_layout = FXHorizontalFrame.new(self, LAYOUT_FILL_X)
  30 
  31     FXLabel.new(input_layout, "&Number to be factored")
  32     input = FXTextField.new(input_layout, 10, nil, FXDataTarget::ID_VALUE, (TEXTFIELD_INTEGER|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK))
  33 
  34     output = FXLabel.new(output_layout, '<Results appearing here soon!>', :opts => LAYOUT_CENTER_X)
  35 
  36     @button = FXButton.new(button_layout, "&Factor", :opts => BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_X)
  37 
  38     @button.connect(SEL_COMMAND) { output.text = input.text }
  39     input.connect(SEL_CHANGED) do |_,_,item|
  40       @mediator.value_changed(item)
  41     end
  42     @mediator = PrimeFactorsMediator.new(self)
  43   end
  44 
  45   def enable_button
  46     @button.enable
  47   end
  48 
  49   def disable_button
  50     @button.disable
  51   end
  52 
  53   def onCmdQuit(sender, sel, ptr)
  54     getApp.exit(0)
  55   end
  56 
  57   def create
  58     super
  59     show(PLACEMENT_SCREEN)
  60   end
  61 end
  62 
  63 if __FILE__ == $0
  64   application = FXApp.new("Calculating Prime Factors", "")
  65   window = PrimeFactorsWindow.new(application)
  66   application.addSignal("SIGINT", window.method(:onCmdQuit))
  67   application.create
  68   application.run
  69 end

PrimeFactorsGuiKata (last edited 2010-03-27 05:05:06 by ZhonJohansen)