Skip to content

Commit

Permalink
Feature/git module (#206)
Browse files Browse the repository at this point in the history
* git module implemented

* unit tests added

* merge conflict resolved

* clang pipeline hotfix

* apple_clang pipeline hotfix

---------

Co-authored-by: Peter Mento <[email protected]>
Co-authored-by: Michał Cieślar <[email protected]>
  • Loading branch information
3 people authored Oct 15, 2023
1 parent 2b8d28f commit bdcced6
Show file tree
Hide file tree
Showing 4 changed files with 302 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ set(FAKER_SOURCES
src/modules/database/Database.cpp
src/modules/music/Music.cpp
src/modules/movie/Movie.cpp
src/modules/git/Git.cpp
src/modules/hacker/Hacker.cpp
src/modules/sport/Sport.cpp
src/modules/videoGame/VideoGame.cpp
Expand Down Expand Up @@ -72,6 +73,7 @@ set(FAKER_UT_SOURCES
src/modules/database/DatabaseTest.cpp
src/modules/music/MusicTest.cpp
src/modules/movie/MovieTest.cpp
src/modules/git/GitTest.cpp
src/modules/hacker/HackerTest.cpp
src/modules/sport/SportTest.cpp
src/modules/videoGame/VideoGameTest.cpp
Expand Down
79 changes: 79 additions & 0 deletions include/faker-cxx/Git.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#pragma once

#include <optional>
#include <string>

#include "faker-cxx/types/Language.h"

namespace faker
{
class Git
{
public:
/**
* @brief Returns a random branch name.
*
* @param maxIssueNum The maximum issue number in branch name. Defaults to `100`.
* @returns Branch name.
*
* @code
* Git::branch() // "capitalize-bus"
* @endcode
*/
static std::string branch(unsigned maxIssueNum = 100);

/**
* @brief Generates a random date in form of string.
*
* @param years The range of years the date may be in the past. Defaults to `15`.
* @returns Commit date.
*
* @code
* Git::commitDate() // "Mon Jan 17 15:05:53 2022 +1100"
* @endcode
*/
static std::string commitDate(unsigned years = 15);

/**
* @brief Generates a random commit entry in form of string.
*
* @param dateYears The range of years the date may be in the past. Defaults to `15`.
* @param shaLength The length of output SHA hash. Defaults to `40`.
* @param language The language set for name generating. Defaults to `English` (could be random, if there was a random language generator).
* @returns Commit entry.
*
* @code
* Git::commitEntry() // "commit 9cbc41bb8ce0438c8de9cb25a1c6ad33441d8aca
Author: Rachel McLaughlin [email protected]
Date: Mon Jan 17 15:05:53 2022 +1100
spawn polyp"
* @endcode
*/
static std::string commitEntry(std::optional<unsigned> dateYears = std::nullopt, std::optional<unsigned> shaLength = std::nullopt, Language language = Language::English);

/**
* @brief Generates a random commit message.
*
* @returns Commit message.
*
* @code
* Git::commitMessage() // "spawn polyp"
* @endcode
*/
static std::string commitMessage();

/**
* @brief Returns a random SHA hash.
*
* @param length The length of output SHA hash. Defaults to `40`.
*
* @returns SHA hash.
*
* @code
* Git::commitSha() // "9cbc41bb8ce0438c8de9cb25a1c6ad33441d8aca"
* @endcode
*/
static std::string commitSha(unsigned length = 40);
};
}
120 changes: 120 additions & 0 deletions src/modules/git/Git.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#include "faker-cxx/Git.h"

#include <string>

#include "faker-cxx/Word.h"
#include "faker-cxx/Number.h"
#include "faker-cxx/Date.h"
#include "faker-cxx/String.h"
#include "faker-cxx/Person.h"
#include "faker-cxx/Internet.h"
#include "faker-cxx/types/Language.h"
#include "../../common/StringHelper.h"
#include "../date/data/MonthNames.h"
#include "fmt/format.h"

namespace faker
{

std::string Git::branch(unsigned maxIssueNum)
{
switch (Number::integer(1, 3))
{
case 1:
return fmt::format("{}-{}", Word::verb(), Word::noun());
case 2:
return fmt::format("{}-{}-{}", Word::verb(), Word::adjective(), Word::noun());
default:
return fmt::format("{}-{}-{}-{}", Number::integer(unsigned (1), maxIssueNum), Word::verb(), Word::adjective(), Word::noun());
}
}

std::string Git::commitDate(unsigned years)
{
std::string date = Date::pastDate(int(years));
std::string outputDate = Date::weekdayAbbreviatedName();

std::vector<std::string> dateSplit = StringHelper::split(date, "-");
std::string year = dateSplit[0];
std::string month = dateSplit[1];
std::string rest = dateSplit[2];

std::vector<std::string> restSplit = StringHelper::split(rest, "T");
std::string day = restSplit[0];

std::string time = StringHelper::split(restSplit[1], "Z")[0];

int timeZone = Number::integer(0, 12);
std::string timeZoneString;
if (Number::integer(0, 1))
{
timeZoneString += "-";
}
else
{
timeZoneString += "+";
}

if (timeZone <= 9)
{
timeZoneString += "0";
}

timeZoneString += std::to_string(timeZone * 100);
if (!timeZone)
{
timeZoneString += "00";
}


return fmt::format("{} {} {} {} {} {}", Date::weekdayAbbreviatedName(), monthAbbreviatedNames[size_t(std::stoi(month)-1)], day, time, year, timeZoneString);
}

std::string Git::commitEntry(std::optional<unsigned> dateYears, std::optional<unsigned> shaLength, Language language)
{
std::string entry = "commit ";
if (shaLength)
{
entry += commitSha(shaLength.emplace());
}
else
{
entry += commitSha();
}

std::string firstName = Person::firstName(language);
std::string lastName = Person::lastName(language);
entry += "\nAuthor: " + firstName + " " + lastName + " " + Internet::email(firstName, lastName) + "\nDate: ";
if (dateYears)
{
entry += commitDate(dateYears.emplace());
}
else
{
entry += commitDate();
}

entry += "\n\n\t" + commitMessage();
return entry;
}

std::string Git::commitMessage()
{
switch (Number::integer(1, 4))
{
case 1:
return fmt::format("{} {}", Word::verb(), Word::noun());
case 2:
return fmt::format("{} {} {}", Word::verb(), Word::adjective(), Word::noun());
case 3:
return fmt::format("{} {} {}", Word::verb(), Word::noun(), Word::adverb());
default:
return fmt::format("{} {} {} {}", Word::verb(), Word::adjective(), Word::noun(), Word::adverb());
}
}

std::string Git::commitSha(unsigned length)
{
return faker::String::hexadecimal(length, HexCasing::Lower, HexPrefix::None);
}
}
101 changes: 101 additions & 0 deletions src/modules/git/GitTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include "faker-cxx/Git.h"

#include <algorithm>

#include "gtest/gtest.h"

#include <string>
#include <regex>
#include <iostream>

#include "faker-cxx/Word.h"
#include "faker-cxx/Number.h"
#include "faker-cxx/Date.h"
#include "faker-cxx/String.h"
#include "faker-cxx/Person.h"
#include "faker-cxx/Internet.h"
#include "faker-cxx/types/Language.h"
#include "../../common/StringHelper.h"
#include "../date/data/MonthNames.h"

using namespace ::testing;
using namespace faker;

class GitTest : public Test
{
public:
inline static const std::string DATE_REGEX = "[A-Z][a-z]{2} [A-Z][a-z]{2,3} (([0-2][0-9])|(3[0-1])) (([0-1][0-9])|(2[0-4])):[0-5][0-9]:[0-5][0-9] [1-2][0-9]{3} (-|\\+)((0[0-9])|(1[0-2]))00";
inline static const std::string MESSAGE_REGEX = R"([a-zA-Z]+(\-[a-zA-Z]+)* ([a-zA-Z\-]+(\-[a-zA-Z]+)*\s)*[a-zA-Z\-]+(\-[a-zA-Z]+)*)";

static std::string generateShaRegex(unsigned length) ;
static std::string generateShaRegex();
};

std::string GitTest::generateShaRegex(unsigned length) {
return "[0-9a-fA-F]{" + std::to_string(length) + "}";
}

std::string GitTest::generateShaRegex() {
return "[0-9a-fA-F]+";
}

TEST_F(GitTest, shouldGenerateBranch)
{
const auto branch = Git::branch();
unsigned long branchSplit = faker::StringHelper::split(branch, "-").size();
std::cout << branch << " | " << branchSplit << std::endl;

ASSERT_TRUE(2 <= branchSplit && branchSplit <= 7);
}

TEST_F(GitTest, branchIssueNumTest)
{
unsigned testValue = unsigned (faker::Number::integer(2, 100));
std::vector<std::string> branch = faker::StringHelper::split(Git::branch(testValue), "-");
bool numberAtFront = false;
int number;
while (!numberAtFront)
{
branch = faker::StringHelper::split(Git::branch(testValue), "-");
try
{
number = std::stoi(branch[0]);
numberAtFront = true;
}
catch (...)
{
continue;
}
}

ASSERT_TRUE(1 <= number && number <= int(testValue));
}

TEST_F(GitTest, shouldGenerateCommitDate)
{
const std::regex dateRegex("^" + GitTest::DATE_REGEX + "$");
ASSERT_TRUE(std::regex_match(Git::commitDate(), dateRegex));
}

TEST_F(GitTest, shouldGenerateCommitEntry)
{
const std::regex entryRegex("^commit " + GitTest::generateShaRegex() +
"\nAuthor: [A-Z][a-zA-Z]+ [A-Z][a-zA-Z]+ .+@[0-9a-zA-Z]+\\.[0-9a-zA-Z]+\nDate: " +
GitTest::DATE_REGEX + "\n\n\t" + GitTest::MESSAGE_REGEX + "$");
ASSERT_TRUE(std::regex_match(Git::commitEntry(), entryRegex));
}

TEST_F(GitTest, shouldGenerateCommitMessage)
{
const std::regex messageRegex("^" + GitTest::MESSAGE_REGEX + "$");
std::string temp = Git::commitMessage();
std::cout << temp << std::endl;
ASSERT_TRUE(std::regex_match(temp, messageRegex));
}

TEST_F(GitTest, shouldGenerateCommitSha)
{
unsigned length = 40;
const std::regex shaRegex("^" + GitTest::generateShaRegex(length) + "$");
ASSERT_TRUE(std::regex_match(Git::commitSha(length), shaRegex));
}

0 comments on commit bdcced6

Please sign in to comment.