From 1b64f05c43826ea01bb70079975542390fde273f Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Thu, 6 Sep 2018 21:52:19 +0200 Subject: [PATCH] [DEV] URI is ready --- etk/fs/Path.cpp | 4 + etk/fs/Path.hpp | 4 + etk/uri/Querry.cpp | 41 -------- etk/uri/Query.cpp | 150 +++++++++++++++++++++++++++ etk/uri/{Querry.hpp => Query.hpp} | 28 +++-- etk/uri/Uri.cpp | 104 +++++++++++++------ etk/uri/Uri.hpp | 40 ++------ lutin_etest.py | 2 +- lutin_etk-test.py | 2 + lutin_etk.py | 7 +- test/testQuery.cpp | 16 +++ test/testUri.cpp | 165 ++++++++++++++++++++++++++++++ 12 files changed, 453 insertions(+), 110 deletions(-) delete mode 100644 etk/uri/Querry.cpp create mode 100644 etk/uri/Query.cpp rename etk/uri/{Querry.hpp => Query.hpp} (68%) create mode 100644 test/testQuery.cpp create mode 100644 test/testUri.cpp diff --git a/etk/fs/Path.cpp b/etk/fs/Path.cpp index 650e33a..e82dc9c 100644 --- a/etk/fs/Path.cpp +++ b/etk/fs/Path.cpp @@ -307,6 +307,10 @@ etk::Path etk::Path::getParent() const { return out; } +void etk::Path::clear() { + m_data.clear(); +} + bool etk::Path::operator== (const etk::Path& _obj) const { return m_data == _obj.m_data; } diff --git a/etk/fs/Path.hpp b/etk/fs/Path.hpp index 979c4c1..a84e36d 100644 --- a/etk/fs/Path.hpp +++ b/etk/fs/Path.hpp @@ -121,6 +121,10 @@ namespace etk { * @return Parent path. */ etk::Path getParent() const; + /** + * @brief Clear data. + */ + void clear(); /** * @brief Check if the 2 Path are identical. * @param[in] _obj Path to compare. diff --git a/etk/uri/Querry.cpp b/etk/uri/Querry.cpp deleted file mode 100644 index 219a610..0000000 --- a/etk/uri/Querry.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/** @file - * @author Edouard DUPIN - * @copyright 2018, Edouard DUPIN, all right reserved - * @license MPL v2.0 (see license file) - */ -#pragma once - -#include - -etk::uri::Query::Querry() { - -} - -etk::uri::Query::Querry(const etk::String& _value) { - -} - -void etk::uri::Query::setEncoded(const etk::String& _value) { - -} - -etk::String etk::uri::Query::getEncoded() const { - return ""; -} - -void etk::uri::Query::set(const etk::String& _key, const etk::String& _value) { - -} - -bool etk::uri::Query::exist(const etk::String& _key) { - return false; -} - -void etk::uri::Query::erase(const etk::String& _key) { - -} - -etk::String etk::uri::Query::get(const etk::String& _key) { - return ""; -} - diff --git a/etk/uri/Query.cpp b/etk/uri/Query.cpp new file mode 100644 index 0000000..bb01048 --- /dev/null +++ b/etk/uri/Query.cpp @@ -0,0 +1,150 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ +#include +#include + +static const etk::String hexData = "0123456789ABCDEF"; + +static etk::String pourcentEncode(const etk::String& _data) { + etk::String out; + for (auto &it : _data) { + if ( (it >= 'a' && it <= 'z') + || (it >= 'A' && it <= 'Z') + || (it >= '0' && it <= '9') + || it == '-' + || it == '_' + || it == '.' + || it == '~') { + out += it; + } else { + out += "%"; + out += hexData[(uint32_t(it)>>4)&0x0F]; + out += hexData[uint32_t(it)&0x0F]; + } + } + return out; +} + +static int32_t convertStringHexToInt(const char _value) { + if (_value >= 'a' && _value <= 'z') { + return int32_t(_value) - int32_t('a') + 10; + } + if (_value >= 'A' && _value <= 'Z') { + return int32_t(_value) - int32_t('A') + 10; + } + if (_value >= '0' && _value <= '9') { + return int32_t(_value) - int32_t('0'); + } + TK_ERROR("Not a hexadecimal Value: '" << _value << "'"); + return 0; +} + +static etk::String pourcentDecode(const etk::String& _data) { + etk::String out; + for (size_t iii=0; iii<_data.size(); ++iii) { + auto it = _data[iii]; + if (it == '%') { + if (iii+2 < _data.size()) { + auto val1 = convertStringHexToInt(_data[iii+1])<<4; + val1 += convertStringHexToInt(_data[iii+2]); + out += char(val1); + iii += 2; + } else { + TK_ERROR("can not convert pourcent ==> input size error: '" << _data << "'"); + return out; + } + } else { + out += it; + } + } + return out; +} + +etk::uri::Query::Query() { + +} + +etk::uri::Query::Query(const etk::String& _value) { + setEncoded(_value); +} + +void etk::uri::Query::setEncoded(const etk::String& _value) { + m_data.clear(); + auto listElements = etk::split(_value, '&'); + for (auto &it : listElements) { + if (it.size() == 0) { + continue; + } + auto offset = it.find('='); + if (offset == etk::String::npos) { + m_data.set(pourcentDecode(it), ""); + continue; + } + m_data.set(pourcentDecode(it.extract(0, offset)), + pourcentDecode(it.extract(offset+1, etk::String::npos))); + } +} + +etk::String etk::uri::Query::getEncoded() const { + etk::String out; + for (auto &it: m_data) { + if (out.empty() == false) { + out += "&"; + } + out += pourcentEncode(it.first); + if (it.second.empty() == false) { + out += "="; + out += pourcentEncode(it.second); + } + } + return out; +} + +etk::String etk::uri::Query::getNotEncoded() const { + etk::String out; + for (auto &it: m_data) { + if (out.empty() == false) { + out += "&"; + } + out += it.first; + if (it.second.empty() == false) { + out += "="; + out += it.second; + } + } + return out; +} + +void etk::uri::Query::set(const etk::String& _key, const etk::String& _value) { + m_data.set(_key, _value); +} + +bool etk::uri::Query::exist(const etk::String& _key) { + return m_data.exist(_key); +} + +void etk::uri::Query::erase(const etk::String& _key) { + m_data.erase(_key); +} + +etk::String etk::uri::Query::get(const etk::String& _key) { + return m_data[_key]; +} + +void etk::uri::Query::clear() { + m_data.clear(); +} + +etk::Stream& etk::operator <<(etk::Stream& _os, const etk::uri::Query& _obj) { + _os << "Query{"; + _os << _obj.getNotEncoded(); + _os << "}"; + return _os; +} + +bool etk::uri::Query::isEmpty() const { + return m_data.size() == 0; +} \ No newline at end of file diff --git a/etk/uri/Querry.hpp b/etk/uri/Query.hpp similarity index 68% rename from etk/uri/Querry.hpp rename to etk/uri/Query.hpp index 29376a1..635e3c7 100644 --- a/etk/uri/Querry.hpp +++ b/etk/uri/Query.hpp @@ -13,23 +13,23 @@ namespace etk { namespace uri { /** - * @brief Querry Interface management. + * @brief query Interface management. */ class Query { private: - etk::Map m_query; //!< Querry data + etk::Map m_data; //!< query data public: ETK_CONSTRUCTOR_MOVE_DEFAULT(Query); ETK_CONSTRUCTOR_COPY_DEFAULT(Query); /** * @brief Default contructor. */ - Querry(); + Query(); /** - * @brief Set with a specific querry string - * @param[in] _value querry data + * @brief Set with a specific query string + * @param[in] _value query data */ - Querry(const etk::String& _value); + Query(const etk::String& _value); /** * @brief Set the encoded query. * @param[in] _value encoded data. @@ -40,6 +40,11 @@ namespace etk { * @return encoded data. */ etk::String getEncoded() const; + /** + * @brief Get the Not encoded query (for debug only). + * @return encoded data. + */ + etk::String getNotEncoded() const; /** * @brief Set an element of the query. * @param[in] _key Key of the query. @@ -64,7 +69,18 @@ namespace etk { * @return associated data. */ etk::String get(const etk::String& _key); + /** + * @brief clear data + */ + void clear(); + /** + * @brief check if the querry is empty + * @return true The querry have no data. false Otherwise + */ + bool isEmpty() const; }; } + //! @not_in_doc + etk::Stream& operator <<(etk::Stream& _os, const etk::uri::Query& _obj); } diff --git a/etk/uri/Uri.cpp b/etk/uri/Uri.cpp index d6e8448..766c259 100644 --- a/etk/uri/Uri.cpp +++ b/etk/uri/Uri.cpp @@ -3,34 +3,10 @@ * @copyright 2018, Edouard DUPIN, all right reserved * @license MPL v2.0 (see license file) */ -#pragma once -#include -#include -#include -#include +#include +#include -namespace etk { - /** - * @brief Uniform resource interface manage internal resource and nerwork resource (like URL) - * Format is manage like : __SCHEME__://__USER__:__PASSWORD__@__SERVER__:__PORT__/__PATH__?__QUERY__#__FRAGMENT__ - */ - class Uri { - private: - etk::String m_scheme; //!< Sheme of the uri. - etk::String m_user; //!< user name - etk::String m_password; //!< password (crypted/hashed) - etk::String m_server; //!< server name - uint16_t m_port; //!< Port of the server - etk::Path m_path; //!< Path data - etk::uri::Query m_query; //!< querry interface - etk::String m_fragment; //!< fragment data - public: - ETK_CONSTRUCTOR_MOVE_DEFAULT(Uri); - ETK_CONSTRUCTOR_COPY_DEFAULT(Uri); - /** - * @brief Default contructor. - */ etk::Uri::Uri() { } @@ -43,14 +19,79 @@ etk::Uri::Uri(const char * _value) { set(_value); } -void etk::Uri::set(const etk::String& _value) { - -} - void etk::Uri::set(const char * _value) { set(etk::String(_value)); } +void etk::Uri::clear() { + m_scheme.clear(); + m_user.clear(); + m_password.clear(); + m_server.clear(); + m_port = 0; + m_path.clear(); + m_query.clear(); + m_fragment.clear(); +} + +void etk::Uri::set(etk::String _value) { + TK_VERBOSE("parse: '" << _value << "'"); + size_t pos = _value.find("://"); + if (pos != etk::String::npos) { + // find scheme + m_scheme = _value.extract(0, pos); + _value = _value.extract(pos+3, etk::String::npos); + TK_VERBOSE("find scheme : '" << m_scheme << "' ==||== '" << _value << "'"); + } + pos = _value.rfind('#'); + if (pos != etk::String::npos) { + // find scheme + m_fragment = _value.extract(pos+1, etk::String::npos); + _value = _value.extract(0, pos); + TK_VERBOSE("find fragment: '" << m_fragment << "' ==||== '" << _value << "'"); + } + pos = _value.rfind('?'); + if (pos != etk::String::npos) { + // find query + m_query.setEncoded(_value.extract(pos+1, etk::String::npos)); + _value = _value.extract(0, pos); + TK_VERBOSE("find query: '" << m_query << "' ==||== '" << _value << "'"); + } + pos = _value.find('/'); + if (pos != etk::String::npos) { + // find path + m_path = _value.extract(pos+1, etk::String::npos); + _value = _value.extract(0, pos); + TK_VERBOSE("find scheme : '" << m_path << "' ==||== '" << _value << "'"); + } + pos = _value.find('@'); + if (pos != etk::String::npos) { + TK_VERBOSE("find server With name"); + // find server with user + etk::String userInfo = _value.extract(0, pos); + size_t pos_2 = userInfo.find(':'); + if (pos_2 != etk::String::npos) { + // find password: + m_user = userInfo.extract(0, pos_2); + m_password = userInfo.extract(pos_2+1, etk::String::npos); + } else { + m_user=userInfo; + m_password=""; + } + _value = _value.extract(pos+1, etk::String::npos); + TK_VERBOSE("find user / pass : '" << m_user << "' / '" << m_password << "' ==||== '" << _value << "'"); + } + pos = _value.find(':'); + if (pos != etk::String::npos) { + m_server = _value.extract(0, pos); + m_port = string_to_uint16_t(_value.extract(pos+1, etk::String::npos)); + } else { + m_server = _value; + m_port = 0; + } + TK_VERBOSE("find server / port : '" << m_server << "' / '" << m_port << "'"); +} + etk::String etk::Uri::get() { etk::String out; if (m_scheme != "") { @@ -76,7 +117,7 @@ etk::String etk::Uri::get() { out += "/"; out += m_path.getString(); } - if(m_query.size() != 0) { + if(m_query.isEmpty() == false) { out += "?"; out += m_query.getEncoded(); } @@ -84,6 +125,7 @@ etk::String etk::Uri::get() { out += "#"; out += m_fragment; } + return out; } const etk::String& etk::Uri::getScheme() const { diff --git a/etk/uri/Uri.hpp b/etk/uri/Uri.hpp index 4a7700b..9341668 100644 --- a/etk/uri/Uri.hpp +++ b/etk/uri/Uri.hpp @@ -9,32 +9,10 @@ #include #include #include +#include +#include namespace etk { - - class Query { - private: - etk::Map m_query; //!< Querry data - public: - ETK_CONSTRUCTOR_MOVE_DEFAULT(Query); - ETK_CONSTRUCTOR_COPY_DEFAULT(Query); - /** - * @brief Default contructor. - */ - Querry(); - /** - * @brief Set with a specific querry string - * @param[in] _value querry data - */ - Querry(const etk::String& _value); - - void setEncoded(const etk::String& _value); - etk::String getEncoded() const; - - void set(const etk::String& _key, const etk::String& _value); - bool exist(const etk::String& _key); - etk::String get(const etk::String& _key); - }; /** * @brief Uniform resource interface manage internal resource and nerwork resource (like URL) * Format is manage like : __SCHEME__://__USER__:__PASSWORD__@__SERVER__:__PORT__/__PATH__?__QUERY__#__FRAGMENT__ @@ -47,7 +25,7 @@ namespace etk { etk::String m_server; //!< server name uint16_t m_port = 0; //!< Port of the server etk::Path m_path; //!< Path data - etk::uri::Query m_query; //!< querry interface + etk::uri::Query m_query; //!< query interface etk::String m_fragment; //!< fragment data public: ETK_CONSTRUCTOR_MOVE_DEFAULT(Uri); @@ -70,7 +48,7 @@ namespace etk { * @brief Contructor with basic URI. * @param[in] _value Element basic URI */ - void set(const etk::String& _value); + void set(etk::String _value); /** * @brief Contructor with basic URI. * @param[in] _value Element basic URI @@ -142,12 +120,12 @@ namespace etk { */ void setPath(const etk::Path& _value); /** - * @brief Get the Querry. - * @return Querry data. + * @brief Get the query. + * @return query data. */ const etk::uri::Query& getQuery() const; /** - * @brief Set the new querry. + * @brief Set the new query. * @param[in] _value Data. */ void setQuery(const etk::uri::Query& _value); @@ -161,6 +139,10 @@ namespace etk { * @param[in] _value New fragment */ void setFragment(const etk::String& _value); + /** + * @brief Clear the structure. + */ + void clear(); }; } diff --git a/lutin_etest.py b/lutin_etest.py index 97ca42b..c78ddbe 100644 --- a/lutin_etest.py +++ b/lutin_etest.py @@ -41,7 +41,7 @@ def configure(target, my_module): my_module.compile_version("c++", 2017) # add dependency of the generic C++ library: my_module.add_depend([ - 'etk-base', + 'etk-core', 'echrono', 'elog', 'cxx' diff --git a/lutin_etk-test.py b/lutin_etk-test.py index 773fdcc..312c506 100644 --- a/lutin_etk-test.py +++ b/lutin_etk-test.py @@ -31,6 +31,8 @@ def configure(target, my_module): 'test/testPath.cpp', 'test/testPermissions.cpp', 'test/testTheme.cpp', + 'test/testUri.cpp', + 'test/testQuery.cpp', ]) """ 'test/ConstructDestruct.cpp', diff --git a/lutin_etk.py b/lutin_etk.py index a989592..d20caaf 100644 --- a/lutin_etk.py +++ b/lutin_etk.py @@ -57,12 +57,13 @@ def configure(target, my_module): 'etk/os/FSNodeRight.cpp', 'etk/archive/Archive.cpp', 'etk/archive/Zip.cpp', + 'etk/uri/Uri.cpp', + 'etk/uri/Query.cpp', ]) my_module.add_header_file([ 'etk/etk.hpp', 'etk/debug.hpp', - 'etk/stdTools.hpp', 'etk/tool.hpp', 'etk/Noise.hpp', 'etk/Color.hpp', @@ -93,6 +94,8 @@ def configure(target, my_module): 'etk/archive/Zip.hpp', 'etk/TreeNode.hpp', 'etk/FlatTree.hpp', + 'etk/uri/Uri.hpp', + 'etk/uri/Query.hpp', ]) # build in C++ mode @@ -103,7 +106,7 @@ def configure(target, my_module): 'm', 'elog', 'ememory', - 'etk-base', + 'etk-core', ]) # TODO: Remove this ==> when ready to remove dependency with stl: my_module.add_depend(['cxx']) diff --git a/test/testQuery.cpp b/test/testQuery.cpp new file mode 100644 index 0000000..8b6dc4e --- /dev/null +++ b/test/testQuery.cpp @@ -0,0 +1,16 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license MPL v2.0 (see license file) + */ + +#include +#include +#include + +TEST(TestQuery, defaultContructor) { + etk::uri::Query query; + EXPECT_EQ(query.getEncoded(), ""); +} \ No newline at end of file diff --git a/test/testUri.cpp b/test/testUri.cpp new file mode 100644 index 0000000..e15c8b9 --- /dev/null +++ b/test/testUri.cpp @@ -0,0 +1,165 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license MPL v2.0 (see license file) + */ + +#include +#include +#include + +TEST(TestUri, defaultContructor) { + etk::Uri uri; + EXPECT_EQ(uri.get(), ""); + EXPECT_EQ(uri.getScheme(), ""); + EXPECT_EQ(uri.getUser(), ""); + EXPECT_EQ(uri.getPassword(), ""); + EXPECT_EQ(uri.getServer(), ""); + EXPECT_EQ(uri.getPort(), 0); + EXPECT_EQ(uri.getPath(), etk::Path("")); + EXPECT_EQ(uri.getQuery().getEncoded(), ""); + EXPECT_EQ(uri.getFragment(), ""); +} + +TEST(TestUri, base_1) { + etk::String value = "__SCHEME__://__USER__:__PASSWORD__@__SERVER__:1234/__PATH__?__QUERY__#__FRAGMENT__"; + etk::Uri uri(value); + EXPECT_EQ(uri.get(), value); + EXPECT_EQ(uri.getScheme(), "__SCHEME__"); + EXPECT_EQ(uri.getUser(), "__USER__"); + EXPECT_EQ(uri.getPassword(), "__PASSWORD__"); + EXPECT_EQ(uri.getServer(), "__SERVER__"); + EXPECT_EQ(uri.getPort(), 1234); + EXPECT_EQ(uri.getPath(), etk::Path("__PATH__")); + EXPECT_EQ(uri.getQuery().getEncoded(), "__QUERY__"); + EXPECT_EQ(uri.getFragment(), "__FRAGMENT__"); +} + +TEST(TestUri, base_2) { + etk::String value = "__SCHEME__://__USER__@__SERVER__:1234/__PATH__?__QUERY__#__FRAGMENT__"; + etk::Uri uri(value); + EXPECT_EQ(uri.get(), value); + EXPECT_EQ(uri.getScheme(), "__SCHEME__"); + EXPECT_EQ(uri.getUser(), "__USER__"); + EXPECT_EQ(uri.getPassword(), ""); + EXPECT_EQ(uri.getServer(), "__SERVER__"); + EXPECT_EQ(uri.getPort(), 1234); + EXPECT_EQ(uri.getPath(), etk::Path("__PATH__")); + EXPECT_EQ(uri.getQuery().getEncoded(), "__QUERY__"); + EXPECT_EQ(uri.getFragment(), "__FRAGMENT__"); +} + +TEST(TestUri, base_3) { + etk::String value = "__SCHEME__://__SERVER__:1234/__PATH__?__QUERY__#__FRAGMENT__"; + etk::Uri uri(value); + EXPECT_EQ(uri.get(), value); + EXPECT_EQ(uri.getScheme(), "__SCHEME__"); + EXPECT_EQ(uri.getUser(), ""); + EXPECT_EQ(uri.getPassword(), ""); + EXPECT_EQ(uri.getServer(), "__SERVER__"); + EXPECT_EQ(uri.getPort(), 1234); + EXPECT_EQ(uri.getPath(), etk::Path("__PATH__")); + EXPECT_EQ(uri.getQuery().getEncoded(), "__QUERY__"); + EXPECT_EQ(uri.getFragment(), "__FRAGMENT__"); +} + +TEST(TestUri, base_4) { + etk::String value = "__SERVER__:1234/__PATH__?__QUERY__#__FRAGMENT__"; + etk::Uri uri(value); + EXPECT_EQ(uri.get(), value); + EXPECT_EQ(uri.getScheme(), ""); + EXPECT_EQ(uri.getUser(), ""); + EXPECT_EQ(uri.getPassword(), ""); + EXPECT_EQ(uri.getServer(), "__SERVER__"); + EXPECT_EQ(uri.getPort(), 1234); + EXPECT_EQ(uri.getPath(), etk::Path("__PATH__")); + EXPECT_EQ(uri.getQuery().getEncoded(), "__QUERY__"); + EXPECT_EQ(uri.getFragment(), "__FRAGMENT__"); +} + +TEST(TestUri, base_5) { + etk::String value = "__SERVER__/__PATH__?__QUERY__#__FRAGMENT__"; + etk::Uri uri(value); + EXPECT_EQ(uri.get(), value); + EXPECT_EQ(uri.getScheme(), ""); + EXPECT_EQ(uri.getUser(), ""); + EXPECT_EQ(uri.getPassword(), ""); + EXPECT_EQ(uri.getServer(), "__SERVER__"); + EXPECT_EQ(uri.getPort(), 0); + EXPECT_EQ(uri.getPath(), etk::Path("__PATH__")); + EXPECT_EQ(uri.getQuery().getEncoded(), "__QUERY__"); + EXPECT_EQ(uri.getFragment(), "__FRAGMENT__"); +} + +TEST(TestUri, base_6) { + etk::String value = "__SERVER__/__PATH__?__QUERY__"; + etk::Uri uri(value); + EXPECT_EQ(uri.get(), value); + EXPECT_EQ(uri.getScheme(), ""); + EXPECT_EQ(uri.getUser(), ""); + EXPECT_EQ(uri.getPassword(), ""); + EXPECT_EQ(uri.getServer(), "__SERVER__"); + EXPECT_EQ(uri.getPort(), 0); + EXPECT_EQ(uri.getPath(), etk::Path("__PATH__")); + EXPECT_EQ(uri.getQuery().getEncoded(), "__QUERY__"); + EXPECT_EQ(uri.getFragment(), ""); +} + +TEST(TestUri, base_7) { + etk::String value = "__SERVER__/__PATH__"; + etk::Uri uri(value); + EXPECT_EQ(uri.get(), value); + EXPECT_EQ(uri.getScheme(), ""); + EXPECT_EQ(uri.getUser(), ""); + EXPECT_EQ(uri.getPassword(), ""); + EXPECT_EQ(uri.getServer(), "__SERVER__"); + EXPECT_EQ(uri.getPort(), 0); + EXPECT_EQ(uri.getPath(), etk::Path("__PATH__")); + EXPECT_EQ(uri.getQuery().getEncoded(), ""); + EXPECT_EQ(uri.getFragment(), ""); +} + +TEST(TestUri, base_8) { + etk::String value = "__SERVER__"; + etk::Uri uri(value); + EXPECT_EQ(uri.get(), value); + EXPECT_EQ(uri.getScheme(), ""); + EXPECT_EQ(uri.getUser(), ""); + EXPECT_EQ(uri.getPassword(), ""); + EXPECT_EQ(uri.getServer(), "__SERVER__"); + EXPECT_EQ(uri.getPort(), 0); + EXPECT_EQ(uri.getPath(), etk::Path("")); + EXPECT_EQ(uri.getQuery().getEncoded(), ""); + EXPECT_EQ(uri.getFragment(), ""); +} + + +TEST(TestUri, base_9) { + etk::String value = "__SERVER__:1234"; + etk::Uri uri(value); + EXPECT_EQ(uri.get(), value); + EXPECT_EQ(uri.getScheme(), ""); + EXPECT_EQ(uri.getUser(), ""); + EXPECT_EQ(uri.getPassword(), ""); + EXPECT_EQ(uri.getServer(), "__SERVER__"); + EXPECT_EQ(uri.getPort(), 1234); + EXPECT_EQ(uri.getPath(), etk::Path("")); + EXPECT_EQ(uri.getQuery().getEncoded(), ""); + EXPECT_EQ(uri.getFragment(), ""); +} + +TEST(TestUri, base_10) { + etk::String value = "__SCHEME__:///__PATH__?__QUERY__"; + etk::Uri uri(value); + EXPECT_EQ(uri.get(), value); + EXPECT_EQ(uri.getScheme(), "__SCHEME__"); + EXPECT_EQ(uri.getUser(), ""); + EXPECT_EQ(uri.getPassword(), ""); + EXPECT_EQ(uri.getServer(), ""); + EXPECT_EQ(uri.getPort(), 0); + EXPECT_EQ(uri.getPath(), etk::Path("__PATH__")); + EXPECT_EQ(uri.getQuery().getEncoded(), "__QUERY__"); + EXPECT_EQ(uri.getFragment(), ""); +}