[commands] Add property tests for command compositions (#4715)

This commit is contained in:
Starlight220
2022-11-28 02:23:56 +02:00
committed by GitHub
parent e4ac09077c
commit 8958b2a4da
31 changed files with 579 additions and 59 deletions

View File

@@ -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() {

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -0,0 +1,204 @@
// 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.
#pragma once
#include <memory>
#include <utility>
#include "CommandTestBase.h"
#include "frc2/command/Commands.h"
#include "gtest/gtest.h"
#include "make_vector.h"
namespace frc2 {
inline namespace single {
template <typename T>
class SingleCompositionRunsWhenDisabledTest : public CommandTestBase {};
TYPED_TEST_SUITE_P(SingleCompositionRunsWhenDisabledTest);
TYPED_TEST_P(SingleCompositionRunsWhenDisabledTest, True) {
auto param = true;
TypeParam command = TypeParam(
cmd::WaitUntil([] { return false; }).IgnoringDisable(param).Unwrap());
EXPECT_EQ(param, command.RunsWhenDisabled());
}
TYPED_TEST_P(SingleCompositionRunsWhenDisabledTest, False) {
auto param = false;
TypeParam command = TypeParam(
cmd::WaitUntil([] { return false; }).IgnoringDisable(param).Unwrap());
EXPECT_EQ(param, command.RunsWhenDisabled());
}
REGISTER_TYPED_TEST_SUITE_P(SingleCompositionRunsWhenDisabledTest, True, False);
template <typename T>
class SingleCompositionInterruptibilityTest : public CommandTestBase {};
TYPED_TEST_SUITE_P(SingleCompositionInterruptibilityTest);
TYPED_TEST_P(SingleCompositionInterruptibilityTest, CancelSelf) {
auto param = Command::InterruptionBehavior::kCancelSelf;
TypeParam command = TypeParam(cmd::WaitUntil([] { return false; })
.WithInterruptBehavior(param)
.Unwrap());
EXPECT_EQ(param, command.GetInterruptionBehavior());
}
TYPED_TEST_P(SingleCompositionInterruptibilityTest, CancelIncoming) {
auto param = Command::InterruptionBehavior::kCancelIncoming;
TypeParam command = TypeParam(cmd::WaitUntil([] { return false; })
.WithInterruptBehavior(param)
.Unwrap());
EXPECT_EQ(param, command.GetInterruptionBehavior());
}
REGISTER_TYPED_TEST_SUITE_P(SingleCompositionInterruptibilityTest, CancelSelf,
CancelIncoming);
#define INSTANTIATE_SINGLE_COMMAND_COMPOSITION_TEST_SUITE(Suite, \
CompositionType) \
INSTANTIATE_TYPED_TEST_SUITE_P(Suite, SingleCompositionInterruptibilityTest, \
CompositionType); \
INSTANTIATE_TYPED_TEST_SUITE_P(Suite, SingleCompositionRunsWhenDisabledTest, \
CompositionType);
} // namespace single
inline namespace multi {
template <typename T>
class MultiCompositionRunsWhenDisabledTest : public CommandTestBase {};
TYPED_TEST_SUITE_P(MultiCompositionRunsWhenDisabledTest);
TYPED_TEST_P(MultiCompositionRunsWhenDisabledTest, OneTrue) {
auto param = true;
TypeParam command = TypeParam(CommandPtr::UnwrapVector(cmd::impl::MakeVector(
cmd::WaitUntil([] { return false; }).IgnoringDisable(param))));
EXPECT_EQ(param, command.RunsWhenDisabled());
}
TYPED_TEST_P(MultiCompositionRunsWhenDisabledTest, OneFalse) {
auto param = false;
TypeParam command = TypeParam(CommandPtr::UnwrapVector(cmd::impl::MakeVector(
cmd::WaitUntil([] { return false; }).IgnoringDisable(param))));
EXPECT_EQ(param, command.RunsWhenDisabled());
}
TYPED_TEST_P(MultiCompositionRunsWhenDisabledTest, AllTrue) {
TypeParam command = TypeParam(CommandPtr::UnwrapVector(cmd::impl::MakeVector(
cmd::WaitUntil([] { return false; }).IgnoringDisable(true),
cmd::WaitUntil([] { return false; }).IgnoringDisable(true),
cmd::WaitUntil([] { return false; }).IgnoringDisable(true))));
EXPECT_EQ(true, command.RunsWhenDisabled());
}
TYPED_TEST_P(MultiCompositionRunsWhenDisabledTest, AllFalse) {
TypeParam command = TypeParam(CommandPtr::UnwrapVector(cmd::impl::MakeVector(
cmd::WaitUntil([] { return false; }).IgnoringDisable(false),
cmd::WaitUntil([] { return false; }).IgnoringDisable(false),
cmd::WaitUntil([] { return false; }).IgnoringDisable(false))));
EXPECT_EQ(false, command.RunsWhenDisabled());
}
TYPED_TEST_P(MultiCompositionRunsWhenDisabledTest, TwoTrueOneFalse) {
TypeParam command = TypeParam(CommandPtr::UnwrapVector(cmd::impl::MakeVector(
cmd::WaitUntil([] { return false; }).IgnoringDisable(true),
cmd::WaitUntil([] { return false; }).IgnoringDisable(true),
cmd::WaitUntil([] { return false; }).IgnoringDisable(false))));
EXPECT_EQ(false, command.RunsWhenDisabled());
}
TYPED_TEST_P(MultiCompositionRunsWhenDisabledTest, TwoFalseOneTrue) {
TypeParam command = TypeParam(CommandPtr::UnwrapVector(cmd::impl::MakeVector(
cmd::WaitUntil([] { return false; }).IgnoringDisable(false),
cmd::WaitUntil([] { return false; }).IgnoringDisable(false),
cmd::WaitUntil([] { return false; }).IgnoringDisable(true))));
EXPECT_EQ(false, command.RunsWhenDisabled());
}
REGISTER_TYPED_TEST_SUITE_P(MultiCompositionRunsWhenDisabledTest, OneTrue,
OneFalse, AllTrue, AllFalse, TwoTrueOneFalse,
TwoFalseOneTrue);
template <typename T>
class MultiCompositionInterruptibilityTest
: public SingleCompositionInterruptibilityTest<T> {};
TYPED_TEST_SUITE_P(MultiCompositionInterruptibilityTest);
TYPED_TEST_P(MultiCompositionInterruptibilityTest, AllCancelSelf) {
TypeParam command = TypeParam(CommandPtr::UnwrapVector(cmd::impl::MakeVector(
cmd::WaitUntil([] {
return false;
}).WithInterruptBehavior(Command::InterruptionBehavior::kCancelSelf),
cmd::WaitUntil([] {
return false;
}).WithInterruptBehavior(Command::InterruptionBehavior::kCancelSelf),
cmd::WaitUntil([] {
return false;
}).WithInterruptBehavior(Command::InterruptionBehavior::kCancelSelf))));
EXPECT_EQ(Command::InterruptionBehavior::kCancelSelf,
command.GetInterruptionBehavior());
}
TYPED_TEST_P(MultiCompositionInterruptibilityTest, AllCancelIncoming) {
TypeParam command = TypeParam(CommandPtr::UnwrapVector(cmd::impl::MakeVector(
cmd::WaitUntil([] {
return false;
}).WithInterruptBehavior(Command::InterruptionBehavior::kCancelIncoming),
cmd::WaitUntil([] {
return false;
}).WithInterruptBehavior(Command::InterruptionBehavior::kCancelIncoming),
cmd::WaitUntil([] { return false; })
.WithInterruptBehavior(
Command::InterruptionBehavior::kCancelIncoming))));
EXPECT_EQ(Command::InterruptionBehavior::kCancelIncoming,
command.GetInterruptionBehavior());
}
TYPED_TEST_P(MultiCompositionInterruptibilityTest, TwoCancelSelfOneIncoming) {
TypeParam command = TypeParam(CommandPtr::UnwrapVector(cmd::impl::MakeVector(
cmd::WaitUntil([] {
return false;
}).WithInterruptBehavior(Command::InterruptionBehavior::kCancelSelf),
cmd::WaitUntil([] {
return false;
}).WithInterruptBehavior(Command::InterruptionBehavior::kCancelSelf),
cmd::WaitUntil([] { return false; })
.WithInterruptBehavior(
Command::InterruptionBehavior::kCancelIncoming))));
EXPECT_EQ(Command::InterruptionBehavior::kCancelSelf,
command.GetInterruptionBehavior());
}
TYPED_TEST_P(MultiCompositionInterruptibilityTest, TwoCancelIncomingOneSelf) {
TypeParam command = TypeParam(CommandPtr::UnwrapVector(cmd::impl::MakeVector(
cmd::WaitUntil([] {
return false;
}).WithInterruptBehavior(Command::InterruptionBehavior::kCancelIncoming),
cmd::WaitUntil([] {
return false;
}).WithInterruptBehavior(Command::InterruptionBehavior::kCancelIncoming),
cmd::WaitUntil([] {
return false;
}).WithInterruptBehavior(Command::InterruptionBehavior::kCancelSelf))));
EXPECT_EQ(Command::InterruptionBehavior::kCancelSelf,
command.GetInterruptionBehavior());
}
REGISTER_TYPED_TEST_SUITE_P(MultiCompositionInterruptibilityTest, AllCancelSelf,
AllCancelIncoming, TwoCancelSelfOneIncoming,
TwoCancelIncomingOneSelf);
#define INSTANTIATE_MULTI_COMMAND_COMPOSITION_TEST_SUITE(Suite, \
CompositionType) \
INSTANTIATE_TYPED_TEST_SUITE_P(Suite, MultiCompositionInterruptibilityTest, \
CompositionType); \
INSTANTIATE_TYPED_TEST_SUITE_P(Suite, MultiCompositionRunsWhenDisabledTest, \
CompositionType);
} // namespace multi
} // namespace frc2

View File

@@ -3,6 +3,7 @@
// the WPILib BSD license file in the root directory of this project.
#include "CommandTestBase.h"
#include "CompositionTestBase.h"
#include "frc2/command/InstantCommand.h"
#include "frc2/command/ParallelCommandGroup.h"
#include "frc2/command/WaitUntilCommand.h"
@@ -115,3 +116,6 @@ TEST_F(ParallelCommandGroupTest, ParallelGroupRequirement) {
EXPECT_TRUE(scheduler.IsScheduled(&command3));
EXPECT_FALSE(scheduler.IsScheduled(&group));
}
INSTANTIATE_MULTI_COMMAND_COMPOSITION_TEST_SUITE(ParallelCommandGroupTest,
ParallelCommandGroup);

View File

@@ -3,6 +3,7 @@
// the WPILib BSD license file in the root directory of this project.
#include "CommandTestBase.h"
#include "CompositionTestBase.h"
#include "frc2/command/InstantCommand.h"
#include "frc2/command/ParallelDeadlineGroup.h"
#include "frc2/command/WaitUntilCommand.h"
@@ -131,3 +132,23 @@ TEST_F(ParallelDeadlineGroupTest, ParallelDeadlineRequirement) {
EXPECT_TRUE(scheduler.IsScheduled(&command3));
EXPECT_FALSE(scheduler.IsScheduled(&group));
}
class TestableDeadlineCommand : public ParallelDeadlineGroup {
static ParallelDeadlineGroup ToCommand(
std::vector<std::unique_ptr<Command>>&& commands) {
std::vector<std::unique_ptr<Command>> vec;
std::unique_ptr<Command> deadline = std::move(commands[0]);
for (unsigned int i = 1; i < commands.size(); i++) {
vec.emplace_back(std::move(commands[i]));
}
return ParallelDeadlineGroup(std::move(deadline), std::move(vec));
}
public:
explicit TestableDeadlineCommand(
std::vector<std::unique_ptr<Command>>&& commands)
: ParallelDeadlineGroup(ToCommand(std::move(commands))) {}
};
INSTANTIATE_MULTI_COMMAND_COMPOSITION_TEST_SUITE(ParallelDeadlineGroupTest,
TestableDeadlineCommand);

View File

@@ -3,6 +3,7 @@
// the WPILib BSD license file in the root directory of this project.
#include "CommandTestBase.h"
#include "CompositionTestBase.h"
#include "frc2/command/InstantCommand.h"
#include "frc2/command/ParallelRaceGroup.h"
#include "frc2/command/SequentialCommandGroup.h"
@@ -202,3 +203,6 @@ TEST_F(ParallelRaceGroupTest, ParallelRaceScheduleTwice) {
EXPECT_FALSE(scheduler.IsScheduled(&group));
}
INSTANTIATE_MULTI_COMMAND_COMPOSITION_TEST_SUITE(ParallelRaceGroupTest,
ParallelRaceGroup);

View File

@@ -3,8 +3,9 @@
// the WPILib BSD license file in the root directory of this project.
#include "CommandTestBase.h"
#include "frc2/command/Commands.h"
#include "CompositionTestBase.h"
#include "frc2/command/FunctionalCommand.h"
#include "frc2/command/RepeatCommand.h"
using namespace frc2;
class RepeatCommandTest : public CommandTestBase {};
@@ -61,30 +62,5 @@ TEST_F(RepeatCommandTest, CallsMethodsCorrectly) {
EXPECT_EQ(1, endCounter);
}
class RepeatCommandInterruptibilityTest
: public CommandTestBaseWithParam<Command::InterruptionBehavior> {};
TEST_P(RepeatCommandInterruptibilityTest, Interruptibility) {
CommandPtr command = cmd::WaitUntil([] { return false; })
.WithInterruptBehavior(GetParam())
.Repeatedly();
EXPECT_EQ(GetParam(), command.get()->GetInterruptionBehavior());
}
INSTANTIATE_TEST_SUITE_P(
RepeatCommandTests, RepeatCommandInterruptibilityTest,
testing::Values(Command::InterruptionBehavior::kCancelIncoming,
Command::InterruptionBehavior::kCancelSelf));
class RepeatCommandRunsWhenDisabledTest
: public CommandTestBaseWithParam<bool> {};
TEST_P(RepeatCommandRunsWhenDisabledTest, RunsWhenDisabled) {
CommandPtr command = cmd::WaitUntil([] { return false; })
.IgnoringDisable(GetParam())
.Repeatedly();
EXPECT_EQ(GetParam(), command.get()->RunsWhenDisabled());
}
INSTANTIATE_TEST_SUITE_P(RepeatCommandTests, RepeatCommandRunsWhenDisabledTest,
testing::Bool());
INSTANTIATE_SINGLE_COMMAND_COMPOSITION_TEST_SUITE(RepeatCommandTest,
RepeatCommand);

View File

@@ -3,6 +3,7 @@
// the WPILib BSD license file in the root directory of this project.
#include "CommandTestBase.h"
#include "CompositionTestBase.h"
#include "frc2/command/ConditionalCommand.h"
#include "frc2/command/InstantCommand.h"
#include "frc2/command/SelectCommand.h"
@@ -57,3 +58,24 @@ TEST_F(SelectCommandTest, SelectCommandRequirement) {
EXPECT_TRUE(scheduler.IsScheduled(&command3));
EXPECT_FALSE(scheduler.IsScheduled(&select));
}
class TestableSelectCommand : public SelectCommand<int> {
static std::vector<std::pair<int, std::unique_ptr<Command>>> ZipVector(
std::vector<std::unique_ptr<Command>>&& commands) {
std::vector<std::pair<int, std::unique_ptr<Command>>> vec;
int index = 0;
for (auto&& command : commands) {
vec.emplace_back(std::make_pair(index, std::move(command)));
index++;
}
return vec;
}
public:
explicit TestableSelectCommand(
std::vector<std::unique_ptr<Command>>&& commands)
: SelectCommand([] { return 0; }, ZipVector(std::move(commands))) {}
};
INSTANTIATE_MULTI_COMMAND_COMPOSITION_TEST_SUITE(SelectCommandTest,
TestableSelectCommand);

View File

@@ -3,6 +3,7 @@
// the WPILib BSD license file in the root directory of this project.
#include "CommandTestBase.h"
#include "CompositionTestBase.h"
#include "frc2/command/InstantCommand.h"
#include "frc2/command/SequentialCommandGroup.h"
#include "frc2/command/WaitUntilCommand.h"
@@ -132,3 +133,6 @@ TEST_F(SequentialCommandGroupTest, SequentialGroupRequirement) {
EXPECT_TRUE(scheduler.IsScheduled(&command3));
EXPECT_FALSE(scheduler.IsScheduled(&group));
}
INSTANTIATE_MULTI_COMMAND_COMPOSITION_TEST_SUITE(SequentialCommandGroupTest,
SequentialCommandGroup);