Skip to content

Commit e176ca7

Browse files
author
James Hagborg
committed
Add unit tests for WhileCommand
1 parent 02ab309 commit e176ca7

File tree

3 files changed

+314
-0
lines changed

3 files changed

+314
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*----------------------------------------------------------------------------*/
2+
/* Copyright (c) FIRST 2016-2017. All Rights Reserved. */
3+
/* Open Source Software - may be modified and shared by FRC teams. The code */
4+
/* must be accompanied by the FIRST BSD license file in the root directory of */
5+
/* the project. */
6+
/*----------------------------------------------------------------------------*/
7+
8+
package edu.wpi.first.wpilibj;
9+
10+
import edu.wpi.first.wpilibj.command.Command;
11+
12+
/**
13+
* A class to simulate a simple command The command keeps track of how many times each method was
14+
* called.
15+
*/
16+
public class MockCommand extends Command {
17+
private int m_initializeCount = 0;
18+
private int m_executeCount = 0;
19+
private int m_isFinishedCount = 0;
20+
private boolean m_hasFinished = false;
21+
private int m_endCount = 0;
22+
private int m_interruptedCount = 0;
23+
24+
protected void initialize() {
25+
++m_initializeCount;
26+
}
27+
28+
protected void execute() {
29+
++m_executeCount;
30+
}
31+
32+
protected boolean isFinished() {
33+
++m_isFinishedCount;
34+
return isHasFinished();
35+
}
36+
37+
protected void end() {
38+
++m_endCount;
39+
}
40+
41+
protected void interrupted() {
42+
++m_interruptedCount;
43+
}
44+
45+
46+
/**
47+
* How many times the initialize method has been called.
48+
*/
49+
public int getInitializeCount() {
50+
return m_initializeCount;
51+
}
52+
53+
/**
54+
* If the initialize method has been called at least once.
55+
*/
56+
public boolean hasInitialized() {
57+
return getInitializeCount() > 0;
58+
}
59+
60+
/**
61+
* How many time the execute method has been called.
62+
*/
63+
public int getExecuteCount() {
64+
return m_executeCount;
65+
}
66+
67+
/**
68+
* How many times the isFinished method has been called.
69+
*/
70+
public int getIsFinishedCount() {
71+
return m_isFinishedCount;
72+
}
73+
74+
/**
75+
* @return what value the isFinished method will return.
76+
*/
77+
public boolean isHasFinished() {
78+
return m_hasFinished;
79+
}
80+
81+
/**
82+
* @param hasFinished set what value the isFinished method will return.
83+
*/
84+
public void setHasFinished(boolean hasFinished) {
85+
m_hasFinished = hasFinished;
86+
}
87+
88+
/**
89+
* How many times the end method has been called.
90+
*/
91+
public int getEndCount() {
92+
return m_endCount;
93+
}
94+
95+
/**
96+
* If the end method has been called at least once.
97+
*/
98+
public boolean hasEnd() {
99+
return getEndCount() > 0;
100+
}
101+
102+
/**
103+
* How many times the interrupted method has been called.
104+
*/
105+
public int getInterruptedCount() {
106+
return m_interruptedCount;
107+
}
108+
109+
/**
110+
* If the interrupted method has been called at least once.
111+
*/
112+
public boolean hasInterrupted() {
113+
return getInterruptedCount() > 0;
114+
}
115+
116+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.usfirst.frc.team69.util.oi.test;
2+
3+
import java.util.function.BooleanSupplier;
4+
5+
public class MockCondition implements BooleanSupplier {
6+
7+
private boolean m_cond;
8+
9+
public MockCondition(boolean startState) {
10+
m_cond = startState;
11+
}
12+
13+
public void set(boolean state) {
14+
m_cond = state;
15+
}
16+
17+
@Override
18+
public boolean getAsBoolean() {
19+
return m_cond;
20+
}
21+
22+
}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package org.usfirst.frc.team69.util.oi.test;
2+
3+
import static org.junit.Assert.*;
4+
5+
import org.junit.Before;
6+
import org.junit.BeforeClass;
7+
import org.junit.Test;
8+
9+
import edu.wpi.first.wpilibj.MockCommand;
10+
import edu.wpi.first.wpilibj.UnitTestUtility;
11+
import edu.wpi.first.wpilibj.command.Command;
12+
import edu.wpi.first.wpilibj.command.InstantCommand;
13+
import edu.wpi.first.wpilibj.command.Scheduler;
14+
import edu.wpi.first.wpilibj.command.Subsystem;
15+
import edu.wpi.first.wpilibj.command.WhileCommand;
16+
17+
public class WhileCommandTest {
18+
19+
private MockCondition condition;
20+
private MockCommand body;
21+
private WhileCommand whileCommand;
22+
23+
@BeforeClass
24+
public static void setUpBeforeClass() throws Exception {
25+
UnitTestUtility.setupMockBase();
26+
}
27+
28+
@Before
29+
public void setUp() throws Exception {
30+
Scheduler.getInstance().removeAll();
31+
32+
condition = new MockCondition(true);
33+
body = new MockCommand();
34+
whileCommand = new WhileCommand(condition, body);
35+
}
36+
37+
@Test
38+
public void testStartup() {
39+
// Nothing is running at first
40+
whileCommand.start();
41+
assertFalse(whileCommand.isRunning());
42+
assertFalse(body.isRunning());
43+
44+
// On the first tick, the while command starts up
45+
Scheduler.getInstance().run();
46+
assertTrue(whileCommand.isRunning());
47+
assertFalse(body.isRunning());
48+
49+
// On the next tick, the body starts up
50+
Scheduler.getInstance().run();
51+
assertTrue(whileCommand.isRunning());
52+
assertTrue(body.isRunning());
53+
}
54+
55+
@Test
56+
public void testWhileCommandRuns() {
57+
// Run the body 10 times, with each iteration taking 5 ticks
58+
whileCommand.start();
59+
Scheduler.getInstance().run(); // queue the command
60+
Scheduler.getInstance().run(); // actually run it
61+
62+
for (int iter = 0; iter < 10; iter++) {
63+
// run 4 ticks normally
64+
for (int tick = 0; tick < 4; tick++) {
65+
Scheduler.getInstance().run();
66+
}
67+
68+
// on the 5th tick it finishes, this takes 2 ticks to happen
69+
body.setHasFinished(true);
70+
Scheduler.getInstance().run(); // re-queue the body
71+
body.setHasFinished(false);
72+
Scheduler.getInstance().run(); // initialize the body
73+
}
74+
75+
assertEquals(10, body.getInitializeCount());
76+
assertEquals(50, body.getExecuteCount());
77+
assertEquals(50, body.getIsFinishedCount());
78+
assertEquals(10, body.getEndCount());
79+
assertEquals(0, body.getInterruptedCount());
80+
}
81+
82+
@Test
83+
public void testTransferRequirements() {
84+
Subsystem req = new Subsystem() {
85+
@Override protected void initDefaultCommand() {}
86+
};
87+
88+
Command bodyWithReqs = new InstantCommand() {
89+
{ requires(req); }
90+
};
91+
92+
WhileCommand whileCommandWithReqs = new WhileCommand(condition, bodyWithReqs);
93+
assertTrue(whileCommandWithReqs.doesRequire(req));
94+
assertFalse(bodyWithReqs.doesRequire(req));
95+
}
96+
97+
@Test
98+
public void testDoesNotRunIfFalse() {
99+
whileCommand.start();
100+
condition.set(false);
101+
102+
Scheduler.getInstance().run(); // queue the whileCommand
103+
Scheduler.getInstance().run(); // should check and stop
104+
105+
assertFalse(whileCommand.isRunning());
106+
assertFalse(body.isRunning());
107+
assertEquals(0, body.getInitializeCount());
108+
assertEquals(0, body.getExecuteCount());
109+
assertEquals(0, body.getIsFinishedCount());
110+
assertEquals(0, body.getEndCount());
111+
assertEquals(0, body.getInterruptedCount());
112+
}
113+
114+
@Test
115+
public void testEndsWhenFalse() {
116+
whileCommand.start();
117+
body.setHasFinished(true);
118+
119+
Scheduler.getInstance().run(); // queue the whileCommand
120+
Scheduler.getInstance().run(); // queue the body
121+
Scheduler.getInstance().run(); // run the body once
122+
123+
condition.set(false);
124+
Scheduler.getInstance().run(); // about to re-queue, but condition is false
125+
126+
assertFalse(whileCommand.isRunning());
127+
assertFalse(body.isRunning());
128+
assertEquals(1, body.getInitializeCount());
129+
assertEquals(1, body.getExecuteCount());
130+
assertEquals(1, body.getIsFinishedCount());
131+
assertEquals(1, body.getEndCount());
132+
assertEquals(0, body.getInterruptedCount());
133+
}
134+
135+
@Test
136+
public void testCancelWhileCommand() {
137+
whileCommand.start();
138+
Scheduler.getInstance().run(); // queue the whileCommand
139+
Scheduler.getInstance().run(); // queue the body
140+
Scheduler.getInstance().run(); // queue run the body once
141+
142+
whileCommand.cancel();
143+
Scheduler.getInstance().run(); // make the cancellation take effect
144+
145+
assertFalse(whileCommand.isRunning());
146+
assertFalse(body.isRunning());
147+
assertEquals(1, body.getInitializeCount());
148+
assertEquals(1, body.getExecuteCount());
149+
assertEquals(1, body.getIsFinishedCount());
150+
assertEquals(0, body.getEndCount());
151+
assertEquals(1, body.getInterruptedCount());
152+
}
153+
154+
@Test
155+
public void testCancelBodyCommand() {
156+
whileCommand.start();
157+
Scheduler.getInstance().run(); // queue the whileCommand
158+
Scheduler.getInstance().run(); // queue the body
159+
Scheduler.getInstance().run(); // queue run the body once
160+
161+
body.cancel();
162+
Scheduler.getInstance().run(); // make the cancellation take effect
163+
Scheduler.getInstance().run(); // Let the command re-queue
164+
Scheduler.getInstance().run(); // Let the command start up again
165+
166+
assertTrue(whileCommand.isRunning());
167+
assertTrue(body.isRunning());
168+
// don't bother checking execute count, that's dependant on
169+
// implementation details of the scheduler (what order it runs the
170+
// two commands in)
171+
assertEquals(2, body.getInitializeCount());
172+
assertEquals(0, body.getEndCount());
173+
assertEquals(1, body.getInterruptedCount());
174+
}
175+
176+
}

0 commit comments

Comments
 (0)