package counters;
import org.junit.*;
import static org.junit.Assert.*;
import counters.SimpleCounter;
import counters.LimitReachedException;
/**
*
* Tests of SimpleCounter
’s advanceValue method.
*
*
*
* Requires JUnit 4.x
.
*
*
* @author Wayne Eberly
*
*/
public class AdvanceValueTest {
/*
*
* Utility to create a counter with a given limit and
* value. It is assumed that each is positive, and that
* the given value is less than the given limit
*
* This is used as setup for tests in which a final call
* (appearing after the use of this utility) to advanceValue
* is examined. In order to help distinguish between problems
* that arise during the use of this routine, and problems
* that arise during this last use of advanceValue, this method
* checks the value of the counter before terminating. If the
* counter's value is not as expected then a warning message
* is displayed and failure of the test is forced.
*
*/
private SimpleCounter makeCounter ( int inLimit, int inValue )
throws LimitReachedException {
SimpleCounter outCounter;
outCounter = new SimpleCounter(inLimit);
for (int i = 0; i < inValue; i++) {
outCounter.advanceValue();
};
if ( outCounter.getValue() != inValue ) {
System.out.println("Initialization failed!");
assertEquals(outCounter.getValue(), inValue);
};
return outCounter;
}
/*
*
* Utility for a simple test, that is, one that does not
* cause an exception to be thrown: It is assumed that the
* given inValue is between 0 and inLimit - 2
*
*/
private void normalTest ( int inLimit, int inValue )
throws LimitReachedException {
SimpleCounter testCounter;
testCounter = makeCounter(inLimit, inValue);
testCounter.advanceValue();
assertEquals(testCounter.getValue(), inValue+1);
}
@Test
public void Test2_0 () throws LimitReachedException {
normalTest(2, 0);
}
@Test
public void Test3_0 () throws LimitReachedException {
normalTest(3, 0);
}
@Test
public void Test3_1 () throws LimitReachedException {
normalTest(3, 1);
}
@Test
public void Test4_0 () throws LimitReachedException {
normalTest(4, 0);
}
@Test
public void Test4_1 () throws LimitReachedException {
normalTest(4, 1);
}
@Test
public void Test4_2 () throws LimitReachedException {
normalTest(4, 2);
}
@Test
public void Test5_0 () throws LimitReachedException {
normalTest(5, 0);
}
@Test
public void Test5_1 () throws LimitReachedException {
normalTest(5, 1);
}
@Test
public void Test5_2 () throws LimitReachedException {
normalTest(5, 2);
}
@Test
public void Test5_3 () throws LimitReachedException {
normalTest(5, 3);
}
@Test
public void Test10_0 () throws LimitReachedException {
normalTest(10, 0);
}
@Test
public void Test11_1 () throws LimitReachedException {
normalTest(11, 1);
}
@Test
public void Test12_6 () throws LimitReachedException {
normalTest(12, 6);
}
@Test
public void Test16_14 () throws LimitReachedException {
normalTest(16, 14);
}
@Test
public void Test7654321_0 () throws LimitReachedException {
normalTest(7654321, 0);
}
@Test
public void Test7654321_803 () throws LimitReachedException {
normalTest(7654321, 803);
}
@Test
public void Test7654321_7654319 () throws LimitReachedException {
normalTest(7654321, 7654319);
}
@Test
public void Test2147483647_2147483644 () throws LimitReachedException {
normalTest(2147483647, 2147483644);
}
@Test
public void Test2147483647_2147483645 () throws LimitReachedException {
normalTest(2147483647, 2147483645);
}
/*
*
* Utility for the first part of a test that does cause
* an exception to be thrown
*
*/
private void exceptionalTest1 ( int inLimit )
throws LimitReachedException {
SimpleCounter testCounter;
testCounter = makeCounter(inLimit, inLimit-1);
testCounter.advanceValue();
}
/*
*
* Utility for the second part of a test that does cause
* an exception to be thrown
*
*/
private void exceptionalTest2 ( int inLimit )
throws LimitReachedException {
SimpleCounter testCounter;
testCounter = makeCounter(inLimit, inLimit-1);
try {
testCounter.advanceValue();
}
catch (LimitReachedException ex) {
assertEquals(testCounter.getValue(), 0);
assertEquals(testCounter.getLimit(), inLimit);
}
}
@Test (expected = LimitReachedException.class)
public void TestFailure1a () throws LimitReachedException {
exceptionalTest1(1);
}
@Test
public void TestFailure1b () throws LimitReachedException {
exceptionalTest2(1);
}
@Test (expected = LimitReachedException.class)
public void TestFailure2a () throws LimitReachedException {
exceptionalTest1(2);
}
@Test
public void TestFailure2b () throws LimitReachedException {
exceptionalTest2(2);
}
@Test (expected = LimitReachedException.class)
public void TestFailure3a () throws LimitReachedException {
exceptionalTest1(3);
}
@Test
public void TestFailure3b () throws LimitReachedException {
exceptionalTest2(3);
}
@Test (expected = LimitReachedException.class)
public void TestFailure4a () throws LimitReachedException {
exceptionalTest1(4);
}
@Test
public void TestFailure4b () throws LimitReachedException {
exceptionalTest2(4);
}
@Test (expected = LimitReachedException.class)
public void TestFailure5a () throws LimitReachedException {
exceptionalTest1(5);
}
@Test
public void TestFailure5b () throws LimitReachedException {
exceptionalTest2(5);
}
@Test (expected = LimitReachedException.class)
public void TestFailure983a () throws LimitReachedException {
exceptionalTest1(983);
}
@Test
public void TestFailure983b () throws LimitReachedException {
exceptionalTest2(983);
}
@Test (expected = LimitReachedException.class)
public void TestFailure2147483647a () throws LimitReachedException {
exceptionalTest1(2147483647);
}
@Test
public void TestFailure2147483647b () throws LimitReachedException {
exceptionalTest2(2147483647);
}
/*
*
* The final tests are included just in case the implementation
* changes significantly and the counter value is differently
* maintained: They test the counter for runs in which the number
* of times that advanceValue is called is significantly higher
* than the counter limit, so that the value is reset to zero
* more than once
*
* It is therefore assumed (although not strictly necessary)
* that inValue is significantly larger than inLimit, when this
* utiliy is used
*
*/
private SimpleCounter makeLongRun (int inLimit, int inValue)
throws LimitReachedException {
SimpleCounter testCounter;
testCounter = new SimpleCounter(inLimit);
int i = 0;
while ( i < inValue ) {
i++;
try
{ testCounter.advanceValue();
assertTrue((i % inLimit) != 0); // No exception thrown
} catch (LimitReachedException ex)
{ assertTrue ((i % inLimit) == 0);
} finally
{ assertEquals((i % inLimit), testCounter.getValue()); };
};
assertEquals(inLimit, testCounter.getLimit());
return testCounter;
}
@Test
public void simpleLongRunTest () throws LimitReachedException {
SimpleCounter testCounter;
testCounter = makeLongRun(1024, 5000);
}
@Test (expected = LimitReachedException.class)
public void exceptionalLongRunTest () throws LimitReachedException {
SimpleCounter testCounter;
testCounter = makeLongRun(1000, 4999);
testCounter.advanceValue();
}
/*
*
* This final long run checks that the counter is reset correctly
* after a LimitReachedException, when the counter's limit is at
* its maximum possible value
*/
@Test
public void extremeLongRunTest () throws LimitReachedException {
SimpleCounter testCounter;
testCounter = makeCounter(2147483647, 2147483646);
try {
testCounter.advanceValue(); // Exception should be thrown
assertEquals(0, 1); // Force test failure
} catch (LimitReachedException ex) {
assertEquals(testCounter.getValue(), 0);
};
testCounter.advanceValue();
assertEquals(testCounter.getValue(), 1);
testCounter.advanceValue();
assertEquals(testCounter.getValue(), 2);
testCounter.advanceValue();
assertEquals(testCounter.getValue(), 3);
assertEquals(testCounter.getLimit(), 2147483647);
}
}