Skip to content
This repository has been archived by the owner on Aug 25, 2018. It is now read-only.

Commit

Permalink
Add convert utilities to tests (copied from example/example_unicode_u…
Browse files Browse the repository at this point in the history
…til.h)

Add nanodbc::test namespace.
Move TestConfig to nanodbc::test::Config.
  • Loading branch information
mloskot committed Sep 18, 2017
1 parent 6aed347 commit 9816996
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 20 deletions.
2 changes: 2 additions & 0 deletions example/example_unicode_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#error Examples do not support the iODBC wide strings
#endif

// TODO: These convert utils need to be extracted to a private
// internal library to share with tests
#ifdef NANODBC_ENABLE_UNICODE
inline nanodbc::string convert(std::string const& in)
{
Expand Down
90 changes: 73 additions & 17 deletions test/base_test_fixture.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,90 @@
#include <sql.h>
#include <sqlext.h>

struct TestConfig
namespace nanodbc
{
nanodbc::string get_connection_string() const
{
namespace test
{

// TODO: These convert utils need to be extracted to a private
// internal library to share with tests
#ifdef NANODBC_ENABLE_UNICODE
#ifdef NANODBC_ENABLE_BOOST
using boost::locale::conv::utf_to_utf;
return utf_to_utf<char16_t>(
connection_string_.c_str(), connection_string_.c_str() + connection_string_.size());
// Workaround for confirmed bug in VS2015 and VS2017 too
// See: https://connect.microsoft.com/VisualStudio/Feedback/Details/1403302
inline nanodbc::string convert(std::string const& in)
{
static_assert(
sizeof(nanodbc::string::value_type) > 1,
"NANODBC_ENABLE_UNICODE mode requires wide string");
nanodbc::string out;
#if defined(__GNUC__) && __GNUC__ < 5
std::vector<wchar_t> characters(in.length());
for (size_t i = 0; i < in.length(); i++)
characters[i] = in[i];
const wchar_t* source = characters.data();
size_t size = wcsnrtombs(nullptr, &source, characters.size(), 0, nullptr);
if (size == std::string::npos)
throw std::range_error("UTF-16 -> UTF-8 conversion error");
out.resize(size);
wcsnrtombs(&out[0], &source, characters.size(), out.length(), nullptr);
#elif defined(_MSC_VER) && (_MSC_VER >= 1900)
auto s = std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t>().from_bytes(
connection_string_);
auto p = reinterpret_cast<char16_t const*>(s.data());
return nanodbc::string(p, p + s.size());
// Workaround for confirmed bug in VS2015 and VS2017 too
// See: https://connect.microsoft.com/VisualStudio/Feedback/Details/1403302
using wide_char_t = nanodbc::string::value_type;
auto s =
std::wstring_convert<std::codecvt_utf8_utf16<wide_char_t>, wide_char_t>().from_bytes(in);
auto p = reinterpret_cast<wide_char_t const*>(s.data());
out.assign(p, p + s.size());
#else
return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>().from_bytes(
connection_string_);
out = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>().from_bytes(in);
#endif
return out;
}

inline std::string convert(nanodbc::string const& in)
{
static_assert(sizeof(nanodbc::string::value_type) > 1, "string must be wide");
std::string out;
#if defined(__GNUC__) && __GNUC__ < 5
size_t size = mbsnrtowcs(nullptr, in.data(), in.length(), 0, nullptr);
if (size == std::string::npos)
throw std::range_error("UTF-8 -> UTF-16 conversion error");
std::vector<wchar_t> characters(size);
const char* source = in.data();
mbsnrtowcs(&characters[0], &source, in.length(), characters.size(), nullptr);
out.resize(size);
for (size_t i = 0; i < in.length(); i++)
out[i] = characters[i];
#elif defined(_MSC_VER) && (_MSC_VER >= 1900)
// Workaround for confirmed bug in VS2015 and VS2017 too
// See: https://connect.microsoft.com/VisualStudio/Feedback/Details/1403302
using wide_char_t = nanodbc::string::value_type;
std::wstring_convert<std::codecvt_utf8_utf16<wide_char_t>, wide_char_t> convert;
auto p = reinterpret_cast<const wide_char_t*>(in.data());
out = convert.to_bytes(p, p + in.size());
#else
return connection_string_;
out = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>().to_bytes(in);
#endif
return out;
}
#else
inline nanodbc::string convert(std::string const& in)
{
return in;
}
#endif

struct Config
{
nanodbc::string get_connection_string() const
{
return convert(connection_string_);
}

std::string connection_string_;
};
extern TestConfig cfg;

}} // namespace nanodbc::test

extern nanodbc::test::Config cfg;

struct base_test_fixture
{
Expand Down
6 changes: 3 additions & 3 deletions test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
#include "base_test_fixture.h" // Must be included last!
// clang-format on

TestConfig cfg;
nanodbc::test::Config cfg;

int main(int argc, char* argv[])
{
try
{
// Specify custom command line options
auto args = Clara::argsToVector(argc, argv);
Clara::CommandLine<TestConfig> cli;
Clara::CommandLine<nanodbc::test::Config> cli;
cli["-c"]["--connection-string"]
.describe("connection string to test database; if not specified, "
"an attempt will be made to read it from environment variables: "
"NANODBC_TEST_CONNSTR or NANODBC_TEST_CONNSTR_<DB>")
.bind(&TestConfig::connection_string_, "string");
.bind(&nanodbc::test::Config::connection_string_, "string");
cli.parseInto(args, cfg);

// Disable custom options to avoid Catch warnings or failures
Expand Down

0 comments on commit 9816996

Please sign in to comment.