読者です 読者をやめる 読者になる 読者になる

正規表現を使わないzip codeのバリデーション(誰得)

tddbcの課題で郵便番号のバリデーションがあったんだけど、正規表現を使ったら負けだと思った。

なので郵便番号のバリデーションを正規表現を使わないで書いてみたけど、こんな感じになるのかなぁ?(仕様変更前のやつですよ。)

def validation? zip_code
  if [3,7].map{|i| zip_code.length == i}.any?
    return is_numbers? zip_code
  end 

  if zip_code.length == 8 and zip_code[3] == "-" 
    return is_numbers? (cut_fourth zip_code) 
  end
  false
end

def is_numbers? zip_code
  zip_code.split("").map{|c| is_a_number? c}.all?
end

def is_a_number? s
  (0..9).map{|i| i.to_s}.map{|i| i == s}.any? 
end

def cut_fourth zip_code
  zip_code[0..2] + zip_code[4..8]
end

テストコードのRSpecはこちら(ペアプロ時に作成したものを流用しただけw)

describe "zip code validation" do
  shared_examples_for :validation do |bool ,zip_codes|
    zip_codes.each do |zip_code| 
      describe "validation? '#{zip_code}'" do
        if bool
          it{ validation?(zip_code).should be_true}
        else
          it{ validation?(zip_code).should be_false}
        end
      end
    end
  end
  
  context "About 3-length string" do
    it_should_behave_like :validation, true, ["000","111"]
    it_should_behave_like :validation, false, ["abc","1 1","---"]
  end 

  context "About 7-length string" do
    it_should_behave_like :validation, true, ["1234567"]
    it_should_behave_like :validation, false, ["aaa1234","123-123"]
  end

  context "About 8-length string" do
    it_should_behave_like :validation, true, ["111-1111"]
    it_should_behave_like :validation, false, ["12345678","1111-111"]
  end

  context "About other-length string" do 
    it_should_behave_like :validation, false, ["","111-","777-1","777-12345"]
  end
end

テストを走らせたときのログ。

zip code validation
  About 8-length string
    it should behave like validation
      validation? '1111-111'
        should be false
      validation? '12345678'
        should be false
    it should behave like validation
      validation? '111-1111'
        should be true
  About 7-length string
    it should behave like validation
      validation? '123-123'
        should be false
      validation? 'aaa1234'
        should be false
    it should behave like validation
      validation? '1234567'
        should be true
  About 3-length string
    it should behave like validation
      validation? 'abc'
        should be false
      validation? '1 1'
        should be false
      validation? '---'
        should be false
    it should behave like validation
      validation? '111'
        should be true
      validation? '000'
        should be true
  About other-length string
    it should behave like validation
      validation? '777-1'
        should be false
      validation? '111-'
        should be false
      validation? ''
        should be false
      validation? '777-12345'
        should be false