Tuesday, March 23, 2010

Test::Ruby Best Practices


-Keep your test cases atomic.
#!/usr/bin/env ruby -Ku
# -*- encoding: utf-8 -*-
require "test/unit"
require_relative "test_unit_extensions"
require_relative "prawn"

class TestInlineStyleParsing < Test::Unit::TestCase
  def setup
    @parser = Prawn::Document::Text::StyleParser
  end

  must "parse italic tags" do
    assert_equal ["Hello ", "<i>", "Fine", "</i>", " World"],
                  @parser.process("Hello <i>Fine</i> World")
  end

  must "parse bold tags" do
    assert_equal ["Some very ", "<b>", "bold text", "</b>"],
                  @parser.process("Some very <b>bold text</b>")
  end

  must "parse mixed italic and bold tags" do
    assert_equal ["Hello ", "<i>", "Fine ", "<b>", "World", "</b>", "</i>"],
                  @parser.process("Hello <i>Fine <b>World</b></i>")
  end

  must "not split out other tags than <i> <b> </i> </b>" do
    assert_equal ["Hello <indigo>Ch", "</b>", "arl", "</b>", "ie</indigo>"],
                  @parser.process("Hello <indigo>Ch</b>arl</b>ie</indigo>")
  end

  must "be able to check whether a string needs to be parsed" do
    assert ! @parser.style_tag?("Hello World")
    assert @parser.style_tag?("Hello <i>Fine</i> World")
  end
end

#!/usr/bin/env ruby -Ku
# -*- encoding: utf-8 -*-
module StyleParser
  extend self

  TAG_PATTERN = %r{(</?[ib]>)}

  def process(text)
    text.split(TAG_PATTERN).reject { |x| x.empty? }
  end

  def style_tag?(text)
    !!(text =~ TAG_PATTERN)
  end
end

class Prawn
  class Document
    class Text
      include StyleParser
    end
  end
end
 
-Test not only input & output but also error cases.
#!/usr/bin/env ruby -Ku
# -*- encoding: utf-8 -*-
require "test/unit"
require_relative "test_unit_extensions"
require_relative "lockbox"

class LockBoxTest < Test::Unit::TestCase
  def setup
    @lock_box = LockBox.new(password: "secret", content: "My Secret Message")
  end

  must "raise an error when an invalid password is used" do
    assert_raises(LockBox::InvalidPassword) do
      @lock_box.unlock("kitten")
    end
  end

  must "Not raise error when a valid password is used" do
    assert_nothing_raised do
      @lock_box.unlock("secret")
    end
  end

  must "prevent access to content by default" do
    assert_raises(LockBox::UnauthorizedAccess) do
      @lock_box.content
    end
  end

  must "allow access to content when box is properly unlocked" do
    assert_nothing_raised do
      @lock_box.unlock("secret")
      @lock_box.content
    end
  end
end

#!/usr/bin/env ruby -Ku
# -*- encoding: utf-8 -*-
class LockBox
  UnauthorizedAccess = Class.new(StandardError)
  InvalidPassword = Class.new(StandardError)

  def initialize(options)
    @locked = true
    @password = options[:password]
    @content = options[:content]
  end

  def unlock(pass)
    @password == pass ? @locked = false : raise(InvalidPassword)
  end

  def content
    @locked ? raise(UnauthorizedAccess) : @content
  end
end

 
-Use rake task to test multiple files.

#!/usr/bin/env ruby -Ku
# -*- encoding: utf-8 -*-
require "rake/testtask"

task  :default => [:test]

Rake::TestTask.new do |test|
  test.libs << "test"
  test.test_files = Dir["test/tc_*.rb"]
  test.verbose = true
end

No comments: