diff --git a/contrib/sjparser/README.contrib b/contrib/sjparser/README.contrib index 3d5da3b8..52d6e70a 100644 --- a/contrib/sjparser/README.contrib +++ b/contrib/sjparser/README.contrib @@ -15,5 +15,7 @@ List of changes to sjparser: * if key appears multiple times, last one wins * Include error location in error message * Typo fixes +* Removed union.h and s_union.h, as well as standalone/embedded (s_)union test cases + diff --git a/contrib/sjparser/library/CMakeLists.txt b/contrib/sjparser/library/CMakeLists.txt index 24fb886a..e834af06 100644 --- a/contrib/sjparser/library/CMakeLists.txt +++ b/contrib/sjparser/library/CMakeLists.txt @@ -26,9 +26,7 @@ set_property(TARGET sjparser PROPERTY SJPARSER_HEADERS sjparser/array.h sjparser/yajl_parser.h sjparser/s_auto_object.h - sjparser/s_union.h sjparser/parser.h - sjparser/union.h sjparser/member.h sjparser/options.h @@ -46,7 +44,7 @@ setup_compilation_options(sjparser) target_link_libraries(sjparser PUBLIC ${YAJL_LIB}) -target_include_directories(sjparser PUBLIC +target_include_directories(sjparser PUBLIC $ $ ) diff --git a/contrib/sjparser/library/documentation/Doxyfile.in b/contrib/sjparser/library/documentation/Doxyfile.in index ca8f2022..899b7b9c 100644 --- a/contrib/sjparser/library/documentation/Doxyfile.in +++ b/contrib/sjparser/library/documentation/Doxyfile.in @@ -802,9 +802,7 @@ INPUT = @SJPARSER_SOURCE_DIR@/sjparser/s_custom_object.h \ @SJPARSER_SOURCE_DIR@/sjparser/array.h \ @SJPARSER_SOURCE_DIR@/sjparser/yajl_parser.h \ @SJPARSER_SOURCE_DIR@/sjparser/s_auto_object.h \ - @SJPARSER_SOURCE_DIR@/sjparser/s_union.h \ @SJPARSER_SOURCE_DIR@/sjparser/parser.h \ - @SJPARSER_SOURCE_DIR@/sjparser/union.h \ @SJPARSER_SOURCE_DIR@/sjparser/member.h \ @SJPARSER_SOURCE_DIR@/sjparser/options.h \ @CUT_README@ diff --git a/contrib/sjparser/library/sjparser/array.h b/contrib/sjparser/library/sjparser/array.h index 0736e3dc..0ce05b81 100644 --- a/contrib/sjparser/library/sjparser/array.h +++ b/contrib/sjparser/library/sjparser/array.h @@ -23,10 +23,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once -#include "internals/array_parser.h" - #include +#include "internals/array_parser.h" + namespace SJParser { /** @brief %Array parser. @@ -103,11 +103,11 @@ template class Array : public ArrayParser { Callback _on_finish; }; -template Array(Array &&)->Array>; +template Array(Array &&) -> Array>; -template Array(Array &)->Array &>; +template Array(Array &) -> Array &>; -template Array(ParserT &&)->Array; +template Array(ParserT &&) -> Array; /****************************** Implementations *******************************/ diff --git a/contrib/sjparser/library/sjparser/internals/array_parser.cpp b/contrib/sjparser/library/sjparser/internals/array_parser.cpp index 51822c58..412dfc26 100644 --- a/contrib/sjparser/library/sjparser/internals/array_parser.cpp +++ b/contrib/sjparser/library/sjparser/internals/array_parser.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include "array_parser.h" + #include "dispatcher.h" namespace SJParser { diff --git a/contrib/sjparser/library/sjparser/internals/dispatcher.cpp b/contrib/sjparser/library/sjparser/internals/dispatcher.cpp index 638ff74a..8ab72c5e 100644 --- a/contrib/sjparser/library/sjparser/internals/dispatcher.cpp +++ b/contrib/sjparser/library/sjparser/internals/dispatcher.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include "dispatcher.h" + #include "token_parser.h" namespace SJParser { diff --git a/contrib/sjparser/library/sjparser/internals/dispatcher.h b/contrib/sjparser/library/sjparser/internals/dispatcher.h index 9a47c684..451b00fd 100644 --- a/contrib/sjparser/library/sjparser/internals/dispatcher.h +++ b/contrib/sjparser/library/sjparser/internals/dispatcher.h @@ -23,12 +23,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once -#include "token_parser.h" - #include #include #include +#include "token_parser.h" + namespace SJParser { class Dispatcher { diff --git a/contrib/sjparser/library/sjparser/internals/ignore.h b/contrib/sjparser/library/sjparser/internals/ignore.h index 8f45d891..a2735cbf 100644 --- a/contrib/sjparser/library/sjparser/internals/ignore.h +++ b/contrib/sjparser/library/sjparser/internals/ignore.h @@ -23,10 +23,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once -#include "token_parser.h" - #include +#include "token_parser.h" + namespace SJParser { class Ignore : public TokenParser { diff --git a/contrib/sjparser/library/sjparser/internals/key_value_parser.h b/contrib/sjparser/library/sjparser/internals/key_value_parser.h index e0fedcb1..36087148 100644 --- a/contrib/sjparser/library/sjparser/internals/key_value_parser.h +++ b/contrib/sjparser/library/sjparser/internals/key_value_parser.h @@ -76,7 +76,6 @@ class KeyValueParser : public TokenParser { template static constexpr bool has_value_type = IsStorageParser>; - using ParsersArrayType = std::array; using ParsersMapType = std::unordered_map; // Returns ValueType if it is available, otherwise ParserType @@ -113,23 +112,21 @@ class KeyValueParser : public TokenParser { MemberParsers(MemberParsers &&other) noexcept = default; MemberParsers &operator=(MemberParsers &&other) noexcept = default; - MemberParsers(ParsersArrayType &parsers_array, ParsersMapType &parsers_map, + MemberParsers(ParsersMapType &parsers_map, std::tuple...> &members) : mbr_parsers(to_member_parser_tuple(members)) { - registerParsers(parsers_array, parsers_map); + registerParsers(parsers_map); } template [[nodiscard]] auto &get() { return std::get(mbr_parsers); } - void registerParsers(ParsersArrayType &parsers_array, - ParsersMapType &parsers_map); + void registerParsers(ParsersMapType &parsers_map); private: template - void registerParser(ParserT &parser, NameT &name, int i, - ParsersArrayType &parsers_array, + void registerParser(ParserT &parser, NameT &name, ParsersMapType &parsers_map); void check_duplicate(bool inserted, NameT &name); @@ -146,12 +143,10 @@ class KeyValueParser : public TokenParser { std::tuple...> mbr_parsers; }; - [[nodiscard]] auto &parsersArray(); [[nodiscard]] auto &parsersMap(); [[nodiscard]] auto &memberParsers(); private: - ParsersArrayType _parsers_array; ParsersMapType _parsers_map; MemberParsers _member_parsers; Ignore _ignore_parser; @@ -163,8 +158,7 @@ class KeyValueParser : public TokenParser { template KeyValueParser::KeyValueParser( std::tuple...> members, ObjectOptions options) - : _member_parsers(_parsers_array, _parsers_map, members), - _options{options} {} + : _member_parsers(_parsers_map, members), _options{options} {} template KeyValueParser::KeyValueParser( @@ -173,7 +167,7 @@ KeyValueParser::KeyValueParser( _member_parsers{std::move(other._member_parsers)}, _ignore_parser{std::move(other._ignore_parser)}, _options{other._options} { - _member_parsers.registerParsers(_parsers_array, _parsers_map); + _member_parsers.registerParsers(_parsers_map); } template @@ -182,7 +176,7 @@ KeyValueParser::operator=(KeyValueParser &&other) noexcept { TokenParser::operator=(std::move(other)); _member_parsers = std::move(other._member_parsers); _parsers_map.clear(); - _member_parsers.registerParsers(_parsers_array, _parsers_map); + _member_parsers.registerParsers(_parsers_map); _ignore_parser = std::move(other._ignore_parser); _options = std::move(other._options); @@ -282,11 +276,6 @@ KeyValueParser::pop() { return std::move(member.parser.pop()); } -template -auto &KeyValueParser::parsersArray() { - return _parsers_array; -} - template auto &KeyValueParser::parsersMap() { return _parsers_map; @@ -299,14 +288,12 @@ auto &KeyValueParser::memberParsers() { template void KeyValueParser::MemberParsers::registerParsers( - ParsersArrayType &parsers_array, ParsersMapType &parsers_map) { + ParsersMapType &parsers_map) { parsers_map.clear(); std::apply( [&](auto &&...xs) { - int i = 0; - ((registerParser(xs.parser, xs.name, i++, parsers_array, parsers_map)), - ...); + ((registerParser(xs.parser, xs.name, parsers_map)), ...); }, mbr_parsers); } @@ -314,10 +301,7 @@ void KeyValueParser::MemberParsers::registerParsers( template template void KeyValueParser::MemberParsers::registerParser( - ParserT &parser, NameT &name, int i, ParsersArrayType &parsers_array, - ParsersMapType &parsers_map) { - parsers_array[i] = &parser; - + ParserT &parser, NameT &name, ParsersMapType &parsers_map) { auto [_, inserted] = parsers_map.insert({name, &parser}); std::ignore = _; diff --git a/contrib/sjparser/library/sjparser/internals/token_parser.cpp b/contrib/sjparser/library/sjparser/internals/token_parser.cpp index 64066fa2..b55a6b47 100644 --- a/contrib/sjparser/library/sjparser/internals/token_parser.cpp +++ b/contrib/sjparser/library/sjparser/internals/token_parser.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include "token_parser.h" + #include "dispatcher.h" namespace SJParser { diff --git a/contrib/sjparser/library/sjparser/map.h b/contrib/sjparser/library/sjparser/map.h index 8af33a4b..b713c61f 100644 --- a/contrib/sjparser/library/sjparser/map.h +++ b/contrib/sjparser/library/sjparser/map.h @@ -23,11 +23,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once +#include + #include "internals/dispatcher.h" #include "internals/token_parser.h" -#include - namespace SJParser { /** @brief %Map parser. @@ -145,11 +145,11 @@ template class Map : public TokenParser { Callback _on_finish; }; -template Map(Map &&)->Map>; +template Map(Map &&) -> Map>; -template Map(Map &)->Map &>; +template Map(Map &) -> Map &>; -template Map(ParserT &&)->Map; +template Map(ParserT &&) -> Map; /****************************** Implementations *******************************/ diff --git a/contrib/sjparser/library/sjparser/member.h b/contrib/sjparser/library/sjparser/member.h index f1e7cb2e..9eb861f4 100644 --- a/contrib/sjparser/library/sjparser/member.h +++ b/contrib/sjparser/library/sjparser/member.h @@ -24,6 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once #include + #include "internals/default_value.h" #include "internals/traits.h" @@ -112,39 +113,40 @@ template struct Member { }; template -Member(const char *, ParserT &&)->Member; +Member(const char *, ParserT &&) -> Member; -template Member(int, ParserT &&)->Member; +template Member(int, ParserT &&) -> Member; -template Member(float, ParserT &&)->Member; +template +Member(float, ParserT &&) -> Member; template -Member(NameT, ParserT &&)->Member; +Member(NameT, ParserT &&) -> Member; template -Member(const char *, ParserT &&, Presence)->Member; +Member(const char *, ParserT &&, Presence) -> Member; template -Member(int, ParserT &&, Presence)->Member; +Member(int, ParserT &&, Presence) -> Member; template -Member(float, ParserT &&, Presence)->Member; +Member(float, ParserT &&, Presence) -> Member; template -Member(NameT, ParserT &&, Presence)->Member; +Member(NameT, ParserT &&, Presence) -> Member; template Member(const char *, ParserT &&, Presence, ValueT) - ->Member; + -> Member; template -Member(int, ParserT &&, Presence, ValueT)->Member; +Member(int, ParserT &&, Presence, ValueT) -> Member; template -Member(float, ParserT &&, Presence, ValueT)->Member; +Member(float, ParserT &&, Presence, ValueT) -> Member; template -Member(NameT, ParserT &&, Presence, ValueT)->Member; +Member(NameT, ParserT &&, Presence, ValueT) -> Member; /****************************** Implementations *******************************/ diff --git a/contrib/sjparser/library/sjparser/object.h b/contrib/sjparser/library/sjparser/object.h index 3a3e932f..eb41cc28 100644 --- a/contrib/sjparser/library/sjparser/object.h +++ b/contrib/sjparser/library/sjparser/object.h @@ -23,10 +23,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once -#include "internals/key_value_parser.h" - #include +#include "internals/key_value_parser.h" + namespace SJParser { /** @brief %Object parser. @@ -156,8 +156,7 @@ class Object : public KeyValueParser { * * @return Reference to n-th member parser. */ - [[nodiscard]] template - ParserType &parser(); + [[nodiscard]] template ParserType &parser(); /** @brief Get the member parsed value and unset the member parser. * @@ -171,8 +170,7 @@ class Object : public KeyValueParser { * @throw std::runtime_error thrown if the member parser value is unset (no * value was parsed or #pop was called for the member parser). */ - template - ValueType &&pop(); + template ValueType &&pop(); #endif protected: @@ -206,11 +204,11 @@ namespace std { */ template -struct tuple_size> // NOLINT +struct tuple_size> // NOLINT : std::integral_constant {}; template -struct tuple_element> { // NOLINT +struct tuple_element> { // NOLINT using type = decltype(std::declval>().template get()); }; diff --git a/contrib/sjparser/library/sjparser/parser.h b/contrib/sjparser/library/sjparser/parser.h index 8724af25..78d413ff 100644 --- a/contrib/sjparser/library/sjparser/parser.h +++ b/contrib/sjparser/library/sjparser/parser.h @@ -65,7 +65,7 @@ class Parser : public ImplHolder::type { ParserT _parser; }; -template Parser(ParserT &&)->Parser; +template Parser(ParserT &&) -> Parser; /****************************** Implementations *******************************/ diff --git a/contrib/sjparser/library/sjparser/s_array.h b/contrib/sjparser/library/sjparser/s_array.h index 64996f58..8cb0daab 100644 --- a/contrib/sjparser/library/sjparser/s_array.h +++ b/contrib/sjparser/library/sjparser/s_array.h @@ -23,10 +23,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once -#include "array.h" - #include +#include "array.h" + namespace SJParser { /** @brief %Array parser, that stores the result in an std::vector of @@ -133,12 +133,13 @@ template class SArray : public Array { Callback _on_finish; }; -template SArray(SArray &&)->SArray>; +template +SArray(SArray &&) -> SArray>; template -SArray(SArray &)->SArray &>; +SArray(SArray &) -> SArray &>; -template SArray(ParserT &&)->SArray; +template SArray(ParserT &&) -> SArray; /****************************** Implementations *******************************/ diff --git a/contrib/sjparser/library/sjparser/s_auto_object.h b/contrib/sjparser/library/sjparser/s_auto_object.h index 94f6decc..8b0b387c 100644 --- a/contrib/sjparser/library/sjparser/s_auto_object.h +++ b/contrib/sjparser/library/sjparser/s_auto_object.h @@ -163,8 +163,7 @@ template class SAutoObject : public Object { * * @return Reference to n-th member parser. */ - [[nodiscard]] template - ParserType &parser(); + [[nodiscard]] template ParserType &parser(); #endif private: diff --git a/contrib/sjparser/library/sjparser/s_custom_object.h b/contrib/sjparser/library/sjparser/s_custom_object.h index a0e4f9d5..d3d8a95c 100644 --- a/contrib/sjparser/library/sjparser/s_custom_object.h +++ b/contrib/sjparser/library/sjparser/s_custom_object.h @@ -175,8 +175,7 @@ class SCustomObject : public Object { * * @return Reference to n-th member parser. */ - [[nodiscard]] template - ParserType &parser(); + [[nodiscard]] template ParserType &parser(); #endif using Object::get; @@ -201,8 +200,7 @@ class SCustomObject : public Object { * @throw std::runtime_error thrown if the member parser value is unset (no * value was parsed or #pop was called for the member parser). */ - template - ValueType &&pop(); + template ValueType &&pop(); #endif using Object::pop; diff --git a/contrib/sjparser/library/sjparser/s_map.h b/contrib/sjparser/library/sjparser/s_map.h index 27dc6ccf..c853149c 100644 --- a/contrib/sjparser/library/sjparser/s_map.h +++ b/contrib/sjparser/library/sjparser/s_map.h @@ -23,10 +23,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once -#include "map.h" - #include +#include "map.h" + namespace SJParser { /** @brief %Map parser, that stores the result in an std::map with std::string @@ -173,11 +173,11 @@ template class SMap : public Map { Callback _on_finish; }; -template SMap(SMap &&)->SMap>; +template SMap(SMap &&) -> SMap>; -template SMap(SMap &)->SMap &>; +template SMap(SMap &) -> SMap &>; -template SMap(ParserT &&)->SMap; +template SMap(ParserT &&) -> SMap; /****************************** Implementations *******************************/ @@ -246,7 +246,8 @@ template void SMap::childParsed() { && !_on_element(Map::currentKey(), Map::parser())) { throw std::runtime_error("Element callback returned false"); } - _values.insert_or_assign(Map::currentKey(), Map::parser().pop()); + _values.insert_or_assign(Map::currentKey(), + Map::parser().pop()); } template void SMap::finish() { diff --git a/contrib/sjparser/library/sjparser/s_union.h b/contrib/sjparser/library/sjparser/s_union.h deleted file mode 100644 index 4470633d..00000000 --- a/contrib/sjparser/library/sjparser/s_union.h +++ /dev/null @@ -1,328 +0,0 @@ -/******************************************************************************* - -Copyright (c) 2016-2017 Denis Tikhomirov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*******************************************************************************/ - -#pragma once - -#include "union.h" - -#include -#include - -namespace SJParser { - -/** @brief %Union of @ref Object "Objects" parser, that stores the result in an - * std::variant of member parser types. - * - * Parses an object from @ref SUnion_Ts "ParserTs" list based on a value of - * the type member. - * - * You can use it standalone (in this case the first member of an object must - * be a type member) or embedded in an object (in this case object members after - * the type member will be parsed by one of union's object parsers). - * - * SUnion type is defined by arguments passed to the constructor. - * - * Empty standalone union will be parsed and marked as unset. - * - * If union type was parsed, then the corresponding object is mandatory - * unless it's member has Presence::Optional and default value set. - * - * @tparam TypeMemberT A type of the type member. Can be int64_t, bool, double - * or std::string. - * - * @tparam ParserTs A list of object parsers. - * @anchor SUnion_Ts - */ - -template -class SUnion : public Union { - public: -#ifdef DOXYGEN_ONLY - /** @brief %Member parser type. - * - * Resolves to n-th member parser type - * - * @tparam n %Member index - */ - template struct ParserType { - /** n-th member parser type */ - using ParserType = NthTypes::template ParserType; - }; -#endif - - /** Stored value type */ - using ValueType = std::variant::ValueType...>; - - /** Finish callback type. */ - using Callback = std::function; - - /** @brief Embedded mode constructor. - * - * This union must be used as a member of an object. In JSON that member's - * content will represent this union's type. Latter members will be parsed by - * one of this union's objects parsers. - * - * @param [in] type Type member's type, please use a TypeHolder wrapper for - * it. - * - * @param [in] members std::tuple of Member structures, describing union - * objects. - * - * @param [in] on_finish (optional) Callback, that will be called after the - * union is parsed. - * The callback will be called with a reference to the parser as an argument. - * If the callback returns false, parsing will be stopped with an error. - */ - template - SUnion(TypeHolder type, - std::tuple...> members, - CallbackT on_finish = nullptr); - - /** @brief Standalone mode constructor. - * - * This union will parse a whole JSON object. Object's first member's name - * must be same as type_member, and latter members will be parsed by one of - * this union's objects parsers. - * - * @param [in] type Type member's type, please use a TypeHolder wrapper for - * it. - * - * @param [in] type_member Type member's name. - * - * @param [in] members std::tuple of Member structures, describing union - * objects. - * - * @param [in] on_finish (optional) Callback, that will be called after the - * union is parsed. - * The callback will be called with a reference to the parser as an argument. - * If the callback returns false, parsing will be stopped with an error. - */ - template - SUnion(TypeHolder type, std::string_view type_member, - std::tuple...> members, - CallbackT on_finish = nullptr); - - /** Move constructor. */ - SUnion(SUnion &&other) noexcept; - - /** Move assignment operator */ - SUnion &operator=(SUnion &&other) noexcept; - - /** @cond INTERNAL Boilerplate. */ - ~SUnion() override = default; - SUnion(const SUnion &) = delete; - SUnion &operator=(const SUnion &) = delete; - /** @endcond */ - - /** @brief Finish callback setter. - * - * @param [in] on_finish Callback, that will be called after the - * union is parsed. - * The callback will be called with a reference to the parser as an argument. - * If the callback returns false, parsing will be stopped with an error. - */ - void setFinishCallback(Callback on_finish); - -#ifdef DOXYGEN_ONLY - /** @brief Check if the parser has a value. - * - * @return True if the parser has some value stored or false otherwise. - */ - [[nodiscard]] bool isSet(); - - /** @brief Check if the parsed union was empy (null). - * - * @return True if the parsed union was empty (null) or false otherwise. - */ - [[nodiscard]] bool isEmpty(); -#endif - - /** @brief Parsed value getter. - * - * @return Const reference to a parsed value. - * - * @throw std::runtime_error Thrown if the value is unset (no value was - * parsed or #pop was called). - */ - [[nodiscard]] const ValueType &get() const; - -#ifdef DOXYGEN_ONLY - /** @brief Member parser getter. - * - * @tparam n Index of the parser's member. - * - * @return Reference to n-th member parser. - */ - [[nodiscard]] template - ParserType &parser(); -#endif - - /** @brief Get the parsed value and unset the parser. - * - * Moves the parsed value out of the parser. - * - * @note If you want to use SCustomObject inside this parser, you need to - * provide both a copy constructor or move constructor and a copy assignment - * operators in the SCustomObject::ValueType, they are used by parser. - * - * @return Rvalue reference to the parsed value. - * - * @throw std::runtime_error Thrown if the value is unset (no value was - * parsed or #pop was called). - */ - ValueType &&pop(); - - private: - void finish() override; - void reset() override; - - // This is placed in the private section because the ValueSetter uses pop on - // all members, so they are always unset after parsing. - using Union::get; - using Union::pop; - using Union::currentMemberId; - - template struct ValueSetter { - ValueSetter(ValueType & /*value*/, - SUnion & /*parser*/) {} - }; - - template - struct ValueSetter - : private ValueSetter { - ValueSetter(ValueType &value, SUnion &parser); - }; - - ValueType _value; - Callback _on_finish; -}; - -/****************************** Implementations *******************************/ - -template -template -SUnion::SUnion( - TypeHolder type, - std::tuple...> members, CallbackT on_finish) - : SUnion{type, {}, std::move(members), std::move(on_finish)} {} - -template -template -SUnion::SUnion( - TypeHolder type, std::string_view type_member, - std::tuple...> members, CallbackT on_finish) - : Union{type, type_member, std::move(members)}, - _on_finish{std::move(on_finish)} {} - -template -SUnion::SUnion(SUnion &&other) noexcept - : Union{std::move(other)}, - _value{std::move(other._value)}, - _on_finish{std::move(other._on_finish)} {} - -template -SUnion &SUnion::operator=( - SUnion &&other) noexcept { - Union::operator=(std::move(other)); - _value = std::move(other._value); - _on_finish = std::move(other._on_finish); - - return *this; -} - -template -void SUnion::setFinishCallback(Callback on_finish) { - _on_finish = on_finish; -} - -template -const typename SUnion::ValueType & -SUnion::get() const { - TokenParser::checkSet(); - return _value; -} - -template -typename SUnion::ValueType && -SUnion::pop() { - TokenParser::checkSet(); - TokenParser::unset(); - return std::move(_value); -} - -template -void SUnion::finish() { - if (TokenParser::isEmpty()) { - TokenParser::unset(); - return; - } - - try { - ValueSetter<0, ParserTs...>(_value, *this); - } catch (std::exception &e) { - TokenParser::unset(); - throw std::runtime_error(std::string("Can not set value: ") + e.what()); - } catch (...) { - TokenParser::unset(); - throw std::runtime_error("Can not set value: unknown exception"); - } - - if (_on_finish && !_on_finish(_value)) { - throw std::runtime_error("Callback returned false"); - } -} - -template -void SUnion::reset() { - Union::reset(); - _value = {}; -} - -template -template -SUnion::ValueSetter:: - ValueSetter(ValueType &value, SUnion &parser) - : ValueSetter{value, parser} { - if (parser.currentMemberId() != n) { - return; - } - - auto &member = parser.memberParsers().template get(); - - if (member.parser.isSet()) { - value = member.parser.pop(); - } else if (member.optional) { - if (!member.default_value.value) { - std::stringstream error; - error << "Optional member #" << n << " does not have a default value"; - throw std::runtime_error(error.str()); - } - value = *member.default_value.value; - } else { - std::stringstream error; - error << "Mandatory member #" << n << " is not present"; - throw std::runtime_error(error.str()); - } -} - -} // namespace SJParser diff --git a/contrib/sjparser/library/sjparser/sjparser.h b/contrib/sjparser/library/sjparser/sjparser.h index c6ea3a2f..2cca3f0d 100644 --- a/contrib/sjparser/library/sjparser/sjparser.h +++ b/contrib/sjparser/library/sjparser/sjparser.h @@ -31,6 +31,4 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "s_auto_object.h" #include "s_custom_object.h" #include "s_map.h" -#include "s_union.h" -#include "union.h" #include "value.h" diff --git a/contrib/sjparser/library/sjparser/union.h b/contrib/sjparser/library/sjparser/union.h deleted file mode 100644 index c0571956..00000000 --- a/contrib/sjparser/library/sjparser/union.h +++ /dev/null @@ -1,387 +0,0 @@ -/******************************************************************************* - -Copyright (c) 2016-2017 Denis Tikhomirov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*******************************************************************************/ - -#pragma once - -#include "internals/key_value_parser.h" -#include "type_holder.h" - -#include - -namespace SJParser { - -/** @brief %Union of @ref Object "Objects" parser. - * - * Parses an object from @ref Union_Ts "ParserTs" list based on a value of - * the type member. - * - * You can use it standalone (in this case the first member of an object must - * be a type member) or embedded in an object (in this case object members after - * the type member will be parsed by one of union's object parsers). - * - * Union type is defined by arguments passed to the constructor. - * - * Empty standalone union will be parsed and marked as unset. - * - * If union type was parsed, then the corresponding object is mandatory - * unless it's member has Presence::Optional set. - * For absent member with default value Union::get<> will return the default - * value and isSet will return false. - * - * @tparam TypeMemberT A type of the type member. Can be int64_t, bool, double - * or std::string. - * - * @tparam ParserTs A list of object parsers. - * @anchor Union_Ts - */ - -template -class Union : public KeyValueParser { - protected: - /** @cond INTERNAL Internal typedef */ - using KVParser = KeyValueParser; - /** @endcond */ - - public: -#ifdef DOXYGEN_ONLY - /** @brief %Member parser type. - * - * Resolves to n-th member parser type - * - * @tparam n %Member index - */ - template struct ParserType { - /** n-th member parser type */ - using ParserType = NthTypes::template ParserType; - }; -#endif - - /** Finish callback type. */ - using Callback = std::function &)>; - - /** @brief Embedded mode constructor. - * - * This union must be used as a member of an object. In JSON that member's - * content will represent this union's type. Latter members will be parsed by - * one of this union's objects parsers. - * - * @param [in] type Type member's type, please use a TypeHolder wrapper for - * it. - * - * @param [in] members std::tuple of Member structures, describing union - * objects. - * - * @param [in] on_finish (optional) Callback, that will be called after the - * union is parsed. - * The callback will be called with a reference to the parser as an argument. - * If the callback returns false, parsing will be stopped with an error. - */ - template - Union(TypeHolder type, - std::tuple...> members, - CallbackT on_finish = nullptr); - - /** @brief Standalone mode constructor. - * - * This union will parse a whole JSON object. Object's first member's name - * must be same as type_member, and latter members will be parsed by one of - * this union's objects parsers. - * - * @param [in] type Type member's type, please use a TypeHolder wrapper for - * it. - * - * @param [in] type_member Type member's name. - * - * @param [in] members std::tuple of Member structures, describing union - * objects. - * - * @param [in] on_finish (optional) Callback, that will be called after the - * union is parsed. - * The callback will be called with a reference to the parser as an argument. - * If the callback returns false, parsing will be stopped with an error. - */ - template - Union(TypeHolder type, std::string_view type_member, - std::tuple...> members, - CallbackT on_finish = nullptr); - - /** Move constructor. */ - Union(Union &&other) noexcept; - - /** Move assignment operator */ - Union &operator=(Union &&other) noexcept; - - /** @cond INTERNAL Boilerplate. */ - ~Union() override = default; - Union(const Union &) = delete; - Union &operator=(const Union &) = delete; - /** @endcond */ - - /** @brief Finish callback setter. - * - * @param [in] on_finish Callback, that will be called after the - * union is parsed. - * The callback will be called with a reference to the parser as an argument. - * If the callback returns false, parsing will be stopped with an error. - */ - void setFinishCallback(Callback on_finish); - - /** @brief Parsed object index getter. - * - * @return Index of a parsed object. - * - * @throw std::runtime_error Thrown if no members were parsed. - */ - [[nodiscard]] size_t currentMemberId(); - -#ifdef DOXYGEN_ONLY - /** @brief Check if the parser has a value. - * - * @return True if the parser parsed something or false otherwise. - */ - [[nodiscard]] bool isSet(); - - /** @brief Check if the parsed union was empy (null). - * - * @return True if the parsed union was empty (null) or false otherwise. - */ - [[nodiscard]] bool isEmpty(); -#endif - -#ifdef DOXYGEN_ONLY - /** @brief Universal member getter. - * - * @tparam n Index of the parser's member. - * - * @return If the n-th member parser stores value (is a Value, SAutoObject, - * SCustomObject, SUnion or SArray), then the method returns a const reference - * to the n-th member parser value. Otherwise, returns a reference to the n-th - * member parser. - * - * @throw std::runtime_error thrown if the member parser value is unset (no - * value was parsed or #pop was called for the member parser). - */ - [[nodiscard]] template auto &get(); - - /** @brief Member parser getter. - * - * @tparam n Index of the parser's member. - * - * @return Reference to n-th member parser. - */ - [[nodiscard]] template - ParserType &parser(); - - /** @brief Get the member parsed value and unset the member parser. - * - * Moves the n-th member parsed value out of the member parser. - * - * @tparam n Index of the parser's member. - * - * @return Rvalue reference to n-th member parser value. - * - * @throw std::runtime_error thrown if the member parser value is unset (no - * value was parsed or #pop was called for the member parser). - */ - template - ValueType &&pop(); -#endif - - protected: - void reset() override; - - private: - void setupIdsMap(); - - using KVParser::on; - - void on(TokenType value) override; - void on(MapStartT /*unused*/) override; - void on(MapKeyT key) override; - - void childParsed() override; - void finish() override; - - template struct MemberChecker { - explicit MemberChecker(Union & /*parser*/) {} - }; - - template - struct MemberChecker - : private MemberChecker { - explicit MemberChecker(Union &parser); - }; - - std::string _type_member; - Callback _on_finish; - std::unordered_map _members_ids_map; - size_t _current_member_id = 0; -}; - -/****************************** Implementations *******************************/ - -template -template -Union::Union( - TypeHolder type, - std::tuple...> members, CallbackT on_finish) - : Union{type, {}, std::move(members), std::move(on_finish)} {} - -template -template -Union::Union( - TypeHolder /*type*/, std::string_view type_member, - std::tuple...> members, CallbackT on_finish) - : KVParser{std::move(members), {}}, - _type_member{type_member}, - _on_finish{std::move(on_finish)} { - static_assert(std::is_constructible_v, - "Invalid callback type"); - setupIdsMap(); -} - -template -Union::Union(Union &&other) noexcept - : KVParser{std::move(other)}, - _type_member{std::move(other._type_member)}, - _on_finish{std::move(other._on_finish)}, - _current_member_id(other._current_member_id) { - setupIdsMap(); -} - -template -Union &Union::operator=( - Union &&other) noexcept { - KVParser::operator=(std::move(other)); - _type_member = std::move(other._type_member); - _on_finish = std::move(other._on_finish); - _current_member_id = other._current_member_id; - setupIdsMap(); - - return *this; -} - -template -void Union::setupIdsMap() { - _members_ids_map.clear(); - size_t index = 0; - for (const auto &id : KVParser::parsersArray()) { - _members_ids_map[id] = index; - ++index; - } -} - -template -void Union::setFinishCallback(Callback on_finish) { - _on_finish = on_finish; -} - -template -size_t Union::currentMemberId() { - TokenParser::checkSet(); - return _current_member_id; -} - -template -void Union::reset() { - _current_member_id = 0; - KVParser::reset(); -} - -template -void Union::on(TokenType value) { - reset(); - KVParser::onMember(value); - _current_member_id = _members_ids_map[KVParser::parsersMap()[value]]; -} - -template -void Union::on(MapStartT /*unused*/) { - if (_type_member.empty()) { - throw std::runtime_error( - "Union with an empty type member can't parse this"); - } - reset(); -} - -template -void Union::on(MapKeyT key) { - if (_type_member.empty()) { - throw std::runtime_error( - "Union with an empty type member can't parse this"); - } - if (key.key != _type_member) { - std::stringstream err; - err << "Unexpected member " << key.key; - throw std::runtime_error(err.str()); - } -} - -template -void Union::childParsed() { - KVParser::endParsing(); - if (_type_member.empty()) { - // The union embedded into an object must propagate the end event to the - // parent. - TokenParser::dispatcher()->on(MapEndT()); - } -} - -template -void Union::finish() { - if (TokenParser::isEmpty()) { - TokenParser::unset(); - return; - } - - try { - MemberChecker<0, ParserTs...>(*this); - } catch (std::exception &e) { - TokenParser::unset(); - throw; - } - - if (_on_finish && !_on_finish(*this)) { - throw std::runtime_error("Callback returned false"); - } -} - -template -template -Union::MemberChecker:: - MemberChecker(Union &parser) - : MemberChecker{parser} { - if (parser.currentMemberId() != n) { - return; - } - - auto &member = parser.memberParsers().template get(); - - if (!member.parser.isSet() && !member.optional) { - std::stringstream error; - error << "Mandatory member #" << n << " is not present"; - throw std::runtime_error(error.str()); - } -} - -} // namespace SJParser diff --git a/contrib/sjparser/library/sjparser/value.h b/contrib/sjparser/library/sjparser/value.h index af0084a6..4ec69b24 100644 --- a/contrib/sjparser/library/sjparser/value.h +++ b/contrib/sjparser/library/sjparser/value.h @@ -23,10 +23,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once -#include "internals/token_parser.h" - #include +#include "internals/token_parser.h" + namespace SJParser { /** @brief Plain value parser. diff --git a/contrib/sjparser/library/sjparser/yajl_parser.h b/contrib/sjparser/library/sjparser/yajl_parser.h index 896bd878..08f6a0c3 100644 --- a/contrib/sjparser/library/sjparser/yajl_parser.h +++ b/contrib/sjparser/library/sjparser/yajl_parser.h @@ -23,13 +23,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once -#include "internals/dispatcher.h" -#include "parsing_error.h" - #include + #include #include +#include "internals/dispatcher.h" +#include "parsing_error.h" + namespace SJParser { /** @brief YAJL parser adapter. diff --git a/contrib/sjparser/tests/CMakeLists.txt b/contrib/sjparser/tests/CMakeLists.txt index 1d2c6d4d..22f55b6f 100644 --- a/contrib/sjparser/tests/CMakeLists.txt +++ b/contrib/sjparser/tests/CMakeLists.txt @@ -7,10 +7,6 @@ add_executable(sjparser_tests src/object.cpp src/scustomobject.cpp src/sautoobject.cpp - src/standalone_union.cpp - src/standalone_sunion.cpp - src/embedded_union.cpp - src/embedded_sunion.cpp src/parsing_error.cpp src/yajl_parser.cpp src/dispatcher.cpp diff --git a/contrib/sjparser/tests/src/array.cpp b/contrib/sjparser/tests/src/array.cpp index 180845c9..93ca6179 100644 --- a/contrib/sjparser/tests/src/array.cpp +++ b/contrib/sjparser/tests/src/array.cpp @@ -22,7 +22,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include + #include "sjparser/sjparser.h" using namespace SJParser; diff --git a/contrib/sjparser/tests/src/dispatcher.cpp b/contrib/sjparser/tests/src/dispatcher.cpp index f79cfd4c..039c7fe7 100644 --- a/contrib/sjparser/tests/src/dispatcher.cpp +++ b/contrib/sjparser/tests/src/dispatcher.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include "sjparser/sjparser.h" #include "test_parser.h" diff --git a/contrib/sjparser/tests/src/embedded_sunion.cpp b/contrib/sjparser/tests/src/embedded_sunion.cpp deleted file mode 100644 index e37e5015..00000000 --- a/contrib/sjparser/tests/src/embedded_sunion.cpp +++ /dev/null @@ -1,588 +0,0 @@ -/******************************************************************************* - -Copyright (c) 2016-2017 Denis Tikhomirov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*******************************************************************************/ - -#include -#include "sjparser/sjparser.h" -#include "test_parser.h" - -using namespace SJParser; - -TEST(EmbeddedSUnion, Empty) { - std::string buf(R"({"type": 1})"); - - Parser parser{Object{std::tuple{Member{ - "type", SUnion{TypeHolder{}, - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, SAutoObject{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - ASSERT_EQ("Can not set value: Mandatory member #0 is not present", - e.sjparserError()); - - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - {"type": 1} - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedSUnion, OptionalMember) { - std::string buf(R"({"type": 1})"); - - Parser parser{Object{std::tuple{Member{ - "type", - SUnion{ - TypeHolder{}, - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}, - Presence::Optional}, - Member{2, SAutoObject{ - std::tuple{Member{"int", Value{}}}}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - ASSERT_EQ( - "Can not set value: Optional member #0 does not have a default value", - e.sjparserError()); - - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - {"type": 1} - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedSUnion, OptionalMemberWithDefaultValue) { - std::string buf(R"({"type": 1})"); - - Parser parser{Object{std::tuple{Member{ - "type", - SUnion{ - TypeHolder{}, - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}, - Presence::Optional, std::tuple{false}}, - Member{2, SAutoObject{ - std::tuple{Member{"int", Value{}}}}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().parser<0>().isSet()); - ASSERT_FALSE(parser.parser().parser<0>().isEmpty()); - - auto variant = parser.parser().get<0>(); - - ASSERT_EQ(0, variant.index()); - - auto object = std::get<0>(variant); - - ASSERT_EQ(false, std::get<0>(object)); -} - -TEST(EmbeddedSUnion, Reset) { - std::string buf(R"({"type": 1, "bool": true, "integer": 10})"); - - Parser parser{Object{std::tuple{Member{ - "type", - SUnion{TypeHolder{}, - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{}}, - Member{"integer", Value{}}}}}, - Member{2, SAutoObject{std::tuple{ - Member{"bool", Value{}}}}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().parser<0>().isSet()); - ASSERT_FALSE(parser.parser().parser<0>().isEmpty()); - - auto variant = parser.parser().get<0>(); - - ASSERT_EQ(0, variant.index()); - - auto object = std::get<0>(variant); - - ASSERT_EQ(true, std::get<0>(object)); - ASSERT_EQ(10, std::get<1>(object)); - - buf = R"(null)"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - ASSERT_TRUE(parser.parser().parser<0>().isEmpty()); -} - -TEST(EmbeddedSUnion, AllValuesMembers) { - std::string buf(R"({"type": 1, "bool": true, "integer": 10})"); - - Parser parser{Object{std::tuple{Member{ - "type", - SUnion{TypeHolder{}, - std::tuple{ - Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{}}, - Member{"integer", Value{}}}}}, - Member{2, SAutoObject{std::tuple{ - Member{"double", Value{}}, - Member{"string", Value{}}}}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - { - auto variant = parser.parser().get<0>(); - - ASSERT_EQ(0, variant.index()); - - auto object = std::get<0>(variant); - - ASSERT_EQ(true, std::get<0>(object)); - ASSERT_EQ(10, std::get<1>(object)); - } - - buf = R"({"type": 2, "double": 11.5, "string": "value"})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - { - auto variant = parser.parser().get<0>(); - - ASSERT_EQ(1, variant.index()); - - auto object = std::get<1>(variant); - - ASSERT_EQ(11.5, std::get<0>(object)); - ASSERT_EQ("value", std::get<1>(object)); - } -} - -TEST(EmbeddedSUnion, StringType) { - std::string buf( - R"( -{ - "type": "1", - "bool": true -})"); - - Parser parser{Object{std::tuple{Member{ - "type", - SUnion{TypeHolder{}, - std::tuple{Member{"1", SAutoObject{std::tuple{ - Member{"bool", Value{}}}}}, - Member{"2", SAutoObject{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - { - auto variant = parser.parser().get<0>(); - - ASSERT_EQ(0, variant.index()); - - ASSERT_EQ(true, std::get<0>(std::get<0>(variant))); - } - - buf = R"( -{ - "type": "2", - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - { - auto variant = parser.parser().get<0>(); - - ASSERT_EQ(1, variant.index()); - - ASSERT_EQ(100, std::get<0>(std::get<1>(variant))); - } -} - -TEST(EmbeddedSUnion, IncorrectTypeType) { - std::string buf( - R"( -{ - "type": "1", - "bool": true -})"); - - Parser parser{Object{std::tuple{Member{ - "type", SUnion{TypeHolder{}, - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, SAutoObject{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Unexpected token string", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": "1", "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedSUnion, IncorrectTypeValue) { - std::string buf( - R"( -{ - "type": 3, - "bool": true -})"); - - Parser parser{Object{std::tuple{Member{ - "type", SUnion{TypeHolder{}, - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, SAutoObject{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Unexpected member 3", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 3, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedSUnion, MembersWithCallbackError) { - std::string buf( - R"( -{ - "type": 1, - "bool": true -})"); - - auto boolCb = [&](const std::tuple &) { return false; }; - - auto intCb = [&](const std::tuple &) { return false; }; - - Parser parser{Object{std::tuple{Member{ - "type", - SUnion{TypeHolder{}, - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{boolCb}}}}}, - Member{2, SAutoObject{std::tuple{Member{ - "int", Value{intCb}}}}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 2, "int": 100 } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedSUnion, SUnionWithCallback) { - std::string buf( - R"( -{ - "type": 1, - "bool": true -})"); - - bool bool_value = false; - int64_t int_value; - - Parser parser{Object{std::tuple{Member{ - "type", SUnion{TypeHolder{}, - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, SAutoObject{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - auto unionCb = - [&](const std::variant, std::tuple> &value) { - if (value.index() == 0) { - bool_value = std::get<0>(std::get<0>(value)); - } else { - int_value = std::get<0>(std::get<1>(value)); - } - return true; - }; - - parser.parser().parser<0>().setFinishCallback(unionCb); - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(true, std::get<0>(std::get<0>(parser.parser().get<0>()))); - ASSERT_EQ(true, bool_value); - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(100, std::get<0>(std::get<1>(parser.parser().get<0>()))); - ASSERT_EQ(100, int_value); -} - -TEST(EmbeddedSUnion, SUnionWithCallbackError) { - std::string buf(R"( -{ - "type": 1, - "bool": true -})"); - - Parser parser{Object{std::tuple{Member{ - "type", SUnion{TypeHolder{}, - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, SAutoObject{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - auto unionCb = - [&](const std::variant, std::tuple> &) { - return false; - }; - - parser.parser().parser<0>().setFinishCallback(unionCb); - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_TRUE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - "type": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedSUnion, SUnionWithUnexpectedObject) { - std::string buf( - R"( -{ - "type": 1, - "error": true -})"); - - Parser parser{Object{std::tuple{Member{ - "type", SUnion{TypeHolder{}, - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, SAutoObject{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Unexpected member error", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 1, "error": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedSUnion, SUnionWithUnexpectedMapStart) { - std::string buf( - R"( -{ - "type": 1, - "bool": true -})"); - - Parser parser{SUnion{ - TypeHolder{}, - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Union with an empty type member can't parse this", - e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedSUnion, SUnionWithUnexpectedMapKey) { - Parser parser{SUnion{TypeHolder{}, - std::tuple{Member{1, SAutoObject{std::tuple{Member{ - "bool", Value{}}}}}, - Member{2, SAutoObject{std::tuple{Member{ - "int", Value{}}}}}}}, - TypeHolder{}}; - - auto test = [](TestParser *parser) { - parser->dispatcher->on(MapKeyT{"test"}); - }; - - try { - parser.run(test); - FAIL() << "No exception thrown"; - } catch (std::runtime_error &e) { - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_STREQ("Union with an empty type member can't parse this", e.what()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedSUnion, EmbeddedSUnionWithParserReference) { - std::string buf( - R"( -{ - "type": 1, - "bool": true, - "string": "value" -})"); - - SAutoObject sautoobject{std::tuple{Member{"bool", Value{}}, - Member{"string", Value{}}}}; - - Parser parser{Object{std::tuple{Member{ - "type", SUnion{TypeHolder{}, - std::tuple{Member{1, sautoobject}, - Member{2, SAutoObject{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(true, std::get<0>(std::get<0>(parser.parser().get<0>()))); - ASSERT_EQ("value", std::get<1>(std::get<0>(parser.parser().get<0>()))); - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(100, std::get<0>(std::get<1>(parser.parser().get<0>()))); - - ASSERT_EQ(&(parser.parser().parser<0>().parser<0>()), &sautoobject); -} diff --git a/contrib/sjparser/tests/src/embedded_union.cpp b/contrib/sjparser/tests/src/embedded_union.cpp deleted file mode 100644 index ec299b1b..00000000 --- a/contrib/sjparser/tests/src/embedded_union.cpp +++ /dev/null @@ -1,557 +0,0 @@ -/******************************************************************************* - -Copyright (c) 2016-2017 Denis Tikhomirov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*******************************************************************************/ - -#include -#include "sjparser/sjparser.h" -#include "test_parser.h" - -using namespace SJParser; - -TEST(EmbeddedUnion, Empty) { - std::string buf(R"({"type": 1})"); - - Parser parser{Object{std::tuple{Member{ - "type", Union{TypeHolder{}, - std::tuple{Member{1, Object{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - ASSERT_EQ("Mandatory member #0 is not present", e.sjparserError()); - - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - {"type": 1} - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedUnion, OptionalMember) { - std::string buf(R"({"type": 1})"); - - Parser parser{Object{std::tuple{Member{ - "type", - Union{TypeHolder{}, - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}, - Presence::Optional}, - Member{2, Object{std::tuple{ - Member{"int", Value{}}}}}}}}}}}; - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().parser<0>().isSet()); - ASSERT_FALSE(parser.parser().parser<0>().isEmpty()); - ASSERT_EQ(0, parser.parser().parser<0>().currentMemberId()); - ASSERT_FALSE(parser.parser().parser<0>().parser<0>().isSet()); -} - -TEST(EmbeddedUnion, OptionalMemberWithDefaultValue) { - std::string buf(R"({"type": 1})"); - - Parser parser{Object{std::tuple{Member{ - "type", - Union{ - TypeHolder{}, - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}, - Presence::Optional, std::tuple{false}}, - Member{2, - Object{std::tuple{Member{"int", Value{}}}}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().parser<0>().isSet()); - ASSERT_FALSE(parser.parser().parser<0>().isEmpty()); - ASSERT_EQ(0, parser.parser().parser<0>().currentMemberId()); - ASSERT_FALSE(parser.parser().parser<0>().parser<0>().isSet()); - ASSERT_EQ(std::tuple{false}, parser.parser().parser<0>().get<0>()); -} - -TEST(EmbeddedUnion, Reset) { - std::string buf(R"({"type": 1, "bool": true, "integer": 10})"); - - Parser parser{Object{std::tuple{Member{ - "type", - Union{TypeHolder{}, - std::tuple{Member{1, Object{std::tuple{ - Member{"bool", Value{}}, - Member{"integer", Value{}}}}}, - Member{2, Object{std::tuple{ - Member{"bool", Value{}}}}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().get<0>().parser<0>().isSet()); - ASSERT_FALSE(parser.parser().parser<0>().isEmpty()); - ASSERT_FALSE(parser.parser().get<0>().parser<1>().isSet()); - ASSERT_EQ(0, parser.parser().get<0>().currentMemberId()); - - ASSERT_EQ(true, parser.parser().get<0>().get<0>().get<0>()); - ASSERT_EQ(10, parser.parser().get<0>().get<0>().get<1>()); - - buf = R"(null)"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - ASSERT_TRUE(parser.parser().parser<0>().isEmpty()); -} - -TEST(EmbeddedUnion, AllValuesMembers) { - std::string buf(R"({"type": 1, "bool": true, "integer": 10})"); - - Parser parser{Object{std::tuple{Member{ - "type", - Union{TypeHolder{}, - std::tuple{ - Member{1, Object{std::tuple{ - Member{"bool", Value{}}, - Member{"integer", Value{}}}}}, - Member{2, Object{std::tuple{ - Member{"double", Value{}}, - Member{"string", Value{}}}}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().get<0>().parser<0>().isSet()); - ASSERT_FALSE(parser.parser().get<0>().parser<1>().isSet()); - ASSERT_EQ(0, parser.parser().get<0>().currentMemberId()); - - ASSERT_EQ(true, parser.parser().get<0>().get<0>().get<0>()); - ASSERT_EQ(10, parser.parser().get<0>().get<0>().get<1>()); - - buf = R"({"type": 2, "double": 11.5, "string": "value"})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().get<0>().parser<0>().isSet()); - ASSERT_TRUE(parser.parser().get<0>().parser<1>().isSet()); - ASSERT_EQ(1, parser.parser().get<0>().currentMemberId()); - - ASSERT_EQ(11.5, parser.parser().get<0>().get<1>().get<0>()); - ASSERT_EQ("value", parser.parser().get<0>().get<1>().get<1>()); -} - -TEST(EmbeddedUnion, StringType) { - std::string buf( - R"( -{ - "type": "1", - "bool": true -})"); - - Parser parser{Object{std::tuple{Member{ - "type", - Union{TypeHolder{}, - std::tuple{ - Member{"1", Object{std::tuple{Member{"bool", Value{}}}}}, - Member{"2", Object{std::tuple{ - Member{"int", Value{}}}}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().get<0>().parser<0>().isSet()); - ASSERT_FALSE(parser.parser().get<0>().parser<1>().isSet()); - ASSERT_EQ(0, parser.parser().get<0>().currentMemberId()); - - ASSERT_EQ(true, parser.parser().get<0>().get<0>().get<0>()); - - buf = R"( -{ - "type": "2", - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().get<0>().parser<0>().isSet()); - ASSERT_TRUE(parser.parser().get<0>().parser<1>().isSet()); - ASSERT_EQ(1, parser.parser().get<0>().currentMemberId()); - - ASSERT_EQ(100, parser.parser().get<0>().get<1>().get<0>()); -} - -TEST(EmbeddedUnion, IncorrectTypeType) { - std::string buf( - R"( -{ - "type": "1", - "bool": true -})"); - - Parser parser{Object{std::tuple{Member{ - "type", Union{TypeHolder{}, - std::tuple{Member{1, Object{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Unexpected token string", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": "1", "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedUnion, IncorrectTypeValue) { - std::string buf( - R"( -{ - "type": 3, - "bool": true -})"); - - Parser parser{Object{std::tuple{Member{ - "type", Union{TypeHolder{}, - std::tuple{Member{1, Object{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Unexpected member 3", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 3, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedUnion, MembersWithCallbackError) { - std::string buf( - R"( -{ - "type": 1, - "bool": true -})"); - - Parser parser{Object{std::tuple{Member{ - "type", Union{TypeHolder{}, - std::tuple{Member{1, Object{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - auto boolCb = - [&](decltype(parser)::ParserType::ParserType<0>::ParserType<0> &) { - return false; - }; - - auto intCb = - [&](decltype(parser)::ParserType::ParserType<0>::ParserType<1> &) { - return false; - }; - - parser.parser().parser<0>().parser<0>().setFinishCallback(boolCb); - parser.parser().parser<0>().parser<1>().setFinishCallback(intCb); - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - "type": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 2, "int": 100 } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedUnion, UnionWithCallback) { - std::string buf( - R"( -{ - "type": 1, - "bool": true -})"); - - bool bool_value = false; - int64_t int_value; - - Parser parser{Object{std::tuple{Member{ - "type", Union{TypeHolder{}, - std::tuple{Member{1, Object{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - auto unionCb = [&](decltype(parser)::ParserType::ParserType<0> &parser) { - if (parser.currentMemberId() == 0) { - bool_value = parser.get<0>().get<0>(); - } else { - int_value = parser.get<1>().get<0>(); - } - return true; - }; - - parser.parser().parser<0>().setFinishCallback(unionCb); - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(true, parser.parser().get<0>().get<0>().get<0>()); - ASSERT_EQ(true, bool_value); - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(100, parser.parser().get<0>().get<1>().get<0>()); - ASSERT_EQ(100, int_value); -} - -TEST(EmbeddedUnion, UnionWithCallbackError) { - std::string buf(R"( -{ - "type": 1, - "bool": true -})"); - - Parser parser{Object{std::tuple{Member{ - "type", Union{TypeHolder{}, - std::tuple{Member{1, Object{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - auto unionCb = [&](decltype(parser)::ParserType::ParserType<0> &) { - return false; - }; - - parser.parser().parser<0>().setFinishCallback(unionCb); - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_TRUE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - "type": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedUnion, UnionWithUnexpectedObject) { - std::string buf( - R"( -{ - "type": 1, - "error": true -})"); - - Parser parser{Object{std::tuple{Member{ - "type", Union{TypeHolder{}, - std::tuple{Member{1, Object{std::tuple{ - Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - - ASSERT_EQ("Unexpected member error", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 1, "error": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedUnion, UnionWithUnexpectedMapStart) { - std::string buf(R"( -{ - "type": 1, - "bool": true -})"); - - Parser parser{Union{ - TypeHolder{}, - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Union with an empty type member can't parse this", - e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedUnion, UnionWithUnexpectedMapKey) { - Parser parser{ - Union{ - TypeHolder{}, - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}, - TypeHolder{}}; - - auto test = [](TestParser *parser) { - parser->dispatcher->on(MapKeyT{"test"}); - }; - - try { - parser.run(test); - FAIL() << "No exception thrown"; - } catch (std::runtime_error &e) { - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_STREQ("Union with an empty type member can't parse this", e.what()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(EmbeddedUnion, EmbeddedUnionWithParserReference) { - std::string buf( - R"( -{ - "type": 1, - "bool": true, - "string": "value" -})"); - - SAutoObject sautoobject{std::tuple{Member{"bool", Value{}}, - Member{"string", Value{}}}}; - - Parser parser{Object{std::tuple{Member{ - "type", Union{TypeHolder{}, - std::tuple{Member{1, sautoobject}, - Member{2, Object{std::tuple{Member{ - "int", Value{}}}}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(true, std::get<0>(parser.parser().get<0>().get<0>())); - ASSERT_EQ("value", std::get<1>(parser.parser().get<0>().get<0>())); - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(100, parser.parser().get<0>().get<1>().get<0>()); - - ASSERT_EQ(&(parser.parser().parser<0>().parser<0>()), &sautoobject); -} diff --git a/contrib/sjparser/tests/src/ignore.cpp b/contrib/sjparser/tests/src/ignore.cpp index d2ee25da..e604eaaa 100644 --- a/contrib/sjparser/tests/src/ignore.cpp +++ b/contrib/sjparser/tests/src/ignore.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include "sjparser/sjparser.h" #include "test_parser.h" diff --git a/contrib/sjparser/tests/src/map.cpp b/contrib/sjparser/tests/src/map.cpp index 80431c51..27689cac 100644 --- a/contrib/sjparser/tests/src/map.cpp +++ b/contrib/sjparser/tests/src/map.cpp @@ -22,7 +22,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include + #include "sjparser/sjparser.h" using namespace SJParser; diff --git a/contrib/sjparser/tests/src/member.cpp b/contrib/sjparser/tests/src/member.cpp index 9316ce92..0a80f385 100644 --- a/contrib/sjparser/tests/src/member.cpp +++ b/contrib/sjparser/tests/src/member.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include "sjparser/sjparser.h" using namespace SJParser; diff --git a/contrib/sjparser/tests/src/object.cpp b/contrib/sjparser/tests/src/object.cpp index b56ad554..1861c149 100644 --- a/contrib/sjparser/tests/src/object.cpp +++ b/contrib/sjparser/tests/src/object.cpp @@ -22,7 +22,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include + #include "sjparser/sjparser.h" using namespace SJParser; diff --git a/contrib/sjparser/tests/src/parser.cpp b/contrib/sjparser/tests/src/parser.cpp index 8746d97f..fc9234d5 100644 --- a/contrib/sjparser/tests/src/parser.cpp +++ b/contrib/sjparser/tests/src/parser.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include "sjparser/sjparser.h" using namespace SJParser; diff --git a/contrib/sjparser/tests/src/parsing_error.cpp b/contrib/sjparser/tests/src/parsing_error.cpp index c997e0d3..e189a2fa 100644 --- a/contrib/sjparser/tests/src/parsing_error.cpp +++ b/contrib/sjparser/tests/src/parsing_error.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include "sjparser/parsing_error.h" + #include using namespace SJParser; diff --git a/contrib/sjparser/tests/src/sarray.cpp b/contrib/sjparser/tests/src/sarray.cpp index a14be47a..b93beab5 100644 --- a/contrib/sjparser/tests/src/sarray.cpp +++ b/contrib/sjparser/tests/src/sarray.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include "sjparser/sjparser.h" using namespace SJParser; diff --git a/contrib/sjparser/tests/src/sautoobject.cpp b/contrib/sjparser/tests/src/sautoobject.cpp index 16949872..3f578824 100644 --- a/contrib/sjparser/tests/src/sautoobject.cpp +++ b/contrib/sjparser/tests/src/sautoobject.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include "sjparser/sjparser.h" using namespace SJParser; diff --git a/contrib/sjparser/tests/src/scustomobject.cpp b/contrib/sjparser/tests/src/scustomobject.cpp index 12f7ab6f..f65a3d32 100644 --- a/contrib/sjparser/tests/src/scustomobject.cpp +++ b/contrib/sjparser/tests/src/scustomobject.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include "sjparser/sjparser.h" using namespace SJParser; diff --git a/contrib/sjparser/tests/src/smap.cpp b/contrib/sjparser/tests/src/smap.cpp index 4edec3e9..21463e61 100644 --- a/contrib/sjparser/tests/src/smap.cpp +++ b/contrib/sjparser/tests/src/smap.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include "sjparser/sjparser.h" using namespace SJParser; diff --git a/contrib/sjparser/tests/src/standalone_sunion.cpp b/contrib/sjparser/tests/src/standalone_sunion.cpp deleted file mode 100644 index 18f72b51..00000000 --- a/contrib/sjparser/tests/src/standalone_sunion.cpp +++ /dev/null @@ -1,781 +0,0 @@ -/******************************************************************************* - -Copyright (c) 2016-2017 Denis Tikhomirov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*******************************************************************************/ - -#include -#include "sjparser/sjparser.h" - -using namespace SJParser; - -TEST(StandaloneSUnion, Empty) { - std::string buf(R"({})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_TRUE(parser.parser().isEmpty()); -} - -TEST(StandaloneSUnion, EmptyWithType) { - std::string buf(R"({"type": 1})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_EQ("Can not set value: Mandatory member #0 is not present", - e.sjparserError()); - - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - {"type": 1} - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneSUnion, OptionalMember) { - std::string buf(R"({"type": 1})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}, - Presence::Optional}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_EQ( - "Can not set value: Optional member #0 does not have a default value", - e.sjparserError()); - - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - {"type": 1} - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneSUnion, OptionalMemberWithDefaultValue) { - std::string buf(R"({"type": 1})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}, - Presence::Optional, std::tuple{false}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - auto variant = parser.parser().get(); - - ASSERT_EQ(0, variant.index()); - - ASSERT_EQ(false, std::get<0>(std::get<0>(variant))); -} - -TEST(StandaloneSUnion, Null) { - std::string buf(R"(null)"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_TRUE(parser.parser().isEmpty()); -} - -TEST(StandaloneSUnion, Reset) { - std::string buf(R"({"type": 1, "bool": true, "integer": 10})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, - SAutoObject{std::tuple{Member{"bool", Value{}}, - Member{"integer", Value{}}}}}, - Member{2, SAutoObject{std::tuple{Member{"bool", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - auto variant = parser.parser().get(); - - ASSERT_EQ(0, variant.index()); - - auto object = std::get<0>(variant); - - ASSERT_EQ(true, std::get<0>(object)); - ASSERT_EQ(10, std::get<1>(object)); - - buf = R"(null)"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_TRUE(parser.parser().isEmpty()); -} - -TEST(StandaloneSUnion, AllValuesMembers) { - std::string buf(R"({"type": 1, "bool": true, "integer": 10})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{}}, - Member{"integer", Value{}}}}}, - Member{2, SAutoObject{std::tuple{ - Member{"double", Value{}}, - Member{"string", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - { - auto variant = parser.parser().get(); - - ASSERT_EQ(0, variant.index()); - - auto object = std::get<0>(variant); - - ASSERT_EQ(true, std::get<0>(object)); - ASSERT_EQ(10, std::get<1>(object)); - } - - buf = R"({"type": 2, "double": 11.5, "string": "value"})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - { - auto variant = parser.parser().get(); - - ASSERT_EQ(1, variant.index()); - - auto object = std::get<1>(variant); - - ASSERT_EQ(11.5, std::get<0>(object)); - ASSERT_EQ("value", std::get<1>(object)); - } -} - -TEST(StandaloneSUnion, StringType) { - std::string buf( - R"( -{ - "type": "1", - "bool": true -})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{"1", SAutoObject{std::tuple{Member{"bool", Value{}}}}}, - Member{"2", - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - { - auto variant = parser.parser().get(); - - ASSERT_EQ(0, variant.index()); - - ASSERT_EQ(true, std::get<0>(std::get<0>(variant))); - } - - buf = R"( -{ - "type": "2", - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - { - auto variant = parser.parser().get(); - - ASSERT_EQ(1, variant.index()); - - ASSERT_EQ(100, std::get<0>(std::get<1>(variant))); - } -} - -TEST(StandaloneSUnion, IncorrectTypeType) { - std::string buf( - R"( -{ - "type": "1", - "bool": true -})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Unexpected token string", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": "1", "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneSUnion, IncorrectTypeValue) { - std::string buf( - R"( -{ - "type": 3, - "bool": true -})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Unexpected member 3", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 3, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneSUnion, IncorrectTypeMember) { - std::string buf( - R"( -{ - "error": 1, - "bool": true -})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Unexpected member error", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "error": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneSUnion, MembersWithCallbackError) { - std::string buf( - R"( -{ - "type": 1, - "bool": true -})"); - - auto boolCb = [&](const std::tuple &) { return false; }; - - auto intCb = [&](const std::tuple &) { return false; }; - - Parser parser{ - SUnion{TypeHolder{}, "type", - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{boolCb}}}}}, - Member{2, SAutoObject{std::tuple{Member{ - "int", Value{intCb}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 2, "int": 100 } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneSUnion, SUnionWithCallback) { - std::string buf( - R"( -{ - "type": 1, - "bool": true -})"); - - bool bool_value = false; - int64_t int_value; - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - auto unionCb = - [&](const std::variant, std::tuple> &value) { - if (value.index() == 0) { - bool_value = std::get<0>(std::get<0>(value)); - } else { - int_value = std::get<0>(std::get<1>(value)); - } - return true; - }; - - parser.parser().setFinishCallback(unionCb); - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(true, std::get<0>(std::get<0>(parser.parser().get()))); - ASSERT_EQ(true, bool_value); - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(100, std::get<0>(std::get<1>(parser.parser().get()))); - ASSERT_EQ(100, int_value); -} - -TEST(StandaloneSUnion, SUnionWithCallbackError) { - std::string buf(R"( -{ - "type": 1, - "bool": true -})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - auto unionCb = - [&](const std::variant, std::tuple> &) { - return false; - }; - - parser.parser().setFinishCallback(unionCb); - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_TRUE(parser.parser().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - "type": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneSUnion, SUnionWithUnexpectedObject) { - std::string buf( - R"( -{ - "type": 1, - "error": true -})"); - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Unexpected member error", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 1, "error": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -template struct MoveStruct { - Member1 member1; - Member2 member2; - static bool copy_used; - - MoveStruct() { - if constexpr (std::is_integral_v< - Member1> || std::is_floating_point_v) { - member1 = 0; - } - if constexpr (std::is_integral_v< - Member2> || std::is_floating_point_v) { - member2 = 0; - } - } - - MoveStruct(const MoveStruct &other) { - member1 = std::move(other.member1); - member2 = std::move(other.member2); - copy_used = true; - } - - MoveStruct &operator=(const MoveStruct &other) { - member1 = std::move(other.member1); - member2 = std::move(other.member2); - copy_used = true; - return *this; - } - - MoveStruct(MoveStruct &&other) { - member1 = std::move(other.member1); - member2 = std::move(other.member2); - } -}; - -template -bool MoveStruct::copy_used = false; - -TEST(StandaloneSUnion, Move) { - std::string buf(R"({"type": 1, "bool": true, "integer": 10})"); - - using ObjectStruct1 = MoveStruct; - using ObjectStruct2 = MoveStruct; - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SCustomObject{TypeHolder{}, - std::tuple{ - Member{"bool", Value{}}, - Member{"integer", Value{}}}}}, - Member{2, SCustomObject{ - TypeHolder{}, - std::tuple{Member{"double", Value{}}, - Member{"string", Value{}}}}}}}}; - - auto objectCb1 = [&](decltype(parser)::ParserType::ParserType<0> &parser, - auto &value) { - value.member1 = parser.get<0>(); - value.member2 = parser.get<1>(); - return true; - }; - - auto objectCb2 = [&](decltype(parser)::ParserType::ParserType<1> &parser, - auto &value) { - value.member1 = parser.get<0>(); - value.member2 = parser.get<1>(); - return true; - }; - - parser.parser().parser<0>().setFinishCallback(objectCb1); - parser.parser().parser<1>().setFinishCallback(objectCb2); - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ObjectStruct1::copy_used = false; - - { - auto variant = parser.parser().pop(); - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_FALSE((ObjectStruct1::copy_used)); - - ASSERT_EQ(0, variant.index()); - - auto &object = std::get<0>(variant); - - ASSERT_EQ(true, object.member1); - ASSERT_EQ(10, object.member2); - } - - buf = R"({"type": 2, "double": 11.5, "string": "value"})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ObjectStruct2::copy_used = false; - - { - auto variant = parser.parser().pop(); - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_FALSE((ObjectStruct2::copy_used)); - - ASSERT_EQ(1, variant.index()); - - auto &object = std::get<1>(variant); - - ASSERT_EQ(11.5, object.member1); - ASSERT_EQ("value", object.member2); - } -} - -TEST(StandaloneSUnion, UnknownExceptionInValueSetter) { - std::string buf(R"({"type": 1, "bool": true})"); - - struct ObjectStruct { - bool throw_on_assign = false; - - ObjectStruct() {} - - ObjectStruct(const ObjectStruct &) {} - - ObjectStruct &operator=(const ObjectStruct &other) { - throw_on_assign = other.throw_on_assign; - if (throw_on_assign) { - throw 10; - } - return *this; - } - }; - - Parser parser{SUnion{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SCustomObject{TypeHolder{}, - std::tuple{Member{"bool", Value{}}}}}, - Member{2, - SAutoObject{std::tuple{Member{"int", Value{}}}}}}}}; - - auto innerObjectCb = [&](decltype(parser)::ParserType::ParserType<0> &, - ObjectStruct &object) { - object.throw_on_assign = true; - return true; - }; - - parser.parser().parser<0>().setFinishCallback(innerObjectCb); - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_EQ("Can not set value: unknown exception", e.sjparserError()); - - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - {"type": 1, "bool": true} - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneSUnion, StandaloneSUnionWithParserReference) { - std::string buf( - R"( -{ - "type": 1, - "bool": true, - "string": "value" -})"); - - SAutoObject sautoobject{std::tuple{Member{"bool", Value{}}, - Member{"string", Value{}}}}; - - Parser parser{SUnion{TypeHolder{}, "type", - std::tuple{Member{1, sautoobject}, - Member{2, SAutoObject{std::tuple{Member{ - "int", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(true, std::get<0>(std::get<0>(parser.parser().get()))); - ASSERT_EQ("value", std::get<1>(std::get<0>(parser.parser().get()))); - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(100, std::get<0>(std::get<1>(parser.parser().get()))); - - ASSERT_EQ(&(parser.parser().parser<0>()), &sautoobject); -} - -TEST(StandaloneSUnion, MoveAssignment) { - std::string buf(R"({"type": 1, "bool": true, "integer": 10})"); - - auto sunion_parser_src = SUnion{ - TypeHolder{}, "type", - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool", Value{}}, - Member{"integer", Value{}}}}}, - Member{2, SAutoObject{std::tuple{ - Member{"double", Value{}}, - Member{"string", Value{}}}}}}}; - auto sunion_parser = SUnion{ - TypeHolder{}, "type", - std::tuple{Member{1, SAutoObject{std::tuple{ - Member{"bool_", Value{}}, - Member{"integer_", Value{}}}}}, - Member{2, SAutoObject{std::tuple{ - Member{"double_", Value{}}, - Member{"string_", Value{}}}}}}}; - sunion_parser = std::move(sunion_parser_src); - - Parser parser{sunion_parser}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - auto variant = parser.parser().get(); - - ASSERT_EQ(0, variant.index()); - - auto object = std::get<0>(variant); - - ASSERT_EQ(true, std::get<0>(object)); - ASSERT_EQ(10, std::get<1>(object)); -} diff --git a/contrib/sjparser/tests/src/standalone_union.cpp b/contrib/sjparser/tests/src/standalone_union.cpp deleted file mode 100644 index de948789..00000000 --- a/contrib/sjparser/tests/src/standalone_union.cpp +++ /dev/null @@ -1,593 +0,0 @@ -/******************************************************************************* - -Copyright (c) 2016-2017 Denis Tikhomirov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*******************************************************************************/ - -#include -#include "sjparser/sjparser.h" - -using namespace SJParser; - -TEST(StandaloneUnion, Empty) { - std::string buf(R"({})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_TRUE(parser.parser().isEmpty()); -} - -TEST(StandaloneUnion, EmptyWithType) { - std::string buf(R"({"type": 1})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_EQ("Mandatory member #0 is not present", e.sjparserError()); - - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - {"type": 1} - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneUnion, OptionalMember) { - std::string buf(R"({"type": 1})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}, - Presence::Optional}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().isSet()); - ASSERT_FALSE(parser.parser().isEmpty()); - ASSERT_EQ(0, parser.parser().currentMemberId()); - ASSERT_FALSE(parser.parser().parser<0>().isSet()); -} - -TEST(StandaloneUnion, OptionalMemberWithDefaultValue) { - std::string buf(R"({"type": 1})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, SAutoObject{std::tuple{Member{"bool", Value{}}}}, - Presence::Optional, std::tuple{false}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().isSet()); - ASSERT_FALSE(parser.parser().isEmpty()); - ASSERT_EQ(0, parser.parser().currentMemberId()); - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - ASSERT_EQ(std::tuple{false}, parser.parser().get<0>()); -} - -TEST(StandaloneUnion, Null) { - std::string buf(R"(null)"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_TRUE(parser.parser().isEmpty()); -} - -TEST(StandaloneUnion, Reset) { - std::string buf(R"({"type": 1, "bool": true, "integer": 10})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}, - Member{"integer", Value{}}}}}, - Member{2, Object{std::tuple{Member{"bool", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().parser<0>().isSet()); - ASSERT_FALSE(parser.parser().isEmpty()); - ASSERT_FALSE(parser.parser().parser<1>().isSet()); - ASSERT_EQ(0, parser.parser().currentMemberId()); - - ASSERT_EQ(true, parser.parser().get<0>().get<0>()); - ASSERT_EQ(10, parser.parser().get<0>().get<1>()); - - buf = R"(null)"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().isSet()); - ASSERT_TRUE(parser.parser().isEmpty()); -} - -TEST(StandaloneUnion, AllValuesMembers) { - std::string buf(R"({"type": 1, "bool": true, "integer": 10})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}, - Member{"integer", Value{}}}}}, - Member{2, - Object{std::tuple{Member{"double", Value{}}, - Member{"string", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().parser<0>().isSet()); - ASSERT_FALSE(parser.parser().parser<1>().isSet()); - ASSERT_EQ(0, parser.parser().currentMemberId()); - - ASSERT_EQ(true, parser.parser().get<0>().get<0>()); - ASSERT_EQ(10, parser.parser().get<0>().get<1>()); - - buf = R"({"type": 2, "double": 11.5, "string": "value"})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - ASSERT_TRUE(parser.parser().parser<1>().isSet()); - ASSERT_EQ(1, parser.parser().currentMemberId()); - - ASSERT_EQ(11.5, parser.parser().get<1>().get<0>()); - ASSERT_EQ("value", parser.parser().get<1>().get<1>()); -} - -TEST(StandaloneUnion, StringType) { - std::string buf( - R"( -{ - "type": "1", - "bool": true -})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{"1", Object{std::tuple{Member{"bool", Value{}}}}}, - Member{"2", Object{std::tuple{Member{"int", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().parser<0>().isSet()); - ASSERT_FALSE(parser.parser().parser<1>().isSet()); - ASSERT_EQ(0, parser.parser().currentMemberId()); - - ASSERT_EQ(true, parser.parser().get<0>().get<0>()); - - buf = R"( -{ - "type": "2", - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_FALSE(parser.parser().parser<0>().isSet()); - ASSERT_TRUE(parser.parser().parser<1>().isSet()); - ASSERT_EQ(1, parser.parser().currentMemberId()); - - ASSERT_EQ(100, parser.parser().get<1>().get<0>()); -} - -TEST(StandaloneUnion, IncorrectTypeType) { - std::string buf( - R"( -{ - "type": "1", - "bool": true -})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Unexpected token string", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": "1", "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneUnion, IncorrectTypeValue) { - std::string buf( - R"( -{ - "type": 3, - "bool": true -})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Unexpected member 3", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 3, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneUnion, IncorrectTypeMember) { - std::string buf( - R"( -{ - "error": 1, - "bool": true -})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Unexpected member error", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "error": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneUnion, MembersWithCallbackError) { - std::string buf( - R"( -{ - "type": 1, - "bool": true -})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - auto boolCb = [&](decltype(parser)::ParserType::ParserType<0> &) { - return false; - }; - - auto intCb = [&](decltype(parser)::ParserType::ParserType<1> &) { - return false; - }; - - parser.parser().parser<0>().setFinishCallback(boolCb); - parser.parser().parser<1>().setFinishCallback(intCb); - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - "type": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 2, "int": 100 } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneUnion, UnionWithCallback) { - std::string buf( - R"( -{ - "type": 1, - "bool": true -})"); - - bool bool_value = false; - int64_t int_value; - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - auto unionCb = [&](decltype(parser)::ParserType &parser) { - if (parser.currentMemberId() == 0) { - bool_value = parser.get<0>().get<0>(); - } else { - int_value = parser.get<1>().get<0>(); - } - return true; - }; - - parser.parser().setFinishCallback(unionCb); - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(true, parser.parser().get<0>().get<0>()); - ASSERT_EQ(true, bool_value); - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(100, parser.parser().get<1>().get<0>()); - ASSERT_EQ(100, int_value); -} - -TEST(StandaloneUnion, UnionWithCallbackError) { - std::string buf(R"( -{ - "type": 1, - "bool": true -})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - auto unionCb = [&](decltype(parser)::ParserType &) { return false; }; - - parser.parser().setFinishCallback(unionCb); - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_TRUE(parser.parser().isSet()); - - ASSERT_EQ("Callback returned false", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - "type": 1, "bool": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneUnion, UnionWithUnexpectedObject) { - std::string buf( - R"( -{ - "type": 1, - "error": true -})"); - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - try { - parser.parse(buf); - FAIL() << "No exception thrown"; - } catch (ParsingError &e) { - ASSERT_FALSE(parser.parser().isSet()); - - ASSERT_EQ("Unexpected member error", e.sjparserError()); - ASSERT_EQ( - R"(parse error: client cancelled parse via callback return value - { "type": 1, "error": true } - (right here) ------^ -)", - e.parserError()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneUnion, RepeatingMembers) { - try { - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}}}}, - Member{1, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - FAIL() << "No exception thrown"; - } catch (std::runtime_error &e) { - ASSERT_STREQ("Member 1 appears more than once", e.what()); - } catch (...) { - FAIL() << "Invalid exception thrown"; - } -} - -TEST(StandaloneUnion, StandaloneUnionWithParserReference) { - std::string buf( - R"( -{ - "type": 1, - "bool": true, - "string": "value" -})"); - - SAutoObject sautoobject{std::tuple{Member{"bool", Value{}}, - Member{"string", Value{}}}}; - - Parser parser{Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, sautoobject}, - Member{2, Object{std::tuple{Member{"int", Value{}}}}}}}}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(true, std::get<0>(parser.parser().get<0>())); - ASSERT_EQ("value", std::get<1>(parser.parser().get<0>())); - - buf = R"( -{ - "type": 2, - "int": 100 -})"; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_EQ(100, parser.parser().get<1>().get<0>()); - - ASSERT_EQ(&(parser.parser().parser<0>()), &sautoobject); -} - -TEST(StandaloneUnion, MoveAssignment) { - std::string buf(R"({"type": 1, "bool": true, "integer": 10})"); - - auto union_parser_src = Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool", Value{}}, - Member{"integer", Value{}}}}}, - Member{2, - Object{std::tuple{Member{"double", Value{}}, - Member{"string", Value{}}}}}}}; - auto union_parser = Union{ - TypeHolder{}, "type", - std::tuple{ - Member{1, Object{std::tuple{Member{"bool_", Value{}}, - Member{"integer_", Value{}}}}}, - Member{2, - Object{std::tuple{Member{"double_", Value{}}, - Member{"string_", Value{}}}}}}}; - union_parser = std::move(union_parser_src); - - Parser parser{union_parser}; - - ASSERT_NO_THROW(parser.parse(buf)); - ASSERT_NO_THROW(parser.finish()); - - ASSERT_TRUE(parser.parser().parser<0>().isSet()); - ASSERT_FALSE(parser.parser().parser<1>().isSet()); - ASSERT_EQ(0, parser.parser().currentMemberId()); - - ASSERT_EQ(true, parser.parser().get<0>().get<0>()); - ASSERT_EQ(10, parser.parser().get<0>().get<1>()); -} diff --git a/contrib/sjparser/tests/src/test_parser.h b/contrib/sjparser/tests/src/test_parser.h index f8a0f163..f5c5008d 100644 --- a/contrib/sjparser/tests/src/test_parser.h +++ b/contrib/sjparser/tests/src/test_parser.h @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include "sjparser/sjparser.h" namespace SJParser { diff --git a/contrib/sjparser/tests/src/value.cpp b/contrib/sjparser/tests/src/value.cpp index a9fadacf..4bbe2016 100644 --- a/contrib/sjparser/tests/src/value.cpp +++ b/contrib/sjparser/tests/src/value.cpp @@ -22,7 +22,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include + #include "sjparser/sjparser.h" #include "test_parser.h" diff --git a/contrib/sjparser/tests/src/yajl_parser.cpp b/contrib/sjparser/tests/src/yajl_parser.cpp index 8b515890..4a3d7a20 100644 --- a/contrib/sjparser/tests/src/yajl_parser.cpp +++ b/contrib/sjparser/tests/src/yajl_parser.cpp @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *******************************************************************************/ #include + #include "sjparser/sjparser.h" using namespace SJParser;