[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

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