Skip to content
Open

Dz3 #11

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6730550
Red: Initial test - ordinary year
vladyslavkv Oct 4, 2018
18c2904
Green: Ordinary year
vladyslavkv Oct 4, 2018
787f8bf
Red: Leap year
vladyslavkv Oct 4, 2018
a117721
Really Red: second ordinary year
vladyslavkv Oct 4, 2018
32be5f6
Green: second ordinary year
vladyslavkv Oct 4, 2018
9b13cff
First refactoring
vladyslavkv Oct 4, 2018
20cf474
Red: ordinary year derived by 100
vladyslavkv Oct 4, 2018
f7b8aa9
Green: ordinary year derived by 100
vladyslavkv Oct 4, 2018
72f75c3
Red: leap year derived by 400
vladyslavkv Oct 4, 2018
ccc746a
Green: leap year derived by 400
vladyslavkv Oct 4, 2018
2de5f43
Second Refactoring
vladyslavkv Oct 4, 2018
25d20eb
Green: acceptance test
vladyslavkv Oct 4, 2018
71de85f
test list
vladyslavkv Oct 25, 2018
dbcb10f
red
vladyslavkv Oct 25, 2018
01b40fd
green
vladyslavkv Oct 25, 2018
3cda13b
red
vladyslavkv Oct 25, 2018
57456a1
green
vladyslavkv Oct 25, 2018
d537457
red
vladyslavkv Oct 25, 2018
68d0a9d
green
vladyslavkv Oct 25, 2018
40c342a
Fixed test conditions
vladyslavkv Oct 25, 2018
08b7d88
red
vladyslavkv Oct 25, 2018
7604a4c
green
vladyslavkv Oct 25, 2018
37bc771
created mock + green test
vladyslavkv Oct 25, 2018
2a5b8a4
red
vladyslavkv Oct 28, 2018
c5de9a6
fixed arch
vladyslavkv Oct 28, 2018
375283d
green
vladyslavkv Oct 28, 2018
38adb5e
red
vladyslavkv Oct 28, 2018
87aa4dc
green
vladyslavkv Oct 28, 2018
b4f1005
red
vladyslavkv Oct 28, 2018
a259c1e
green
vladyslavkv Oct 28, 2018
fc096f7
red
vladyslavkv Oct 28, 2018
d5a89d1
green
vladyslavkv Oct 28, 2018
566be7a
red
vladyslavkv Oct 28, 2018
5ac2e8e
green
vladyslavkv Oct 28, 2018
dd17fa5
red
vladyslavkv Oct 28, 2018
28b7341
green
vladyslavkv Oct 28, 2018
1f6b60c
red
vladyslavkv Oct 29, 2018
39d087a
green
vladyslavkv Oct 29, 2018
80415e0
red
vladyslavkv Oct 29, 2018
84d911c
green
vladyslavkv Oct 29, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions tdd_intro/homework/01_leap_year/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,54 @@ If your language provides a method in the standard library that does this look-u
*/

#include <gtest/gtest.h>

bool IsLeapYear(int year)
{
return (year % 100 == 0) ? (year % 400 == 0) : (year % 4 == 0);
}

TEST(YearTest, OrdinaryYear)
{
EXPECT_FALSE(IsLeapYear(1997));
}

TEST(YearTest, OrdinaryYearSecond)
{
EXPECT_FALSE(IsLeapYear(1995));
}

TEST(YearTest, LeapYear)
{
EXPECT_TRUE(IsLeapYear(1996));
}

TEST(YearTest, OrdinaryYearDerivedBy100)
{
EXPECT_FALSE(IsLeapYear(1900));
}

TEST(YearTest, OrdinaryYearDerivedBy400)
{
EXPECT_TRUE(IsLeapYear(2000));
}

TEST(YearTest, AcceptenceTest)
{
EXPECT_TRUE(IsLeapYear(1952));
EXPECT_TRUE(IsLeapYear(1956));
EXPECT_TRUE(IsLeapYear(1960));
EXPECT_TRUE(IsLeapYear(1964));
EXPECT_TRUE(IsLeapYear(1968));
EXPECT_TRUE(IsLeapYear(1972));
EXPECT_TRUE(IsLeapYear(1976));

EXPECT_FALSE(IsLeapYear(1953));
EXPECT_FALSE(IsLeapYear(1957));
EXPECT_FALSE(IsLeapYear(1961));
EXPECT_FALSE(IsLeapYear(421));
EXPECT_FALSE(IsLeapYear(643));
EXPECT_FALSE(IsLeapYear(121));
EXPECT_FALSE(IsLeapYear(75));

ASSERT_NO_THROW(IsLeapYear(100));
}
243 changes: 229 additions & 14 deletions tdd_intro/homework/04_weather_client/test.cpp
Original file line number Diff line number Diff line change
@@ -1,58 +1,50 @@
/*
Weather Client

You are going to develop a program that gets the statistics about weather in the current city
using information from a certain server. The goal is to calculate statistics using the data from weather server.

To communicate with the weather server you have to implement interface IWeatherServer,
which provides the raw string from the real server for the requested day and time.

The real server (i.e. "weather.com") gets the requests in this format:
"<date>;<time>", for example:
"31.08.2018;03:00"

The server answers on requests with string like this:
"20;181;5.1"
This string contains the weather for the requested time and means next:
"<air_temperature_in_celsius>;<wind_direction_in_degrees>:<wind_speed>".
Wind direction value may be in range from 0 to 359 inclusively, temperature may be negative.

The task:
1. Implement fake server, because interacting with real network is inacceptable within the unit tests.
To do this, you need to use real server responses. Fortunately, you've collected some results for the several dates from the weather server.
Each line means "<request>" : "<response>":

"31.08.2018;03:00" : "20;181;5.1"
"31.08.2018;09:00" : "23;204;4.9"
"31.08.2018;15:00" : "33;193;4.3"
"31.08.2018;21:00" : "26;179;4.5"

"01.09.2018;03:00" : "19;176;4.2"
"01.09.2018;09:00" : "22;131;4.1"
"01.09.2018;15:00" : "31;109;4.0"
"01.09.2018;21:00" : "24;127;4.1"

"02.09.2018;03:00" : "21;158;3.8"
"02.09.2018;09:00" : "25;201;3.5"
"02.09.2018;15:00" : "34;258;3.7"
"02.09.2018;21:00" : "27;299;4.0"

IMPORTANT:
* Server returns empty string if request is invalid.
* Real server stores weather only for times 03:00, 09:00, 15:00 and 21:00 for every date. Do not use other hours in a day.

2. Implement IWeatherClient using fake server.
*/

#include <gtest/gtest.h>
#include <gmock/gmock.h>

using namespace testing;

struct Weather
{
short temperature = 0;
unsigned short windDirection = 0;
double windSpeed = 0;
bool operator==(const Weather& right)
short temperature;
unsigned short windDirection;
double windSpeed;
bool operator==(const Weather& right) const
{
return temperature == right.temperature &&
windDirection == right.windDirection &&
Expand All @@ -79,3 +71,226 @@ class IWeatherClient
virtual double GetAverageWindDirection(IWeatherServer& server, const std::string& date) = 0;
virtual double GetMaximumWindSpeed(IWeatherServer& server, const std::string& date) = 0;
};

// TO DO list + test list:
// 1. Function ParseWeatherString parse string from server and create WeatherStruct
// 1.1 Correct string with positive temperature
// 1.2 Correct string with negative temperature
// 1.3 Empty string
// 1.4 String with invalid wind direction degree
// 1.5 Incorrect formatting
// 1.6 Acceptence
// 2. Method IWeatherServer::GetWeather Get weather struct from date string
// 2.1 Correct dates 03:00, 09:00, 15:00 and 21:00
// 2.2 Incorrect format
// 2.3 Incorrect time
// 2.4 Acceptence
// 3. Create server mock
// 4. Create WeatherClient
// 4.1. All functions: Get correct value
// 4.2. All functions: Get another correct value
// 4.3. All functions: Invalid input data

Weather ParseWeatherString(const std::string& input)
{
Weather weather {0, 0, 0};
size_t index1 = input.find(";", 0);
size_t index2 = input.find(";", index1 + 1);
if (index1 != -1 && index2 != -1)
{
unsigned short windDirection = std::stoul(input.substr(index1 + 1, index2));
if (windDirection <= 360 && windDirection >= 0)
{
weather.windDirection = windDirection;
weather.temperature = std::stol(input.substr(0, index1 + 1));
weather.windSpeed = std::stod(input.substr(index2 + 1));
}
}
return weather;
}

class FakeServer : public IWeatherServer
{
public:
MOCK_METHOD1(GetWeather, std::string(const std::string& request));
};

using WeatherSet = std::vector<Weather>;

WeatherSet GetWeatherSet(IWeatherServer& serv, const std::string& date)
{
const std::vector<std::string> timeSet = {"03:00", "09:00", "15:00", "21:00"};
WeatherSet set;
for (const auto& time : timeSet)
{
set.push_back(ParseWeatherString(serv.GetWeather(date + ";" + time)));
}
return set;
}

short GetAverageTemp(const WeatherSet& set)
{
if (set.empty())
{
return 0;
}

int average = 0;
for (const auto& w : set)
{
average += w.temperature;
}
return average / set.size();
}

short GetMinTemp(const WeatherSet& set)
{
if (set.empty())
{
return 0;
}

short min = set[0].temperature;
for (const auto& w : set)
{
min = std::min(w.temperature, min);
}
return min;
}

short GetMaxTemp(const WeatherSet& set)
{
if (set.empty())
{
return 0;
}

short min = set[0].temperature;
for (const auto& w : set)
{
min = std::max(w.temperature, min);
}
return min;
}

unsigned short GetAverageWindDirection(const WeatherSet& set)
{
if (set.empty())
{
return 0;
}

unsigned int average = 0;
for (const auto& w : set)
{
average += w.windDirection;
}
return average / set.size();
}

double GetMaximumWindSpeed(const WeatherSet& set)
{
if (set.empty())
{
return 0;
}

double min = set[0].windSpeed;
for (const auto& w : set)
{
min = std::max(w.windSpeed, min);
}
return min;
}

TEST(Weather, ParseResponseCorrect)
{
Weather w = {20, 181, 5.1};
EXPECT_EQ(w, ParseWeatherString("20;181;5.1"));
}

TEST(Weather, ParseResponseCorrect2)
{
Weather w = {-24, 142, 7.1};
EXPECT_EQ(w, ParseWeatherString("-24;142;7.1"));
}

TEST(Weather, ParseResponseEmpty)
{
Weather w = {0, 0, 0};
EXPECT_EQ(w, ParseWeatherString(""));
}

TEST(Weather, ParseResponseIncorrectDirection)
{
Weather w = {0, 0, 0};
EXPECT_EQ(w, ParseWeatherString("24;400;7.1"));
}

// --------------------------

TEST(Weather, ParseCorrectDate)
{
FakeServer serv;
EXPECT_CALL(serv, GetWeather("31.08.2018;03:00")).WillOnce(Return("20;181;5.1"));

Weather w = {20, 181, 5.1};
EXPECT_EQ(w, ParseWeatherString(serv.GetWeather("31.08.2018;03:00")));
}

TEST(Weather, ParseCorrectDataSet)
{
FakeServer serv;
EXPECT_CALL(serv, GetWeather("31.08.2018;03:00")).WillOnce(Return("20;181;5.1"));
EXPECT_CALL(serv, GetWeather("31.08.2018;09:00")).WillOnce(Return("23;204;4.9"));
EXPECT_CALL(serv, GetWeather("31.08.2018;15:00")).WillOnce(Return("33;193;4.3"));
EXPECT_CALL(serv, GetWeather("31.08.2018;21:00")).WillOnce(Return("26;179;4.5"));

WeatherSet weatherSet = {{20, 181, 5.1}, {23, 204, 4.9}, {33, 193, 4.3}, {26, 179, 4.5}};

EXPECT_EQ(weatherSet, GetWeatherSet(serv, "31.08.2018"));
}

// ------------------------------

TEST(Weather, GetAverageTemperature)
{
WeatherSet weatherSet = {{20, 181, 5.1}, {23, 204, 4.9}, {33, 193, 4.3}, {26, 179, 4.5}};
EXPECT_EQ(GetAverageTemp(weatherSet), 25);
}

TEST(Weather, GetAverageTemperature2)
{
WeatherSet weatherSet = {{25, 181, 5.1}, {23, 204, 4.9}, {33, 193, 4.3}, {26, 179, 4.5}};
EXPECT_EQ(GetAverageTemp(weatherSet), 26);
}

TEST(Weather, GetAverageTemperatureEmpty)
{
WeatherSet weatherSet = {};
EXPECT_EQ(GetAverageTemp(weatherSet), 0);
}

TEST(Weather, GetMinimumTemperature)
{
WeatherSet weatherSet = {{20, 181, 5.1}, {23, 204, 4.9}, {33, 193, 4.3}, {26, 179, 4.5}};
EXPECT_EQ(GetMinTemp(weatherSet), 20);
}

TEST(Weather, GetMaximumTemperature)
{
WeatherSet weatherSet = {{20, 181, 5.1}, {23, 204, 4.9}, {33, 193, 4.3}, {26, 179, 4.5}};
EXPECT_EQ(GetMaxTemp(weatherSet), 33);
}

TEST(Weather, GetAverageWindDirection)
{
WeatherSet weatherSet = {{20, 181, 5.1}, {23, 204, 4.9}, {33, 193, 4.3}, {26, 179, 4.5}};
EXPECT_EQ(GetAverageWindDirection(weatherSet), 189);
}

TEST(Weather, GetMaximumWindSpeed)
{
WeatherSet weatherSet = {{20, 181, 5.1}, {23, 204, 4.9}, {33, 193, 4.3}, {26, 179, 4.5}};
EXPECT_EQ(GetMaximumWindSpeed(weatherSet), 5.1);
}