diff --git a/cpp/Platform.Data.Tests/AllTests.cpp b/cpp/Platform.Data.Tests/AllTests.cpp index 5b3e8ed0..5b8b2de6 100644 --- a/cpp/Platform.Data.Tests/AllTests.cpp +++ b/cpp/Platform.Data.Tests/AllTests.cpp @@ -5,3 +5,4 @@ #include "LinksConstantsTests.cpp" #include "ILinksTests.cpp" #include "PointTests.cpp" +#include "ExceptionsTests.cpp" diff --git a/cpp/Platform.Data.Tests/ExceptionsTests.cpp b/cpp/Platform.Data.Tests/ExceptionsTests.cpp new file mode 100644 index 00000000..be0ffe7a --- /dev/null +++ b/cpp/Platform.Data.Tests/ExceptionsTests.cpp @@ -0,0 +1,273 @@ +#include +#include +#include +#include + +// Include all exception headers +#include "../Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h" +#include "../Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h" +#include "../Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h" +#include "../Platform.Data/Exceptions/LinksLimitReachedException.h" +#include "../Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h" + +using namespace Platform::Data::Exceptions; + +// Test ArgumentLinkDoesNotExistsException +TEST(ExceptionsTests, ArgumentLinkDoesNotExistsExceptionInheritance) +{ + // Test that it properly inherits from std::invalid_argument + ArgumentLinkDoesNotExistsException ex; + EXPECT_TRUE(dynamic_cast(&ex) != nullptr); + EXPECT_TRUE(dynamic_cast(&ex) != nullptr); +} + +TEST(ExceptionsTests, ArgumentLinkDoesNotExistsExceptionConstructors) +{ + // Test default constructor + ArgumentLinkDoesNotExistsException ex1; + EXPECT_NE(ex1.what(), nullptr); + + // Test string constructor + ArgumentLinkDoesNotExistsException ex2("Test message"); + EXPECT_STREQ(ex2.what(), "Test message"); + + // Test link constructor + ArgumentLinkDoesNotExistsException ex3(42); + std::string whatStr(ex3.what()); + EXPECT_TRUE(whatStr.find("42") != std::string::npos); + + // Test link and argument name constructor + ArgumentLinkDoesNotExistsException ex4(42, "testArg"); + std::string whatStr2(ex4.what()); + EXPECT_TRUE(whatStr2.find("42") != std::string::npos); + EXPECT_TRUE(whatStr2.find("testArg") != std::string::npos); + + // Test inner exception constructor (note: inner exception info is not stored in std::invalid_argument) + std::runtime_error inner("inner"); + ArgumentLinkDoesNotExistsException ex5("outer", inner); + EXPECT_STREQ(ex5.what(), "outer"); +} + +TEST(ExceptionsTests, ArgumentLinkDoesNotExistsExceptionThrowCatch) +{ + // Test that it can be thrown and caught as std::invalid_argument + try { + throw ArgumentLinkDoesNotExistsException(123, "testParam"); + } catch (const std::invalid_argument& e) { + std::string whatStr(e.what()); + EXPECT_TRUE(whatStr.find("123") != std::string::npos); + EXPECT_TRUE(whatStr.find("testParam") != std::string::npos); + } + + // Test that it can be caught as std::exception + try { + throw ArgumentLinkDoesNotExistsException("test message"); + } catch (const std::exception& e) { + EXPECT_STREQ(e.what(), "test message"); + } +} + +// Test ArgumentLinkHasDependenciesException +TEST(ExceptionsTests, ArgumentLinkHasDependenciesExceptionInheritance) +{ + ArgumentLinkHasDependenciesException ex; + EXPECT_TRUE(dynamic_cast(&ex) != nullptr); + EXPECT_TRUE(dynamic_cast(&ex) != nullptr); +} + +TEST(ExceptionsTests, ArgumentLinkHasDependenciesExceptionConstructors) +{ + // Test default constructor + ArgumentLinkHasDependenciesException ex1; + EXPECT_NE(ex1.what(), nullptr); + + // Test string constructor + ArgumentLinkHasDependenciesException ex2("Test message"); + EXPECT_STREQ(ex2.what(), "Test message"); + + // Test link constructor + ArgumentLinkHasDependenciesException ex3(42); + std::string whatStr(ex3.what()); + EXPECT_TRUE(whatStr.find("42") != std::string::npos); + + // Test link and parameter name constructor + ArgumentLinkHasDependenciesException ex4(42, "testParam"); + std::string whatStr2(ex4.what()); + EXPECT_TRUE(whatStr2.find("42") != std::string::npos); + EXPECT_TRUE(whatStr2.find("testParam") != std::string::npos); +} + +TEST(ExceptionsTests, ArgumentLinkHasDependenciesExceptionThrowCatch) +{ + try { + throw ArgumentLinkHasDependenciesException(123, "testParam"); + } catch (const std::invalid_argument& e) { + std::string whatStr(e.what()); + EXPECT_TRUE(whatStr.find("123") != std::string::npos); + EXPECT_TRUE(whatStr.find("testParam") != std::string::npos); + } +} + +// Test LinksLimitReachedExceptionBase +TEST(ExceptionsTests, LinksLimitReachedExceptionBaseInheritance) +{ + class TestLinksLimitReachedExceptionBase : public LinksLimitReachedExceptionBase { + public: + TestLinksLimitReachedExceptionBase(std::string message) : LinksLimitReachedExceptionBase(message) {} + }; + + TestLinksLimitReachedExceptionBase ex("test"); + EXPECT_TRUE(dynamic_cast(&ex) != nullptr); +} + +TEST(ExceptionsTests, LinksLimitReachedExceptionBaseMessage) +{ + class TestLinksLimitReachedExceptionBase : public LinksLimitReachedExceptionBase { + public: + TestLinksLimitReachedExceptionBase(std::string message) : LinksLimitReachedExceptionBase(message) {} + }; + + TestLinksLimitReachedExceptionBase ex("test message"); + EXPECT_STREQ(ex.what(), "test message"); +} + +TEST(ExceptionsTests, LinksLimitReachedExceptionBaseDefaultMessage) +{ + EXPECT_FALSE(LinksLimitReachedExceptionBase::DefaultMessage.empty()); + EXPECT_TRUE(LinksLimitReachedExceptionBase::DefaultMessage.find("лимит") != std::string::npos); +} + +// Test LinksLimitReachedException +TEST(ExceptionsTests, LinksLimitReachedExceptionInheritance) +{ + LinksLimitReachedException ex; + EXPECT_TRUE(dynamic_cast(&ex) != nullptr); + EXPECT_TRUE(dynamic_cast(&ex) != nullptr); +} + +TEST(ExceptionsTests, LinksLimitReachedExceptionConstructors) +{ + // Test default constructor + LinksLimitReachedException ex1; + std::string whatStr1(ex1.what()); + EXPECT_TRUE(whatStr1.find("лимит") != std::string::npos); + + // Test string constructor + LinksLimitReachedException ex2("Custom message"); + EXPECT_STREQ(ex2.what(), "Custom message"); + + // Test limit constructor + LinksLimitReachedException ex3(1000); + std::string whatStr3(ex3.what()); + EXPECT_TRUE(whatStr3.find("1000") != std::string::npos); + EXPECT_TRUE(whatStr3.find("лимит") != std::string::npos); +} + +TEST(ExceptionsTests, LinksLimitReachedExceptionThrowCatch) +{ + try { + throw LinksLimitReachedException(500); + } catch (const LinksLimitReachedExceptionBase& e) { + std::string whatStr(e.what()); + EXPECT_TRUE(whatStr.find("500") != std::string::npos); + } + + try { + throw LinksLimitReachedException("test"); + } catch (const std::exception& e) { + EXPECT_STREQ(e.what(), "test"); + } +} + +// Test LinkWithSameValueAlreadyExistsException +TEST(ExceptionsTests, LinkWithSameValueAlreadyExistsExceptionInheritance) +{ + LinkWithSameValueAlreadyExistsException ex; + EXPECT_TRUE(dynamic_cast(&ex) != nullptr); +} + +TEST(ExceptionsTests, LinkWithSameValueAlreadyExistsExceptionConstructors) +{ + // Test default constructor + LinkWithSameValueAlreadyExistsException ex1; + std::string whatStr1(ex1.what()); + EXPECT_TRUE(whatStr1.find("значением") != std::string::npos); + + // Test string constructor + LinkWithSameValueAlreadyExistsException ex2("Custom message"); + EXPECT_STREQ(ex2.what(), "Custom message"); +} + +TEST(ExceptionsTests, LinkWithSameValueAlreadyExistsExceptionDefaultMessage) +{ + EXPECT_FALSE(LinkWithSameValueAlreadyExistsException::DefaultMessage.empty()); + EXPECT_TRUE(LinkWithSameValueAlreadyExistsException::DefaultMessage.find("значением") != std::string::npos); +} + +TEST(ExceptionsTests, LinkWithSameValueAlreadyExistsExceptionThrowCatch) +{ + try { + throw LinkWithSameValueAlreadyExistsException("test message"); + } catch (const std::exception& e) { + EXPECT_STREQ(e.what(), "test message"); + } + + try { + throw LinkWithSameValueAlreadyExistsException(); + } catch (const std::exception& e) { + std::string whatStr(e.what()); + EXPECT_TRUE(whatStr.find("значением") != std::string::npos); + } +} + +// Test that all exceptions can be caught as std::exception +TEST(ExceptionsTests, AllExceptionsCatchableAsStdException) +{ + // Test ArgumentLinkDoesNotExistsException + try { + throw ArgumentLinkDoesNotExistsException("test"); + } catch (const std::exception& e) { + EXPECT_STREQ(e.what(), "test"); + } + + // Test ArgumentLinkHasDependenciesException + try { + throw ArgumentLinkHasDependenciesException("test"); + } catch (const std::exception& e) { + EXPECT_STREQ(e.what(), "test"); + } + + // Test LinksLimitReachedException + try { + throw LinksLimitReachedException("test"); + } catch (const std::exception& e) { + EXPECT_STREQ(e.what(), "test"); + } + + // Test LinkWithSameValueAlreadyExistsException + try { + throw LinkWithSameValueAlreadyExistsException("test"); + } catch (const std::exception& e) { + EXPECT_STREQ(e.what(), "test"); + } +} + +// Test template instantiation with different types +TEST(ExceptionsTests, TemplateInstantiationWithDifferentTypes) +{ + // Test with int + ArgumentLinkDoesNotExistsException intEx(42); + EXPECT_TRUE(dynamic_cast(&intEx) != nullptr); + + // Test with long + ArgumentLinkDoesNotExistsException longEx(123456L); + EXPECT_TRUE(dynamic_cast(&longEx) != nullptr); + + // Test with unsigned int + ArgumentLinkHasDependenciesException uintEx(42u); + EXPECT_TRUE(dynamic_cast(&uintEx) != nullptr); + + // Test LinksLimitReachedException with different types + LinksLimitReachedException sizeEx(1000); + EXPECT_TRUE(dynamic_cast(&sizeEx) != nullptr); +} \ No newline at end of file diff --git a/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h b/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h index 352f82da..31f18d89 100644 --- a/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h +++ b/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h @@ -1,17 +1,22 @@ -namespace Platform::Data::Exceptions +#pragma once +#include +#include +#include "Platform.Converters.Fallback.h" + +namespace Platform::Data::Exceptions { template class ArgumentLinkDoesNotExistsException; template class ArgumentLinkDoesNotExistsException : public std::invalid_argument { - public: ArgumentLinkDoesNotExistsException(TLinkAddress link, std::string argumentName) : std::invalid_argument(FormatMessage(link, argumentName), argumentName) { } + public: ArgumentLinkDoesNotExistsException(TLinkAddress link, std::string argumentName) : std::invalid_argument(FormatMessage(link, argumentName)) { } public: ArgumentLinkDoesNotExistsException(TLinkAddress link) : std::invalid_argument(FormatMessage(link)) { } - public: ArgumentLinkDoesNotExistsException(std::string message, const std::exception& innerException) : std::invalid_argument(message, innerException) { } + public: ArgumentLinkDoesNotExistsException(std::string message, const std::exception& innerException) : std::invalid_argument(message) { } public: ArgumentLinkDoesNotExistsException(std::string message) : std::invalid_argument(message) { } - public: ArgumentLinkDoesNotExistsException() { } + public: ArgumentLinkDoesNotExistsException() : std::invalid_argument("") { } private: static std::string FormatMessage(TLinkAddress link, std::string argumentName) { return std::string("Связь [").append(Platform::Converters::To(link)).append("] переданная в аргумент [").append(argumentName).append("] не существует."); } diff --git a/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h b/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h index 06f47c1e..23d7cfe8 100644 --- a/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h +++ b/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h @@ -1,17 +1,22 @@ -namespace Platform::Data::Exceptions +#pragma once +#include +#include +#include "Platform.Converters.Fallback.h" + +namespace Platform::Data::Exceptions { template class ArgumentLinkHasDependenciesException; template class ArgumentLinkHasDependenciesException : public std::invalid_argument { - public: ArgumentLinkHasDependenciesException(TLinkAddress link, std::string paramName) : std::invalid_argument(FormatMessage(link, paramName), paramName) { } + public: ArgumentLinkHasDependenciesException(TLinkAddress link, std::string paramName) : std::invalid_argument(FormatMessage(link, paramName)) { } public: ArgumentLinkHasDependenciesException(TLinkAddress link) : std::invalid_argument(FormatMessage(link)) { } - public: ArgumentLinkHasDependenciesException(std::string message, const std::exception& innerException) : std::invalid_argument(message, innerException) { } + public: ArgumentLinkHasDependenciesException(std::string message, const std::exception& innerException) : std::invalid_argument(message) { } public: ArgumentLinkHasDependenciesException(std::string message) : std::invalid_argument(message) { } - public: ArgumentLinkHasDependenciesException() { } + public: ArgumentLinkHasDependenciesException() : std::invalid_argument("") { } private: static std::string FormatMessage(TLinkAddress link, std::string paramName) { return std::string("У связи [").append(Platform::Converters::To(link)).append("] переданной в аргумент [").append(paramName).append("] присутствуют зависимости, которые препятствуют изменению её внутренней структуры."); } diff --git a/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h b/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h index 5b2c69d5..71d992d4 100644 --- a/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h +++ b/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h @@ -1,13 +1,21 @@ -namespace Platform::Data::Exceptions +#pragma once +#include +#include + +namespace Platform::Data::Exceptions { class LinkWithSameValueAlreadyExistsException : public std::exception { + private: std::string _message; + public: inline static std::string DefaultMessage = "Связь с таким же значением уже существует."; - public: LinkWithSameValueAlreadyExistsException(std::string message, const std::exception& innerException) : base(message, innerException) { } + public: LinkWithSameValueAlreadyExistsException(std::string message, const std::exception& innerException) : _message(message) { } - public: LinkWithSameValueAlreadyExistsException(std::string message) : base(message) { } + public: LinkWithSameValueAlreadyExistsException(std::string message) : _message(message) { } - public: LinkWithSameValueAlreadyExistsException() : base(DefaultMessage) { } + public: LinkWithSameValueAlreadyExistsException() : _message(DefaultMessage) { } + + public: const char* what() const noexcept override { return _message.c_str(); } }; } diff --git a/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h b/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h index 521cb35c..79372328 100644 --- a/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h +++ b/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h @@ -1,9 +1,14 @@ -namespace Platform::Data::Exceptions +#pragma once +#include +#include "LinksLimitReachedExceptionBase.h" +#include "Platform.Converters.Fallback.h" + +namespace Platform::Data::Exceptions { template class LinksLimitReachedException; template class LinksLimitReachedException : public LinksLimitReachedExceptionBase { - public: LinksLimitReachedException(TLinkAddress limit) : this(FormatMessage(limit)) { } + public: LinksLimitReachedException(TLinkAddress limit) : LinksLimitReachedExceptionBase(FormatMessage(limit)) { } public: LinksLimitReachedException(std::string message, const std::exception& innerException) : LinksLimitReachedExceptionBase(message, innerException) { } diff --git a/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h b/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h index 37ab3c78..82a7a868 100644 --- a/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h +++ b/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h @@ -1,11 +1,19 @@ -namespace Platform::Data::Exceptions +#pragma once +#include +#include + +namespace Platform::Data::Exceptions { class LinksLimitReachedExceptionBase : public std::exception { + private: std::string _message; + public: inline static std::string DefaultMessage = "Достигнут лимит количества связей в хранилище."; - protected: LinksLimitReachedExceptionBase(std::string message, const std::exception& innerException) : base(message, innerException) { } + protected: LinksLimitReachedExceptionBase(std::string message, const std::exception& innerException) : _message(message) { } - protected: LinksLimitReachedExceptionBase(std::string message) : base(message) { } + protected: LinksLimitReachedExceptionBase(std::string message) : _message(message) { } + + public: const char* what() const noexcept override { return _message.c_str(); } }; } diff --git a/cpp/Platform.Data/Exceptions/Platform.Converters.Fallback.h b/cpp/Platform.Data/Exceptions/Platform.Converters.Fallback.h new file mode 100644 index 00000000..27c47094 --- /dev/null +++ b/cpp/Platform.Data/Exceptions/Platform.Converters.Fallback.h @@ -0,0 +1,22 @@ +#pragma once +#include + +// Try to include Platform.Converters, but provide fallback if not available +#ifdef __has_include + #if __has_include() + #include + #define HAS_PLATFORM_CONVERTERS + #endif +#endif + +// Fallback converter if Platform.Converters is not available +#ifndef HAS_PLATFORM_CONVERTERS +namespace Platform { namespace Converters { + template + TTarget To(const TSource& source) { + std::stringstream ss; + ss << source; + return ss.str(); + } +}} +#endif \ No newline at end of file diff --git a/experiments/simple_exception_test.cpp b/experiments/simple_exception_test.cpp new file mode 100644 index 00000000..2111ddff --- /dev/null +++ b/experiments/simple_exception_test.cpp @@ -0,0 +1,90 @@ +#include +#include +#include +#include + +// Mock Platform::Converters::To for testing +namespace Platform { +namespace Converters { + template + std::string To(int value) { + return std::to_string(value); + } +} +} + +// Include our exception headers +#include "../cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h" +#include "../cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h" +#include "../cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h" +#include "../cpp/Platform.Data/Exceptions/LinksLimitReachedException.h" +#include "../cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h" + +using namespace Platform::Data::Exceptions; + +int main() { + std::cout << "Testing exception inheritance and functionality..." << std::endl; + + try { + // Test ArgumentLinkDoesNotExistsException + std::cout << "Testing ArgumentLinkDoesNotExistsException..." << std::endl; + ArgumentLinkDoesNotExistsException ex1(42, "testParam"); + std::cout << "Message: " << ex1.what() << std::endl; + + // Test inheritance + std::exception* basePtr = &ex1; + std::cout << "Can be cast to std::exception: " << (basePtr != nullptr ? "YES" : "NO") << std::endl; + + std::invalid_argument* invalidArgPtr = dynamic_cast(&ex1); + std::cout << "Can be cast to std::invalid_argument: " << (invalidArgPtr != nullptr ? "YES" : "NO") << std::endl; + + // Test ArgumentLinkHasDependenciesException + std::cout << "\nTesting ArgumentLinkHasDependenciesException..." << std::endl; + ArgumentLinkHasDependenciesException ex2(123, "depParam"); + std::cout << "Message: " << ex2.what() << std::endl; + + // Test LinksLimitReachedException + std::cout << "\nTesting LinksLimitReachedException..." << std::endl; + LinksLimitReachedException ex3(1000); + std::cout << "Message: " << ex3.what() << std::endl; + + LinksLimitReachedExceptionBase* baseExPtr = &ex3; + std::cout << "Can be cast to LinksLimitReachedExceptionBase: " << (baseExPtr != nullptr ? "YES" : "NO") << std::endl; + + // Test LinkWithSameValueAlreadyExistsException + std::cout << "\nTesting LinkWithSameValueAlreadyExistsException..." << std::endl; + LinkWithSameValueAlreadyExistsException ex4; + std::cout << "Default message: " << ex4.what() << std::endl; + + // Test exception throwing and catching + std::cout << "\nTesting exception throwing and catching..." << std::endl; + + try { + throw ArgumentLinkDoesNotExistsException(999, "throwTest"); + } catch (const std::invalid_argument& e) { + std::cout << "Caught ArgumentLinkDoesNotExistsException as std::invalid_argument: " << e.what() << std::endl; + } + + try { + throw LinksLimitReachedException("Custom limit message"); + } catch (const std::exception& e) { + std::cout << "Caught LinksLimitReachedException as std::exception: " << e.what() << std::endl; + } + + try { + throw LinkWithSameValueAlreadyExistsException("Custom value message"); + } catch (const std::exception& e) { + std::cout << "Caught LinkWithSameValueAlreadyExistsException as std::exception: " << e.what() << std::endl; + } + + std::cout << "\nAll tests completed successfully!" << std::endl; + return 0; + + } catch (const std::exception& e) { + std::cout << "ERROR: Caught unexpected exception: " << e.what() << std::endl; + return 1; + } catch (...) { + std::cout << "ERROR: Caught unknown exception" << std::endl; + return 1; + } +} \ No newline at end of file diff --git a/experiments/standalone_exception_test.cpp b/experiments/standalone_exception_test.cpp new file mode 100644 index 00000000..410522bf --- /dev/null +++ b/experiments/standalone_exception_test.cpp @@ -0,0 +1,197 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// Simple converter mock for testing +template +std::string ToStr(const T& value) { + std::stringstream ss; + ss << value; + return ss.str(); +} + +// Standalone exception definitions for testing (without external dependencies) +namespace Platform::Data::Exceptions +{ + // ArgumentLinkDoesNotExistsException + template class ArgumentLinkDoesNotExistsException; + template + class ArgumentLinkDoesNotExistsException : public std::invalid_argument + { + public: ArgumentLinkDoesNotExistsException(TLinkAddress link, std::string argumentName) : std::invalid_argument(FormatMessage(link, argumentName)) { } + + public: ArgumentLinkDoesNotExistsException(TLinkAddress link) : std::invalid_argument(FormatMessage(link)) { } + + public: ArgumentLinkDoesNotExistsException(std::string message, const std::exception& innerException) : std::invalid_argument(message) { } + + public: ArgumentLinkDoesNotExistsException(std::string message) : std::invalid_argument(message) { } + + public: ArgumentLinkDoesNotExistsException() : std::invalid_argument("") { } + + private: static std::string FormatMessage(TLinkAddress link, std::string argumentName) { + return std::string("Связь [").append(ToStr(link)).append("] переданная в аргумент [").append(argumentName).append("] не существует."); + } + + private: static std::string FormatMessage(TLinkAddress link) { + return std::string("Связь [").append(ToStr(link)).append("] переданная в качестве аргумента не существует."); + } + }; + + // ArgumentLinkHasDependenciesException + template class ArgumentLinkHasDependenciesException; + template + class ArgumentLinkHasDependenciesException : public std::invalid_argument + { + public: ArgumentLinkHasDependenciesException(TLinkAddress link, std::string paramName) : std::invalid_argument(FormatMessage(link, paramName)) { } + + public: ArgumentLinkHasDependenciesException(TLinkAddress link) : std::invalid_argument(FormatMessage(link)) { } + + public: ArgumentLinkHasDependenciesException(std::string message, const std::exception& innerException) : std::invalid_argument(message) { } + + public: ArgumentLinkHasDependenciesException(std::string message) : std::invalid_argument(message) { } + + public: ArgumentLinkHasDependenciesException() : std::invalid_argument("") { } + + private: static std::string FormatMessage(TLinkAddress link, std::string paramName) { + return std::string("У связи [").append(ToStr(link)).append("] переданной в аргумент [").append(paramName).append("] присутствуют зависимости, которые препятствуют изменению её внутренней структуры."); + } + + private: static std::string FormatMessage(TLinkAddress link) { + return std::string("У связи [").append(ToStr(link)).append("] переданной в качестве аргумента присутствуют зависимости, которые препятствуют изменению её внутренней структуры."); + } + }; + + // LinksLimitReachedExceptionBase + class LinksLimitReachedExceptionBase : public std::exception + { + private: std::string _message; + + public: inline static std::string DefaultMessage = "Достигнут лимит количества связей в хранилище."; + + protected: LinksLimitReachedExceptionBase(std::string message, const std::exception& innerException) : _message(message) { } + + protected: LinksLimitReachedExceptionBase(std::string message) : _message(message) { } + + public: const char* what() const noexcept override { return _message.c_str(); } + }; + + // LinksLimitReachedException + template class LinksLimitReachedException; + template + class LinksLimitReachedException : public LinksLimitReachedExceptionBase + { + public: LinksLimitReachedException(TLinkAddress limit) : LinksLimitReachedExceptionBase(FormatMessage(limit)) { } + + public: LinksLimitReachedException(std::string message, const std::exception& innerException) : LinksLimitReachedExceptionBase(message, innerException) { } + + public: LinksLimitReachedException(std::string message) : LinksLimitReachedExceptionBase(message) { } + + public: LinksLimitReachedException() : LinksLimitReachedExceptionBase(DefaultMessage) { } + + private: static std::string FormatMessage(TLinkAddress limit) { + return std::string("Достигнут лимит количества связей в хранилище (").append(ToStr(limit)).append(")."); + } + }; + + // LinkWithSameValueAlreadyExistsException + class LinkWithSameValueAlreadyExistsException : public std::exception + { + private: std::string _message; + + public: inline static std::string DefaultMessage = "Связь с таким же значением уже существует."; + + public: LinkWithSameValueAlreadyExistsException(std::string message, const std::exception& innerException) : _message(message) { } + + public: LinkWithSameValueAlreadyExistsException(std::string message) : _message(message) { } + + public: LinkWithSameValueAlreadyExistsException() : _message(DefaultMessage) { } + + public: const char* what() const noexcept override { return _message.c_str(); } + }; +} + +using namespace Platform::Data::Exceptions; + +int main() { + std::cout << "Testing exception inheritance and functionality..." << std::endl; + + try { + // Test ArgumentLinkDoesNotExistsException + std::cout << "Testing ArgumentLinkDoesNotExistsException..." << std::endl; + ArgumentLinkDoesNotExistsException ex1(42, "testParam"); + std::cout << "Message: " << ex1.what() << std::endl; + + // Test inheritance + std::exception* basePtr = &ex1; + std::cout << "Can be cast to std::exception: " << (basePtr != nullptr ? "YES" : "NO") << std::endl; + + std::invalid_argument* invalidArgPtr = dynamic_cast(&ex1); + std::cout << "Can be cast to std::invalid_argument: " << (invalidArgPtr != nullptr ? "YES" : "NO") << std::endl; + + // Test ArgumentLinkHasDependenciesException + std::cout << "\nTesting ArgumentLinkHasDependenciesException..." << std::endl; + ArgumentLinkHasDependenciesException ex2(123, "depParam"); + std::cout << "Message: " << ex2.what() << std::endl; + + // Test LinksLimitReachedException + std::cout << "\nTesting LinksLimitReachedException..." << std::endl; + LinksLimitReachedException ex3(1000); + std::cout << "Message: " << ex3.what() << std::endl; + + LinksLimitReachedExceptionBase* baseExPtr = &ex3; + std::cout << "Can be cast to LinksLimitReachedExceptionBase: " << (baseExPtr != nullptr ? "YES" : "NO") << std::endl; + + // Test LinkWithSameValueAlreadyExistsException + std::cout << "\nTesting LinkWithSameValueAlreadyExistsException..." << std::endl; + LinkWithSameValueAlreadyExistsException ex4; + std::cout << "Default message: " << ex4.what() << std::endl; + + // Test exception throwing and catching + std::cout << "\nTesting exception throwing and catching..." << std::endl; + + try { + throw ArgumentLinkDoesNotExistsException(999, "throwTest"); + } catch (const std::invalid_argument& e) { + std::cout << "Caught ArgumentLinkDoesNotExistsException as std::invalid_argument: " << e.what() << std::endl; + } + + try { + throw LinksLimitReachedException("Custom limit message"); + } catch (const std::exception& e) { + std::cout << "Caught LinksLimitReachedException as std::exception: " << e.what() << std::endl; + } + + try { + throw LinkWithSameValueAlreadyExistsException("Custom value message"); + } catch (const std::exception& e) { + std::cout << "Caught LinkWithSameValueAlreadyExistsException as std::exception: " << e.what() << std::endl; + } + + // Test polymorphic behavior + std::cout << "\nTesting polymorphic behavior..." << std::endl; + std::vector> exceptions; + exceptions.push_back(std::make_unique>("poly test 1")); + exceptions.push_back(std::make_unique>("poly test 2")); + exceptions.push_back(std::make_unique>("poly test 3")); + exceptions.push_back(std::make_unique("poly test 4")); + + for (const auto& ex : exceptions) { + std::cout << "Polymorphic exception message: " << ex->what() << std::endl; + } + + std::cout << "\nAll tests completed successfully!" << std::endl; + return 0; + + } catch (const std::exception& e) { + std::cout << "ERROR: Caught unexpected exception: " << e.what() << std::endl; + return 1; + } catch (...) { + std::cout << "ERROR: Caught unknown exception" << std::endl; + return 1; + } +} \ No newline at end of file diff --git a/experiments/test_exceptions b/experiments/test_exceptions new file mode 100755 index 00000000..10bdf7e0 Binary files /dev/null and b/experiments/test_exceptions differ diff --git a/experiments/test_real_exceptions b/experiments/test_real_exceptions new file mode 100755 index 00000000..890dc475 Binary files /dev/null and b/experiments/test_real_exceptions differ diff --git a/experiments/test_real_exceptions.cpp b/experiments/test_real_exceptions.cpp new file mode 100644 index 00000000..e7c37a14 --- /dev/null +++ b/experiments/test_real_exceptions.cpp @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include +#include + +// Include the actual exception headers +#include "../cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h" +#include "../cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h" +#include "../cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h" +#include "../cpp/Platform.Data/Exceptions/LinksLimitReachedException.h" +#include "../cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h" + +using namespace Platform::Data::Exceptions; + +int main() { + std::cout << "Testing real exception headers..." << std::endl; + + try { + // Test ArgumentLinkDoesNotExistsException + std::cout << "\nTesting ArgumentLinkDoesNotExistsException..." << std::endl; + ArgumentLinkDoesNotExistsException ex1(42, "testParam"); + std::cout << "Message: " << ex1.what() << std::endl; + + // Test inheritance + std::exception* basePtr = &ex1; + std::cout << "Can be cast to std::exception: " << (basePtr != nullptr ? "YES" : "NO") << std::endl; + + std::invalid_argument* invalidArgPtr = dynamic_cast(&ex1); + std::cout << "Can be cast to std::invalid_argument: " << (invalidArgPtr != nullptr ? "YES" : "NO") << std::endl; + + // Test ArgumentLinkHasDependenciesException + std::cout << "\nTesting ArgumentLinkHasDependenciesException..." << std::endl; + ArgumentLinkHasDependenciesException ex2(123, "depParam"); + std::cout << "Message: " << ex2.what() << std::endl; + + // Test LinksLimitReachedException + std::cout << "\nTesting LinksLimitReachedException..." << std::endl; + LinksLimitReachedException ex3(1000); + std::cout << "Message: " << ex3.what() << std::endl; + + LinksLimitReachedExceptionBase* baseExPtr = &ex3; + std::cout << "Can be cast to LinksLimitReachedExceptionBase: " << (baseExPtr != nullptr ? "YES" : "NO") << std::endl; + + // Test LinkWithSameValueAlreadyExistsException + std::cout << "\nTesting LinkWithSameValueAlreadyExistsException..." << std::endl; + LinkWithSameValueAlreadyExistsException ex4; + std::cout << "Default message: " << ex4.what() << std::endl; + + // Test exception throwing and catching + std::cout << "\nTesting exception throwing and catching..." << std::endl; + + try { + throw ArgumentLinkDoesNotExistsException(999, "throwTest"); + } catch (const std::invalid_argument& e) { + std::cout << "Caught ArgumentLinkDoesNotExistsException as std::invalid_argument: " << e.what() << std::endl; + } + + try { + throw LinksLimitReachedException("Custom limit message"); + } catch (const std::exception& e) { + std::cout << "Caught LinksLimitReachedException as std::exception: " << e.what() << std::endl; + } + + try { + throw LinkWithSameValueAlreadyExistsException("Custom value message"); + } catch (const std::exception& e) { + std::cout << "Caught LinkWithSameValueAlreadyExistsException as std::exception: " << e.what() << std::endl; + } + + std::cout << "\nAll tests completed successfully!" << std::endl; + return 0; + + } catch (const std::exception& e) { + std::cout << "ERROR: Caught unexpected exception: " << e.what() << std::endl; + return 1; + } catch (...) { + std::cout << "ERROR: Caught unknown exception" << std::endl; + return 1; + } +} \ No newline at end of file