-
-
Save cm-tokuda/9e8ec8adc2c4af78ae13b4ca96ec85e6 to your computer and use it in GitHub Desktop.
TDDワークショップ成果物
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tddbc.range; | |
/** | |
* 整数閉区間とは数直線上のある区切りの間の数(整数)の集合であり、両端の区切りを含む。 | |
* | |
* @author tokuda.mitsuki | |
*/ | |
public class ClosedRange { | |
private int lower; | |
private int upper; | |
/** | |
* 下端点と上端点から、整数閉区間のインスタンスを作る。 | |
* | |
* @param lower 下端点 | |
* @param upper 上端点 | |
* @throws IllegalArgumentException 上端点が下端点よりも小さい場合 | |
*/ | |
public ClosedRange(int lower, int upper) { | |
if (lower > upper) { | |
throw new IllegalArgumentException("upper ["+upper+"] must be greater than or equal to lower ["+lower+"]"); | |
} | |
this.lower = lower; | |
this.upper = upper; | |
} | |
/** | |
* 整数閉区間の文字列表現を得る。 | |
* | |
* @return 整数閉区間の文字列表現 | |
*/ | |
@Override | |
public String toString() { | |
return "["+lower+","+upper+"]"; | |
} | |
/** | |
* 別の閉区間と等価かどうかを返す。 | |
* | |
* @param obj 別の閉区間 | |
* @return 等価の場合は {@code true}、等価でない場合は {@code false} | |
*/ | |
@Override | |
public boolean equals(Object obj) { | |
if (this == obj) | |
return true; | |
if (obj == null) | |
return false; | |
if (getClass() != obj.getClass()) | |
return false; | |
ClosedRange other = (ClosedRange) obj; | |
if (lower != other.lower) | |
return false; | |
if (upper != other.upper) | |
return false; | |
return true; | |
} | |
@Override | |
public int hashCode() { | |
final int prime = 31; | |
int result = 1; | |
result = prime * result + lower; | |
result = prime * result + upper; | |
return result; | |
} | |
/** | |
* 指定した整数を含むかどうかを判定する。 | |
* | |
* @param element 判定対象の整数 | |
* @return 含む場合は {@code true}、含まない場合は {@code false} | |
*/ | |
public boolean contains(int element) { | |
return lower <= element && element <= upper; | |
} | |
/** | |
* 指定した別の閉区間を完全に含むかどうかを判定する。 | |
* | |
* @param other 判定対象の閉区間 | |
* @return 完全に含む場合は {@code true}、含まない場合は {@code false} | |
*/ | |
public boolean contains(ClosedRange other) { | |
return this.lower <= other.lower && other.upper <= this.upper; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tddbc.range; | |
import static org.junit.Assert.*; | |
import org.junit.Before; | |
import org.junit.Test; | |
import org.junit.experimental.runners.Enclosed; | |
import org.junit.runner.RunWith; | |
@RunWith(Enclosed.class) | |
public class ClosedRangeTest { | |
// public static class 整数閉区間を示すオブジェクトをつくれる { | |
// @Test | |
// public void 整数閉区間は下端点と上端点を持つ() { | |
// // exercise | |
// ClosedRange acutual = new ClosedRange(3, 8); | |
// // verify | |
// assertNotNull(acutual); | |
// } | |
// } | |
public static class 文字列としても表現できる { | |
@Test | |
public void Range_3_8が文字列として3_8と表現される() throws Exception { | |
// setup | |
ClosedRange sut = new ClosedRange(3, 8); | |
// exercise | |
String actual = sut.toString(); | |
// verify | |
assertEquals("[3,8]", actual); | |
} | |
@Test | |
public void Range_5_10が文字列として5_10と表現される() throws Exception { | |
// setup | |
ClosedRange sut = new ClosedRange(5, 10); | |
// exercise | |
String actual = sut.toString(); | |
// verify | |
assertEquals("[5,10]", actual); | |
} | |
} | |
public static class 別の閉区間と等価かどうか判定できる { | |
private ClosedRange sut; | |
@Before | |
public void setUp() { | |
sut = new ClosedRange(3, 8); | |
} | |
@Test | |
public void Range_3_8同士は等価である() throws Exception { | |
// setup | |
ClosedRange range = new ClosedRange(3, 8); | |
// exercise | |
boolean actual = sut.equals(range); | |
// verify | |
assertTrue(actual); | |
} | |
@Test | |
public void Range_3_8とRange_3_9は等価でない() throws Exception { | |
// setup | |
ClosedRange range = new ClosedRange(3, 9); | |
// exercise | |
boolean actual = sut.equals(range); | |
// verify | |
assertFalse(actual); | |
} | |
} | |
public static class 整数の閉区間は指定した整数を含むかどうかを判定できる { | |
private ClosedRange sut; | |
@Before | |
public void setUp() { | |
sut = new ClosedRange(3, 8); | |
} | |
@Test | |
public void Range_3_8は3を含む() throws Exception { | |
// exercise | |
boolean actual = sut.contains(3); | |
// verify | |
assertTrue(actual); | |
} | |
@Test | |
public void Range_3_8は2を含まない() throws Exception { | |
// exercise | |
boolean actual = sut.contains(2); | |
// verify | |
assertFalse(actual); | |
} | |
@Test | |
public void Range_3_8は8を含む() throws Exception { | |
// exercise | |
boolean actual = sut.contains(8); | |
// verify | |
assertTrue(actual); | |
} | |
@Test | |
public void Range_3_8は9を含まない() throws Exception { | |
// exercise | |
boolean actual = sut.contains(9); | |
// verify | |
assertFalse(actual); | |
} | |
@Test | |
public void Range_3_3は3を含む() throws Exception { | |
// setup | |
ClosedRange sut = new ClosedRange(3, 3); | |
// exercise | |
boolean actual = sut.contains(3); | |
// verify | |
assertTrue(actual); | |
} | |
} | |
public static class 別の閉区間を完全に含まれるかどうかも判定できる { | |
private ClosedRange sut; | |
@Before | |
public void setUp() { | |
sut = new ClosedRange(3, 8); | |
} | |
@Test | |
public void Range_3_8はRange_3_8を完全に内包する() throws Exception { | |
// setup | |
ClosedRange range = new ClosedRange(3, 8); | |
// exercise | |
boolean actual = sut.contains(range); | |
// verify | |
assertTrue(actual); | |
/* 迷い | |
* assertTrue(sut.contains(new ClosedRange(3, 8))); | |
*/ | |
} | |
@Test | |
public void Range_3_8はRange_1_2を完全に内包しない() throws Exception { | |
// setup | |
ClosedRange range = new ClosedRange(1, 2); | |
// exercise | |
boolean actual = sut.contains(range); | |
// verify | |
assertFalse(actual); | |
} | |
@Test | |
public void Range_3_8はRange_1_3を完全に内包しない() throws Exception { | |
// setup | |
ClosedRange range = new ClosedRange(1, 3); | |
// exercise | |
boolean actual = sut.contains(range); | |
// verify | |
assertFalse(actual); | |
} | |
@Test | |
public void Range_3_8はRange_8_10を完全に内包しない() throws Exception { | |
// setup | |
ClosedRange range = new ClosedRange(8, 10); | |
// exercise | |
boolean actual = sut.contains(range); | |
// verify | |
assertFalse(actual); | |
} | |
@Test | |
public void Range_3_8はRange_9_10を完全に内包しない() throws Exception { | |
// setup | |
ClosedRange range = new ClosedRange(9, 10); | |
// exercise | |
boolean actual = sut.contains(range); | |
// verify | |
assertFalse(actual); | |
} | |
@Test | |
public void Range_3_8はRange_2_9を完全に内包しない() throws Exception { | |
// setup | |
ClosedRange range = new ClosedRange(2, 9); | |
// exercise | |
boolean actual = sut.contains(range); | |
// verify | |
assertFalse(actual); | |
} | |
} | |
public static class 上端点より下端点が大きい閉区間を作ることはできない { | |
@Test | |
public void Range_8_3を作ろうとするとIllegalArgumentExceptionが飛ぶ() { | |
try { | |
// exercise | |
new ClosedRange(8, 3); | |
fail(); | |
} catch (IllegalArgumentException e) { | |
// verify | |
assertEquals("upper [3] must be greater than or equal to lower [8]", e.getMessage()); | |
} | |
} | |
@Test | |
public void Range_10_1を作ろうとするとIllegalArgumentExceptionが飛ぶ() { | |
try { | |
// exercise | |
new ClosedRange(10, 1); | |
fail(); | |
} catch (IllegalArgumentException e) { | |
// verify | |
assertEquals("upper [1] must be greater than or equal to lower [10]", e.getMessage()); | |
} | |
} | |
@Test | |
public void Range_3_3は作れる() { | |
// exercise | |
new ClosedRange(3, 3); | |
} | |
@Test | |
public void Range_m8_m3は作れる() { | |
// exercise | |
new ClosedRange(-8, -3); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TODO | |
============== | |
// compile error driven でコードを作って行く役割を果たしたが、完成後、無意味に...。 | |
- [x] 整数閉区間を示すオブジェクトをつくれる。(コンストラクト) | |
- [x] 整数閉区間は下端点と上端点を持つ | |
// 本質的じゃないので最初は後回しにしようと思った、が色々確認しやすいので最初に持ってきた。 | |
- [x] 文字列としても表現できる(例: 下端点 3, 上端点 8 の整数閉区間の文字列表記は "[3,8]")。 | |
- [x] Range_3_8が文字列として3_8と表現される | |
- [x] Range_5_10が文字列として5_10と表現される | |
// 最初は 1, 10 あたりの値を使っていたが、境界値を意識して値を組み直した。 | |
- [x] 整数の閉区間は指定した整数を含むかどうかを判定できる。 | |
- [x] Range_3_8は3を含む | |
- [x] Range_3_8は8を含む | |
- [x] Range_3_8は2を含まない | |
- [x] Range_3_8は9を含まない | |
- [x] Range_3_3は3を含む // 後から立ちもどり | |
// Eclipseのgeneratorでさっと実装。 | |
// コピぺミスで、「テストのテストを実装で行う」エピソード発生。 | |
- [x] 別の閉区間と等価かどうか判定できる。 | |
- [x] Range_3_8同士は等価である | |
- [x] Range_3_8とRange_3_9は等価でない | |
// otherとthisを間違えたにもかかわらず、落ちるテストは1つだけだったことに驚愕。 | |
- [x] 別の閉区間を完全に含まれるかどうかも判定できる。 | |
- [x] Range_3_8はRange_3_8を完全に内包する | |
- [x] Range_3_8はRange_1_2を完全に内包しない | |
- [x] Range_3_8はRange_1_3を完全に内包しない | |
- [x] Range_3_8はRange_8_10を完全に内包しない | |
- [x] Range_3_8はRange_9_10を完全に内包しない | |
- [x] Range_3_8はRange_2_9を完全に内包しない | |
// 負数への意識が芽生えた。 | |
- [x] 上端点より下端点が大きい閉区間を作ることはできない。(コンストラクト) | |
- [x] Range_8_3を作ろうとするとIllegalArgumentExceptionが飛ぶ | |
- [x] Range_10_1を作ろうとするとIllegalArgumentExceptionが飛ぶ | |
- [x] Range_3_3は作れる | |
- [x] Range_m8_m3は作れる | |
// 感想 | |
testにもってかれて、javadocへの意識が薄れる。。。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment