i need help understanding what i am missing in the logic for my json utility method that is returning an array of elements. I am not that familiar with rapidjson and can only add debug prints in my code. So my json.h file looks like below
template <>
std::vector<std::string> fetchStringArray<std::vector<std::string>>(const rapidjson::Value& value){
std::cout<<"Entern";
std::vector<std::string> elements;
if (!value.IsArray()) {
std::cout<<"Early Exitn";
return elements;
}
for (auto& item : value.GetArray()) {
if (item.IsString()) {
elements.push_back(item.GetString());
}
}
std::cout<<"Successn";
return elements;
}
template <>
vector<string> fetchStringArray<vector<string>>(const string& jsonString, const string& key){
std::cout<<"2n";
rapidjson::Document document;
std::cout <<"JsonString "<<jsonString<<"n";
document.Parse(jsonString);
if(document.HasMember("key")){
std::cout <<"key found "<<"n";
}
if (document.HasParseError()) {
return std::vector<string>();
}
return fetchStringArray<vector<string>>(document);
}
template <class CollectionT>
CollectionT fetchStringArray(const string& jsonString, const string& key) {
std::cout<<"4n";
auto values = fetchStringArray<std::vector<std::string>>(jsonString, key);
return CollectionT{values.begin(), values.end()};
}
The jsontests.cpp test file looks like below
/// test fixture.
class JsonTests : public ::testing::Test {};
/**
* Test fetchStringArray
*/
TEST_F(JsonTests, test_fetchStringArray) {
char key[] = "key";
auto entries = fetchStringArray<std::set<std::string>>(R"({"key":["ONE","TWO"]})", key);
ASSERT_EQ(entries.size(), 2u);
EXPECT_NE(entries.find("ONE"), entries.end());
EXPECT_NE(entries.find("TWO"), entries.end());
}
But when i run the test i get thE FOLLOWING OUTPUT
4
2
JsonString {"key":["ONE","TWO"]}
key found
Enter
Early Exit
/Foo/test/JsonTestS.cpp:23: Failure
Expected: entries.size()
Which is: 0
To be equal to: 2u
Which is: 2
[ FAILED ] JsonTests.test_fetchStringArray (0 ms)
Any help or pointers will be greatly appreciated.
2
To fix the issue, you need to extract the rapidjson::Value associated with the key from the document and pass that to the function fetchStringArray.
Here’s how you can modify your code:
template <>
std::vector<std::string> fetchStringArray<std::vector<std::string>>(const rapidjson::Value& value) {
std::cout << "Entern";
std::vector<std::string> elements;
if (!value.IsArray()) {
std::cout << "Early Exitn";
return elements;
}
for (auto& item : value.GetArray()) {
if (item.IsString()) {
elements.push_back(item.GetString());
}
}
std::cout << "Successn";
return elements;
}
template <>
std::vector<std::string> fetchStringArray<std::vector<std::string>>(const std::string& jsonString, const std::string& key) {
std::cout << "2n";
rapidjson::Document document;
std::cout << "JsonString " << jsonString << "n";
document.Parse(jsonString.c_str());
if (document.HasParseError()) {
return std::vector<std::string>();
}
if (document.HasMember(key.c_str())) { // Use c_str() to convert std::string to const char*
std::cout << "key foundn";
const rapidjson::Value& value = document[key.c_str()];
return fetchStringArray<std::vector<std::string>>(value); // Pass the value associated with the key
}
return std::vector<std::string>(); // If the key is not found, return an empty vector
}
template <class CollectionT>
CollectionT fetchStringArray(const std::string& jsonString, const std::string& key) {
std::cout << "4n";
auto values = fetchStringArray<std::vector<std::string>>(jsonString, key);
return CollectionT{values.begin(), values.end()};
}
Науменко Михайло Вікторович is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.