Skip to content

Commit f7c84a6

Browse files
author
James Hagborg
committed
Improve unit tests and add forLoop to CommandBuilder
1 parent e176ca7 commit f7c84a6

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

src/main/java/org/usfirst/frc/team69/util/CommandBuilder.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,29 @@ public CommandBuilder whileLoop(BooleanSupplier condition, Command body) {
193193
return this;
194194
}
195195

196+
// This needs to be a class, so we can pass-by-reference to the loop command
197+
private static class Counter {
198+
public int value = 0;
199+
}
200+
201+
/**
202+
* Run a command a given number of times. This is effectively a for loop,
203+
* although the command cannot make use of the value of the counter.
204+
*
205+
* This uses {@link #whileLoop(BooleanSupplier, Command)} under the hood,
206+
* so the semantics are the same as that.
207+
*
208+
* @param count The number of times to run the command.
209+
* @param body The body of the command to execute.
210+
* @return This CommandBuilder object
211+
*/
212+
public CommandBuilder forLoop(int count, Command body) {
213+
Counter counter = new Counter();
214+
m_cmdGroup.addSequential(QuickCommand.oneShot(null, () -> counter.value = 0));
215+
m_cmdGroup.addSequential(new WhileCommand(() -> counter.value++ < count, body));
216+
return this;
217+
}
218+
196219
/**
197220
* End any command currently running on the subsystem. This is accomplished
198221
* by running a command which ends instantly, which requires the given
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.usfirst.frc.team69.util.oi.test;
2+
3+
import static org.junit.Assert.*;
4+
5+
import java.util.concurrent.TimeUnit;
6+
7+
import org.junit.BeforeClass;
8+
import org.junit.Rule;
9+
import org.junit.Test;
10+
import org.junit.rules.Timeout;
11+
import org.usfirst.frc.team69.util.CommandBuilder;
12+
13+
import edu.wpi.first.wpilibj.MockCommand;
14+
import edu.wpi.first.wpilibj.UnitTestUtility;
15+
import edu.wpi.first.wpilibj.command.Command;
16+
import edu.wpi.first.wpilibj.command.Scheduler;
17+
18+
public class ForCommandTest {
19+
20+
// We're looping conditional on code under test, want to make sure that doesn't break
21+
@Rule
22+
public Timeout globalTimeout = new Timeout(100, TimeUnit.MILLISECONDS);
23+
24+
@BeforeClass
25+
public static void setUpBeforeClass() throws Exception {
26+
UnitTestUtility.setupMockBase();
27+
}
28+
29+
@Test
30+
public void testForLoop() {
31+
MockCommand mockCommand = new MockCommand();
32+
mockCommand.setHasFinished(true);
33+
Command loopCommand = new CommandBuilder()
34+
.forLoop(10, mockCommand)
35+
.build();
36+
loopCommand.start();
37+
Scheduler.getInstance().run();
38+
39+
while (loopCommand.isRunning()) {
40+
Scheduler.getInstance().run();
41+
}
42+
43+
assertEquals(10, mockCommand.getExecuteCount());
44+
assertEquals(10, mockCommand.getIsFinishedCount());
45+
assertEquals(10, mockCommand.getInitializeCount());
46+
assertEquals(10, mockCommand.getEndCount());
47+
assertEquals(0, mockCommand.getInterruptedCount());
48+
}
49+
50+
}

src/test/java/org/usfirst/frc/team69/util/oi/test/MockCondition.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
public class MockCondition implements BooleanSupplier {
66

77
private boolean m_cond;
8+
private int timesChecked = 0;
89

910
public MockCondition(boolean startState) {
1011
m_cond = startState;
@@ -16,7 +17,11 @@ public void set(boolean state) {
1617

1718
@Override
1819
public boolean getAsBoolean() {
20+
timesChecked++;
1921
return m_cond;
2022
}
2123

24+
public int getTimesChecked() {
25+
return timesChecked;
26+
}
2227
}

src/test/java/org/usfirst/frc/team69/util/oi/test/WhileCommandTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ public void testWhileCommandRuns() {
7777
assertEquals(50, body.getIsFinishedCount());
7878
assertEquals(10, body.getEndCount());
7979
assertEquals(0, body.getInterruptedCount());
80+
// The loop ran 10 times, and started an 11th
81+
assertEquals(11, condition.getTimesChecked());
8082
}
8183

8284
@Test
@@ -109,6 +111,7 @@ public void testDoesNotRunIfFalse() {
109111
assertEquals(0, body.getIsFinishedCount());
110112
assertEquals(0, body.getEndCount());
111113
assertEquals(0, body.getInterruptedCount());
114+
assertEquals(1, condition.getTimesChecked());
112115
}
113116

114117
@Test
@@ -130,6 +133,8 @@ public void testEndsWhenFalse() {
130133
assertEquals(1, body.getIsFinishedCount());
131134
assertEquals(1, body.getEndCount());
132135
assertEquals(0, body.getInterruptedCount());
136+
// checked once at start, another at end
137+
assertEquals(2, condition.getTimesChecked());
133138
}
134139

135140
@Test
@@ -149,6 +154,7 @@ public void testCancelWhileCommand() {
149154
assertEquals(1, body.getIsFinishedCount());
150155
assertEquals(0, body.getEndCount());
151156
assertEquals(1, body.getInterruptedCount());
157+
assertEquals(1, condition.getTimesChecked());
152158
}
153159

154160
@Test
@@ -171,6 +177,7 @@ public void testCancelBodyCommand() {
171177
assertEquals(2, body.getInitializeCount());
172178
assertEquals(0, body.getEndCount());
173179
assertEquals(1, body.getInterruptedCount());
180+
assertEquals(2, condition.getTimesChecked());
174181
}
175182

176183
}

0 commit comments

Comments
 (0)