mike-neckのブログ

Java or Groovy or Swift or Golang

コップ本の14章まで読み終わったので、10章のElementに対するテストを書いてみた

こんにちわ、みけです。

表記の通り、コップ本の14章(表明と単体テスト)まで読み終わったので、10章(合成と継承)に出てくるElementに対するテストを書いてみました。

Scala TestFunSuiteShouldMatchersトレイトとともに使いました。

package reading

import org.scalatest.{ShouldMatchers, FunSuite}

class LineElementSuite extends FunSuite with ShouldMatchers {
  test("LineElement#height should return 1 ") {
    val line: Element = Element.elem("line")
    line.height should be (1)
  }

  test("LineElement#width should return its string size") {
    val string = "this is line element"
    val line: Element = Element.elem(string)
    line.width should be (string.length)
  }

  test("LineElement#contents should return " +
    "its original string as Array") {
    val item: String = "test"
    val line: Element = Element.elem(item)
    line.contents should be (Array(item))
  }
}

class UniformElementSuite extends FunSuite with ShouldMatchers {
  test("UniformElement#height should return " +
    "the value passed to function elem") {
    val elem: Element = Element.elem('*', 2, 3)
    elem.height should be (3)
  }

  test("UniformElement#width should return " +
    "the value passed to function elem") {
    val elem: Element = Element.elem('*', 2, 3)
    elem.width should be (2)
  }

  test("UniformElement#contents returns filled String") {
    val elem: Element = Element.elem('*', 2, 3)
    elem.contents should be (Array("**", "**", "**"))
  }

  test("elem throws IllegalArgumentException " +
    "when width parameter is negative") {
    an [IllegalArgumentException] should be thrownBy Element.elem('h', -1, 0)
  }

  test("elem throws IllegalArgumentException " +
    "when height parameter is negative") {
    an [IllegalArgumentException] should be thrownBy Element.elem('e', 1, -1)
  }

  test("elem doesn't throw IllegalArgumentException " +
    "when width parameter is 0") {
    noException should be thrownBy Element.elem('n', 0, 1)
  }

  test("elem doesn't throw IllegalArgumentException " +
    "when height parameter is 0") {
    noException should be thrownBy Element.elem('n', 1, 0)
  }
}

class ArrayElementSuite extends FunSuite with ShouldMatchers {
  test("ArrayElement#width returns its first item's length") {
    val strings: Array[String] = Array(
      "1234567890",
      "123",
      "12345678901")
    Element.elem(strings).width should be(11)
  }

  test("ArrayElement#height returns its size(case of 1)") {
    Element.elem(Array("1")).height should be(1)
  }

  test("ArrayElement#height returns its size(case of empty array)") {
    Element.elem(Array[String]()).height should be(0)
  }

  test("ArrayElement#height returns its size(case of 5)") {
    Element.elem(Array("1", "2", "3", "4", "5")).height should be(5)
  }

  test("ArrayElement#contents returns original array") {
    val array: Array[String] = Array("aa", "bb", "cc")
    Element.elem(array).contents should be(array)
  }
}

class ElementSuite extends FunSuite with ShouldMatchers {
  test("Element#above adds argument after self element") {
    val top: Element = Element.elem("aaa")
    val bottom: Element = Element.elem("btm")
    val element: Element = top above bottom
    element.contents should be(Array("aaa", "btm"))
  }

  test("Element#beside concatenates argument element right") {
    val left: Element = Element.elem("aaa")
    val right: Element = Element.elem("bbb")
    val array: Array[String] = (left beside right).contents
    array should be(Array("aaabbb"))
  }

  test("Element#beside generates an element with the same height " +
    "as the argument's if argument's height is greater than self's") {
    val left: Element = Element.elem(Array("aaa", "bbb"))
    val right: Element = Element.elem(Array("aaa", "bbb", "rest"))
    (left beside right).height should be(3)
  }

  test("Element#heighten returns self if argument w equals to height") {
    val elem: Element = Element.elem(Array("aaa", "bbb"))
    val heighten: Element = elem.heighten(2)
    heighten should be(elem)
  }

  test("Element#widen returns self if argument w is lower than width") {
    val elem: Element = Element.elem(Array("aaa", "bbb"))
    val widen: Element = elem.widen(1)
    widen should be(elem)
  }

  test("Element#heighten returns new element if argument w is 1 greater than height") {
    val elem: Element = Element.elem("aaa")
    val heighten: Element = elem.heighten(2)
    heighten.height should be(2)
  }

  test("Element#heighten returns new element with a blank row " +
    "on its top and bottom when w is 2 greater than height") {
    val elem: Element = Element.elem("aaa")
    val heighten: Element = elem.heighten(3)
    heighten.contents should be(Array("   ", "aaa", "   "))
  }

  test("Element#widen returns new element " +
    "if argument w is 1 greater than width") {
    val elem: Element = Element.elem("aaa")
    val widen: Element = elem.widen(4)
    widen.width should be(4)
  }

  test("Element#widen returns new element with blank at left and right " +
    "if argument w is 2 greater than width") {
    val elem: Element = Element.elem("aaa")
    val widen: Element = elem.widen(5)
    widen.contents should be(Array(" aaa "))
  }
}

コップ本と異なる部分

Scala Testについてコップ本と内容で少し違ったところは以下のとおり(なおScala Testのバージョンは2.1.6)

  • evaluating {some execution} should produce[SomeException]が非推奨になっていて代わりにan [SomeException] should be thrownBy {some execution}を使ったこと

僕の勝手な実装

僕の都合でコップ本と一部内容を変更したのは以下のとおり

  • Element#widthcontents(0)lengthを返すのが気持ち悪いので、次のようにした
  def width: Int = contents.map(_.length).max

この変更によってwidthに対するテストはコップ本と異なるテストになっています。

class ArrayElementSuite extends FunSuite with ShouldMatchers {
  test("ArrayElement#width returns its first item's length") {
    val strings: Array[String] = Array(
      "1234567890",
      "123",
      "12345678901")
    Element.elem(strings).width should be(11)
  }
}

コップ本と同じ実装であれば、次のテストが正しい

class ArrayElementSuite extends FunSuite with ShouldMatchers {
  test("ArrayElement#width returns its first item's length") {
    val strings: Array[String] = Array(
      "1234567890",
      "123",
      "12345678901")
    Element.elem(strings).width should be(10)
  }
}

以上