Skip to content

Instantly share code, notes, and snippets.

@cm-tokuda cm-tokuda/ClosedRange.java Secret
Last active Aug 2, 2017

Embed
What would you like to do?
TDDワークショップ成果物
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;
}
}
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_8Range_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_83を含む() throws Exception {
// exercise
boolean actual = sut.contains(3);
// verify
assertTrue(actual);
}
@Test
public void Range_3_82を含まない() throws Exception {
// exercise
boolean actual = sut.contains(2);
// verify
assertFalse(actual);
}
@Test
public void Range_3_88を含む() throws Exception {
// exercise
boolean actual = sut.contains(8);
// verify
assertTrue(actual);
}
@Test
public void Range_3_89を含まない() throws Exception {
// exercise
boolean actual = sut.contains(9);
// verify
assertFalse(actual);
}
@Test
public void Range_3_33を含む() 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_8Range_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_8Range_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_8Range_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_8Range_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_8Range_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_8Range_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);
}
}
}
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
You can’t perform that action at this time.