Skip to content

Commit 6255458

Browse files
committed
Tests added for Logger class
1 parent 5273e08 commit 6255458

File tree

2 files changed

+225
-0
lines changed

2 files changed

+225
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ target_link_libraries(meowstro PRIVATE meowstro_lib)
208208
add_executable(meowstro_tests
209209
tests/main.cpp
210210
tests/unit/test_GameStats.cpp
211+
tests/unit/test_Logger.cpp
211212
)
212213

213214
target_link_libraries(meowstro_tests

tests/unit/test_Logger.cpp

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
#include <gtest/gtest.h>
2+
#include <sstream>
3+
#include <iostream>
4+
#include "Logger.hpp"
5+
#include "GameStats.hpp"
6+
7+
// Test fixture for Logger tests that can capture output
8+
class LoggerTest : public ::testing::Test {
9+
protected:
10+
void SetUp() override {
11+
// Save original stream buffers
12+
original_cout = std::cout.rdbuf();
13+
original_cerr = std::cerr.rdbuf();
14+
15+
// Redirect cout and cerr to our string streams
16+
std::cout.rdbuf(cout_buffer.rdbuf());
17+
std::cerr.rdbuf(cerr_buffer.rdbuf());
18+
}
19+
20+
void TearDown() override {
21+
// Restore original stream buffers
22+
std::cout.rdbuf(original_cout);
23+
std::cerr.rdbuf(original_cerr);
24+
}
25+
26+
std::stringstream cout_buffer;
27+
std::stringstream cerr_buffer;
28+
std::streambuf* original_cout;
29+
std::streambuf* original_cerr;
30+
};
31+
32+
// Test LogLevel enum values
33+
TEST_F(LoggerTest, LogLevelEnumValues) {
34+
EXPECT_EQ(static_cast<int>(LogLevel::ERROR), 0);
35+
EXPECT_EQ(static_cast<int>(LogLevel::WARNING), 1);
36+
EXPECT_EQ(static_cast<int>(LogLevel::INFO), 2);
37+
EXPECT_EQ(static_cast<int>(LogLevel::DEBUG), 3);
38+
}
39+
40+
// Test basic log functionality with different levels
41+
TEST_F(LoggerTest, BasicLogFunctionality) {
42+
Logger::log(LogLevel::INFO, "Test info message");
43+
std::string output = cout_buffer.str();
44+
EXPECT_TRUE(output.find("[INFO] Test info message") != std::string::npos);
45+
46+
cout_buffer.str(""); // Clear buffer
47+
cout_buffer.clear();
48+
49+
Logger::log(LogLevel::DEBUG, "Test debug message");
50+
output = cout_buffer.str();
51+
EXPECT_TRUE(output.find("[DEBUG] Test debug message") != std::string::npos);
52+
}
53+
54+
// Test error and warning messages go to stderr
55+
TEST_F(LoggerTest, ErrorWarningToStderr) {
56+
Logger::log(LogLevel::ERROR, "Test error message");
57+
std::string error_output = cerr_buffer.str();
58+
EXPECT_TRUE(error_output.find("[ERROR] Test error message") != std::string::npos);
59+
EXPECT_TRUE(cout_buffer.str().empty()); // Should not appear in cout
60+
61+
cerr_buffer.str(""); // Clear buffer
62+
cerr_buffer.clear();
63+
64+
Logger::log(LogLevel::WARNING, "Test warning message");
65+
error_output = cerr_buffer.str();
66+
EXPECT_TRUE(error_output.find("[WARN] Test warning message") != std::string::npos);
67+
EXPECT_TRUE(cout_buffer.str().empty()); // Should not appear in cout
68+
}
69+
70+
// Test convenience methods
71+
TEST_F(LoggerTest, ConvenienceMethods) {
72+
Logger::error("Error via convenience method");
73+
std::string error_output = cerr_buffer.str();
74+
EXPECT_TRUE(error_output.find("[ERROR] Error via convenience method") != std::string::npos);
75+
76+
cerr_buffer.str("");
77+
cerr_buffer.clear();
78+
79+
Logger::warning("Warning via convenience method");
80+
error_output = cerr_buffer.str();
81+
EXPECT_TRUE(error_output.find("[WARN] Warning via convenience method") != std::string::npos);
82+
83+
Logger::info("Info via convenience method");
84+
std::string info_output = cout_buffer.str();
85+
EXPECT_TRUE(info_output.find("[INFO] Info via convenience method") != std::string::npos);
86+
87+
cout_buffer.str("");
88+
cout_buffer.clear();
89+
90+
Logger::debug("Debug via convenience method");
91+
info_output = cout_buffer.str();
92+
EXPECT_TRUE(info_output.find("[DEBUG] Debug via convenience method") != std::string::npos);
93+
}
94+
95+
// Test logObject template method
96+
TEST_F(LoggerTest, LogObjectTemplate) {
97+
// Test with integer
98+
Logger::logObject(LogLevel::INFO, 42);
99+
std::string output = cout_buffer.str();
100+
EXPECT_TRUE(output.find("[INFO] 42") != std::string::npos);
101+
102+
cout_buffer.str("");
103+
cout_buffer.clear();
104+
105+
// Test with double
106+
Logger::logObject(LogLevel::DEBUG, 3.14159);
107+
output = cout_buffer.str();
108+
EXPECT_TRUE(output.find("[DEBUG] 3.14159") != std::string::npos);
109+
110+
cout_buffer.str("");
111+
cout_buffer.clear();
112+
113+
// Test with string
114+
std::string test_string = "Hello World";
115+
Logger::logObject(LogLevel::INFO, test_string);
116+
output = cout_buffer.str();
117+
EXPECT_TRUE(output.find("[INFO] Hello World") != std::string::npos);
118+
}
119+
120+
// Test logObject with GameStats (assuming it has operator<< overloaded)
121+
TEST_F(LoggerTest, LogObjectWithGameStats) {
122+
GameStats stats(100, 5, 8, 2);
123+
Logger::logObject(LogLevel::INFO, stats);
124+
std::string output = cout_buffer.str();
125+
126+
// Should contain the formatted GameStats output
127+
EXPECT_TRUE(output.find("[INFO]") != std::string::npos);
128+
EXPECT_TRUE(output.find("Final Stats") != std::string::npos);
129+
EXPECT_TRUE(output.find("Score: 100") != std::string::npos);
130+
}
131+
132+
// Test empty message handling
133+
TEST_F(LoggerTest, EmptyMessage) {
134+
Logger::log(LogLevel::INFO, "");
135+
std::string output = cout_buffer.str();
136+
EXPECT_TRUE(output.find("[INFO]") != std::string::npos);
137+
138+
Logger::info("");
139+
cout_buffer.str("");
140+
cout_buffer.clear();
141+
142+
Logger::info("");
143+
output = cout_buffer.str();
144+
EXPECT_TRUE(output.find("[INFO]") != std::string::npos);
145+
}
146+
147+
// Test message with special characters
148+
TEST_F(LoggerTest, SpecialCharacters) {
149+
Logger::info("Message with newlines\nand tabs\tand symbols!@#$%");
150+
std::string output = cout_buffer.str();
151+
EXPECT_TRUE(output.find("[INFO] Message with newlines\nand tabs\tand symbols!@#$%") != std::string::npos);
152+
}
153+
154+
// Test very long message
155+
TEST_F(LoggerTest, LongMessage) {
156+
std::string long_message(1000, 'A');
157+
Logger::info(long_message);
158+
std::string output = cout_buffer.str();
159+
EXPECT_TRUE(output.find("[INFO] " + long_message) != std::string::npos);
160+
}
161+
162+
// Test multiple consecutive log calls
163+
TEST_F(LoggerTest, MultipleLogCalls) {
164+
Logger::info("First message");
165+
Logger::warning("Second message");
166+
Logger::debug("Third message");
167+
168+
std::string cout_output = cout_buffer.str();
169+
std::string cerr_output = cerr_buffer.str();
170+
171+
// Info and debug should be in cout
172+
EXPECT_TRUE(cout_output.find("[INFO] First message") != std::string::npos);
173+
EXPECT_TRUE(cout_output.find("[DEBUG] Third message") != std::string::npos);
174+
175+
// Warning should be in cerr
176+
EXPECT_TRUE(cerr_output.find("[WARN] Second message") != std::string::npos);
177+
}
178+
179+
// Test SDL error logging methods (these will test the method structure,
180+
// but won't test actual SDL errors since SDL may not be initialized in tests)
181+
TEST_F(LoggerTest, SDLErrorLoggingMethods) {
182+
// These methods will call SDL_GetError() etc., but in a test environment
183+
// they might return empty strings or default error messages
184+
185+
Logger::logSDLError(LogLevel::ERROR, "SDL initialization failed");
186+
std::string error_output = cerr_buffer.str();
187+
EXPECT_TRUE(error_output.find("[ERROR] SDL initialization failed:") != std::string::npos);
188+
189+
cerr_buffer.str("");
190+
cerr_buffer.clear();
191+
192+
Logger::logSDLImageError(LogLevel::WARNING, "Image loading failed");
193+
error_output = cerr_buffer.str();
194+
EXPECT_TRUE(error_output.find("[WARN] Image loading failed:") != std::string::npos);
195+
196+
cerr_buffer.str("");
197+
cerr_buffer.clear();
198+
199+
Logger::logSDLTTFError(LogLevel::ERROR, "Font loading failed");
200+
error_output = cerr_buffer.str();
201+
EXPECT_TRUE(error_output.find("[ERROR] Font loading failed:") != std::string::npos);
202+
203+
cerr_buffer.str("");
204+
cerr_buffer.clear();
205+
206+
Logger::logSDLMixerError(LogLevel::ERROR, "Audio initialization failed");
207+
error_output = cerr_buffer.str();
208+
EXPECT_TRUE(error_output.find("[ERROR] Audio initialization failed:") != std::string::npos);
209+
}
210+
211+
// Test that log calls are thread-safe (basic test)
212+
TEST_F(LoggerTest, BasicThreadSafety) {
213+
// Simple test that multiple calls don't interfere
214+
for (int i = 0; i < 10; ++i) {
215+
Logger::info("Message " + std::to_string(i));
216+
}
217+
218+
std::string output = cout_buffer.str();
219+
220+
// Check that all messages appear
221+
for (int i = 0; i < 10; ++i) {
222+
EXPECT_TRUE(output.find("Message " + std::to_string(i)) != std::string::npos);
223+
}
224+
}

0 commit comments

Comments
 (0)