Skip to content

Commit

Permalink
Add tests for overload resolution and AddRequirements() semantics
Browse files Browse the repository at this point in the history
  • Loading branch information
KangarooKoala committed Aug 24, 2023
1 parent b45879d commit 2ada82b
Showing 1 changed file with 158 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// 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.

#include <wpi/array.h>

#include "CommandTestBase.h"
#include "frc2/command/Command.h"
#include "frc2/command/RunCommand.h"

using namespace frc2;

class OverloadResolver {
public:
OverloadResolver(std::function<void()> requirementsOverload,
std::function<void()> smallSetOverload,
std::function<void()> subsystemOverload)
: m_requirementsOverload{requirementsOverload},
m_smallSetOverload{smallSetOverload},
m_subsystemOverload{subsystemOverload} {}

void AddRequirements(Requirements requirements) { m_requirementsOverload(); }

void AddRequirements(wpi::SmallSet<Subsystem*, 4> requirements) {
m_smallSetOverload();
}

void AddRequirements(Subsystem* requirement) { m_subsystemOverload(); }

private:
std::function<void()> m_requirementsOverload;
std::function<void()> m_smallSetOverload;
std::function<void()> m_subsystemOverload;
};

TEST(AddRequirementsTest, OverloadResolution) {
TestSubsystem requirement;

int requirementsOverloadCounter = 0;
int smallSetOverloadCounter = 0;
int subsystemOverloadCounter = 0;

OverloadResolver overloadResolver([&] { requirementsOverloadCounter++; },
[&] { smallSetOverloadCounter++; },
[&] { subsystemOverloadCounter++; });

// Check initializer list
// Have to use two elements to select the Requirements overload instead of the
// Subsystem* overload
overloadResolver.AddRequirements({&requirement, &requirement});
EXPECT_EQ(requirementsOverloadCounter, 1);
EXPECT_EQ(smallSetOverloadCounter, 0);
EXPECT_EQ(subsystemOverloadCounter, 0);

// Check span
std::span<Subsystem* const> requirementsSpan;

overloadResolver.AddRequirements(requirementsSpan);
EXPECT_EQ(requirementsOverloadCounter, 2);
EXPECT_EQ(smallSetOverloadCounter, 0);
EXPECT_EQ(subsystemOverloadCounter, 0);

// Check wpi::SmallSet
wpi::SmallSet<Subsystem*, 4> requirementsSet;

overloadResolver.AddRequirements(requirementsSet);
EXPECT_EQ(requirementsOverloadCounter, 2);
EXPECT_EQ(smallSetOverloadCounter, 1);
EXPECT_EQ(subsystemOverloadCounter, 0);

// Check subsystem pointer
overloadResolver.AddRequirements(&requirement);
EXPECT_EQ(requirementsOverloadCounter, 2);
EXPECT_EQ(smallSetOverloadCounter, 1);
EXPECT_EQ(subsystemOverloadCounter, 1);
}

TEST(AddRequirementsTest, InitializerListSemantics) {
TestSubsystem requirement1;
TestSubsystem requirement2;

RunCommand command([] {});
command.AddRequirements({&requirement1, &requirement2});
EXPECT_TRUE(command.HasRequirement(&requirement1));
EXPECT_TRUE(command.HasRequirement(&requirement2));
EXPECT_EQ(command.GetRequirements().size(), 2u);
}

TEST(AddRequirementsTest, InitializerListDuplicatesSemantics) {
TestSubsystem requirement;

RunCommand command([] {});
command.AddRequirements({&requirement, &requirement});
EXPECT_TRUE(command.HasRequirement(&requirement));
EXPECT_EQ(command.GetRequirements().size(), 1u);
}

TEST(AddRequirementsTest, SpanSemantics) {
TestSubsystem requirement1;
TestSubsystem requirement2;

wpi::array<Subsystem* const, 2> requirementsArray(&requirement1,
&requirement2);

RunCommand command([] {});
command.AddRequirements(std::span{requirementsArray});
EXPECT_TRUE(command.HasRequirement(&requirement1));
EXPECT_TRUE(command.HasRequirement(&requirement2));
EXPECT_EQ(command.GetRequirements().size(), 2u);
}

TEST(AddRequirementsTest, SpanDuplicatesSemantics) {
TestSubsystem requirement;

wpi::array<Subsystem* const, 2> requirementsArray(&requirement, &requirement);

RunCommand command([] {});
command.AddRequirements(std::span{requirementsArray});
EXPECT_TRUE(command.HasRequirement(&requirement));
EXPECT_EQ(command.GetRequirements().size(), 1u);
}

TEST(AddRequirementsTest, SmallSetSemantics) {
TestSubsystem requirement1;
TestSubsystem requirement2;

wpi::SmallSet<Subsystem*, 4> requirementsSet;
requirementsSet.insert(&requirement1);
requirementsSet.insert(&requirement2);

RunCommand command([] {});
command.AddRequirements(requirementsSet);
EXPECT_TRUE(command.HasRequirement(&requirement1));
EXPECT_TRUE(command.HasRequirement(&requirement2));
EXPECT_EQ(command.GetRequirements().size(), 2u);
}

TEST(AddRequirementsTest, SubsystemPointerSemantics) {
TestSubsystem requirement1;
TestSubsystem requirement2;

RunCommand command([] {});
command.AddRequirements(&requirement1);
command.AddRequirements(&requirement2);
EXPECT_TRUE(command.HasRequirement(&requirement1));
EXPECT_TRUE(command.HasRequirement(&requirement2));
EXPECT_EQ(command.GetRequirements().size(), 2u);
}

TEST(AddRequirementsTest, SubsystemPointerDuplicatesSemantics) {
TestSubsystem requirement;

RunCommand command([] {});
command.AddRequirements(&requirement);
command.AddRequirements(&requirement);
EXPECT_TRUE(command.HasRequirement(&requirement));
EXPECT_EQ(command.GetRequirements().size(), 1u);
}

0 comments on commit 2ada82b

Please sign in to comment.