From 4aa36151f548659aa0a3e331448f7e7c986a987d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 1 Dec 2017 01:15:10 +0000 Subject: Split the parser tests away from the connection tests and introduce a better helper --- libdbpp/unittests/Jamfile.jam | 14 +++++- libdbpp/unittests/testConnection.cpp | 60 ----------------------- libdbpp/unittests/testParse.cpp | 95 ++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 61 deletions(-) create mode 100644 libdbpp/unittests/testParse.cpp diff --git a/libdbpp/unittests/Jamfile.jam b/libdbpp/unittests/Jamfile.jam index f43c909..d0500f0 100644 --- a/libdbpp/unittests/Jamfile.jam +++ b/libdbpp/unittests/Jamfile.jam @@ -17,6 +17,18 @@ run ..//adhocutil boost_utf dbpp-local-postgresql + : + testConnection + ; + +run + testParse.cpp ../sqlParse.ll + : : : + ROOT=\"$(me)\" + BOOST_TEST_DYN_LINK + ..//dbppcore + ..//adhocutil + boost_utf parseTest.sql unterminatedComment.sql unterminatedString.sql @@ -25,7 +37,7 @@ run scriptDir.sql stringParse.sql : - testConnection + testParse ; alias libpq : : : : diff --git a/libdbpp/unittests/testConnection.cpp b/libdbpp/unittests/testConnection.cpp index 066b4ad..e738511 100644 --- a/libdbpp/unittests/testConnection.cpp +++ b/libdbpp/unittests/testConnection.cpp @@ -29,66 +29,6 @@ BOOST_AUTO_TEST_CASE( resolve ) BOOST_REQUIRE_THROW(DB::ConnectionFactory::createNew("otherdb", "doesn't matter"), AdHoc::LoadLibraryException); } -BOOST_AUTO_TEST_CASE( parseBad ) -{ - auto mock = DB::ConnectionFactory::createNew("MockDb", "doesn't matter"); - std::fstream s("/bad"); - BOOST_REQUIRE_THROW(mock->executeScript(s, rootDir), DB::SqlParseException); - delete mock; -} - -BOOST_AUTO_TEST_CASE( parse ) -{ - auto mock = DB::ConnectionFactory::createNew("MockDb", "doesn't matter"); - std::fstream s((rootDir / "parseTest.sql").string()); - mock->executeScript(s, rootDir); - MockDb * mockdb = dynamic_cast(mock); - BOOST_REQUIRE(mockdb); - BOOST_REQUIRE_EQUAL(3, mockdb->executed.size()); - BOOST_REQUIRE_EQUAL("INSERT INTO name(t, i) VALUES('string', 3)", mockdb->executed[1]); - delete mock; -} - -BOOST_AUTO_TEST_CASE( parse2 ) -{ - auto mock = DB::ConnectionPtr(DB::ConnectionFactory::createNew("MockDb", "doesn't matter")); - auto mockdb = boost::dynamic_pointer_cast(mock); - BOOST_REQUIRE(mockdb); - std::ifstream s; - - s.open((rootDir / "dollarQuote.sql").string()); - mock->executeScript(s, rootDir); - s.close(); - - s.open((rootDir / "scriptDir.sql").string()); - mock->executeScript(s, rootDir); - s.close(); - - s.open((rootDir / "stringParse.sql").string()); - mock->executeScript(s, rootDir); - s.close(); - BOOST_REQUIRE_EQUAL(4, mockdb->executed.size()); - BOOST_REQUIRE_EQUAL("INSERT INTO name(t, i) VALUES('fancy string '' \\' \\r \\n', 7)", mockdb->executed[3]); - - BOOST_REQUIRE_THROW({ - s.open((rootDir / "unterminatedComment.sql").string()); - mock->executeScript(s, rootDir); - }, DB::SqlParseException); - s.close(); - - BOOST_REQUIRE_THROW({ - s.open((rootDir / "unterminatedDollarQuote.sql").string()); - mock->executeScript(s, rootDir); - }, DB::SqlParseException); - s.close(); - - BOOST_REQUIRE_THROW({ - s.open((rootDir / "unterminatedString.sql").string()); - mock->executeScript(s, rootDir); - }, DB::SqlParseException); - s.close(); -} - BOOST_AUTO_TEST_CASE( finish ) { auto mock = DB::ConnectionFactory::createNew("MockDb", "doesn't matter"); diff --git a/libdbpp/unittests/testParse.cpp b/libdbpp/unittests/testParse.cpp new file mode 100644 index 0000000..1272f9b --- /dev/null +++ b/libdbpp/unittests/testParse.cpp @@ -0,0 +1,95 @@ +#define BOOST_TEST_MODULE DbConnection +#include + +#include +#include +#include +#include +#include +#include +#include + +typedef std::vector SQLs; +BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE(SQLs); + +class RecordingParser : std::fstream, public DB::SqlParse { + public: + RecordingParser(const boost::filesystem::path & p) : + std::fstream(p.string()), + DB::SqlParse(*this, p.parent_path()) + { + } + + void Comment(const std::string & c) const + { + comments.push_back(c); + } + + void Statement(const std::string & s) const + { + executed.push_back(s); + } + + mutable SQLs comments; + mutable SQLs executed; +}; + +template +void assertFail(const boost::filesystem::path & p) +{ + BOOST_TEST_CONTEXT(p) { + BOOST_REQUIRE_THROW({ + RecordingParser s(p); + s.Execute(); + }, E); + } +} + +BOOST_AUTO_TEST_CASE( parseBad ) +{ + assertFail("/bad"); +} + +BOOST_AUTO_TEST_CASE( parse ) +{ + RecordingParser p(rootDir / "parseTest.sql"); + p.Execute(); + BOOST_REQUIRE_EQUAL(p.executed.size(), 3); + BOOST_REQUIRE_EQUAL(p.executed[1], "INSERT INTO name(t, i) VALUES('string', 3)"); +} + +BOOST_AUTO_TEST_CASE( parseDollarQuote ) +{ + RecordingParser p(rootDir / "dollarQuote.sql"); + p.Execute(); +} + +BOOST_AUTO_TEST_CASE( parseScriptDir ) +{ + RecordingParser p(rootDir / "scriptDir.sql"); + p.Execute(); +} + +BOOST_AUTO_TEST_CASE( parseStringParse ) +{ + RecordingParser p(rootDir / "stringParse.sql"); + p.Execute(); + BOOST_REQUIRE_EQUAL(2, p.executed.size()); + BOOST_REQUIRE_EQUAL("INSERT INTO name(t, i) VALUES('fancy string '' \\' \\r \\n', 7)", p.executed[1]); +} + +BOOST_AUTO_TEST_CASE( parseUnterminateComment ) +{ + assertFail(rootDir / "unterminatedComment.sql"); +} + +BOOST_AUTO_TEST_CASE( parseUnterminateDollarQuote ) +{ + assertFail(rootDir / "unterminatedDollarQuote.sql"); +} + +BOOST_AUTO_TEST_CASE( parseUnterminateString ) +{ + assertFail(rootDir / "unterminatedString.sql"); +} + -- cgit v1.2.3