mirror of
https://github.com/gabime/spdlog.git
synced 2024-12-25 10:01:33 +08:00
Added unit tests (catch based)
This commit is contained in:
parent
056352cf42
commit
2f81e54568
12
tests/Makefile
Normal file
12
tests/Makefile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
CXX ?= g++
|
||||||
|
CXXFLAGS = -D_WIN32_WINNT=0x600 -march=native -Wall -Wextra -Wshadow -pedantic -std=c++11 -pthread -Wl,--no-as-needed -I../include
|
||||||
|
|
||||||
|
all: %.cpp
|
||||||
|
$(CXX) $^ -o tests $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
|
||||||
|
clean:
|
||||||
|
rm -f tests *.o logs/*
|
||||||
|
|
||||||
|
rebuild: clean all
|
||||||
|
|
||||||
|
|
||||||
|
|
9427
tests/catch.hpp
Normal file
9427
tests/catch.hpp
Normal file
File diff suppressed because it is too large
Load Diff
136
tests/file_log.cpp
Normal file
136
tests/file_log.cpp
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
static std::string file_contents(const std::string& filename)
|
||||||
|
{
|
||||||
|
std::ifstream ifs(filename);
|
||||||
|
if (!ifs)
|
||||||
|
throw std::exception("Failed open file ");
|
||||||
|
return std::string((std::istreambuf_iterator<char>(ifs)),
|
||||||
|
(std::istreambuf_iterator<char>()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static std::size_t count_lines(const std::string& filename)
|
||||||
|
{
|
||||||
|
std::ifstream ifs(filename);
|
||||||
|
if (!ifs)
|
||||||
|
throw std::exception("Failed open file ");
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
size_t counter = 0;
|
||||||
|
while(std::getline(ifs, line))
|
||||||
|
counter++;
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream::pos_type filesize(const std::string& filename)
|
||||||
|
{
|
||||||
|
std::ifstream ifs(filename, std::ifstream::ate | std::ifstream::binary);
|
||||||
|
if (!ifs)
|
||||||
|
throw std::exception("Failed open file ");
|
||||||
|
|
||||||
|
return ifs.tellg();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delete_logs()
|
||||||
|
{
|
||||||
|
spdlog::drop_all();
|
||||||
|
#ifdef _WIN32
|
||||||
|
system("del /F /Q logs\\*");
|
||||||
|
#else
|
||||||
|
system("rm -f logs/*");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("simple_file_logger", "[simple_logger]]")
|
||||||
|
{
|
||||||
|
delete_logs();
|
||||||
|
std::string filename = "logs/simple_log.txt";
|
||||||
|
|
||||||
|
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger", filename);
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
auto logger = spdlog::create<spdlog::sinks::simple_file_sink_mt>("logger2", filename);
|
||||||
|
, spdlog::spdlog_ex);
|
||||||
|
|
||||||
|
logger->set_pattern("%v");
|
||||||
|
logger->info("Test message {}", 1);
|
||||||
|
logger->info("Test message {}", 2);
|
||||||
|
logger->flush();
|
||||||
|
REQUIRE(file_contents(filename) == std::string("Test message 1\nTest message 2\n"));
|
||||||
|
REQUIRE(count_lines(filename) == 2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("rotating_file_logger1", "[rotating_logger]]")
|
||||||
|
{
|
||||||
|
delete_logs();
|
||||||
|
std::string basename = "logs/rotating_log";
|
||||||
|
auto logger = spdlog::rotating_logger_mt("logger", basename, 1024, 0, true);
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
logger->info("Test message {}", i);
|
||||||
|
|
||||||
|
auto filename = basename + ".txt";
|
||||||
|
REQUIRE(count_lines(filename) == 10);
|
||||||
|
for (int i = 0; i < 1000; i++)
|
||||||
|
logger->info("Test message {}", i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("rotating_file_logger2", "[rotating_logger]]")
|
||||||
|
{
|
||||||
|
delete_logs();
|
||||||
|
std::string basename = "logs/rotating_log";
|
||||||
|
auto logger = spdlog::rotating_logger_mt("logger", basename, 1024, 1, false);
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
logger->info("Test message {}", i);
|
||||||
|
|
||||||
|
logger->flush();
|
||||||
|
auto filename = basename + ".txt";
|
||||||
|
REQUIRE(count_lines(filename) == 10);
|
||||||
|
for (int i = 0; i < 1000; i++)
|
||||||
|
logger->info("Test message {}", i);
|
||||||
|
|
||||||
|
logger->flush();
|
||||||
|
REQUIRE(filesize(filename) <= 1024);
|
||||||
|
auto filename1 = basename + ".1.txt";
|
||||||
|
REQUIRE(filesize(filename1) <= 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("daily_logger", "[daily_logger]]")
|
||||||
|
{
|
||||||
|
|
||||||
|
delete_logs();
|
||||||
|
//calculate filename (time based)
|
||||||
|
std::string basename = "logs/daily_log";
|
||||||
|
std::tm tm = spdlog::details::os::localtime();
|
||||||
|
fmt::MemoryWriter w;
|
||||||
|
w.write("{}_{:04d}-{:02d}-{:02d}_{:02d}-{:02d}.txt", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min);
|
||||||
|
|
||||||
|
auto logger = spdlog::daily_logger_mt("logger", basename, 0, 0, true);
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
logger->info("Test message {}", i);
|
||||||
|
|
||||||
|
auto filename = w.str();
|
||||||
|
REQUIRE(count_lines(filename) == 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
87
tests/format.cpp
Normal file
87
tests/format.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
std::string log_info(const T& what, spdlog::level::level_enum logger_level = spdlog::level::info) {
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss);
|
||||||
|
|
||||||
|
spdlog::logger oss_logger("oss", oss_sink);
|
||||||
|
oss_logger.set_level(logger_level);
|
||||||
|
oss_logger.set_pattern("%v");
|
||||||
|
oss_logger.info() << what;
|
||||||
|
|
||||||
|
//strip last eol and return the logged string
|
||||||
|
auto eol_size = strlen(spdlog::details::os::eol());
|
||||||
|
return oss.str().substr(0, oss.str().length() - eol_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//User defined class with operator<<
|
||||||
|
struct some_logged_class
|
||||||
|
{
|
||||||
|
some_logged_class(const std::string val) :value(val) {};
|
||||||
|
std::string value;
|
||||||
|
};
|
||||||
|
std::ostream& operator<<(std::ostream& os, const some_logged_class& c) {
|
||||||
|
return os << c.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("basic_logging ", "[basic_logging]") {
|
||||||
|
//const char
|
||||||
|
REQUIRE(log_info("Hello") == "Hello");
|
||||||
|
REQUIRE(log_info("") == "");
|
||||||
|
|
||||||
|
//std::string
|
||||||
|
REQUIRE(log_info(std::string("Hello")) == "Hello");
|
||||||
|
REQUIRE(log_info(std::string()) == std::string());
|
||||||
|
|
||||||
|
//Numbers
|
||||||
|
REQUIRE(log_info(5) == "5");
|
||||||
|
REQUIRE(log_info(5.6) == "5.6");
|
||||||
|
|
||||||
|
//User defined class
|
||||||
|
REQUIRE(log_info(some_logged_class("some_val")) == "some_val");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("log_levels", "[log_levels]")
|
||||||
|
{
|
||||||
|
REQUIRE(log_info("Hello", spdlog::level::err) == "");
|
||||||
|
REQUIRE(log_info("Hello", spdlog::level::critical) == "");
|
||||||
|
REQUIRE(log_info("Hello", spdlog::level::emerg) == "");
|
||||||
|
REQUIRE(log_info("Hello", spdlog::level::alert) == "");
|
||||||
|
REQUIRE(log_info("Hello", spdlog::level::info) == "Hello");
|
||||||
|
REQUIRE(log_info("Hello", spdlog::level::debug) == "Hello");
|
||||||
|
REQUIRE(log_info("Hello", spdlog::level::trace) == "Hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("invalid_format", "[format]")
|
||||||
|
{
|
||||||
|
|
||||||
|
using namespace spdlog::sinks;
|
||||||
|
spdlog::logger null_logger("null_logger", std::make_shared<null_sink_st>());
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
null_logger.info("{} {}", "first"),
|
||||||
|
spdlog::spdlog_ex);
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
null_logger.info("{0:f}", "aads"),
|
||||||
|
spdlog::spdlog_ex);
|
||||||
|
|
||||||
|
REQUIRE_THROWS_AS(
|
||||||
|
null_logger.info("{0:kk}", 123),
|
||||||
|
spdlog::spdlog_ex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
10
tests/includes.h
Normal file
10
tests/includes.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <ostream>
|
||||||
|
#include <chrono>
|
||||||
|
#include "catch.hpp"
|
||||||
|
#include "../include/spdlog/spdlog.h"
|
||||||
|
#include "../include/spdlog/sinks/null_sink.h"
|
0
tests/logs/placeholder.txt
Normal file
0
tests/logs/placeholder.txt
Normal file
2
tests/main.cpp
Normal file
2
tests/main.cpp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include "catch.hpp"
|
53
tests/registry.cpp
Normal file
53
tests/registry.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
static const char *logger_name = "null_logger";
|
||||||
|
|
||||||
|
TEST_CASE("register_drop", "[registry]")
|
||||||
|
{
|
||||||
|
spdlog::drop_all();
|
||||||
|
spdlog::create<spdlog::sinks::null_sink_mt>(logger_name);
|
||||||
|
REQUIRE(spdlog::get(logger_name)!=nullptr);
|
||||||
|
//Throw if registring existing name
|
||||||
|
REQUIRE_THROWS_AS(spdlog::create<spdlog::sinks::null_sink_mt>(logger_name), spdlog::spdlog_ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("explicit register" "[registry]")
|
||||||
|
{
|
||||||
|
spdlog::drop_all();
|
||||||
|
auto logger = std::make_shared<spdlog::logger>(logger_name, std::make_shared<spdlog::sinks::null_sink_st>());
|
||||||
|
spdlog::register_logger(logger);
|
||||||
|
REQUIRE(spdlog::get(logger_name) != nullptr);
|
||||||
|
//Throw if registring existing name
|
||||||
|
REQUIRE_THROWS_AS(spdlog::create<spdlog::sinks::null_sink_mt>(logger_name), spdlog::spdlog_ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("drop" "[registry]")
|
||||||
|
{
|
||||||
|
spdlog::drop_all();
|
||||||
|
spdlog::create<spdlog::sinks::null_sink_mt>(logger_name);
|
||||||
|
spdlog::drop(logger_name);
|
||||||
|
REQUIRE_FALSE(spdlog::get(logger_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("drop_all" "[registry]")
|
||||||
|
{
|
||||||
|
spdlog::drop_all();
|
||||||
|
spdlog::create<spdlog::sinks::null_sink_mt>(logger_name);
|
||||||
|
spdlog::create<spdlog::sinks::null_sink_mt>("name2");
|
||||||
|
spdlog::drop_all();
|
||||||
|
REQUIRE_FALSE(spdlog::get(logger_name));
|
||||||
|
REQUIRE_FALSE(spdlog::get("name2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("drop non existing" "[registry]")
|
||||||
|
{
|
||||||
|
spdlog::drop_all();
|
||||||
|
spdlog::create<spdlog::sinks::null_sink_mt>(logger_name);
|
||||||
|
spdlog::drop("some_name");
|
||||||
|
REQUIRE_FALSE(spdlog::get("some_name"));
|
||||||
|
REQUIRE(spdlog::get(logger_name));
|
||||||
|
spdlog::drop_all();
|
||||||
|
}
|
||||||
|
|
89
tests/tests.vcxproj
Normal file
89
tests/tests.vcxproj
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="file_log.cpp" />
|
||||||
|
<ClCompile Include="format.cpp" />
|
||||||
|
<ClCompile Include="main.cpp" />
|
||||||
|
<ClCompile Include="registry.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="catch.hpp" />
|
||||||
|
<ClInclude Include="includes.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{1274FDEC-109A-45DF-8AEC-E3334C3A925F}</ProjectGuid>
|
||||||
|
<RootNamespace>tests</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>$(ProjectDir)</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)\$(Configuration-obj)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-debug</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>$(ProjectDir)</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)\$(Configuration)-obj\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
16
tests/tests.vcxproj.filters
Normal file
16
tests/tests.vcxproj.filters
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Headers">
|
||||||
|
<UniqueIdentifier>{9e4e82c2-35fe-4707-a66a-5cc069b44224}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="catch.hpp">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="includes.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
Loading…
Reference in New Issue
Block a user