mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-23 01:21:42 +00:00
[commands] Add property tests for command compositions (#4715)
This commit is contained in:
@@ -9,6 +9,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import edu.wpi.first.wpilibj.DriverStation;
|
||||
import edu.wpi.first.wpilibj.simulation.DriverStationSim;
|
||||
import edu.wpi.first.wpilibj2.command.Command.InterruptionBehavior;
|
||||
import java.util.Set;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
@@ -47,6 +48,7 @@ public class CommandTestBase {
|
||||
when(m_mockCommand.getRequirements()).thenReturn(Set.of(requirements));
|
||||
when(m_mockCommand.isFinished()).thenReturn(false);
|
||||
when(m_mockCommand.runsWhenDisabled()).thenReturn(runWhenDisabled);
|
||||
when(m_mockCommand.getInterruptionBehavior()).thenReturn(InterruptionBehavior.kCancelSelf);
|
||||
}
|
||||
|
||||
public Command getMock() {
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.wpilibj2.command;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
import edu.wpi.first.wpilibj2.command.Command.InterruptionBehavior;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
interface MultiCompositionTestBase<T extends Command> extends SingleCompositionTestBase<T> {
|
||||
T compose(Command... members);
|
||||
|
||||
@Override
|
||||
default T composeSingle(Command member) {
|
||||
return compose(member);
|
||||
}
|
||||
|
||||
static Stream<Arguments> interruptible() {
|
||||
return Stream.of(
|
||||
arguments(
|
||||
"AllCancelSelf",
|
||||
InterruptionBehavior.kCancelSelf,
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelSelf),
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelSelf),
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelSelf)),
|
||||
arguments(
|
||||
"AllCancelIncoming",
|
||||
InterruptionBehavior.kCancelIncoming,
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelIncoming),
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelIncoming),
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelIncoming)),
|
||||
arguments(
|
||||
"TwoCancelSelfOneIncoming",
|
||||
InterruptionBehavior.kCancelSelf,
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelSelf),
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelSelf),
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelIncoming)),
|
||||
arguments(
|
||||
"TwoCancelIncomingOneSelf",
|
||||
InterruptionBehavior.kCancelSelf,
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelIncoming),
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelIncoming),
|
||||
new WaitUntilCommand(() -> false)
|
||||
.withInterruptBehavior(InterruptionBehavior.kCancelSelf)));
|
||||
}
|
||||
|
||||
@MethodSource
|
||||
@ParameterizedTest(name = "interruptible[{index}]: {0}")
|
||||
default void interruptible(
|
||||
@SuppressWarnings("unused") String name,
|
||||
InterruptionBehavior expected,
|
||||
Command command1,
|
||||
Command command2,
|
||||
Command command3) {
|
||||
var command = compose(command1, command2, command3);
|
||||
assertEquals(expected, command.getInterruptionBehavior());
|
||||
}
|
||||
|
||||
static Stream<Arguments> runsWhenDisabled() {
|
||||
return Stream.of(
|
||||
arguments(
|
||||
"AllFalse",
|
||||
false,
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(false),
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(false),
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(false)),
|
||||
arguments(
|
||||
"AllTrue",
|
||||
true,
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(true),
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(true),
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(true)),
|
||||
arguments(
|
||||
"TwoTrueOneFalse",
|
||||
false,
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(true),
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(true),
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(false)),
|
||||
arguments(
|
||||
"TwoFalseOneTrue",
|
||||
false,
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(false),
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(false),
|
||||
new WaitUntilCommand(() -> false).ignoringDisable(true)));
|
||||
}
|
||||
|
||||
@MethodSource
|
||||
@ParameterizedTest(name = "runsWhenDisabled[{index}]: {0}")
|
||||
default void runsWhenDisabled(
|
||||
@SuppressWarnings("unused") String name,
|
||||
boolean expected,
|
||||
Command command1,
|
||||
Command command2,
|
||||
Command command3) {
|
||||
var command = compose(command1, command2, command3);
|
||||
assertEquals(expected, command.runsWhenDisabled());
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,8 @@ import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ParallelCommandGroupTest extends CommandTestBase {
|
||||
class ParallelCommandGroupTest extends CommandTestBase
|
||||
implements MultiCompositionTestBase<ParallelCommandGroup> {
|
||||
@Test
|
||||
void parallelGroupScheduleTest() {
|
||||
try (CommandScheduler scheduler = new CommandScheduler()) {
|
||||
@@ -126,4 +127,9 @@ class ParallelCommandGroupTest extends CommandTestBase {
|
||||
assertThrows(
|
||||
IllegalArgumentException.class, () -> new ParallelCommandGroup(command1, command2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParallelCommandGroup compose(Command... members) {
|
||||
return new ParallelCommandGroup(members);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,11 @@ import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.internal.verification.VerificationModeFactory.times;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ParallelDeadlineGroupTest extends CommandTestBase {
|
||||
class ParallelDeadlineGroupTest extends CommandTestBase
|
||||
implements MultiCompositionTestBase<ParallelDeadlineGroup> {
|
||||
@Test
|
||||
void parallelDeadlineScheduleTest() {
|
||||
try (CommandScheduler scheduler = new CommandScheduler()) {
|
||||
@@ -122,4 +124,9 @@ class ParallelDeadlineGroupTest extends CommandTestBase {
|
||||
assertThrows(
|
||||
IllegalArgumentException.class, () -> new ParallelDeadlineGroup(command1, command2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParallelDeadlineGroup compose(Command... members) {
|
||||
return new ParallelDeadlineGroup(members[0], Arrays.copyOfRange(members, 1, members.length));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ParallelRaceGroupTest extends CommandTestBase {
|
||||
class ParallelRaceGroupTest extends CommandTestBase
|
||||
implements MultiCompositionTestBase<ParallelRaceGroup> {
|
||||
@Test
|
||||
void parallelRaceScheduleTest() {
|
||||
try (CommandScheduler scheduler = new CommandScheduler()) {
|
||||
@@ -202,4 +203,9 @@ class ParallelRaceGroupTest extends CommandTestBase {
|
||||
assertFalse(scheduler.isScheduled(group));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParallelRaceGroup compose(Command... members) {
|
||||
return new ParallelRaceGroup(members);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
class RepeatCommandTest extends CommandTestBase {
|
||||
class RepeatCommandTest extends CommandTestBase
|
||||
implements SingleCompositionTestBase<RepeatCommand> {
|
||||
@Test
|
||||
void callsMethodsCorrectly() {
|
||||
var initCounter = new AtomicInteger(0);
|
||||
@@ -66,18 +64,8 @@ class RepeatCommandTest extends CommandTestBase {
|
||||
assertEquals(1, endCounter.get());
|
||||
}
|
||||
|
||||
@EnumSource(Command.InterruptionBehavior.class)
|
||||
@ParameterizedTest
|
||||
void interruptible(Command.InterruptionBehavior interruptionBehavior) {
|
||||
var command =
|
||||
new WaitUntilCommand(() -> false).withInterruptBehavior(interruptionBehavior).repeatedly();
|
||||
assertEquals(interruptionBehavior, command.getInterruptionBehavior());
|
||||
}
|
||||
|
||||
@ValueSource(booleans = {true, false})
|
||||
@ParameterizedTest
|
||||
void runWhenDisabled(boolean runsWhenDisabled) {
|
||||
var command = new WaitUntilCommand(() -> false).ignoringDisable(runsWhenDisabled).repeatedly();
|
||||
assertEquals(runsWhenDisabled, command.runsWhenDisabled());
|
||||
@Override
|
||||
public RepeatCommand composeSingle(Command member) {
|
||||
return member.repeatedly();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,11 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class SelectCommandTest extends CommandTestBase {
|
||||
class SelectCommandTest extends CommandTestBase implements MultiCompositionTestBase<SelectCommand> {
|
||||
@Test
|
||||
void selectCommandTest() {
|
||||
try (CommandScheduler scheduler = new CommandScheduler()) {
|
||||
@@ -105,4 +106,13 @@ class SelectCommandTest extends CommandTestBase {
|
||||
verify(command3, never()).end(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectCommand compose(Command... members) {
|
||||
var map = new HashMap<Object, Command>();
|
||||
for (int i = 0; i < members.length; i++) {
|
||||
map.put(i, members[i]);
|
||||
}
|
||||
return new SelectCommand(map, () -> 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class SequentialCommandGroupTest extends CommandTestBase {
|
||||
class SequentialCommandGroupTest extends CommandTestBase
|
||||
implements MultiCompositionTestBase<SequentialCommandGroup> {
|
||||
@Test
|
||||
void sequentialGroupScheduleTest() {
|
||||
try (CommandScheduler scheduler = new CommandScheduler()) {
|
||||
@@ -121,4 +122,9 @@ class SequentialCommandGroupTest extends CommandTestBase {
|
||||
assertTrue(scheduler.isScheduled(command3));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SequentialCommandGroup compose(Command... members) {
|
||||
return new SequentialCommandGroup(members);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.wpilibj2.command;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
public interface SingleCompositionTestBase<T extends Command> {
|
||||
T composeSingle(Command member);
|
||||
|
||||
@EnumSource(Command.InterruptionBehavior.class)
|
||||
@ParameterizedTest
|
||||
default void interruptible(Command.InterruptionBehavior interruptionBehavior) {
|
||||
var command =
|
||||
composeSingle(
|
||||
new WaitUntilCommand(() -> false).withInterruptBehavior(interruptionBehavior));
|
||||
assertEquals(interruptionBehavior, command.getInterruptionBehavior());
|
||||
}
|
||||
|
||||
@ValueSource(booleans = {true, false})
|
||||
@ParameterizedTest
|
||||
default void runWhenDisabled(boolean runsWhenDisabled) {
|
||||
var command =
|
||||
composeSingle(new WaitUntilCommand(() -> false).ignoringDisable(runsWhenDisabled));
|
||||
assertEquals(runsWhenDisabled, command.runsWhenDisabled());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user