Skip to content

Commit

Permalink
Make sure iterator_input_adapter advances iterators correctly
Browse files Browse the repository at this point in the history
When parsing a string containing two JSON values using iterators, after
parsing, iterator_input_adapter should have advanced to the first
character of the second value.
Add a unit test to check that this is true.
  • Loading branch information
falbrechtskirchinger committed Jun 20, 2022
1 parent 87cda1d commit 3458089
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions tests/src/unit-deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ SOFTWARE.
using nlohmann::json;

#include <iostream>
#include <iterator>
#include <sstream>
#include <valarray>

Expand Down Expand Up @@ -184,6 +185,52 @@ struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
return false;
}
};

template <typename T>
class proxy_iterator
{
public:
using iterator = typename T::iterator;
using value_type = typename std::iterator_traits<iterator>::value_type;
using reference = typename std::iterator_traits<iterator>::reference;
using pointer = typename std::iterator_traits<iterator>::pointer;
using difference_type =
typename std::iterator_traits<iterator>::difference_type;
using iterator_category = std::input_iterator_tag;

proxy_iterator() = default;
explicit proxy_iterator(iterator& it) : m_it(std::addressof(it)) {}

proxy_iterator& operator++()
{
++*m_it;
return *this;
}

proxy_iterator& operator--()
{
--*m_it;
return *this;
}

bool operator==(const proxy_iterator& rhs) const
{
return (m_it && rhs.m_it) ? (*m_it == *rhs.m_it) : (m_it == rhs.m_it);
}

bool operator!=(const proxy_iterator& rhs) const
{
return !(*this == rhs);
}

reference operator*() const
{
return **m_it;
}

private:
iterator* m_it = nullptr;
};
} // namespace

TEST_CASE("deserialization")
Expand Down Expand Up @@ -538,6 +585,28 @@ TEST_CASE("deserialization")
CHECK(l.events.size() == 1);
CHECK(l.events == std::vector<std::string>({"parse_error(1)"}));
}

SECTION("iterator_input_adapter advances iterators correctly")
{
using nlohmann::json;
using nlohmann::detail::input_format_t;
using nlohmann::detail::json_sax_dom_parser;
using proxy = proxy_iterator<std::string>;

std::string str1 = "[1]";
std::string str2 = "[2]";
std::string str = str1 + str2;

auto first = str.begin();
auto last = str.end();
json j;
json_sax_dom_parser<json> sax(j, true);

CHECK(json::sax_parse(proxy(first), proxy(last), &sax,
input_format_t::json, false));
CHECK(j.dump() == str1);
CHECK(std::string(first, last) == str2);
}
}

// these cases are required for 100% line coverage
Expand Down

0 comments on commit 3458089

Please sign in to comment.