// ----------------------------------------------------------------------
// File: parsing.cc
// Author: Georgios Bitzes - CERN
// ----------------------------------------------------------------------
/************************************************************************
* qclient - A simple redis C++ client with support for redirects *
* Copyright (C) 2019 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#include "qclient/ResponseParsing.hh"
#include "qclient/ResponseBuilder.hh"
#include
using namespace qclient;
TEST(ResponseParsing, StatusParserErr) {
redisReplyPtr reply = ResponseBuilder::makeStr("test test");
StatusParser parser(reply);
ASSERT_FALSE(parser.ok());
ASSERT_TRUE(parser.value().empty());
ASSERT_EQ(parser.err(), "Unexpected reply type; was expecting STATUS, received \"test test\"");
StatusParser parser2(reply.get());
ASSERT_FALSE(parser2.ok());
ASSERT_TRUE(parser2.value().empty());
ASSERT_EQ(parser2.err(), "Unexpected reply type; was expecting STATUS, received \"test test\"");
}
TEST(ResponseParsing, StatusParser) {
redisReplyPtr reply = ResponseBuilder::makeStatus("some status");
StatusParser parser(reply);
ASSERT_TRUE(parser.ok());
ASSERT_TRUE(parser.err().empty());
ASSERT_EQ(parser.value(), "some status");
}
TEST(ResponseParsing, IntegerParserErr) {
redisReplyPtr reply = ResponseBuilder::makeStatus("aaa");
IntegerParser parser(reply);
ASSERT_FALSE(parser.ok());
ASSERT_EQ(parser.err(), "Unexpected reply type; was expecting INTEGER, received aaa");
}
TEST(ResponseParsing, IntegerParser) {
redisReplyPtr reply = ResponseBuilder::makeInt(13);
IntegerParser parser(reply);
ASSERT_TRUE(parser.ok());
ASSERT_EQ(parser.value(), 13);
}
TEST(ResponseParsing, StringParser) {
redisReplyPtr reply = ResponseBuilder::makeStr("turtles");
StringParser parser(reply);
ASSERT_TRUE(parser.ok());
ASSERT_TRUE(parser.err().empty());
ASSERT_EQ(parser.value(), "turtles");
}
TEST(ResponseParsing, StringParserErr) {
redisReplyPtr reply = ResponseBuilder::makeInt(13);
StringParser parser(reply);
ASSERT_FALSE(parser.ok());
ASSERT_EQ(parser.err(), "Unexpected reply type; was expecting STRING, received (integer) 13");
}
TEST(ResponseParsing, HgetallParserNull) {
HgetallParser parser(nullptr);
ASSERT_FALSE(parser.ok());
ASSERT_EQ(parser.err(), "Received null redisReply");
}
TEST(ResponseParsing, HgetallParserErrInt) {
HgetallParser parser(ResponseBuilder::makeInt(13));
ASSERT_FALSE(parser.ok());
ASSERT_EQ(parser.err(), "Unexpected reply type; was expecting ARRAY, received (integer) 13");
}
TEST(ResponseParsing, HgetallParserErrOddElements) {
std::vector vec = { "1", "2", "3" };
HgetallParser parser(ResponseBuilder::makeStringArray(vec));
ASSERT_FALSE(parser.ok());
ASSERT_EQ(parser.err(), "Unexpected number of elements; expected a multiple of 2, received 3");
}
TEST(ResponseParsing, HgetallParserErrBadTypesInArray) {
ResponseBuilder builder;
builder.feed("*2\r\n$1\r\na\r\n+3\r\n");
redisReplyPtr reply;
ASSERT_EQ(ResponseBuilder::Status::kOk, builder.pull(reply));
HgetallParser parser(reply);
ASSERT_FALSE(parser.ok());
ASSERT_EQ(parser.err(), "Unexpected reply type for element #1: Unexpected reply type; was expecting STRING, received 3");
}
TEST(ResponseParsing, HgetallParserEmpty) {
std::vector emptyVec;
HgetallParser parser(ResponseBuilder::makeStringArray(emptyVec));
ASSERT_TRUE(parser.ok());
ASSERT_TRUE(parser.err().empty());
ASSERT_TRUE(parser.value().empty());
}
TEST(ResponseParsing, HgetallDuplicate) {
std::vector vec = { "1", "2", "1", "4" };
HgetallParser parser(ResponseBuilder::makeStringArray(vec));
ASSERT_FALSE(parser.ok());
ASSERT_EQ(parser.err(), "Found duplicate key: '1'");
}
TEST(ResponseParsing, Hgetall) {
std::vector vec = { "1", "2", "3", "4" };
HgetallParser parser(ResponseBuilder::makeStringArray(vec));
ASSERT_TRUE(parser.ok());
ASSERT_TRUE(parser.err().empty());
std::map val = parser.value();
ASSERT_EQ(val.size(), 2u);
ASSERT_EQ(val["1"], "2");
ASSERT_EQ(val["3"], "4");
}