Compare commits

...

9 Commits
v0.1.0 ... main

Author SHA1 Message Date
jorenchik
9564021612 removed not reached comment 2024-04-12 21:51:34 +03:00
jorenchik
523e4e6feb fix: linked modules and validation to tests 2024-04-12 21:50:55 +03:00
jorenchik
455105351c feat: white box tests 2024-04-12 21:24:30 +03:00
0563475e29 docs: fix readme 2024-03-15 13:54:06 +02:00
Kristofers Solo
3119cd0fd2 chore(version): bump up the version
- New version: 0.1.1
- Add project name
2024-03-14 12:51:49 +02:00
Kristofers Solo
90c78eaa04 refactor: add static to functions
- Update functions to be declared as static for improved code clarity
- No functional changes made, only internal refactoring
2024-03-14 12:49:58 +02:00
Jorens Shtekels
7f0a51f5b8 docs: remove usage 2024-03-14 09:00:59 +02:00
Jorens Shtekels
9c9929565b
Merge pull request #16 from jorenchik/develop
top-down rule in validation.cc
2024-03-14 08:56:50 +02:00
Jorens Shtekels
099dd2e94b refactor[validation func]: restructured the order of function for the top down rule
Not that important, but it's more nice :3
2024-03-14 08:55:41 +02:00
10 changed files with 167 additions and 54 deletions

View File

@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.1...3.28)
project(
Template
VERSION 0.1.0
Mafia
VERSION 0.1.1
LANGUAGES CXX)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
@ -23,6 +23,8 @@ target_link_libraries(validation PRIVATE modules)
target_include_directories(main PUBLIC "${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/modules")
target_link_libraries(test_validation PRIVATE validation)
target_link_libraries(test_validation PRIVATE modules)
target_include_directories(
test_validation PUBLIC "${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/modules")

View File

@ -14,8 +14,6 @@ Direktorija `modules` ir saistīta ar datu sagatavošanu pirms funkcijas
izsaukuma. `test_validation.cc` ir viens testa fails, kas satur testus.
[GTest](https://github.com/google/googletest) tiek izmantots testiem.
## Lietojums
## Kompilācija uz Linux un MacOS
Kompilācijai operētājsistēmā Linux ir nepieciešams cmake un

View File

@ -16,8 +16,6 @@ Directory `modules` is concerned with preparation of data prior to the function
call. `test_validation.cc` is a single test file that contain the tests.
[GTest](https://github.com/google/googletest) is used for tests.
## Usage
## Compilation on Linux and MacOS
Compilation on Linux and MacOS requires cmake and CXX compiler (e.g., g++).
@ -40,7 +38,7 @@ You know what to do.
### ninja
```bash
cmake -G Ninja -B
cmake -G Ninja -B buld
# or
# cmake -G Ninja -B build -D CMAKE_CXX_COMPILER=g++-13 # MacOS
cd build

View File

@ -4,6 +4,8 @@
#include <string>
Player::Player() {}
Player::Player(uint32_t id, std::string username, Role role, PlayerStatus status):
id(id),
username(username),

View File

@ -18,5 +18,6 @@ struct Player {
PlayerStatus status;
Player(uint32_t id, std::string username, Role role, PlayerStatus status);
Player();
bool operator==(const Player &other) const;
};

View File

@ -3,6 +3,9 @@
#include <initializer_list>
#include <vector>
Role::Role(){
}
Role::Role(std::initializer_list<Action> actions): Role(std::vector<Action>(actions)) {
}

View File

@ -9,4 +9,5 @@ struct Role {
std::vector<Action> actions;
explicit Role(std::vector<Action> actions);
Role(std::initializer_list<Action> actions);
Role();
};

View File

@ -1,7 +1,107 @@
#include "gtest/gtest.h"
#include "modules/role.hh"
#include "modules/room.hh"
#include "validation.hh"
TEST(ExampleTest, Example) {
EXPECT_EQ(1, 1);
#include "gtest/gtest.h"
#include <string>
struct TestFixtures {
static const Action kill;
static const Action heal;
static const Action vote;
static Role role1;
static Event event1;
static Event event2;
static Event event3;
static std::vector<Event> relatedEvents;
static Player player1;
static Player player2;
static Room room1;
};
const Action TestFixtures::kill = Action("kill", true);
const Action TestFixtures::heal = Action("heal", true);
const Action TestFixtures::vote = Action("vote", true);
Role TestFixtures::role1 = Role({vote, kill, heal});
Event TestFixtures::event1 = Event("Event 1", 1710087355, 1, true, {}, {});
Event TestFixtures::event2 = Event("Event 2", 1710087363, 1, true, {kill}, {});
Event TestFixtures::event3 = Event("Event 3", 1710087369, 1, true, {}, {kill});
std::vector<Event> TestFixtures::relatedEvents = std::vector<Event>({event2, event3});
Player TestFixtures::player1 = Player(69, "player1", role1, PlayerStatus::Alive);
Player TestFixtures::player2 = Player(420, "player2", role1, PlayerStatus::Alive);
Room TestFixtures::room1 =
Room(1, "Room 1", 1710087364, RoomStatus::InProgress, std::vector<Player> {player1, player2});
TEST(ValidateActionBranchDecisionTests, ReachesNoActorReturn) {
ValidationStatus status = validate_action(
nullptr, &TestFixtures::kill, &TestFixtures::room1, &TestFixtures::relatedEvents, &TestFixtures::player2);
ASSERT_EQ(ValidationStatus::NoActor, status);
}
TEST(ValidateActionBranchDecisionTests, ReachesNoActionReturn) {
ValidationStatus status = validate_action(
&TestFixtures::player1, nullptr, &TestFixtures::room1, &TestFixtures::relatedEvents, &TestFixtures::player2);
ASSERT_EQ(ValidationStatus::NoAction, status);
}
TEST(ValidateActionBranchDecisionTests, ReachesNoRoomReturn) {
ValidationStatus status = validate_action(
&TestFixtures::player1, &TestFixtures::kill, nullptr, &TestFixtures::relatedEvents, &TestFixtures::player2);
ASSERT_EQ(ValidationStatus::NoRoom, status);
}
TEST(ValidateActionBranchDecisionTests, ReachesNoRelatedEventsReturn) {
ValidationStatus status = validate_action(
&TestFixtures::player1, &TestFixtures::kill, &TestFixtures::room1, nullptr, &TestFixtures::player2);
ASSERT_EQ(ValidationStatus::NoRelatedEvents, status);
}
TEST(ValidateActionBranchDecisionTests, ReachesNotInTheRoomReturn) {
Room emptyRoom = Room(2, "Room 4", 1710087394, RoomStatus::InProgress, {});
ValidationStatus status = validate_action(
&TestFixtures::player1, &TestFixtures::kill, &emptyRoom, &TestFixtures::relatedEvents, &TestFixtures::player2);
ASSERT_EQ(ValidationStatus::PlayerNotInRoom, status);
}
TEST(ValidateActionBranchDecisionTests, ReachesNoTargetReturn) {
ValidationStatus status = validate_action(
&TestFixtures::player1, &TestFixtures::kill, &TestFixtures::room1, &TestFixtures::relatedEvents, nullptr);
ASSERT_EQ(ValidationStatus::NoTargetPlayerSpecified, status);
}
TEST(ValidateActionBranchDecisionTests, ReachesGameNotInProgressReturn) {
Room roomNotInProgress =
Room(2, "Room 5", 1710087394, RoomStatus::Ended, {TestFixtures::player1, TestFixtures::player2});
ValidationStatus status = validate_action(&TestFixtures::player1,
&TestFixtures::kill,
&roomNotInProgress,
&TestFixtures::relatedEvents,
&TestFixtures::player2);
ASSERT_EQ(ValidationStatus::RoomNotInProgress, status);
}
TEST(ValidateActionBranchDecisionTests, ReachesActionProhibitedReturn) {
std::vector<Event> noAllowingEvent = std::vector<Event>();
ValidationStatus status = validate_action(
&TestFixtures::player1, &TestFixtures::kill, &TestFixtures::room1, &noAllowingEvent, &TestFixtures::player2);
ASSERT_EQ(ValidationStatus::ActionProhibited, status);
}
TEST(ValidateActionBranchDecisionTests, ReachesActionDoesntBelongToTheRoleReturn) {
Role roleWithNoMatchingAction = Role({TestFixtures::vote, TestFixtures::heal});
Player player1 = Player(69, "player1", roleWithNoMatchingAction, PlayerStatus::Alive);
ValidationStatus status = validate_action(
&player1, &TestFixtures::kill, &TestFixtures::room1, &TestFixtures::relatedEvents, &TestFixtures::player2);
ASSERT_EQ(ValidationStatus::ActionDoesNotBelongToRole, status);
}
TEST(ValidateActionBranchDecisionTests, ReachesNoTopLevelReturn) {
ValidationStatus status = validate_action(&TestFixtures::player1,
&TestFixtures::kill,
&TestFixtures::room1,
&TestFixtures::relatedEvents,
&TestFixtures::player2);
ASSERT_EQ(ValidationStatus::ActionValid, status);
}
int main(int argc, char *argv[]) {

View File

@ -9,48 +9,9 @@
#include <algorithm>
#include <string>
/**
* Check if a player belongs to a given room.
*
* @param player Pointer to the player object.
* @param room Pointer to the room object.
* @return `true` if the player belongs to the room, otherwise `false`.
*/
bool player_belongs_to_room(const Player *player, const Room *room) {
return std::find(room->players.begin(), room->players.end(), *player) != room->players.end();
}
/**
* Check if an action belongs to a given role.
*
* @param role Pointer to the role object.
* @param action Pointer to the action object.
* @return `true` if the action belongs to the role, otherwise `false`.
*/
bool action_belongs_to_role(const Role *role, const Action *action) {
return std::find(role->actions.begin(), role->actions.end(), *action) != role->actions.end();
}
/**
* Check if an action is allowed based on relevant events.
*
* @param action Pointer to the action object.
* @param relevantEvents Pointer to the vector of relevant events.
* @return `true` if the action is allowed, otherwise `false`.
*/
bool is_action_allowed(const Action *action, std::vector<Event> *relevant_events) {
bool allowed = false; // Actions are disabled by default
std::sort(relevant_events->begin(), relevant_events->end());
for (const auto &event : *relevant_events) {
if (std::find(event.prohibits.begin(), event.prohibits.end(), *action) != event.prohibits.end()) {
allowed = false;
}
if (std::find(event.allows.begin(), event.allows.end(), *action) != event.allows.end()) {
allowed = true;
}
}
return allowed;
}
static bool player_belongs_to_room(const Player *player, const Room *room);
static bool action_belongs_to_role(const Role *role, const Action *action);
static bool is_action_allowed(const Action *action, std::vector<Event> *relevant_events);
/**
* Validate if an action is valid for a player in a room based on related events.
@ -98,6 +59,55 @@ ValidationStatus validate_action(
return ValidationStatus::ActionValid;
}
/**
* Check if a player belongs to a given room.
*
* @param player Pointer to the player object.
* @param room Pointer to the room object.
* @return `true` if the player belongs to the room, otherwise `false`.
*/
static bool player_belongs_to_room(const Player *player, const Room *room) {
return std::find(room->players.begin(), room->players.end(), *player) != room->players.end();
}
/**
* Check if an action belongs to a given role.
*
* @param role Pointer to the role object.
* @param action Pointer to the action object.
* @return `true` if the action belongs to the role, otherwise `false`.
*/
static bool action_belongs_to_role(const Role *role, const Action *action) {
return std::find(role->actions.begin(), role->actions.end(), *action) != role->actions.end();
}
/**
* Check if an action is allowed based on relevant events.
*
* @param action Pointer to the action object.
* @param relevantEvents Pointer to the vector of relevant events.
* @return `true` if the action is allowed, otherwise `false`.
*/
static bool is_action_allowed(const Action *action, std::vector<Event> *relevant_events) {
bool allowed = false; // Actions are disabled by default
std::sort(relevant_events->begin(), relevant_events->end());
for (const auto &event : *relevant_events) {
if (std::find(event.prohibits.begin(), event.prohibits.end(), *action) != event.prohibits.end()) {
allowed = false;
}
if (std::find(event.allows.begin(), event.allows.end(), *action) != event.allows.end()) {
allowed = true;
}
}
return allowed;
}
/**
* Convert a ValidationStatus enum value to its corresponding string representation.
*
* @param status The ValidationStatus enum value to convert.
* @return The string representation of the given ValidationStatus.
*/
std::string ValidationStatusUtils::to_string(ValidationStatus status) {
switch (status) {
case ValidationStatus::PlayerNotInRoom: return "player not in room";

View File

@ -20,8 +20,6 @@ enum class ValidationStatus {
ActionValid,
};
std::string validation_status_to_string(ValidationStatus status);
ValidationStatus
validate_action(Player *actor, const Action *action, Room *room, std::vector<Event> *relatedEvents, Player *target);