summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-12-08 16:12:01 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-12-08 16:12:01 +0100
commite7f97a4c8da44a696bb7e71b9dd54e8d271e24d0 (patch)
treea9b58f48cb4c1fd0114a3cb27b755633fe47fc6f /test
parent79903130b6240347743f191bb9b8d670524a300e (diff)
added more unit test for the new BufferClass, fixed a few bugs (merely inefficiencies -- no major problems found so far)
Diffstat (limited to 'test')
-rw-r--r--test/core/utils/CharReaderTest.cpp211
1 files changed, 211 insertions, 0 deletions
diff --git a/test/core/utils/CharReaderTest.cpp b/test/core/utils/CharReaderTest.cpp
index ef022a9..260b135 100644
--- a/test/core/utils/CharReaderTest.cpp
+++ b/test/core/utils/CharReaderTest.cpp
@@ -16,6 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <sstream>
#include <string>
#include <iostream>
@@ -40,6 +41,9 @@ TEST(Buffer, simpleRead)
// We're not at the end of the stream
ASSERT_FALSE(buf.atEnd(cursor));
+ // The cursor must be at zero
+ ASSERT_EQ(0, buf.offset(cursor));
+
// Try to read the test string
std::string res;
while (buf.read(cursor, c)) {
@@ -49,10 +53,30 @@ TEST(Buffer, simpleRead)
// The cursor must be at the end
ASSERT_TRUE(buf.atEnd(cursor));
+ // The cursor must be one byond the last byte
+ ASSERT_EQ(testStr.size(), buf.offset(cursor));
+
// The two strings must equal
ASSERT_STREQ(testStr.c_str(), res.c_str());
}
+TEST(Buffer, cursorManagement)
+{
+ Buffer buf{""};
+
+ Buffer::CursorId c1 = buf.createCursor();
+ Buffer::CursorId c2 = buf.createCursor();
+ Buffer::CursorId c3 = buf.createCursor();
+
+ ASSERT_EQ(0, c1);
+ ASSERT_EQ(1, c2);
+ ASSERT_EQ(2, c3);
+
+ buf.deleteCursor(c2);
+ Buffer::CursorId c4 = buf.createCursor();
+ ASSERT_EQ(1, c4);
+}
+
TEST(Buffer, twoCursors)
{
std::string testStr{"this is a test"};
@@ -93,6 +117,193 @@ TEST(Buffer, twoCursors)
ASSERT_EQ(testStr, res2);
}
+TEST(Buffer, copyCursors)
+{
+ std::string testStr{"test1 test2 test3"};
+
+ // Create buffer with the test string
+ char c;
+ Buffer buf{testStr};
+
+ // Create two read cursors
+ Buffer::CursorId cur1 = buf.createCursor();
+ Buffer::CursorId cur2 = buf.createCursor();
+
+ ASSERT_FALSE(buf.atEnd(cur1));
+ ASSERT_FALSE(buf.atEnd(cur2));
+
+ // Read the first six characters with cursor one
+ std::string res1;
+ for (int i = 0; i < 6; i++) {
+ if (buf.read(cur1, c)) {
+ res1.append(&c, 1);
+ }
+ }
+ ASSERT_EQ("test1 ", res1);
+ ASSERT_FALSE(buf.atEnd(cur1));
+
+ // Copy cur1 to cur2, free cur1
+ buf.copyCursor(cur1, cur2);
+ buf.deleteCursor(cur1);
+
+ std::string res2;
+ for (int i = 0; i < 6; i++) {
+ if (buf.read(cur2, c)) {
+ res2.append(&c, 1);
+ }
+ }
+ ASSERT_EQ("test2 ", res2);
+ ASSERT_FALSE(buf.atEnd(cur2));
+
+ // Create a new cursor as copy of cur2
+ Buffer::CursorId cur3 = buf.createCursor(cur2);
+ std::string res3;
+ for (int i = 0; i < 6; i++) {
+ if (buf.read(cur3, c)) {
+ res3.append(&c, 1);
+ }
+ }
+ ASSERT_EQ("test3", res3);
+
+ ASSERT_TRUE(buf.atEnd(cur3));
+}
+
+// Generates some pseudo-random data
+// (inspired by "Numerical Recipes, Third Edition", Chapter 7.17)
+static std::vector<char> generateData(size_t len)
+{
+ const uint32_t B1 = 17;
+ const uint32_t B2 = 15;
+ const uint32_t B3 = 5;
+ uint32_t v = 0xF3A99148;
+ std::vector<char> res;
+ for (size_t i = 0; i < len; i++) {
+ v = v ^ (v >> B1);
+ v = v ^ (v << B2);
+ v = v ^ (v >> B3);
+ res.push_back(v & 0xFF);
+ }
+ return res;
+}
+
+struct VectorReadState {
+ size_t offs;
+ const std::vector<char> &data;
+
+ VectorReadState(const std::vector<char> &data) : offs(0), data(data) {}
+};
+
+static size_t readFromVector(char *buf, size_t size, void *userData)
+{
+ VectorReadState &state = *(static_cast<VectorReadState *>(userData));
+ size_t tar = std::min(state.offs + size, state.data.size());
+ for (size_t i = state.offs; i < tar; i++) {
+ *buf = state.data[i];
+ buf++;
+ }
+ size_t res = tar - state.offs;
+
+// std::cout << "called readFromVector, read from " << state.offs << " to "
+// << tar << ", total " << res << " byte, requested " << size
+// << " byte" << std::endl;
+
+ state.offs = tar;
+ return res;
+}
+
+static constexpr size_t DATA_LENGTH = 256 * 1024 + 795;
+static const std::vector<char> DATA = generateData(DATA_LENGTH);
+
+TEST(Buffer, simpleStream)
+{
+ VectorReadState state(DATA);
+
+ Buffer buf{readFromVector, &state};
+ Buffer::CursorId cursor = buf.createCursor();
+
+ char c;
+ std::vector<char> res;
+ while (buf.read(cursor, c)) {
+ res.push_back(c);
+ }
+
+ // We must be at the end of the buffer and the cursor offset must be set
+ // correctly
+ ASSERT_TRUE(buf.atEnd(cursor));
+ ASSERT_EQ(DATA_LENGTH, buf.offset(cursor));
+
+ // The read data and the original data must be equal
+ ASSERT_EQ(DATA, res);
+}
+
+TEST(Buffer, streamTwoCursors)
+{
+ VectorReadState state(DATA);
+
+ Buffer buf{readFromVector, &state};
+ Buffer::CursorId cur1 = buf.createCursor();
+ Buffer::CursorId cur2 = buf.createCursor();
+
+ char c;
+
+ std::vector<char> res1;
+ while (buf.read(cur1, c)) {
+ res1.push_back(c);
+ }
+
+ ASSERT_TRUE(buf.atEnd(cur1));
+ ASSERT_FALSE(buf.atEnd(cur2));
+ ASSERT_EQ(DATA_LENGTH, buf.offset(cur1));
+ ASSERT_EQ(0, buf.offset(cur2));
+
+ std::vector<char> res2;
+ while (buf.read(cur2, c)) {
+ res2.push_back(c);
+ }
+
+ ASSERT_TRUE(buf.atEnd(cur1));
+ ASSERT_TRUE(buf.atEnd(cur2));
+ ASSERT_EQ(DATA_LENGTH, buf.offset(cur1));
+ ASSERT_EQ(DATA_LENGTH, buf.offset(cur2));
+
+ // The read data and the original data must be equal
+ ASSERT_EQ(DATA, res1);
+ ASSERT_EQ(DATA, res2);
+}
+
+TEST(Buffer, streamTwoCursorsInterleaved)
+{
+ VectorReadState state(DATA);
+
+ Buffer buf{readFromVector, &state};
+ Buffer::CursorId cur1 = buf.createCursor();
+ Buffer::CursorId cur2 = buf.createCursor();
+
+ char c;
+
+ std::vector<char> res1;
+ std::vector<char> res2;
+ while (!buf.atEnd(cur1) || !buf.atEnd(cur2)) {
+ for (int i = 0; i < 100; i++) {
+ if (buf.read(cur1, c)) {
+ res1.push_back(c);
+ }
+ }
+ for (int i = 0; i < 120; i++) {
+ if (buf.read(cur2, c)) {
+ res2.push_back(c);
+ }
+ }
+ }
+
+ ASSERT_EQ(DATA_LENGTH, buf.offset(cur1));
+ ASSERT_EQ(DATA_LENGTH, buf.offset(cur2));
+
+ // The read data and the original data must be equal
+ ASSERT_EQ(DATA, res1);
+ ASSERT_EQ(DATA, res2);
+}
+
}
}