BIND 10 trac2375, updated. 07f579f28c3c3810ddef3cc94af16590075016f1 [2375] Tests for simple versions of getToken
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Nov 13 13:40:52 UTC 2012
The branch, trac2375 has been updated
via 07f579f28c3c3810ddef3cc94af16590075016f1 (commit)
from 9dbf3b1de0f8897483b2ee17ee113a3e8b95b3cc (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 07f579f28c3c3810ddef3cc94af16590075016f1
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Tue Nov 13 14:39:15 2012 +0100
[2375] Tests for simple versions of getToken
No fancy stuff yet, like ungetting tokens, changes of parentheses count,
etc. Just the basic stuff.
-----------------------------------------------------------------------
Summary of changes:
src/lib/dns/master_lexer.cc | 6 ++
src/lib/dns/master_lexer.h | 8 ++
src/lib/dns/tests/master_lexer_unittest.cc | 130 +++++++++++++++++++++++++++-
3 files changed, 143 insertions(+), 1 deletion(-)
-----------------------------------------------------------------------
diff --git a/src/lib/dns/master_lexer.cc b/src/lib/dns/master_lexer.cc
index e99485a..af653ff 100644
--- a/src/lib/dns/master_lexer.cc
+++ b/src/lib/dns/master_lexer.cc
@@ -134,6 +134,12 @@ MasterLexer::ungetToken() {
// TODO
}
+const State*
+MasterLexer::start() {
+ // TODO
+ return (NULL);
+}
+
namespace {
const char* const error_text[] = {
"lexer not started", // NOT_STARTED
diff --git a/src/lib/dns/master_lexer.h b/src/lib/dns/master_lexer.h
index 31b9f8e..c5f88d5 100644
--- a/src/lib/dns/master_lexer.h
+++ b/src/lib/dns/master_lexer.h
@@ -186,6 +186,14 @@ public:
/// getNextToken() was not called since the last change of the source.
void ungetToken();
+protected:
+ /// \brief Call the State::start()
+ ///
+ /// This calls the State::start() method and returns the result. It is
+ /// a virtual method so tests can override it to mock some different
+ /// behaviour.
+ virtual const master_lexer_internal::State* start();
+
private:
struct MasterLexerImpl;
MasterLexerImpl* impl_;
diff --git a/src/lib/dns/tests/master_lexer_unittest.cc b/src/lib/dns/tests/master_lexer_unittest.cc
index c91639e..16ac3ef 100644
--- a/src/lib/dns/tests/master_lexer_unittest.cc
+++ b/src/lib/dns/tests/master_lexer_unittest.cc
@@ -21,6 +21,7 @@
#include <boost/lexical_cast.hpp>
#include <boost/function.hpp>
+#include <boost/scoped_ptr.hpp>
#include <string>
#include <sstream>
@@ -29,16 +30,48 @@ using namespace isc::dns;
using std::string;
using std::stringstream;
using boost::lexical_cast;
+using boost::scoped_ptr;
+using master_lexer_internal::State;
namespace {
+// This acts like the normal MasterLexer. It, however, allows to mock the start()
+// method to return some given state instead of the auto-detected ones.
+class TestedMasterLexer : public MasterLexer {
+public:
+ TestedMasterLexer() :
+ fake_start_(NULL)
+ {}
+ // During the next call to start(), return the given state instead of the
+ // auto-detected one.
+ void pushFakeStart(const State* state) {
+ fake_start_ = state;
+ }
+protected:
+ virtual const State* start() {
+ if (fake_start_ != NULL) {
+ // There's a fake start, so remove it (not to be used next time)
+ // and return it.
+ const State* result = fake_start_;
+ fake_start_ = NULL;
+ return (result);
+ } else {
+ // No fake start ready. So we act the usual way, by delegating it to
+ // the parent class.
+ return (MasterLexer::start());
+ }
+ }
+private:
+ const State* fake_start_;
+};
+
class MasterLexerTest : public ::testing::Test {
protected:
MasterLexerTest() :
expected_stream_name("stream-" + lexical_cast<string>(&ss))
{}
- MasterLexer lexer;
+ TestedMasterLexer lexer;
stringstream ss;
const string expected_stream_name;
};
@@ -126,4 +159,99 @@ TEST_F(MasterLexerTest, invalidClose) {
EXPECT_THROW(lexer.popSource(), isc::InvalidOperation);
}
+// Test it is not possible to get token when no source is available.
+TEST_F(MasterLexerTest, noSource) {
+ EXPECT_THROW(lexer.getNextToken(), isc::InvalidOperation);
+}
+
+// Getting a token directly from the start() method.
+TEST_F(MasterLexerTest, tokenFromStart) {
+ // A class that sets the token directly in start() and returns no
+ // state. This is equivalent to the State::start() doing so.
+ class StartLexer : public MasterLexer {
+ public:
+ StartLexer() :
+ token_(MasterLexer::Token::END_OF_LINE)
+ {}
+ virtual const State* start() {
+ // We don't have access directly inside the implementation.
+ // We get the fake state, run it to install the token.
+ // Then we just delete it ourself and return NULL.
+ State* state(State::getFakeState(NULL, 0, &token_));
+ state->handle(*this);
+ delete state;
+ return (NULL);
+ }
+ private:
+ MasterLexer::Token token_;
+ } lexer;
+ lexer.pushSource(ss);
+
+ // The token gets out.
+ MasterLexer::Token generated(lexer.getNextToken());
+ EXPECT_EQ(MasterLexer::Token::END_OF_LINE, generated.getType());
+}
+
+// Getting a token with a single iteration through the states.
+TEST_F(MasterLexerTest, simpleGetToken) {
+ // Prepare the fake state.
+ MasterLexer::Token token(MasterLexer::Token::END_OF_LINE);
+ scoped_ptr<State> state(State::getFakeState(NULL, 3, &token));
+ lexer.pushFakeStart(state.get());
+ // Push some source inside.
+ ss << "12345";
+ lexer.pushSource(ss);
+
+ // Get the token.
+ MasterLexer::Token generated(lexer.getNextToken());
+ // It is the same token (well, on a different address)
+ // We can't compare directly, so compare types.
+ EXPECT_EQ(token.getType(), generated.getType());
+ // 3 characters were read from the source.
+ // We test by extracting the rest and comparing.
+ int rest;
+ ss >> rest;
+ EXPECT_EQ(rest, 45);
+}
+
+// A token that takes multiple states.
+//
+// The first state sets the token as well as the second. The second one should
+// survive and be returned.
+TEST_F(MasterLexerTest, chainGetToken) {
+ // Build the states
+ MasterLexer::Token t1(MasterLexer::Token::END_OF_LINE);
+ MasterLexer::Token t2(MasterLexer::Token::INITIAL_WS);
+ scoped_ptr<State> s2(State::getFakeState(NULL, 1, &t2));
+ scoped_ptr<State> s1(State::getFakeState(s2.get(), 2, &t1));
+ // Put something into the source
+ ss << "12345";
+ lexer.pushSource(ss);
+
+ // Get the token.
+ MasterLexer::Token generated(lexer.getNextToken());
+ // It is the same token as the second one (well, on a different address)
+ // We can't compare directly, so compare types.
+ EXPECT_EQ(t2.getType(), generated.getType());
+ // 3 characters were read from the source.
+ // We test by extracting the rest and comparing.
+ int rest;
+ ss >> rest;
+ EXPECT_EQ(rest, 45);
+}
+
+// Test getting a token without overriding the start() method (well, it
+// is overriden, but no fake state is set, so it refers to the real one).
+//
+// This also tests the real start() passes the options, otherwise we wouldn't
+// get the initial whitespace.
+TEST_F(MasterLexerTest, realStart) {
+ ss << " \n42";
+ lexer.pushSource(ss);
+
+ // The correct one gets out.
+ MasterLexer::Token generated(lexer.getNextToken());
+ EXPECT_EQ(MasterLexer::Token::INITIAL_WS, generated.getType());
+}
+
}
More information about the bind10-changes
mailing list